6.4.8-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainercover 6.4.8-rc1 review
This is the start of the stable review cycle for the 6.4.8 release. There are 239 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.4.8-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.4.8-rc1
Dan Carpenter <[email protected]>
dma-buf: fix an error pointer vs NULL bug
Christian König <[email protected]>
dma-buf: keep the signaling time of merged fences v3
Jann Horn <[email protected]>
mm/mempolicy: Take VMA lock before replacing policy
Sidhartha Kumar <[email protected]>
mm/memory-failure: fix hardware poison check in unpoison_memory()
Jann Horn <[email protected]>
mm: fix memory ordering for mm_lock_seq and vm_lock_seq
Jann Horn <[email protected]>
mm: lock VMA in dup_anon_vma() before setting ->anon_vma
Ilya Dryomov <[email protected]>
rbd: retrieve and check lock owner twice before blocklisting
Ilya Dryomov <[email protected]>
rbd: harden get_lock_owner_info() a bit
Ilya Dryomov <[email protected]>
rbd: make get_lock_owner_info() return a single locker or NULL
Joe Thornber <[email protected]>
dm cache policy smq: ensure IO doesn't prevent cleaner policy progress
Radhakrishna Sripada <[email protected]>
drm/i915/dpt: Use shmem for dpt objects
Xiubo Li <[email protected]>
ceph: never send metrics if disable_send_metrics is set
Ahmad Fatoum <[email protected]>
thermal: of: fix double-free on unregistration
Johan Hovold <[email protected]>
PM: sleep: wakeirq: fix wake irq arming
Mark Brown <[email protected]>
arm64/sme: Set new vector length before reallocating
Mark Brown <[email protected]>
ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register
Paolo Abeni <[email protected]>
mptcp: more accurate NL event generation
Stefan Haberland <[email protected]>
s390/dasd: print copy pair message only for the correct error
Stefan Haberland <[email protected]>
s390/dasd: fix hanging device after quiesce/resume
Eric Van Hensbergen <[email protected]>
fs/9p: remove unnecessary invalidate_inode_pages2
Eric Van Hensbergen <[email protected]>
fs/9p: fix type mismatch in file cache mode helper
Eric Van Hensbergen <[email protected]>
fs/9p: fix typo in comparison logic for cache mode
Eric Van Hensbergen <[email protected]>
fs/9p: remove unnecessary and overrestrictive check
Dominique Martinet <[email protected]>
9p: fix ignored return value in v9fs_dir_release
Chenguang Zhao <[email protected]>
LoongArch: BPF: Enable bpf_probe_read{, str}() on LoongArch
Tiezhu Yang <[email protected]>
LoongArch: BPF: Fix check condition to call lu32id in move_imm()
WANG Rui <[email protected]>
LoongArch: Fix return value underflow in exception path
Andy Shevchenko <[email protected]>
Revert "um: Use swap() to make code cleaner"
Johan Hovold <[email protected]>
soundwire: fix enumeration completion
Matthieu Baerts <[email protected]>
selftests: mptcp: join: only check for ip6tables if needed
Sean Christopherson <[email protected]>
selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
Jason Gunthorpe <[email protected]>
iommufd: Set end correctly when doing batch carry
Jens Axboe <[email protected]>
io_uring: gate iowait schedule on having pending requests
Christian Marangi <[email protected]>
net: dsa: qca8k: fix mdb add/del case with 0 VID
Christian Marangi <[email protected]>
net: dsa: qca8k: fix broken search_and_del
Christian Marangi <[email protected]>
net: dsa: qca8k: fix search_and_insert wrong handling of new rule
Christian Marangi <[email protected]>
net: dsa: qca8k: enable use_single_write for qca8xxx
Alex Elder <[email protected]>
net: ipa: only reset hashed tables when supported
Jason Wang <[email protected]>
virtio-net: fix race between set queues and probe
Demi Marie Obenour <[email protected]>
xen: speed up grant-table reclaim
Dan Carpenter <[email protected]>
proc/vmcore: fix signedness bug in read_from_oldmem()
Peter Zijlstra <[email protected]>
locking/rtmutex: Fix task->pi_waiters integrity
Marc Zyngier <[email protected]>
irqchip/gic-v4.1: Properly lock VPEs when doing a directLPI invalidation
Jonas Gorski <[email protected]>
irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
Alexander Steffen <[email protected]>
tpm_tis: Explicitly check for error code
Guanghui Feng <[email protected]>
ACPI/IORT: Remove erroneous id_count check in iort_node_get_rmr_info()
Namjae Jeon <[email protected]>
ksmbd: check if a mount point is crossed during path lookup
Trond Myklebust <[email protected]>
nfsd: Remove incorrect check in nfsd4_validate_stateid
Christian Brauner <[email protected]>
file: always lock position for FMODE_ATOMIC_POS
Kim Phillips <[email protected]>
x86/cpu: Enable STIBP on AMD if Automatic IBRS is enabled
Yazen Ghannam <[email protected]>
x86/MCE/AMD: Decrement threshold_bank refcount when removing threshold blocks
Filipe Manana <[email protected]>
btrfs: check for commit error at btrfs_attach_transaction_barrier()
Filipe Manana <[email protected]>
btrfs: check if the transaction was aborted at btrfs_wait_for_commit()
Filipe Manana <[email protected]>
btrfs: account block group tree when calculating global reserve size
Naohiro Aota <[email protected]>
btrfs: zoned: do not enable async discard
Guenter Roeck <[email protected]>
hwmon: (pmbus_core) Fix Deadlock in pmbus_regulator_get_status
Patrick Rudolph <[email protected]>
hwmon: (pmbus_core) Fix NULL pointer dereference
Patrick Rudolph <[email protected]>
hwmon: (pmbus_core) Fix pmbus_is_enabled()
Aleksa Savic <[email protected]>
hwmon: (aquacomputer_d5next) Fix incorrect PWM value readout
Gilles Buloz <[email protected]>
hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
Baskaran Kannan <[email protected]>
hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature
Luka Guzenko <[email protected]>
ALSA: hda/relatek: Enable Mute LED on HP 250 G8
Pavel Asyutchenko <[email protected]>
ALSA: hda/realtek: Support ASUS G713PV laptop
Oliver Neukum <[email protected]>
Revert "xhci: add quirk for host controllers that don't update endpoint DCS"
Chaoyuan Peng <[email protected]>
tty: n_gsm: fix UAF in gsm_cleanup_mux
Zhang Shurong <[email protected]>
staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext()
Larry Finger <[email protected]>
staging: r8712: Fix memory leak in _r8712_init_xmit_priv()
Greg Kroah-Hartman <[email protected]>
Documentation: security-bugs.rst: clarify CVE handling
Greg Kroah-Hartman <[email protected]>
Documentation: security-bugs.rst: update preferences when dealing with the linux-distros group
Dan Carpenter <[email protected]>
Revert "usb: xhci: tegra: Fix error check"
Ricardo Ribalda <[email protected]>
usb: xhci-mtk: set the dma max_seg_size
Frank Li <[email protected]>
usb: cdns3: fix incorrect calculation of ep_buf_size when more than one config
Łukasz Bartosik <[email protected]>
USB: quirks: add quirk for Focusrite Scarlett
Guiting Shen <[email protected]>
usb: ohci-at91: Fix the unhandle interrupt when resume
Xu Yang <[email protected]>
usb: misc: ehset: fix wrong if condition
Jisheng Zhang <[email protected]>
usb: dwc3: don't reset device side if dwc3 was configured as host-only
Gratian Crisan <[email protected]>
usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy
Jakub Vanek <[email protected]>
Revert "usb: dwc3: core: Enable AutoRetry feature in the controller"
Kyle Tso <[email protected]>
usb: typec: Use sysfs_emit_at when concatenating the string
Kyle Tso <[email protected]>
usb: typec: Iterate pds array when showing the pd list
Kyle Tso <[email protected]>
usb: typec: Set port->pd before adding device for typec_port
Samuel Thibault <[email protected]>
TIOCSTI: always enable for CAP_SYS_ADMIN
Marc Kleine-Budde <[email protected]>
can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED
Johan Hovold <[email protected]>
USB: serial: simple: sort driver entries
Oliver Neukum <[email protected]>
USB: serial: simple: add Kaufmann RKS+CAN VCP
Mohsen Tahmasebi <[email protected]>
USB: serial: option: add Quectel EC200A module support
Jerry Meng <[email protected]>
USB: serial: option: support Quectel EM060K_128
Samuel Holland <[email protected]>
serial: sifive: Fix sifive_serial_console_setup() section
Ruihong Luo <[email protected]>
serial: 8250_dw: Preserve original value of DLF register
Biju Das <[email protected]>
tty: serial: sh-sci: Fix sleeping in atomic context
Johan Hovold <[email protected]>
serial: qcom-geni: drop bogus runtime pm state update
Sean Christopherson <[email protected]>
KVM: x86: Disallow KVM_SET_SREGS{2} if incoming CR0 is invalid
Sean Christopherson <[email protected]>
KVM: VMX: Don't fudge CR0 and CR4 for restricted L2 guest
Sean Christopherson <[email protected]>
KVM: Grab a reference to KVM for VM and vCPU stats file descriptors
Michael Grzeschik <[email protected]>
usb: gadget: core: remove unbalanced mutex_unlock in usb_gadget_activate
Zqiang <[email protected]>
USB: gadget: Fix the memory leak in raw_gadget driver
Frank Li <[email protected]>
usb: gadget: call usb_gadget_check_config() to verify UDC capability
Dan Carpenter <[email protected]>
Revert "usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()"
Zheng Yejian <[email protected]>
tracing: Fix warning in trace_buffered_event_disable()
Zheng Yejian <[email protected]>
ring-buffer: Fix wrong stat of cpu_buffer->read
Arnd Bergmann <[email protected]>
ata: pata_ns87415: mark ns87560_tf_read static
Hugh Dickins <[email protected]>
tmpfs: fix Documentation of noswap and huge mount options
Jason Gunthorpe <[email protected]>
iommufd: IOMMUFD_DESTROY should not increase the refcount
Ming Lei <[email protected]>
ublk: return -EINTR if breaking from waiting for existed users in DEL_DEV
Ming Lei <[email protected]>
ublk: fail to recover device if queue setup is interrupted
Ming Lei <[email protected]>
ublk: fail to start device if queue setup is interrupted
Rob Clark <[email protected]>
drm/msm: Disallow submit with fence id 0
Sindhu Devale <[email protected]>
RDMA/irdma: Report correct WC error
Sindhu Devale <[email protected]>
RDMA/irdma: Fix op_type reporting in CQEs
Dan Carpenter <[email protected]>
drm/amd/display: Unlock on error path in dm_handle_mst_sideband_msg_ready_event()
Mario Limonciello <[email protected]>
drm/amd: Fix an error handling mistake in psp_sw_init()
Yu Kuai <[email protected]>
dm raid: protect md_stop() with 'reconfig_mutex'
Yu Kuai <[email protected]>
dm raid: clean up four equivalent goto tags in raid_ctr()
Yu Kuai <[email protected]>
dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
Stefano Stabellini <[email protected]>
xenbus: check xen_domain in xenbus_probe_initcall
Christophe JAILLET <[email protected]>
drm/i915: Fix an error handling path in igt_write_huge()
Steve French <[email protected]>
smb3: do not set NTLMSSP_VERSION flag for negotiate not auth request
Bart Van Assche <[email protected]>
block: Fix a source code comment in include/uapi/linux/blkzoned.h
Matus Gajdos <[email protected]>
ASoC: fsl_spdif: Silence output on stop
Breno Leitao <[email protected]>
cxl/acpi: Return 'rc' instead of '0' in cxl_parse_cfmws()
Breno Leitao <[email protected]>
cxl/acpi: Fix a use-after-free in cxl_parse_cfmws()
Rob Clark <[email protected]>
drm/msm: Fix hw_fence error path cleanup
Gaosheng Cui <[email protected]>
drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
Selvin Xavier <[email protected]>
RDMA/bnxt_re: Fix hang during driver unload
Kashyap Desai <[email protected]>
RDMA/bnxt_re: add helper function __poll_for_resp
Kashyap Desai <[email protected]>
RDMA/bnxt_re: Simplify the function that sends the FW commands
Kashyap Desai <[email protected]>
RDMA/bnxt_re: use shadow qd while posting non blocking rcfw command
Kashyap Desai <[email protected]>
RDMA/bnxt_re: Avoid the command wait if firmware is inactive
Kashyap Desai <[email protected]>
RDMA/bnxt_re: Enhance the existing functions that wait for FW responses
Kashyap Desai <[email protected]>
RDMA/bnxt_re: Prevent handling any completions after qp destroy
Thomas Bogendoerfer <[email protected]>
RDMA/mthca: Fix crash when polling CQ for shared QPs
Shiraz Saleem <[email protected]>
RDMA/core: Update CMA destination address on rdma_resolve_addr
Shiraz Saleem <[email protected]>
RDMA/irdma: Fix data race on CQP request done
Shiraz Saleem <[email protected]>
RDMA/irdma: Fix data race on CQP completion stats
Shiraz Saleem <[email protected]>
RDMA/irdma: Add missing read barriers
Rob Clark <[email protected]>
drm/msm/adreno: Fix snapshot BINDLESS_DATA size
Marijn Suijten <[email protected]>
drm/msm/dsi: Drop unused regulators from QCM2290 14nm DSI PHY config
Dmitry Baryshkov <[email protected]>
drm/msm/dpu: drop enum dpu_core_perf_data_bus_id
Jonathan Marek <[email protected]>
drm/msm/dpu: add missing flush and fetch bits for DMA4/DMA5 planes
Dmitry Baryshkov <[email protected]>
drm/msm/mdss: correct UBWC programming for SM8550
Dan Carpenter <[email protected]>
RDMA/mlx4: Make check for invalid flags stricter
Christophe JAILLET <[email protected]>
fs/9p: Fix a datatype used with V9FS_DIRECT_IO
Fedor Pchelkin <[email protected]>
tipc: stop tipc crypto on failure in tipc_node_create
Yuanjun Gong <[email protected]>
tipc: check return value of pskb_trim()
Yuanjun Gong <[email protected]>
benet: fix return value check in be_lancer_xmit_workarounds()
Lin Ma <[email protected]>
net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64
Wei Fang <[email protected]>
net: fec: tx processing does not call XDP APIs if budget is 0
Arkadiusz Kubalewski <[email protected]>
tools: ynl-gen: fix enum index in _decode_enum(..)
Linus Torvalds <[email protected]>
mm: suppress mm fault logging if fatal signal already pending
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: disallow rule addition to bound chain via NFTA_RULE_CHAIN_ID
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: skip immediate deactivate in _PREPARE_ERROR
Florian Westphal <[email protected]>
netfilter: nft_set_rbtree: fix overlap expiration walk
Muhammad Husaini Zulkifli <[email protected]>
igc: Fix Kernel Panic during ndo_tx_timeout callback
Lin Ma <[email protected]>
macvlan: add forgotten nla_policy for IFLA_MACVLAN_BC_CUTOFF
Kirill A. Shutemov <[email protected]>
x86/traps: Fix load_unaligned_zeropad() handling for shared TDX memory
Maxim Mikityanskiy <[email protected]>
platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100
Vincent Whitchurch <[email protected]>
net: stmmac: Apply redundant write work around on 4.xx too
Suman Ghosh <[email protected]>
octeontx2-af: Fix hash extraction enable configuration
Hangbin Liu <[email protected]>
team: reset team's flags when down link is P2P device
Hangbin Liu <[email protected]>
bonding: reset bond's flags when down link is P2P device
Jedrzej Jagielski <[email protected]>
ice: Fix memory management in ice_ethtool_fdir.c
Stewart Smith <[email protected]>
tcp: Reduce chance of collisions in inet6_hashfn().
Wei Fang <[email protected]>
net: fec: avoid tx queue timeout when XDP is enabled
Maciej Żenczykowski <[email protected]>
ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new temporary address
Yuanjun Gong <[email protected]>
ethernet: atheros: fix return value check in atl1e_tso_csum()
Yuanjun Gong <[email protected]>
atheros: fix return value check in atl1_tso()
Harshit Mogalapalli <[email protected]>
phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe()
Jiri Benc <[email protected]>
vxlan: fix GRO with VXLAN-GPE
Jiri Benc <[email protected]>
vxlan: generalize vxlan_parse_gpe_hdr and remove unused args
Jiri Benc <[email protected]>
vxlan: calculate correct header length for GPE
Jijie Shao <[email protected]>
net: hns3: fix wrong bw weight of disabled tc issue
Jijie Shao <[email protected]>
net: hns3: fix wrong tc bandwidth weight data issue
Hao Lan <[email protected]>
net: hns3: fix the imp capability bit cannot exceed 32 bits issue
Jiawen Wu <[email protected]>
net: phy: marvell10g: fix 88x3310 power up
Jacob Keller <[email protected]>
iavf: check for removal state before IAVF_FLAG_PF_COMMS_FAILED
Jacob Keller <[email protected]>
iavf: fix potential deadlock on allocation failure
Wang Ming <[email protected]>
i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir()
Arnd Bergmann <[email protected]>
media: mtk_jpeg_core: avoid unused-variable warning
Randy Dunlap <[email protected]>
media: mtk-jpeg: move data/code inside CONFIG_OF blocks
Nicolas Dufresne <[email protected]>
media: amphion: Fix firmware path to match linux-firmware
Sakari Ailus <[email protected]>
media: staging: atomisp: select V4L2_FWNODE
Sakari Ailus <[email protected]>
media: tc358746: Address compiler warnings
Dan Carpenter <[email protected]>
soundwire: amd: Fix a check for errors in probe()
Srinivas Kandagatla <[email protected]>
soundwire: qcom: update status correctly with mask
Adrien Thierry <[email protected]>
phy: qcom-snps-femto-v2: properly enable ref clock
Adrien Thierry <[email protected]>
phy: qcom-snps-femto-v2: keep cfg_ahb_clk enabled during runtime suspend
Guillaume Ranquet <[email protected]>
phy: mediatek: hdmi: mt8195: fix prediv bad upper limit test
Dan Carpenter <[email protected]>
phy: phy-mtk-dp: Fix an error code in probe()
Ojaswin Mujoo <[email protected]>
ext4: fix rbtree traversal bug in ext4_mb_use_preallocated
Ritesh Harjani <[email protected]>
ext4: mballoc: Remove useless setting of ac_criteria
Kemeng Shi <[email protected]>
ext4: add EXT4_MB_HINT_GOAL_ONLY test in ext4_mb_use_preallocated
Zhang Yi <[email protected]>
jbd2: fix a race when checking checkpoint buffer busy
Zhang Yi <[email protected]>
jbd2: remove journal_clean_one_cp_list()
Zhang Yi <[email protected]>
jbd2: remove t_checkpoint_io_list
Daniel Miess <[email protected]>
drm/amd/display: Prevent vtotal from being set to 0
Daniel Miess <[email protected]>
drm/amd/display: Fix possible underflow for displays with large vblank
Gabe Teeger <[email protected]>
drm/amd/display: update extended blank for dcn314 onwards
Rodrigo Siqueira <[email protected]>
drm/amd/display: Add FAMS validation before trying to use it
Liam R. Howlett <[email protected]>
maple_tree: fix 32 bit mas_next testing
Liam R. Howlett <[email protected]>
maple_tree: add __init and __exit to test module
Christian König <[email protected]>
drm/ttm: never consider pinned BOs for eviction&swap
Mario Limonciello <[email protected]>
drm/amd/display: Set minimum requirement for using PSR-SU on Phoenix
Mario Limonciello <[email protected]>
drm/amd/display: Set minimum requirement for using PSR-SU on Rembrandt
Cruise Hung <[email protected]>
drm/amd/display: Update correct DCN314 register header
Dmytro Laktyushkin <[email protected]>
drm/amd/display: fix dcn315 single stream crb allocation
Dmytro Laktyushkin <[email protected]>
drm/amd/display: add pixel rate based CRB allocation support
Michael Strauss <[email protected]>
drm/amd/display: Keep disable aux-i delay as 0
Michael Strauss <[email protected]>
drm/amd/display: Convert Delaying Aux-I Disable To Monitor Patch
Rick Wertenbroek <[email protected]>
PCI: rockchip: Don't advertise MSI-X in PCIe capabilities
Rick Wertenbroek <[email protected]>
PCI: rockchip: Fix window mapping and address translation for endpoint
Rick Wertenbroek <[email protected]>
PCI: rockchip: Remove writes to unused registers
Ilpo Järvinen <[email protected]>
PCI/ASPM: Avoid link retraining race
Ilpo Järvinen <[email protected]>
PCI/ASPM: Factor out pcie_wait_for_retrain()
Bjorn Helgaas <[email protected]>
PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link()
Christophe JAILLET <[email protected]>
i2c: nomadik: Remove a useless call in the remove function
Andi Shyti <[email protected]>
i2c: nomadik: Use devm_clk_get_enabled()
Andi Shyti <[email protected]>
i2c: nomadik: Remove unnecessary goto label
Markus Elfring <[email protected]>
i2c: Improve size determinations
Markus Elfring <[email protected]>
i2c: Delete error messages for failed memory allocations
Filipe Manana <[email protected]>
btrfs: fix race between quota disable and relocation
Christoph Hellwig <[email protected]>
btrfs: fix fsverify read error handling in end_page_read
Christoph Hellwig <[email protected]>
btrfs: factor out a btrfs_verify_page helper
Guenter Roeck <[email protected]>
regmap: Disable locking for RBTREE and MAPLE unit tests
Bartosz Golaszewski <[email protected]>
gpio: mvebu: fix irq domain leak
Uwe Kleine-König <[email protected]>
gpio: mvebu: Make use of devm_pwmchip_add
Hans de Goede <[email protected]>
gpio: tps68470: Make tps68470_gpio_output() always set the initial value
Ondrej Mosnacek <[email protected]>
io_uring: don't audit the capability check in io_uring_create()
Sven Schnelle <[email protected]>
s390/mm: fix per vma lock fault handling
Claudio Imbrenda <[email protected]>
KVM: s390: pv: fix index value of replaced ASCE
Claudio Imbrenda <[email protected]>
KVM: s390: pv: simplify shutdown and fix race
Haren Myneni <[email protected]>
powerpc/pseries/vas: Hold mmap_mutex after mmap lock during window close
Ross Lagerwall <[email protected]>
blk-mq: Fix stall due to recursive flush plug
Sudeep Holla <[email protected]>
KVM: arm64: Handle kvm_arm_init failure correctly in finalize_pkvm
Zhihao Cheng <[email protected]>
jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint
Heiner Kallweit <[email protected]>
r8169: revert 2ab19de62d67 ("r8169: remove ASPM restrictions now that ASPM is disabled during NAPI poll")
Mario Limonciello <[email protected]>
drm/amd: Align SMU11 SMU_MSG_OverridePcieParameters implementation with SMU13
Mario Limonciello <[email protected]>
drm/amd: Move helper for dynamic speed switch check out of smu13
Shyam Sundar S K <[email protected]>
platform/x86/amd/pmf: reduce verbosity of apmf_get_system_params
Shyam Sundar S K <[email protected]>
platform/x86/amd/pmf: Notify OS power slider update
-------------
Diffstat:
Documentation/ABI/testing/sysfs-module | 11 + Documentation/admin-guide/hw-vuln/spectre.rst | 11 +- Documentation/filesystems/tmpfs.rst | 45 +- Documentation/process/security-bugs.rst | 37 +- Makefile | 4 +- arch/arm64/include/asm/virt.h | 1 + arch/arm64/kernel/fpsimd.c | 4 +- arch/arm64/kvm/arm.c | 9 +- arch/arm64/kvm/pkvm.c | 2 +- arch/loongarch/Kconfig | 1 + arch/loongarch/lib/clear_user.S | 3 +- arch/loongarch/lib/copy_user.S | 3 +- arch/loongarch/net/bpf_jit.h | 2 +- arch/powerpc/platforms/pseries/vas.c | 9 +- arch/s390/kvm/pv.c | 8 +- arch/s390/mm/fault.c | 2 + arch/s390/mm/gmap.c | 1 + arch/um/os-Linux/sigio.c | 7 +- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 3 +- arch/x86/kernel/cpu/bugs.c | 15 +- arch/x86/kernel/cpu/mce/amd.c | 4 +- arch/x86/kernel/traps.c | 18 +- arch/x86/kvm/svm/svm.c | 6 + arch/x86/kvm/vmx/vmx.c | 41 +- arch/x86/kvm/x86.c | 34 +- block/blk-core.c | 3 +- block/blk-mq.c | 9 +- drivers/acpi/arm64/iort.c | 3 - drivers/ata/pata_ns87415.c | 2 +- drivers/base/power/power.h | 1 + drivers/base/power/wakeirq.c | 12 +- drivers/base/regmap/regmap-kunit.c | 3 + drivers/block/rbd.c | 124 ++- drivers/block/ublk_drv.c | 11 +- drivers/char/tpm/tpm_tis_core.c | 9 +- drivers/cxl/acpi.c | 5 +- drivers/dma-buf/dma-fence-unwrap.c | 26 +- drivers/dma-buf/dma-fence.c | 7 +- drivers/gpio/gpio-mvebu.c | 26 +- drivers/gpio/gpio-tps68470.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 19 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 3 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 25 +- drivers/gpu/drm/amd/display/dc/dc.h | 3 - drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 + drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 1 + drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 + drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 +- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 7 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c | 1 + .../drm/amd/display/dc/dcn315/dcn315_resource.c | 106 ++- .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 23 +- .../gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c | 25 +- .../gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h | 3 + .../amd/display/dc/dml/dcn31/display_mode_vba_31.c | 39 +- .../display/dc/dml/dcn31/display_rq_dlg_calc_31.c | 3 +- .../gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 15 +- .../dc/dml/dcn314/display_rq_dlg_calc_314.c | 16 +- .../drm/amd/display/dc/dml/display_mode_structs.h | 3 +- .../gpu/drm/amd/display/dc/dml/display_mode_vba.c | 6 + .../link_dp_training_fixed_vs_pe_retimer.c | 23 +- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 + drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 +- drivers/gpu/drm/amd/display/dmub/src/Makefile | 2 +- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 5 + drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 + drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c | 67 ++ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h | 35 + drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 12 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 89 +-- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 21 +- drivers/gpu/drm/drm_syncobj.c | 6 +- drivers/gpu/drm/i915/display/intel_dpt.c | 4 +- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 13 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 - drivers/gpu/drm/msm/msm_fence.c | 6 + drivers/gpu/drm/msm/msm_gem_submit.c | 16 +- drivers/gpu/drm/msm/msm_mdss.c | 19 +- drivers/gpu/drm/ttm/ttm_bo.c | 6 + drivers/hwmon/aquacomputer_d5next.c | 2 +- drivers/hwmon/k10temp.c | 17 +- drivers/hwmon/nct7802.c | 2 +- drivers/hwmon/pmbus/pmbus_core.c | 20 +- drivers/i2c/busses/i2c-ibm_iic.c | 4 +- drivers/i2c/busses/i2c-nomadik.c | 42 +- drivers/i2c/busses/i2c-sh7760.c | 3 +- drivers/i2c/busses/i2c-tiny-usb.c | 4 +- drivers/infiniband/core/cma.c | 2 + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 28 +- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 355 ++++++--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 26 + drivers/infiniband/hw/irdma/ctrl.c | 31 +- drivers/infiniband/hw/irdma/defs.h | 46 +- drivers/infiniband/hw/irdma/hw.c | 3 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/puda.c | 6 + drivers/infiniband/hw/irdma/type.h | 2 + drivers/infiniband/hw/irdma/uk.c | 5 +- drivers/infiniband/hw/irdma/utils.c | 8 +- drivers/infiniband/hw/mlx4/qp.c | 18 +- drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- drivers/iommu/iommufd/device.c | 12 +- drivers/iommu/iommufd/iommufd_private.h | 15 +- drivers/iommu/iommufd/main.c | 78 +- drivers/iommu/iommufd/pages.c | 2 +- drivers/irqchip/irq-bcm6345-l1.c | 14 +- drivers/irqchip/irq-gic-v3-its.c | 75 +- drivers/md/dm-cache-policy-smq.c | 28 +- drivers/md/dm-raid.c | 20 +- drivers/md/md.c | 2 + drivers/media/i2c/tc358746.c | 4 +- drivers/media/platform/amphion/vpu_core.c | 4 +- .../media/platform/mediatek/jpeg/mtk_jpeg_core.c | 830 ++++++++++----------- .../media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 4 +- .../media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 4 +- drivers/net/bonding/bond_main.c | 5 + drivers/net/can/usb/gs_usb.c | 2 + drivers/net/dsa/qca/qca8k-8xxx.c | 7 +- drivers/net/dsa/qca/qca8k-common.c | 19 +- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 7 +- drivers/net/ethernet/atheros/atlx/atl1.c | 7 +- drivers/net/ethernet/emulex/benet/be_main.c | 3 +- drivers/net/ethernet/freescale/fec_main.c | 18 +- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 +- .../hisilicon/hns3/hns3_common/hclge_comm_cmd.c | 21 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 17 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 3 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 3 +- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2 +- drivers/net/ethernet/intel/iavf/iavf_main.c | 11 +- drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c | 26 +- drivers/net/ethernet/intel/igc/igc_main.c | 40 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- .../ethernet/marvell/octeontx2/af/rvu_npc_hash.c | 43 +- .../ethernet/marvell/octeontx2/af/rvu_npc_hash.h | 8 +- drivers/net/ethernet/realtek/r8169_main.c | 27 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 +- drivers/net/ipa/ipa_table.c | 22 +- drivers/net/macvlan.c | 1 + drivers/net/phy/marvell10g.c | 7 + drivers/net/team/team.c | 9 + drivers/net/virtio_net.c | 4 +- drivers/net/vxlan/vxlan_core.c | 165 ++-- drivers/pci/controller/pcie-rockchip-ep.c | 156 ++-- drivers/pci/controller/pcie-rockchip.h | 40 +- drivers/pci/pcie/aspm.c | 55 +- drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 2 +- drivers/phy/mediatek/phy-mtk-dp.c | 2 +- drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 72 +- drivers/platform/x86/amd/pmf/acpi.c | 23 +- drivers/platform/x86/amd/pmf/core.c | 9 +- drivers/platform/x86/amd/pmf/pmf.h | 16 + drivers/platform/x86/amd/pmf/sps.c | 74 +- drivers/platform/x86/msi-laptop.c | 8 +- drivers/s390/block/dasd_3990_erp.c | 2 +- drivers/s390/block/dasd_ioctl.c | 1 + drivers/soundwire/amd_manager.c | 4 +- drivers/soundwire/bus.c | 8 +- drivers/soundwire/qcom.c | 2 +- drivers/staging/ks7010/ks_wlan_net.c | 6 +- drivers/staging/media/atomisp/Kconfig | 1 + drivers/staging/rtl8712/rtl871x_xmit.c | 43 +- drivers/staging/rtl8712/xmit_linux.c | 6 + drivers/thermal/thermal_of.c | 27 +- drivers/tty/n_gsm.c | 4 +- drivers/tty/serial/8250/8250_dwlib.c | 6 +- drivers/tty/serial/qcom_geni_serial.c | 7 - drivers/tty/serial/sh-sci.c | 2 +- drivers/tty/serial/sifive.c | 2 +- drivers/tty/tty_io.c | 2 +- drivers/usb/cdns3/cdns3-gadget.c | 4 +- drivers/usb/core/quirks.c | 4 + drivers/usb/dwc3/core.c | 20 +- drivers/usb/dwc3/core.h | 3 - drivers/usb/dwc3/dwc3-pci.c | 6 +- drivers/usb/gadget/composite.c | 4 + drivers/usb/gadget/legacy/raw_gadget.c | 12 +- drivers/usb/gadget/udc/core.c | 1 - drivers/usb/gadget/udc/tegra-xudc.c | 8 +- drivers/usb/host/ohci-at91.c | 8 +- drivers/usb/host/xhci-mtk.c | 1 + drivers/usb/host/xhci-pci.c | 4 +- drivers/usb/host/xhci-ring.c | 25 +- drivers/usb/host/xhci-tegra.c | 8 +- drivers/usb/misc/ehset.c | 8 +- drivers/usb/serial/option.c | 6 + drivers/usb/serial/usb-serial-simple.c | 73 +- drivers/usb/typec/class.c | 15 +- drivers/xen/grant-table.c | 40 +- drivers/xen/xenbus/xenbus_probe.c | 3 + fs/9p/fid.h | 6 +- fs/9p/v9fs.h | 2 +- fs/9p/vfs_dir.c | 5 +- fs/9p/vfs_file.c | 5 +- fs/btrfs/block-rsv.c | 5 + fs/btrfs/disk-io.c | 7 +- fs/btrfs/extent_io.c | 21 +- fs/btrfs/qgroup.c | 18 +- fs/btrfs/transaction.c | 10 +- fs/btrfs/zoned.c | 3 + fs/ceph/metric.c | 2 +- fs/ext4/mballoc.c | 200 ++++- fs/file.c | 6 +- fs/jbd2/checkpoint.c | 197 ++--- fs/jbd2/commit.c | 3 +- fs/jbd2/transaction.c | 17 +- fs/nfsd/nfs4state.c | 2 - fs/proc/vmcore.c | 2 +- fs/smb/client/sess.c | 4 +- fs/smb/server/ksmbd_netlink.h | 3 +- fs/smb/server/smb2pdu.c | 27 +- fs/smb/server/vfs.c | 58 +- fs/smb/server/vfs.h | 4 +- include/linux/dma-fence.h | 2 +- include/linux/jbd2.h | 7 +- include/linux/mm.h | 29 +- include/linux/mm_types.h | 28 + include/linux/mmap_lock.h | 10 +- include/net/ipv6.h | 8 +- include/net/vxlan.h | 13 +- include/trace/events/jbd2.h | 12 +- include/uapi/linux/blkzoned.h | 10 +- io_uring/io_uring.c | 25 +- kernel/locking/rtmutex.c | 172 +++-- kernel/locking/rtmutex_api.c | 2 +- kernel/locking/rtmutex_common.h | 47 +- kernel/locking/ww_mutex.h | 12 +- kernel/signal.c | 4 + kernel/trace/ring_buffer.c | 22 +- kernel/trace/trace_events.c | 14 +- lib/test_maple_tree.c | 163 ++-- mm/memory-failure.c | 2 +- mm/mempolicy.c | 15 +- mm/mmap.c | 1 + net/ceph/messenger.c | 1 + net/ipv6/addrconf.c | 14 +- net/mptcp/protocol.c | 3 +- net/netfilter/nf_tables_api.c | 5 +- net/netfilter/nft_immediate.c | 27 +- net/netfilter/nft_set_rbtree.c | 20 +- net/sched/sch_mqprio.c | 14 + net/tipc/crypto.c | 3 +- net/tipc/node.c | 2 +- sound/pci/hda/patch_realtek.c | 2 + sound/soc/codecs/wm8904.c | 3 + sound/soc/fsl/fsl_spdif.c | 2 + tools/net/ynl/lib/ynl.py | 4 +- tools/testing/radix-tree/linux/init.h | 1 + tools/testing/radix-tree/maple.c | 143 ++-- tools/testing/selftests/net/mptcp/mptcp_join.sh | 4 +- tools/testing/selftests/rseq/rseq.c | 28 +- virt/kvm/kvm_main.c | 24 + 264 files changed, 3622 insertions(+), 2136 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/239 platform/x86/amd/pmf: Notify OS power slider update
From: Shyam Sundar S K <[email protected]>
commit 33c9ab5b493a0e922b06c12fed4fdcb862212cda upstream.
APMF fn8 can notify EC about the OS slider position change. Add this capability to the PMF driver so that it can call the APMF fn8 based on the changes in the Platform profile events.
--- drivers/platform/x86/amd/pmf/acpi.c | 21 ++++++++++ drivers/platform/x86/amd/pmf/core.c | 9 +++- drivers/platform/x86/amd/pmf/pmf.h | 16 +++++++ drivers/platform/x86/amd/pmf/sps.c | 74 ++++++++++++++++++++++++++++++++++-- 4 files changed, 114 insertions(+), 6 deletions(-)
drivers/platform/x86/amd/pmf/acpi.c +21 -0
@@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(stru data, sizeof(*data)); } +int apmf_os_power_slider_update (struct amd_pmf_dev *pdev,u8 event) +{ +struct os_power_slider args; +struct acpi_buffer params; +union acpi_object *info; +int err =0 ; + + args.size =sizeof (args); + args.slider_event = event; + + params.length =sizeof (args); + params.pointer = (void *)&args; + + info =apmf_if_call (pdev,APMF_FUNC_OS_POWER_SLIDER_UPDATE , ¶ms); +if (!info) + err = -EIO ; + +kfree (info); +return err; +} +static void apmf_sbios_heartbeat_notify (struct work_struct *work) { struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work);
drivers/platform/x86/amd/pmf/core.c +7 -2
@@ -71,7 +71,11 @@ static int amd_pmf_pwr_src_notify_call(sreturn NOTIFY_DONE ; } -amd_pmf_set_sps_power_limits (pmf); +if (is_apmf_func_supported (pmf,APMF_FUNC_STATIC_SLIDER_GRANULAR )) +amd_pmf_set_sps_power_limits (pmf); + +if (is_apmf_func_supported (pmf,APMF_FUNC_OS_POWER_SLIDER_UPDATE )) +amd_pmf_power_slider_update_event (pmf);return NOTIFY_OK ; }
@@ -295,7 +299,8 @@ static void amd_pmf_init_features(structint ret;/* Enable Static Slider */ -if (is_apmf_func_supported (dev,APMF_FUNC_STATIC_SLIDER_GRANULAR )) { +if (is_apmf_func_supported (dev,APMF_FUNC_STATIC_SLIDER_GRANULAR ) || +is_apmf_func_supported (dev,APMF_FUNC_OS_POWER_SLIDER_UPDATE )) {amd_pmf_init_sps (dev); dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call;power_supply_reg_notifier (&dev->pwr_src_notifier);
drivers/platform/x86/amd/pmf/pmf.h +16 -0
@@ -21,6 +21,7 @@#define APMF_FUNC_SBIOS_HEARTBEAT 4#define APMF_FUNC_AUTO_MODE 5#define APMF_FUNC_SET_FAN_IDX 7 +#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8#define APMF_FUNC_STATIC_SLIDER_GRANULAR 9#define APMF_FUNC_DYN_SLIDER_AC 11#define APMF_FUNC_DYN_SLIDER_DC 12
@@ -44,6 +45,14 @@#define GET_STT_LIMIT_APU 0x20#define GET_STT_LIMIT_HS2 0x21 +/* OS slider update notification */ +#define DC_BEST_PERF 0 +#define DC_BETTER_PERF 1 +#define DC_BATTERY_SAVER 3 +#define AC_BEST_PERF 4 +#define AC_BETTER_PERF 5 +#define AC_BETTER_BATTERY 6 +/* Fan Index for Auto Mode */ #define FAN_INDEX_AUTO 0xFFFFFFFF
@@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular {struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX ][POWER_MODE_MAX ]; }; +struct os_power_slider { +u16 size; +u8 slider_event; +} __packed; +struct fan_table_control {bool manual;unsigned long fan_id;
@@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_devint amd_pmf_init_metrics_table (struct amd_pmf_dev *dev);int amd_pmf_get_power_source (void );int apmf_install_handler (struct amd_pmf_dev *pmf_dev); +int apmf_os_power_slider_update (struct amd_pmf_dev *dev,u8 flag);/* SPS Layer */ int amd_pmf_get_pprof_modes (struct amd_pmf_dev *pmf);
@@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dint apmf_get_static_slider_granular (struct amd_pmf_dev *pdev,struct apmf_static_slider_granular_output *output);bool is_pprof_balanced (struct amd_pmf_dev *pmf); +int amd_pmf_power_slider_update_event (struct amd_pmf_dev *dev);int apmf_update_fan_idx (struct amd_pmf_dev *pdev,bool manual,u32 idx);
drivers/platform/x86/amd/pmf/sps.c +70 -4
94 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 2/239 platform/x86/amd/pmf: reduce verbosity of apmf_get_system_params
In reply to Greg Kroah-HartmanFrom: Shyam Sundar S K <[email protected]>
commit 839e90e75e695b3d9ee17f5a2811e7ee5aea8d4a upstream.
apmf_get_system_params() failure is not a critical event, reduce its verbosity from dev_err to dev_dbg.
--- drivers/platform/x86/amd/pmf/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/amd/pmf/acpi.c +1 -1
@@ -310,7 +310,7 @@ int apmf_acpi_init(struct amd_pmf_dev *p ret =apmf_get_system_params (pmf_dev);if (ret) { -dev_err (pmf_dev->dev,"APMF apmf_get_system_params failed :%d\n" , ret); +dev_dbg (pmf_dev->dev,"APMF apmf_get_system_params failed :%d\n" , ret); goto out; }
Greg Kroah-Hartman
maintainerPATCH 3/239 drm/amd: Move helper for dynamic speed switch check out of smu13
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
commit 188623076d0f1a500583d392b6187056bf7cc71a upstream.
This helper is used for checking if the connected host supports the feature, it can be moved into generic code to be used by other smu implementations as well.
--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 19 +++++++++++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 21 +-------------------- 3 files changed, 21 insertions(+), 20 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +1 -0
@@ -1246,6 +1246,7 @@ int amdgpu_device_gpu_recover(struct amdvoid amdgpu_device_pci_config_reset (struct amdgpu_device *adev);int amdgpu_device_pci_reset (struct amdgpu_device *adev);bool amdgpu_device_need_post (struct amdgpu_device *adev); +bool amdgpu_device_pcie_dynamic_switching_supported (void );bool amdgpu_device_should_use_aspm (struct amdgpu_device *adev);bool amdgpu_device_aspm_support_quirk (void );
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +19 -0
@@ -1352,6 +1352,25 @@ bool amdgpu_device_need_post(struct amdgreturn true; } +/* +* Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic +* speed switching. Until we have confirmation from Intel that a specific host +* supports it, it's safer that we keep it disabled for all. +* +* https://edc.intel.com/content/www/us/en/design/products/platforms/details/raptor-lake-s/13th-generation-core-processors-datasheet-volume-1-of-2/005/pci-express-support/ +* https://gitlab.freedesktop.org/drm/amd/-/issues/2663 +*/ +bool amdgpu_device_pcie_dynamic_switching_supported (void ) +{ +#if IS_ENABLED (CONFIG_X86 ) +struct cpuinfo_x86 *c = &cpu_data (0 ); + +if (c->x86_vendor ==X86_VENDOR_INTEL ) +return false; +#endif +return true; +} +/** * amdgpu_device_should_use_aspm - check if the device should program ASPM *
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +1 -20
@@ -2454,25 +2454,6 @@ int smu_v13_0_mode1_reset(struct smu_conreturn ret; } -/* -* Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic -* speed switching. Until we have confirmation from Intel that a specific host -* supports it, it's safer that we keep it disabled for all. -* -* https://edc.intel.com/content/www/us/en/design/products/platforms/details/raptor-lake-s/13th-generation-core-processors-datasheet-volume-1-of-2/005/pci-express-support/ -* https://gitlab.freedesktop.org/drm/amd/-/issues/2663 -*/ -static bool smu_v13_0_is_pcie_dynamic_switching_supported (void ) -{ -#if IS_ENABLED (CONFIG_X86 ) -struct cpuinfo_x86 *c = &cpu_data (0 ); - -if (c->x86_vendor ==X86_VENDOR_INTEL ) -return false; -#endif -return true; -} -int smu_v13_0_update_pcie_parameters (struct smu_context *smu,uint32_t pcie_gen_cap,uint32_t pcie_width_cap)
@@ -2484,7 +2465,7 @@ int smu_v13_0_update_pcie_parameters(struint32_t smu_pcie_arg;int ret, i; -if (!smu_v13_0_is_pcie_dynamic_switching_supported ()) { +if (!amdgpu_device_pcie_dynamic_switching_supported ()) {if (pcie_table->pcie_gen[num_of_levels -1 ] < pcie_gen_cap) pcie_gen_cap = pcie_table->pcie_gen[num_of_levels -1 ];
Greg Kroah-Hartman
maintainerPATCH 4/239 drm/amd: Align SMU11 SMU_MSG_OverridePcieParameters implementation with SMU13
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
commit e701156ccc6c7a5f104a968dda74cd6434178712 upstream.
SMU13 overrides dynamic PCIe lane width and dynamic speed by when on certain hosts. commit 38e4ced80479 ("drm/amd/pm: conditionally disable pcie lane switching for some sienna_cichlid SKUs") worked around this issue by setting up certain SKUs to set up certain limits, but the same fundamental problem with those hosts affects all SMU11 implmentations as well, so align the SMU11 and SMU13 driver handling.
--- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 93 +++------------- 1 file changed, 20 insertions(+), 73 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +20 -73
@@ -2081,89 +2081,36 @@ static int sienna_cichlid_display_disablreturn ret; } -static void sienna_cichlid_get_override_pcie_settings (struct smu_context *smu, -uint32_t *gen_speed_override, -uint32_t *lane_width_override) -{ -struct amdgpu_device *adev = smu->adev; - - *gen_speed_override =0xff ; - *lane_width_override =0xff ; - -switch (adev->pdev->device) { -case 0x73A0 : -case 0x73A1 : -case 0x73A2 : -case 0x73A3 : -case 0x73AB : -case 0x73AE : -/* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */ - *lane_width_override =6 ; -break ; -case 0x73E0 : -case 0x73E1 : -case 0x73E3 : - *lane_width_override =4 ; -break ; -case 0x7420 : -case 0x7421 : -case 0x7422 : -case 0x7423 : -case 0x7424 : - *lane_width_override =3 ; -break ; -default : -break ; - } -} - -#define MAX (a, b) ((a) > (b) ? (a) : (b)) -static int sienna_cichlid_update_pcie_parameters (struct smu_context *smu,uint32_t pcie_gen_cap,uint32_t pcie_width_cap) {struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; -uint32_t gen_speed_override, lane_width_override; -uint8_t *table_member1, *table_member2; -uint32_t min_gen_speed, max_gen_speed; -uint32_t min_lane_width, max_lane_width; -uint32_t smu_pcie_arg; +u32 smu_pcie_arg;int ret, i; -GET_PPTABLE_MEMBER (PcieGenSpeed, &table_member1); -GET_PPTABLE_MEMBER (PcieLaneCount, &table_member2); - -sienna_cichlid_get_override_pcie_settings (smu, - &gen_speed_override, - &lane_width_override); - -/* PCIE gen speed override */ -if (gen_speed_override !=0xff ) { - min_gen_speed =MIN (pcie_gen_cap, gen_speed_override); - max_gen_speed =MIN (pcie_gen_cap, gen_speed_override); - }else { - min_gen_speed =MAX (0 , table_member1[0 ]); - max_gen_speed =MIN (pcie_gen_cap, table_member1[1 ]); - min_gen_speed = min_gen_speed > max_gen_speed ? - max_gen_speed : min_gen_speed; - } - pcie_table->pcie_gen[0 ] = min_gen_speed; - pcie_table->pcie_gen[1 ] = max_gen_speed; - -/* PCIE lane width override */ -if (lane_width_override !=0xff ) { - min_lane_width =MIN (pcie_width_cap, lane_width_override); - max_lane_width =MIN (pcie_width_cap, lane_width_override); +/* PCIE gen speed and lane width override */ +if (!amdgpu_device_pcie_dynamic_switching_supported ()) { +if (pcie_table->pcie_gen[NUM_LINK_LEVELS -1 ] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS -1 ]; + +if (pcie_table->pcie_lane[NUM_LINK_LEVELS -1 ] < pcie_width_cap) + pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS -1 ]; + +/* Force all levels to use the same settings */ +for (i =0 ; i <NUM_LINK_LEVELS ; i++) { + pcie_table->pcie_gen[i] = pcie_gen_cap; + pcie_table->pcie_lane[i] = pcie_width_cap; + } }else { - min_lane_width =MAX (1 , table_member2[0 ]); - max_lane_width =MIN (pcie_width_cap, table_member2[1 ]); - min_lane_width = min_lane_width > max_lane_width ? - max_lane_width : min_lane_width; +for (i =0 ; i <NUM_LINK_LEVELS ; i++) { +if (pcie_table->pcie_gen[i] > pcie_gen_cap) + pcie_table->pcie_gen[i] = pcie_gen_cap; +if (pcie_table->pcie_lane[i] > pcie_width_cap) + pcie_table->pcie_lane[i] = pcie_width_cap; + } } - pcie_table->pcie_lane[0 ] = min_lane_width; - pcie_table->pcie_lane[1 ] = max_lane_width;for (i =0 ; i <NUM_LINK_LEVELS ; i++) { smu_pcie_arg = (i << 16 |
Greg Kroah-Hartman
maintainerPATCH 5/239 r8169: revert 2ab19de62d67 ("r8169: remove ASPM restrictions now that ASPM is disabled during NAPI poll")
In reply to Greg Kroah-HartmanFrom: Heiner Kallweit <[email protected]>
commit cf2ffdea0839398cb0551762af7f5efb0a6e0fea upstream.
There have been reports that on a number of systems this change breaks network connectivity. Therefore effectively revert it. Mainly affected seem to be systems where BIOS denies ASPM access to OS.
Due to later changes we can't do a direct revert.
--- drivers/net/ethernet/realtek/r8169_main.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
drivers/net/ethernet/realtek/r8169_main.c +26 -1
@@ -623,6 +623,7 @@ struct rtl8169_private {int cfg9346_usage_count; unsigned supports_gmii:1; + unsigned aspm_manageable:1;dma_addr_t counters_phys_addr;struct rtl8169_counters *counters;struct rtl8169_tc_offsets tc_offset;
@@ -2746,7 +2747,8 @@ static void rtl_hw_aspm_clkreq_enable(stif (tp->mac_version <RTL_GIGA_MAC_VER_32 )return ; -if (enable) { +/* Don't enable ASPM in the chip if OS can't control ASPM */ +if (enable && tp->aspm_manageable) {/* On these chip versions ASPM can even harm * bus communication of other PCI devices. */
@@ -5156,6 +5158,16 @@ done:rtl_rar_set (tp, mac_addr); } +/* register is set if system vendor successfully tested ASPM 1.2 */ +static bool rtl_aspm_is_safe (struct rtl8169_private *tp) +{ +if (tp->mac_version >=RTL_GIGA_MAC_VER_61 && +r8168_mac_ocp_read (tp,0xc0b2 ) &0xf ) +return true; + +return false; +} +static int rtl_init_one (struct pci_dev *pdev,const struct pci_device_id *ent) {struct rtl8169_private *tp;
@@ -5227,6 +5239,19 @@ static int rtl_init_one(struct pci_dev * tp->mac_version = chipset; +/* Disable ASPM L1 as that cause random device stop working +* problems as well as full system hangs for some PCIe devices users. +* Chips from RTL8168h partially have issues with L1.2, but seem +* to work fine with L1 and L1.1. +*/ +if (rtl_aspm_is_safe (tp)) + rc =0 ; +else if (tp->mac_version >=RTL_GIGA_MAC_VER_46 ) + rc =pci_disable_link_state (pdev,PCIE_LINK_STATE_L1_2 ); +else + rc =pci_disable_link_state (pdev,PCIE_LINK_STATE_L1 ); + tp->aspm_manageable = !rc; + tp->dash_type =rtl_check_dash (tp); tp->cp_cmd =RTL_R16 (tp, CPlusCmd) &CPCMD_MASK ;
Greg Kroah-Hartman
maintainerPATCH 6/239 jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit e34c8dd238d0c9368b746480f313055f5bab5040 ]
Following process,
jbd2_journal_commit_transaction
// there are several dirty buffer heads in transaction->t_checkpoint_list
P1 wb_workfnjbd2_log_do_checkpoint
if (buffer_locked(bh)) // false
__block_write_full_page
trylock_buffer(bh) test_clear_buffer_dirty(bh)
if (!buffer_dirty(bh))
__jbd2_journal_remove_checkpoint(jh)
if (buffer_write_io_error(bh)) // false
>> bh IO error occurs <<
jbd2_cleanup_journal_tail
__jbd2_update_log_tail
jbd2_write_superblock
// The bh won't be replayed in next mount.
, which could corrupt the ext4 image, fetch a reproducer in [Link].
Since writeback process clears buffer dirty after locking buffer head, we can fix it by try locking buffer and check dirtiness while buffer is locked, the buffer head can be removed if it is neither dirty nor locked.
--- fs/jbd2/checkpoint.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
fs/jbd2/checkpoint.c +17 -15
@@ -221,20 +221,6 @@ int jbd2_log_do_checkpoint(journal_t *journal) jh = transaction->t_checkpoint_list; bh =jh2bh (jh); -/* -* The buffer may be writing back, or flushing out in the -* last couple of cycles, or re-adding into a new transaction, -* need to check it again until it's unlocked. -*/ -if (buffer_locked (bh)) { -get_bh (bh); -spin_unlock (&journal->j_list_lock); -wait_on_buffer (bh); -/* the journal_head may have gone by now */ -BUFFER_TRACE (bh,"brelse" ); -__brelse (bh); - goto retry; - }if (jh->b_transaction !=NULL ) {transaction_t *t = jh->b_transaction;tid_t tid = t->t_tid;
@@ -269,7 +255,22 @@ int jbd2_log_do_checkpoint(journal_t *journal)spin_lock (&journal->j_list_lock); goto restart; } -if (!buffer_dirty (bh)) { +if (!trylock_buffer (bh)) { +/* +* The buffer is locked, it may be writing back, or +* flushing out in the last couple of cycles, or +* re-adding into a new transaction, need to check +* it again until it's unlocked. +*/ +get_bh (bh); +spin_unlock (&journal->j_list_lock); +wait_on_buffer (bh); +/* the journal_head may have gone by now */ +BUFFER_TRACE (bh,"brelse" ); +__brelse (bh); + goto retry; + }else if (!buffer_dirty (bh)) { +unlock_buffer (bh);BUFFER_TRACE (bh,"remove from checkpoint" );/* * If the transaction was released or the checkpoint
@@ -279,6 +280,7 @@ int jbd2_log_do_checkpoint(journal_t *journal) !transaction->t_checkpoint_list) goto out; }else { +unlock_buffer (bh);/* * We are about to write the buffer, it could be * raced by some other transaction shrink or buffer
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 7/239 KVM: arm64: Handle kvm_arm_init failure correctly in finalize_pkvm
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
[ Upstream commit fa729bc7c9c8c17a2481358c841ef8ca920485d3 ]
Currently there is no synchronisation between finalize_pkvm() and kvm_arm_init() initcalls. The finalize_pkvm() proceeds happily even if kvm_arm_init() fails resulting in the following warning on all the CPUs and eventually a HYP panic:
| kvm [1]: IPA Size Limit: 48 bits | kvm [1]: Failed to init hyp memory protection | kvm [1]: error initializing Hyp mode: -22 | | <snip> | | WARNING: CPU: 0 PID: 0 at arch/arm64/kvm/pkvm.c:226 _kvm_host_prot_finalize+0x30/0x50 | Modules linked in: | CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.4.0 #237 | Hardware name: FVP Base RevC (DT) | pstate: 634020c5 (nZCv daIF +PAN -UAO +TCO +DIT -SSBS BTYPE=--) | pc : _kvm_host_prot_finalize+0x30/0x50 | lr : __flush_smp_call_function_queue+0xd8/0x230 | | Call trace: | _kvm_host_prot_finalize+0x3c/0x50 | on_each_cpu_cond_mask+0x3c/0x6c | pkvm_drop_host_privileges+0x4c/0x78 | finalize_pkvm+0x3c/0x5c | do_one_initcall+0xcc/0x240 | do_initcall_level+0x8c/0xac | do_initcalls+0x54/0x94 | do_basic_setup+0x1c/0x28 | kernel_init_freeable+0x100/0x16c | kernel_init+0x20/0x1a0 | ret_from_fork+0x10/0x20 | Failed to finalize Hyp protection: -22 | dtb=fvp-base-revc.dtb | kvm [95]: nVHE hyp BUG at: arch/arm64/kvm/hyp/nvhe/mem_protect.c:540! | kvm [95]: nVHE call trace: | kvm [95]: [<ffff800081052984>] __kvm_nvhe_hyp_panic+0xac/0xf8 | kvm [95]: [<ffff800081059644>] __kvm_nvhe_handle_host_mem_abort+0x1a0/0x2ac | kvm [95]: [<ffff80008105511c>] __kvm_nvhe_handle_trap+0x4c/0x160 | kvm [95]: [<ffff8000810540fc>] __kvm_nvhe___skip_pauth_save+0x4/0x4 | kvm [95]: ---[ end nVHE call trace ]--- | kvm [95]: Hyp Offset: 0xfffe8db00ffa0000 | Kernel panic - not syncing: HYP panic: | PS:a34023c9 PC:0000f250710b973c ESR:00000000f2000800 | FAR:ffff000800cb00d0 HPFAR:000000000880cb00 PAR:0000000000000000 | VCPU:0000000000000000 | CPU: 3 PID: 95 Comm: kworker/u16:2 Tainted: G W 6.4.0 #237 | Hardware name: FVP Base RevC (DT) | Workqueue: rpciod rpc_async_schedule | Call trace: | dump_backtrace+0xec/0x108 | show_stack+0x18/0x2c | dump_stack_lvl+0x50/0x68 | dump_stack+0x18/0x24 | panic+0x138/0x33c | nvhe_hyp_panic_handler+0x100/0x184 | new_slab+0x23c/0x54c | ___slab_alloc+0x3e4/0x770 | kmem_cache_alloc_node+0x1f0/0x278 | __alloc_skb+0xdc/0x294 | tcp_stream_alloc_skb+0x2c/0xf0 | tcp_sendmsg_locked+0x3d0/0xda4 | tcp_sendmsg+0x38/0x5c | inet_sendmsg+0x44/0x60 | sock_sendmsg+0x1c/0x34 | xprt_sock_sendmsg+0xdc/0x274 | xs_tcp_send_request+0x1ac/0x28c | xprt_transmit+0xcc/0x300 | call_transmit+0x78/0x90 | __rpc_execute+0x114/0x3d8 | rpc_async_schedule+0x28/0x48 | process_one_work+0x1d8/0x314 | worker_thread+0x248/0x474 | kthread+0xfc/0x184 | ret_from_fork+0x10/0x20 | SMP: stopping secondary CPUs | Kernel Offset: 0x57c5cb460000 from 0xffff800080000000 | PHYS_OFFSET: 0x80000000 | CPU features: 0x00000000,1035b7a3,ccfe773f | Memory Limit: none | ---[ end Kernel panic - not syncing: HYP panic: | PS:a34023c9 PC:0000f250710b973c ESR:00000000f2000800 | FAR:ffff000800cb00d0 HPFAR:000000000880cb00 PAR:0000000000000000 | VCPU:0000000000000000 ]---
Fix it by checking for the successfull initialisation of kvm_arm_init() in finalize_pkvm() before proceeding any futher.
--- arch/arm64/include/asm/virt.h | 1 + arch/arm64/kvm/arm.c | 9 ++++++++- arch/arm64/kvm/pkvm.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-)
arch/arm64/include/asm/virt.h +1 -0
@@ -78,6 +78,7 @@ extern u32 __boot_cpu_mode[2];void __hyp_set_vectors (phys_addr_t phys_vector_base);void __hyp_reset_vectors (void ); +bool is_kvm_arm_initialised (void );DECLARE_STATIC_KEY_FALSE (kvm_protected_mode_initialized);
arch/arm64/kvm/arm.c +8 -1
@@ -51,11 +51,16 @@ DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); -static bool vgic_present; +static bool vgic_present, kvm_arm_initialised; static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);DEFINE_STATIC_KEY_FALSE (userspace_irqchip_in_use); +bool is_kvm_arm_initialised (void ) +{ +return kvm_arm_initialised; +} +int kvm_arch_vcpu_should_kick (struct kvm_vcpu *vcpu) {return kvm_vcpu_exiting_guest_mode (vcpu) ==IN_GUEST_MODE ;
@@ -2396,6 +2401,8 @@ static __init int kvm_arm_init(void)if (err) goto out_subs; + kvm_arm_initialised = true; +return 0 ; out_subs:
arch/arm64/kvm/pkvm.c +1 -1
@@ -243,7 +243,7 @@ static int __init finalize_pkvm(void) {int ret; -if (!is_protected_kvm_enabled ()) +if (!is_protected_kvm_enabled () || !is_kvm_arm_initialised ())return 0 ;/*
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 8/239 blk-mq: Fix stall due to recursive flush plug
In reply to Greg Kroah-HartmanFrom: Ross Lagerwall <[email protected]>
[ Upstream commit 70904263512a74a3b8941dd9e6e515ca6fc57821 ]
We have seen rare IO stalls as follows:
* blk_mq_plug_issue_direct() is entered with an mq_list containing two requests.
* For the first request, it sets last == false and enters the driver's queue_rq callback.
* The driver queue_rq callback indirectly calls schedule() which calls blk_flush_plug(). This may happen if the driver has the BLK_MQ_F_BLOCKING flag set and is allowed to sleep in ->queue_rq.
* blk_flush_plug() handles the remaining request in the mq_list. mq_list is now empty.
* The original call to queue_rq resumes (with last == false).
* The loop in blk_mq_plug_issue_direct() terminates because there are no remaining requests in mq_list.
The IO is now stalled because the last request submitted to the driver had last == false and there was no subsequent call to commit_rqs().
Fix this by returning early in blk_mq_flush_plug_list() if rq_count is 0 which it will be in the recursive case, rather than checking if the mq_list is empty. At the same time, adjust one of the callers to skip the mq_list empty check as it is not necessary.
--- block/blk-core.c | 3 +-- block/blk-mq.c | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-)
block/blk-core.c +1 -2
@@ -1141,8 +1141,7 @@ void __blk_flush_plug(struct blk_plug *plug, bool from_schedule) {if (!list_empty (&plug->cb_list))flush_plug_callbacks (plug, from_schedule); -if (!rq_list_empty (plug->mq_list)) -blk_mq_flush_plug_list (plug, from_schedule); +blk_mq_flush_plug_list (plug, from_schedule);/* * Unconditionally flush out cached requests, even if the unplug * event came from schedule. Since we know hold references to the
block/blk-mq.c +8 -1
@@ -2754,7 +2754,14 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) {struct request *rq; -if (rq_list_empty (plug->mq_list)) +/* +* We may have been called recursively midway through handling +* plug->mq_list via a schedule() in the driver's queue_rq() callback. +* To avoid mq_list changing under our feet, clear rq_count early and +* bail out specifically if rq_count is 0 rather than checking +* whether the mq_list is empty. +*/ +if (plug->rq_count ==0 )return ; plug->rq_count =0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 9/239 powerpc/pseries/vas: Hold mmap_mutex after mmap lock during window close
In reply to Greg Kroah-HartmanFrom: Haren Myneni <[email protected]>
[ Upstream commit b59c9dc4d9d47b3c4572d826603fde507055b656 ]
Commit 8ef7b9e1765a ("powerpc/pseries/vas: Close windows with DLPAR core removal") unmaps the window paste address and issues HCALL to close window in the hypervisor for migration or DLPAR core removal events. So holds mmap_mutex and then mmap lock before unmap the paste address. But if the user space issue mmap paste address at the same time with the migration event, coproc_mmap() is called after holding the mmap lock which can trigger deadlock when trying to acquire mmap_mutex in coproc_mmap().
t1: mmap() call to mmap t2: Migration event
window paste address
do_mmap2() migration_store()
ksys_mmap_pgoff() pseries_migrate_partition()
vm_mmap_pgoff() vas_migration_handler()
Acquire mmap lock reconfig_close_windows()
do_mmap() lock mmap_mutex
mmap_region() Acquire mmap lock
call_mmap() //Wait for mmap lock
coproc_mmap() unmap vma
lock mmap_mutex update window status
//wait for mmap_mutex Release mmap lock
mmap vma unlock mmap_mutex
update window status
unlock mmap_mutex
...
Release mmap lock
Fix this deadlock issue by holding mmap lock first before mmap_mutex in reconfig_close_windows().
--- arch/powerpc/platforms/pseries/vas.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/platforms/pseries/vas.c +7 -2
@@ -744,6 +744,12 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds, } task_ref = &win->vas_win.task_ref; +/* +* VAS mmap (coproc_mmap()) and its fault handler +* (vas_mmap_fault()) are called after holding mmap lock. +* So hold mmap mutex after mmap_lock to avoid deadlock. +*/ +mmap_write_lock (task_ref->mm);mutex_lock (&task_ref->mmap_mutex); vma = task_ref->vma;/*
@@ -752,7 +758,6 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,*/ win->vas_win.status |= flag; -mmap_write_lock (task_ref->mm);/* * vma is set in the original mapping. But this mapping * is done with mmap() after the window is opened with ioctl.
@@ -762,8 +767,8 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,if (vma)zap_vma_pages (vma); -mmap_write_unlock (task_ref->mm);mutex_unlock (&task_ref->mmap_mutex); +mmap_write_unlock (task_ref->mm);/* * Close VAS window in the hypervisor, but do not * free vas_window struct since it may be reused
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 10/239 KVM: s390: pv: simplify shutdown and fix race
In reply to Greg Kroah-HartmanFrom: Claudio Imbrenda <[email protected]>
[ Upstream commit 5ff92181577a89ed12ad4e0e5813751faf16a139 ]
Simplify the shutdown of non-protected VMs. There is no need to do complex manipulations of the counter if it was zero.
This also fixes a very rare race which caused pages to be torn down from the address space with a non-zero counter even on older machines that don't support the UVC instruction, causing a crash.
Message-ID: <[email protected]>
--- arch/s390/kvm/pv.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/s390/kvm/pv.c +6 -2
@@ -411,8 +411,12 @@ int kvm_s390_pv_deinit_cleanup_all(struct kvm *kvm, u16 *rc, u16 *rrc)u16 _rc, _rrc;int cc =0 ; -/* Make sure the counter does not reach 0 before calling s390_uv_destroy_range */ -atomic_inc (&kvm->mm->context.protected_count); +/* +* Nothing to do if the counter was already 0. Otherwise make sure +* the counter does not reach 0 before calling s390_uv_destroy_range. +*/ +if (!atomic_inc_not_zero (&kvm->mm->context.protected_count)) +return 0 ; *rc =1 ;/* If the current VM is protected, destroy it */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 11/239 KVM: s390: pv: fix index value of replaced ASCE
In reply to Greg Kroah-HartmanFrom: Claudio Imbrenda <[email protected]>
[ Upstream commit c2fceb59bbda16468bda82b002383bff59de89ab ]
The index field of the struct page corresponding to a guest ASCE should be 0. When replacing the ASCE in s390_replace_asce(), the index of the new ASCE should also be set to 0.
Having the wrong index might lead to the wrong addresses being passed around when notifying pte invalidations, and eventually to validity intercepts (VM crash) if the prefix gets unmapped and the notifier gets called with the wrong address.
Message-ID: <[email protected]>
--- arch/s390/mm/gmap.c | 1 + 1 file changed, 1 insertion(+)
arch/s390/mm/gmap.c +1 -0
@@ -2846,6 +2846,7 @@ int s390_replace_asce(struct gmap *gmap) page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER );if (!page)return -ENOMEM ; + page->index =0 ; table =page_to_virt (page);memcpy (table, gmap->table,1UL << (CRST_ALLOC_ORDER +PAGE_SHIFT ));
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 12/239 s390/mm: fix per vma lock fault handling
In reply to Greg Kroah-HartmanFrom: Sven Schnelle <[email protected]>
[ Upstream commit 7686762d1ed092db4d120e29b565712c969dc075 ]
With per-vma locks, handle_mm_fault() may return non-fatal error flags. In this case the code should reset the fault flags before returning.
--- arch/s390/mm/fault.c | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/mm/fault.c +2 -0
@@ -421,6 +421,8 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access)vma_end_read (vma);if (!(fault &VM_FAULT_RETRY )) {count_vm_vma_lock_event (VMA_LOCK_SUCCESS ); +if (likely (!(fault &VM_FAULT_ERROR ))) + fault =0 ; goto out; }count_vm_vma_lock_event (VMA_LOCK_RETRY );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 13/239 io_uring: dont audit the capability check in io_uring_create()
In reply to Greg Kroah-HartmanFrom: Ondrej Mosnacek <[email protected]>
[ Upstream commit 6adc2272aaaf84f34b652cf77f770c6fcc4b8336 ]
The check being unconditional may lead to unwanted denials reported by LSMs when a process has the capability granted by DAC, but denied by an LSM. In the case of SELinux such denials are a problem, since they can't be effectively filtered out via the policy and when not silenced, they produce noise that may hide a true problem or an attack.
Since not having the capability merely means that the created io_uring context will be accounted against the current user's RLIMIT_MEMLOCK limit, we can disable auditing of denials for this check by using ns_capable_noaudit() instead of capable().
--- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/io_uring.c +1 -1
@@ -3859,7 +3859,7 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, ctx->syscall_iopoll =1 ; ctx->compat =in_compat_syscall (); -if (!capable (CAP_IPC_LOCK )) +if (!ns_capable_noaudit (&init_user_ns,CAP_IPC_LOCK )) ctx->user =get_uid (current_user ());/*
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 14/239 gpio: tps68470: Make tps68470_gpio_output() always set the initial value
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 5a7adc6c1069ce31ef4f606ae9c05592c80a6ab5 ]
Make tps68470_gpio_output() call tps68470_gpio_set() for output-only pins too, so that the initial value passed to gpiod_direction_output() is honored for these pins too.
--- drivers/gpio/gpio-tps68470.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpio/gpio-tps68470.c +3 -3
@@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset,struct tps68470_gpio_data *tps68470_gpio =gpiochip_get_data (gc);struct regmap *regmap = tps68470_gpio->tps68470_regmap; +/* Set the initial value */ +tps68470_gpio_set (gc, offset, value); +/* rest are always outputs */ if (offset >=TPS68470_N_REGULAR_GPIO )return 0 ; -/* Set the initial value */ -tps68470_gpio_set (gc, offset, value); -return regmap_update_bits (regmap,TPS68470_GPIO_CTL_REG_A (offset),TPS68470_GPIO_MODE_MASK ,TPS68470_GPIO_MODE_OUT_CMOS );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 15/239 gpio: mvebu: Make use of devm_pwmchip_add
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit 1945063eb59e64d2919cb14d54d081476d9e53bb ]
This allows to get rid of a call to pwmchip_remove() in the error path. There is no .remove function for this driver, so this change fixes a resource leak when a gpio-mvebu device is unbound.
--- drivers/gpio/gpio-mvebu.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/gpio/gpio-mvebu.c +2 -6
@@ -874,7 +874,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,spin_lock_init (&mvpwm->lock); -return pwmchip_add (&mvpwm->chip); +return devm_pwmchip_add (dev, &mvpwm->chip); }#ifdef CONFIG_DEBUG_FS
@@ -1243,8 +1243,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)if (!mvchip->domain) {dev_err (&pdev->dev,"couldn't allocate irq domain %s (DT).\n" , mvchip->chip.label); - err = -ENODEV ; - goto err_pwm; +return -ENODEV ; } err = irq_alloc_domain_generic_chips(
@@ -1296,9 +1295,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) err_domain:irq_domain_remove (mvchip->domain); -err_pwm: -pwmchip_remove (&mvchip->mvpwm->chip); -return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 16/239 gpio: mvebu: fix irq domain leak
In reply to Greg Kroah-HartmanFrom: Bartosz Golaszewski <[email protected]>
[ Upstream commit 644ee70267a934be27370f9aa618b29af7290544 ]
Uwe Kleine-König pointed out we still have one resource leak in the mvebu driver triggered on driver detach. Let's address it with a custom devm action.
--- drivers/gpio/gpio-mvebu.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/gpio/gpio-mvebu.c +13 -5
@@ -1112,6 +1112,13 @@ static int mvebu_gpio_probe_syscon(struct platform_device *pdev,return 0 ; } +static void mvebu_gpio_remove_irq_domain (void *data) +{ +struct irq_domain *domain = data; + +irq_domain_remove (domain); +} +static int mvebu_gpio_probe (struct platform_device *pdev) {struct mvebu_gpio_chip *mvchip;
@@ -1246,13 +1253,18 @@ static int mvebu_gpio_probe(struct platform_device *pdev)return -ENODEV ; } + err =devm_add_action_or_reset (&pdev->dev, mvebu_gpio_remove_irq_domain, + mvchip->domain); +if (err) +return err; + err =irq_alloc_domain_generic_chips ( mvchip->domain, ngpios,2 , np->name, handle_level_irq,IRQ_NOREQUEST |IRQ_NOPROBE |IRQ_LEVEL ,0 ,0 );if (err) {dev_err (&pdev->dev,"couldn't allocate irq chips %s (DT).\n" , mvchip->chip.label); - goto err_domain; +return err; }/*
@@ -1292,10 +1304,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) }return 0 ; - -err_domain: -irq_domain_remove (mvchip->domain); -return err; }static struct platform_driver mvebu_gpio_driver = {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 17/239 regmap: Disable locking for RBTREE and MAPLE unit tests
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit a9e26169cfda651802f88262a315146fbe4bc74c ]
REGCACHE_RBTREE and REGCACHE_MAPLE dynamically allocate memory for regmap operations. This is incompatible with spinlock based locking which is used for fast_io operations. Disable locking for the associated unit tests to avoid lockdep splashes.
--- drivers/base/regmap/regmap-kunit.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/base/regmap/regmap-kunit.c +3 -0
@@ -58,6 +58,9 @@ static struct regmap *gen_regmap(struct regmap_config *config,int i;struct reg_default *defaults; + config->disable_locking = config->cache_type ==REGCACHE_RBTREE || + config->cache_type ==REGCACHE_MAPLE ; + buf =kmalloc (size,GFP_KERNEL );if (!buf)return ERR_PTR (-ENOMEM );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 18/239 btrfs: factor out a btrfs_verify_page helper
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit ed9ee98ecb4fdbdfe043ee3eec0a65c0745d8669 ]
Split all the conditionals for the fsverity calls in end_page_read into a btrfs_verify_page helper to keep the code readable and make additional refactoring easier.
Stable-dep-of: 2c14f0ffdd30 ("btrfs: fix fsverify read error handling in end_page_read")
--- fs/btrfs/extent_io.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
fs/btrfs/extent_io.c +10 -5
@@ -478,6 +478,15 @@ void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end, start, end, page_ops, NULL); } +static bool btrfs_verify_page (struct page *page,u64 start) +{ +if (!fsverity_active (page->mapping->host) || +PageError (page) ||PageUptodate (page) || + start >=i_size_read (page->mapping->host)) +return true; +return fsverity_verify_page (page); +} +static void end_page_read (struct page *page,bool uptodate,u64 start,u32 len) {struct btrfs_fs_info *fs_info =btrfs_sb (page->mapping->host->i_sb);
@@ -486,11 +495,7 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len) start + len <= page_offset(page) + PAGE_SIZE);if (uptodate) { -if (fsverity_active (page->mapping->host) && - !PageError (page) && - !PageUptodate (page) && - start <i_size_read (page->mapping->host) && - !fsverity_verify_page (page)) { +if (!btrfs_verify_page (page, start)) {btrfs_page_set_error (fs_info, page, start, len); }else {btrfs_page_set_uptodate (fs_info, page, start, len);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 19/239 btrfs: fix fsverify read error handling in end_page_read
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 2c14f0ffdd30bd3d321ad5fe76fcf701746e1df6 ]
Also clear the uptodate bit to make sure the page isn't seen as uptodate in the page cache if fsverity verification fails.
--- fs/btrfs/extent_io.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
fs/btrfs/extent_io.c +2 -6
@@ -494,12 +494,8 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len)ASSERT (page_offset (page) <= start && start + len <=page_offset (page) +PAGE_SIZE ); -if (uptodate) { -if (!btrfs_verify_page (page, start)) { -btrfs_page_set_error (fs_info, page, start, len); - }else { -btrfs_page_set_uptodate (fs_info, page, start, len); - } +if (uptodate &&btrfs_verify_page (page, start)) { +btrfs_page_set_uptodate (fs_info, page, start, len); }else {btrfs_page_clear_uptodate (fs_info, page, start, len);btrfs_page_set_error (fs_info, page, start, len);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 20/239 btrfs: fix race between quota disable and relocation
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
[ Upstream commit 8a4a0b2a3eaf75ca8854f856ef29690c12b2f531 ]
If we disable quotas while we have a relocation of a metadata block group that has extents belonging to the quota root, we can cause the relocation to fail with -ENOENT. This is because relocation builds backref nodes for extents of the quota root and later needs to walk the backrefs and access the quota root - however if in between a task disables quotas, it results in deleting the quota root from the root tree (with btrfs_del_root(), called from btrfs_quota_disable().
This can be sporadically triggered by test case btrfs/255 from fstests:
$ ./check btrfs/255 FSTYP -- btrfs PLATFORM -- Linux/x86_64 debian0 6.4.0-rc6-btrfs-next-134+ #1 SMP PREEMPT_DYNAMIC Thu Jun 15 11:59:28 WEST 2023 MKFS_OPTIONS -- /dev/sdc MOUNT_OPTIONS -- /dev/sdc /home/fdmanana/btrfs-tests/scratch_1
btrfs/255 6s ... _check_dmesg: something found in dmesg (see /home/fdmanana/git/hub/xfstests/results//btrfs/255.dmesg)
- output mismatch (see /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad)
# --- tests/btrfs/255.out 2023-03-02 21:47:53.876609426 +0000 # +++ /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad 2023-06-16 10:20:39.267563212 +0100 # @@ -1,2 +1,4 @@
# QA output created by 255
# +ERROR: error during balancing '/home/fdmanana/btrfs-tests/scratch_1': No such file or directory
# +There may be more info in syslog - try dmesg | tail
# Silence is golden
# ...
(Run 'diff -u /home/fdmanana/git/hub/xfstests/tests/btrfs/255.out /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad' to see the entire diff)
Ran: btrfs/255
Failures: btrfs/255
Failed 1 of 1 tests
To fix this make the quota disable operation take the cleaner mutex, as relocation of a block group also takes this mutex. This is also what we do when deleting a subvolume/snapshot, we take the cleaner mutex in the cleaner kthread (at cleaner_kthread()) and then we call btrfs_del_root() at btrfs_drop_snapshot() while under the protection of the cleaner mutex.
--- fs/btrfs/qgroup.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
fs/btrfs/qgroup.c +15 -3
@@ -1232,12 +1232,23 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)int ret =0 ;/* -* We need to have subvol_sem write locked, to prevent races between -* concurrent tasks trying to disable quotas, because we will unlock -* and relock qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes. +* We need to have subvol_sem write locked to prevent races with +* snapshot creation. */ lockdep_assert_held_write (&fs_info->subvol_sem); +/* +* Lock the cleaner mutex to prevent races with concurrent relocation, +* because relocation may be building backrefs for blocks of the quota +* root while we are deleting the root. This is like dropping fs roots +* of deleted snapshots/subvolumes, we need the same protection. +* +* This also prevents races between concurrent tasks trying to disable +* quotas, because we will unlock and relock qgroup_ioctl_lock across +* BTRFS_FS_QUOTA_ENABLED changes. +*/ +mutex_lock (&fs_info->cleaner_mutex); +mutex_lock (&fs_info->qgroup_ioctl_lock);if (!fs_info->quota_root) goto out;
@@ -1319,6 +1330,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)btrfs_end_transaction (trans); else if (trans) ret =btrfs_end_transaction (trans); +mutex_unlock (&fs_info->cleaner_mutex);return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 21/239 i2c: Delete error messages for failed memory allocations
In reply to Greg Kroah-HartmanFrom: Markus Elfring <[email protected]>
[ Upstream commit 6b3b21a8542fd2fb6ffc61bc13b9419f0c58ebad ]
These issues were detected by using the Coccinelle software.
Stable-dep-of: 05f933d5f731 ("i2c: nomadik: Remove a useless call in the remove function")
--- drivers/i2c/busses/i2c-ibm_iic.c | 4 +--- drivers/i2c/busses/i2c-nomadik.c | 1 - drivers/i2c/busses/i2c-sh7760.c | 1 - drivers/i2c/busses/i2c-tiny-usb.c | 4 +--- 4 files changed, 2 insertions(+), 8 deletions(-)
drivers/i2c/busses/i2c-ibm_iic.c +1 -3
@@ -694,10 +694,8 @@ static int iic_probe(struct platform_device *ofdev)int ret; dev =kzalloc (sizeof (*dev),GFP_KERNEL ); -if (!dev) { -dev_err (&ofdev->dev,"failed to allocate device data\n" ); +if (!dev)return -ENOMEM ; - }platform_set_drvdata (ofdev, dev);
drivers/i2c/busses/i2c-nomadik.c +0 -1
@@ -972,7 +972,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) dev =devm_kzalloc (&adev->dev,sizeof (struct nmk_i2c_dev ),GFP_KERNEL );if (!dev) { -dev_err (&adev->dev,"cannot allocate memory\n" ); ret = -ENOMEM ; goto err_no_mem; }
drivers/i2c/busses/i2c-sh7760.c +0 -1
@@ -445,7 +445,6 @@ static int sh7760_i2c_probe(struct platform_device *pdev) id =kzalloc (sizeof (struct cami2c ),GFP_KERNEL );if (!id) { -dev_err (&pdev->dev,"no mem for private data\n" ); ret = -ENOMEM ; goto out0; }
drivers/i2c/busses/i2c-tiny-usb.c +1 -3
@@ -226,10 +226,8 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface,/* allocate memory for our device state and initialize it */ dev =kzalloc (sizeof (*dev),GFP_KERNEL ); -if (dev ==NULL ) { -dev_err (&interface->dev,"Out of memory\n" ); +if (!dev) goto error; - } dev->usb_dev =usb_get_dev (interface_to_usbdev (interface)); dev->interface = interface;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 22/239 i2c: Improve size determinations
In reply to Greg Kroah-HartmanFrom: Markus Elfring <[email protected]>
[ Upstream commit 06e989578232da33a7fe96b04191b862af8b2cec ]
Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Stable-dep-of: 05f933d5f731 ("i2c: nomadik: Remove a useless call in the remove function")
--- drivers/i2c/busses/i2c-nomadik.c | 2 +- drivers/i2c/busses/i2c-sh7760.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-nomadik.c +1 -1
@@ -970,7 +970,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)struct i2c_vendor_data *vendor = id->data;u32 max_fifo_threshold = (vendor->fifodepth /2 ) -1 ; - dev =devm_kzalloc (&adev->dev,sizeof (struct nmk_i2c_dev ),GFP_KERNEL ); + dev =devm_kzalloc (&adev->dev,sizeof (*dev),GFP_KERNEL );if (!dev) { ret = -ENOMEM ; goto err_no_mem;
drivers/i2c/busses/i2c-sh7760.c +1 -1
@@ -443,7 +443,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev) goto out0; } - id =kzalloc (sizeof (struct cami2c ),GFP_KERNEL ); + id =kzalloc (sizeof (*id),GFP_KERNEL );if (!id) { ret = -ENOMEM ; goto out0;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 23/239 i2c: nomadik: Remove unnecessary goto label
In reply to Greg Kroah-HartmanFrom: Andi Shyti <[email protected]>
[ Upstream commit 1c5d33fff0d375e4ab7c4261dc62a286babbb4c6 ]
The err_no_mem goto label doesn't do anything. Remove it.
Stable-dep-of: 05f933d5f731 ("i2c: nomadik: Remove a useless call in the remove function")
--- drivers/i2c/busses/i2c-nomadik.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/i2c/busses/i2c-nomadik.c +8 -13
@@ -971,10 +971,9 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)u32 max_fifo_threshold = (vendor->fifodepth /2 ) -1 ; dev =devm_kzalloc (&adev->dev,sizeof (*dev),GFP_KERNEL ); -if (!dev) { - ret = -ENOMEM ; - goto err_no_mem; - } +if (!dev) +return -ENOMEM ; + dev->vendor = vendor; dev->adev = adev;nmk_i2c_of_probe (np, dev);
@@ -995,30 +994,27 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) dev->virtbase =devm_ioremap (&adev->dev, adev->res.start,resource_size (&adev->res)); -if (!dev->virtbase) { - ret = -ENOMEM ; - goto err_no_mem; - } +if (!dev->virtbase) +return -ENOMEM ; dev->irq = adev->irq[0 ]; ret =devm_request_irq (&adev->dev, dev->irq, i2c_irq_handler,0 ,DRIVER_NAME , dev);if (ret) {dev_err (&adev->dev,"cannot claim the irq %d\n" , dev->irq); - goto err_no_mem; +return ret; } dev->clk =devm_clk_get (&adev->dev,NULL );if (IS_ERR (dev->clk)) {dev_err (&adev->dev,"could not get i2c clock\n" ); - ret =PTR_ERR (dev->clk); - goto err_no_mem; +return PTR_ERR (dev->clk); } ret =clk_prepare_enable (dev->clk);if (ret) {dev_err (&adev->dev,"can't prepare_enable clock\n" ); - goto err_no_mem; +return ret; }init_hw (dev);
@@ -1049,7 +1045,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) err_no_adap:clk_disable_unprepare (dev->clk); - err_no_mem:return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 24/239 i2c: nomadik: Use devm_clk_get_enabled()
In reply to Greg Kroah-HartmanFrom: Andi Shyti <[email protected]>
[ Upstream commit 9c7174db4cdd111e10d19eed5c36fd978a14c8a2 ]
Replace the pair of functions, devm_clk_get() andclk_prepare_enable(), with a single functiondevm_clk_get_enabled().
Stable-dep-of: 05f933d5f731 ("i2c: nomadik: Remove a useless call in the remove function")
--- drivers/i2c/busses/i2c-nomadik.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
drivers/i2c/busses/i2c-nomadik.c +3 -15
@@ -1005,18 +1005,12 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)return ret; } - dev->clk =devm_clk_get (&adev->dev,NULL ); + dev->clk =devm_clk_get_enabled (&adev->dev,NULL );if (IS_ERR (dev->clk)) { -dev_err (&adev->dev,"could not get i2c clock\n" ); +dev_err (&adev->dev,"could enable i2c clock\n" );return PTR_ERR (dev->clk); } - ret =clk_prepare_enable (dev->clk); -if (ret) { -dev_err (&adev->dev,"can't prepare_enable clock\n" ); -return ret; - } -init_hw (dev); adap = &dev->adap;
@@ -1037,16 +1031,11 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) ret =i2c_add_adapter (adap);if (ret) - goto err_no_adap; +return ret;pm_runtime_put (&adev->dev);return 0 ; - - err_no_adap: -clk_disable_unprepare (dev->clk); - -return ret; }static void nmk_i2c_remove (struct amba_device *adev)
@@ -1060,7 +1049,6 @@ static void nmk_i2c_remove(struct amba_device *adev)clear_all_interrupts (dev);/* disable the controller */ i2c_clr_bit (dev->virtbase +I2C_CR ,I2C_CR_PE ); -clk_disable_unprepare (dev->clk);release_mem_region (res->start,resource_size (res)); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 25/239 i2c: nomadik: Remove a useless call in the remove function
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 05f933d5f7318b03ff2028c1704dc867ac16f2c7 ]
Since commit 235602146ec9 ("i2c-nomadik: turn the platform driver to an amba driver"), there is no more request_mem_region() call in this driver.
So remove the release_mem_region() call from the remove function which is likely a left over.
--- drivers/i2c/busses/i2c-nomadik.c | 2 -- 1 file changed, 2 deletions(-)
drivers/i2c/busses/i2c-nomadik.c +0 -2
@@ -1040,7 +1040,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)static void nmk_i2c_remove (struct amba_device *adev) { -struct resource *res = &adev->res;struct nmk_i2c_dev *dev =amba_get_drvdata (adev);i2c_del_adapter (&dev->adap);
@@ -1049,7 +1048,6 @@ static void nmk_i2c_remove(struct amba_device *adev)clear_all_interrupts (dev);/* disable the controller */ i2c_clr_bit (dev->virtbase +I2C_CR ,I2C_CR_PE ); -release_mem_region (res->start,resource_size (res)); }static struct i2c_vendor_data vendor_stn8815 = {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 26/239 PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link()
In reply to Greg Kroah-HartmanFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit f5297a01ee805d7fa569d288ed65fc0f9ac9b03d ]
"pcie_retrain_link" is not a question with a true/false answer, so "bool" isn't quite the right return type. Return 0 for success or -ETIMEDOUT if the retrain failed. No functional change intended.
Stable-dep-of: e7e39756363a ("PCI/ASPM: Avoid link retraining race")
--- drivers/pci/pcie/aspm.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/pci/pcie/aspm.c +11 -9
@@ -193,7 +193,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) link->clkpm_disable = blacklist ?1 :0 ; } -static bool pcie_retrain_link (struct pcie_link_state *link) +static int pcie_retrain_link (struct pcie_link_state *link) {struct pci_dev *parent = link->pdev;unsigned long end_jiffies;
@@ -220,7 +220,9 @@ static bool pcie_retrain_link(struct pcie_link_state *link)break ;msleep (1 ); }while (time_before (jiffies, end_jiffies)); -return !(reg16 &PCI_EXP_LNKSTA_LT ); +if (reg16 &PCI_EXP_LNKSTA_LT ) +return -ETIMEDOUT ; +return 0 ; }/*
@@ -289,15 +291,15 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) reg16 &= ~PCI_EXP_LNKCTL_CCC ;pcie_capability_write_word (parent,PCI_EXP_LNKCTL , reg16); -if (pcie_retrain_link (link)) -return ; +if (pcie_retrain_link (link)) { -/* Training failed. Restore common clock configurations */ -pci_err (parent,"ASPM: Could not configure common clock\n" ); -list_for_each_entry (child, &linkbus->devices, bus_list) -pcie_capability_write_word (child,PCI_EXP_LNKCTL , +/* Training failed. Restore common clock configurations */ +pci_err (parent,"ASPM: Could not configure common clock\n" ); +list_for_each_entry (child, &linkbus->devices, bus_list) +pcie_capability_write_word (child,PCI_EXP_LNKCTL , child_reg[PCI_FUNC (child->devfn)]); -pcie_capability_write_word (parent,PCI_EXP_LNKCTL , parent_reg); +pcie_capability_write_word (parent,PCI_EXP_LNKCTL , parent_reg); + } }/* Convert L0s latency encoding to ns */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 27/239 PCI/ASPM: Factor out pcie_wait_for_retrain()
In reply to Greg Kroah-HartmanFrom: Ilpo Järvinen <[email protected]>
[ Upstream commit 9c7f136433d26592cb4d9cd00b4e15c33d9797c6 ]
Factor pcie_wait_for_retrain() out from pcie_retrain_link(). No functional change intended.
[bhelgaas: split out from
https: //lore.kernel.org/r/[email protected]]
Stable-dep-of: e7e39756363a ("PCI/ASPM: Avoid link retraining race")
--- drivers/pci/pcie/aspm.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
drivers/pci/pcie/aspm.c +18 -12
@@ -193,10 +193,26 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) link->clkpm_disable = blacklist ?1 :0 ; } +static int pcie_wait_for_retrain (struct pci_dev *pdev) +{ +unsigned long end_jiffies; +u16 reg16; + +/* Wait for Link Training to be cleared by hardware */ + end_jiffies = jiffies +LINK_RETRAIN_TIMEOUT ; +do { +pcie_capability_read_word (pdev,PCI_EXP_LNKSTA , ®16); +if (!(reg16 &PCI_EXP_LNKSTA_LT )) +return 0 ; +msleep (1 ); + }while (time_before (jiffies, end_jiffies)); + +return -ETIMEDOUT ; +} +static int pcie_retrain_link (struct pcie_link_state *link) {struct pci_dev *parent = link->pdev; -unsigned long end_jiffies;u16 reg16;pcie_capability_read_word (parent,PCI_EXP_LNKCTL , ®16);
@@ -212,17 +228,7 @@ static int pcie_retrain_link(struct pcie_link_state *link)pcie_capability_write_word (parent,PCI_EXP_LNKCTL , reg16); } -/* Wait for link training end. Break out after waiting for timeout */ - end_jiffies = jiffies +LINK_RETRAIN_TIMEOUT ; -do { -pcie_capability_read_word (parent,PCI_EXP_LNKSTA , ®16); -if (!(reg16 &PCI_EXP_LNKSTA_LT )) -break ; -msleep (1 ); - }while (time_before (jiffies, end_jiffies)); -if (reg16 &PCI_EXP_LNKSTA_LT ) -return -ETIMEDOUT ; -return 0 ; +return pcie_wait_for_retrain (parent); }/*
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 28/239 PCI/ASPM: Avoid link retraining race
In reply to Greg Kroah-HartmanFrom: Ilpo Järvinen <[email protected]>
[ Upstream commit e7e39756363ad5bd83ddeae1063193d0f13870fd ]
PCIe r6.0.1, sec 7.5.3.7, recommends setting the link control parameters, then waiting for the Link Training bit to be clear before setting the Retrain Link bit.
This avoids a race where the LTSSM may not use the updated parameters if it is already in the midst of link training because of other normal link activity.
Wait for the Link Training bit to be clear before toggling the Retrain Link bit to ensure that the LTSSM uses the updated link control parameters.
[bhelgaas: commit log, return 0 (success)/-ETIMEDOUT instead of bool for both pcie_wait_for_retrain() and the existing pcie_retrain_link()]
--- drivers/pci/pcie/aspm.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/pci/pcie/aspm.c +11 -0
@@ -213,8 +213,19 @@ static int pcie_wait_for_retrain(struct pci_dev *pdev)static int pcie_retrain_link (struct pcie_link_state *link) {struct pci_dev *parent = link->pdev; +int rc;u16 reg16; +/* +* Ensure the updated LNKCTL parameters are used during link +* training by checking that there is no ongoing link training to +* avoid LTSSM race as recommended in Implementation Note at the +* end of PCIe r6.0.1 sec 7.5.3.7. +*/ + rc =pcie_wait_for_retrain (parent); +if (rc) +return rc; +pcie_capability_read_word (parent,PCI_EXP_LNKCTL , ®16); reg16 |=PCI_EXP_LNKCTL_RL ;pcie_capability_write_word (parent,PCI_EXP_LNKCTL , reg16);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 29/239 PCI: rockchip: Remove writes to unused registers
In reply to Greg Kroah-HartmanFrom: Rick Wertenbroek <[email protected]>
[ Upstream commit 92a9c57c325dd51682d428ba960d961fec3c8a08 ]
Remove write accesses to registers that are marked "unused" (and therefore read-only) in the technical reference manual (TRM) (see RK3399 TRM 17.6.8.1)
Stable-dep-of: dc73ed0f1b8b ("PCI: rockchip: Fix window mapping and address translation for endpoint")
--- drivers/pci/controller/pcie-rockchip-ep.c | 10 ---------- 1 file changed, 10 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +0 -10
@@ -61,10 +61,6 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip, ROCKCHIP_PCIE_AT_OB_REGION_DESC0(region));rockchip_pcie_write (rockchip,0 ,ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (region)); -rockchip_pcie_write (rockchip,0 , -ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0 (region)); -rockchip_pcie_write (rockchip,0 , -ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1 (region)); } static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
@@ -114,12 +110,6 @@ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, PCIE_CORE_OB_REGION_ADDR0_LO_ADDR); addr1 =upper_32_bits (cpu_addr); } - -/* CPU bus address region */ -rockchip_pcie_write (rockchip, addr0, -ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0 (r)); -rockchip_pcie_write (rockchip, addr1, -ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1 (r)); } static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 30/239 PCI: rockchip: Fix window mapping and address translation for endpoint
In reply to Greg Kroah-HartmanFrom: Rick Wertenbroek <[email protected]>
[ Upstream commit dc73ed0f1b8bddd7f2bf70d123e68ffc99ad71ce ]
The RK3399 PCI endpoint core has 33 windows for PCIe space, now in the driver up to 32 fixed size (1M) windows are used and pages are allocated and mapped accordingly. The driver first used a single window and allocated space inside which caused translation issues (between CPU space and PCI space) because a window can only have a single translation at a given time, which if multiple pages are allocated inside will cause conflicts. Now each window is a single region of 1M which will always guarantee that the translation is not in conflict.
Set the translation register addresses for physical function. As documented in the technical reference manual (TRM) section 17.5.5 "PCIe Address Translation" and section 17.6.8 "Address Translation Registers Description"
--- drivers/pci/controller/pcie-rockchip-ep.c | 128 ++++++++++------------ drivers/pci/controller/pcie-rockchip.h | 35 +++--- 2 files changed, 75 insertions(+), 88 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +55 -73
@@ -64,52 +64,29 @@ static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip, }static void rockchip_pcie_prog_ep_ob_atu (struct rockchip_pcie *rockchip,u8 fn, -u32 r,u32 type,u64 cpu_addr, -u64 pci_addr,size_t size) +u32 r,u64 cpu_addr,u64 pci_addr, +size_t size) { -u64 sz =1ULL <<fls64 (size -1 ); -int num_pass_bits =ilog2 (sz); -u32 addr0, addr1, desc0, desc1; -bool is_nor_msg = (type ==AXI_WRAPPER_NOR_MSG ); +int num_pass_bits =fls64 (size -1 ); +u32 addr0, addr1, desc0; -/* The minimal region size is 1MB */ if (num_pass_bits <8 ) num_pass_bits =8 ; - cpu_addr -= rockchip->mem_res->start; - addr0 = ((is_nor_msg ?0x10 : (num_pass_bits -1 )) & -PCIE_CORE_OB_REGION_ADDR0_NUM_BITS ) | - (lower_32_bits (cpu_addr) &PCIE_CORE_OB_REGION_ADDR0_LO_ADDR ); - addr1 =upper_32_bits (is_nor_msg ? cpu_addr : pci_addr); - desc0 =ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN (fn) | type; - desc1 =0 ; - -if (is_nor_msg) { -rockchip_pcie_write (rockchip,0 , -ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0 (r)); -rockchip_pcie_write (rockchip,0 , -ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1 (r)); -rockchip_pcie_write (rockchip, desc0, -ROCKCHIP_PCIE_AT_OB_REGION_DESC0 (r)); -rockchip_pcie_write (rockchip, desc1, -ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (r)); - }else { -/* PCI bus address region */ -rockchip_pcie_write (rockchip, addr0, -ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0 (r)); -rockchip_pcie_write (rockchip, addr1, -ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1 (r)); -rockchip_pcie_write (rockchip, desc0, -ROCKCHIP_PCIE_AT_OB_REGION_DESC0 (r)); -rockchip_pcie_write (rockchip, desc1, -ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (r)); - - addr0 = - ((num_pass_bits -1 ) &PCIE_CORE_OB_REGION_ADDR0_NUM_BITS ) | - (lower_32_bits (cpu_addr) & -PCIE_CORE_OB_REGION_ADDR0_LO_ADDR ); - addr1 =upper_32_bits (cpu_addr); - } + addr0 = ((num_pass_bits -1 ) &PCIE_CORE_OB_REGION_ADDR0_NUM_BITS ) | + (lower_32_bits (pci_addr) &PCIE_CORE_OB_REGION_ADDR0_LO_ADDR ); + addr1 =upper_32_bits (pci_addr); + desc0 =ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN (fn) |AXI_WRAPPER_MEM_WRITE ; + +/* PCI bus address region */ +rockchip_pcie_write (rockchip, addr0, +ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0 (r)); +rockchip_pcie_write (rockchip, addr1, +ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1 (r)); +rockchip_pcie_write (rockchip, desc0, +ROCKCHIP_PCIE_AT_OB_REGION_DESC0 (r)); +rockchip_pcie_write (rockchip,0 , +ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (r)); } static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
@@ -248,26 +225,20 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar)); } +static inline u32 rockchip_ob_region (phys_addr_t addr) +{ +return (addr >>ilog2 (SZ_1M )) &0x1f ; +} +static int rockchip_pcie_ep_map_addr (struct pci_epc *epc,u8 fn,u8 vfn,phys_addr_t addr,u64 pci_addr,size_t size) {struct rockchip_pcie_ep *ep =epc_get_drvdata (epc);struct rockchip_pcie *pcie = &ep->rockchip; -u32 r; +u32 r =rockchip_ob_region (addr); - r =find_first_zero_bit (&ep->ob_region_map,BITS_PER_LONG ); -/* -* Region 0 is reserved for configuration space and shouldn't -* be used elsewhere per TRM, so leave it out. -*/ -if (r >= ep->max_regions -1 ) { -dev_err (&epc->dev,"no free outbound region\n" ); -return -EINVAL ; - } - -rockchip_pcie_prog_ep_ob_atu (pcie, fn, r,AXI_WRAPPER_MEM_WRITE , addr, - pci_addr, size); +rockchip_pcie_prog_ep_ob_atu (pcie, fn, r, addr, pci_addr, size);set_bit (r, &ep->ob_region_map); ep->ob_addr[r] = addr;
@@ -282,15 +253,11 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,struct rockchip_pcie *rockchip = &ep->rockchip;u32 r; -for (r =0 ; r < ep->max_regions -1 ; r++) +for (r =0 ; r < ep->max_regions; r++)if (ep->ob_addr[r] == addr)break ; -/* -* Region 0 is reserved for configuration space and shouldn't -* be used elsewhere per TRM, so leave it out. -*/ -if (r == ep->max_regions -1 ) +if (r == ep->max_regions)return ;rockchip_pcie_clear_ep_ob_atu (rockchip, r);
@@ -387,7 +354,8 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,struct rockchip_pcie *rockchip = &ep->rockchip;u32 flags, mme, data, data_mask;u8 msi_count; -u64 pci_addr, pci_addr_mask =0xff ; +u64 pci_addr; +u32 r;/* Check MSI enable bit */ flags = rockchip_pcie_read(&ep->rockchip,
@@ -421,21 +389,20 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,ROCKCHIP_PCIE_EP_FUNC_BASE (fn) +ROCKCHIP_PCIE_EP_MSI_CTRL_REG + PCI_MSI_ADDRESS_LO); - pci_addr &=GENMASK_ULL (63 ,2 );/* Set the outbound region if needed. */ -if (unlikely (ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) || +if (unlikely (ep->irq_pci_addr != (pci_addr &PCIE_ADDR_MASK ) || ep->irq_pci_fn != fn)) { -rockchip_pcie_prog_ep_ob_atu (rockchip, fn, ep->max_regions -1 , -AXI_WRAPPER_MEM_WRITE , + r =rockchip_ob_region (ep->irq_phys_addr); +rockchip_pcie_prog_ep_ob_atu (rockchip, fn, r, ep->irq_phys_addr, - pci_addr & ~pci_addr_mask, - pci_addr_mask +1 ); - ep->irq_pci_addr = (pci_addr & ~pci_addr_mask); + pci_addr &PCIE_ADDR_MASK , + ~PCIE_ADDR_MASK +1 ); + ep->irq_pci_addr = (pci_addr &PCIE_ADDR_MASK ); ep->irq_pci_fn = fn; } -writew (data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask)); +writew (data, ep->irq_cpu_addr + (pci_addr & ~PCIE_ADDR_MASK ));return 0 ; }
@@ -517,6 +484,8 @@ static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,if (err <0 || ep->max_regions >MAX_REGION_LIMIT ) ep->max_regions =MAX_REGION_LIMIT ; + ep->ob_region_map =0 ; + err =of_property_read_u8 (dev->of_node,"max-functions" , &ep->epc->max_functions);if (err <0 )
@@ -537,7 +506,8 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)struct rockchip_pcie *rockchip;struct pci_epc *epc;size_t max_regions; -int err; +struct pci_epc_mem_window *windows =NULL ; +int err, i; ep =devm_kzalloc (dev,sizeof (*ep),GFP_KERNEL );if (!ep)
@@ -584,15 +554,27 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)/* Only enable function 0 by default */ rockchip_pcie_write (rockchip,BIT (0 ),PCIE_CORE_PHY_FUNC_CFG ); - err =pci_epc_mem_init (epc, rockchip->mem_res->start, -resource_size (rockchip->mem_res),PAGE_SIZE ); + windows =devm_kcalloc (dev, ep->max_regions, +sizeof (struct pci_epc_mem_window ),GFP_KERNEL ); +if (!windows) { + err = -ENOMEM ; + goto err_uninit_port; + } +for (i =0 ; i < ep->max_regions; i++) { + windows[i].phys_base = rockchip->mem_res->start + (SZ_1M * i); + windows[i].size =SZ_1M ; + windows[i].page_size =SZ_1M ; + } + err =pci_epc_multi_mem_init (epc, windows, ep->max_regions); +devm_kfree (dev, windows); +if (err <0 ) {dev_err (dev,"failed to initialize the memory space\n" ); goto err_uninit_port; } ep->irq_cpu_addr =pci_epc_mem_alloc_addr (epc, &ep->irq_phys_addr, -SZ_128K ); +SZ_1M );if (!ep->irq_cpu_addr) {dev_err (dev,"failed to reserve memory space for MSI\n" ); err = -ENOMEM ;
drivers/pci/controller/pcie-rockchip.h +20 -15
@@ -139,6 +139,7 @@#define PCIE_RC_RP_ATS_BASE 0x400000#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 +#define PCIE_EP_PF_CONFIG_REGS_BASE 0x800000#define PCIE_RC_CONFIG_BASE 0xa00000#define PCIE_EP_CONFIG_BASE 0xa00000#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)
@@ -157,10 +158,11 @@#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20) +#define PCIE_ADDR_MASK 0xffffff00#define PCIE_CORE_AXI_CONF_BASE 0xc00000#define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0)#define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f -#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR 0xffffff00 +#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK#define PCIE_CORE_OB_REGION_ADDR1 (PCIE_CORE_AXI_CONF_BASE + 0x4)#define PCIE_CORE_OB_REGION_DESC0 (PCIE_CORE_AXI_CONF_BASE + 0x8)#define PCIE_CORE_OB_REGION_DESC1 (PCIE_CORE_AXI_CONF_BASE + 0xc)
@@ -168,7 +170,7 @@#define PCIE_CORE_AXI_INBOUND_BASE 0xc00800#define PCIE_RP_IB_ADDR0 (PCIE_CORE_AXI_INBOUND_BASE + 0x0)#define PCIE_CORE_IB_REGION_ADDR0_NUM_BITS 0x3f -#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR 0xffffff00 +#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR PCIE_ADDR_MASK#define PCIE_RP_IB_ADDR1 (PCIE_CORE_AXI_INBOUND_BASE + 0x4)/* Size of one AXI Region (not Region 0) */
@@ -233,13 +235,15 @@#define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16)#define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24)#define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1 -#define ROCKCHIP_PCIE_EP_FUNC_BASE (fn) (((fn) << 12) & GENMASK(19, 12)) +#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3 +#define ROCKCHIP_PCIE_EP_FUNC_BASE (fn) \ + (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12))) +#define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE (fn) \ + (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12)))#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn, bar) \ - (PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008) + (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn, bar) \ - (PCIE_RC_RP_ATS_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008) -#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x0000 + ((r) & 0x1f) * 0x0020) + (PCIE_CORE_AXI_CONF_BASE + 0x082c + (fn) * 0x0040 + (bar) * 0x0008)#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12)#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN (devfn) \ (((devfn) << 12) & \
@@ -247,20 +251,21 @@#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20)#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS (bus) \ (((bus) << 20) & ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK) +#define PCIE_RC_EP_ATR_OB_REGIONS_1_32 (PCIE_CORE_AXI_CONF_BASE + 0x0020) +#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0 (r) \ + (PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0000 + ((r) & 0x1f) * 0x0020)#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x0004 + ((r) & 0x1f) * 0x0020) + (PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0004 + ((r) & 0x1f) * 0x0020)#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23)#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24)#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN (devfn) \ (((devfn) << 24) & ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x0008 + ((r) & 0x1f) * 0x0020) -#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x000c + ((r) & 0x1f) * 0x0020) -#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x0018 + ((r) & 0x1f) * 0x0020) -#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1 (r) \ - (PCIE_RC_RP_ATS_BASE + 0x001c + ((r) & 0x1f) * 0x0020) + (PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0008 + ((r) & 0x1f) * 0x0020) +#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1 (r) \ + (PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x000c + ((r) & 0x1f) * 0x0020) +#define ROCKCHIP_PCIE_AT_OB_REGION_DESC2 (r) \ + (PCIE_RC_EP_ATR_OB_REGIONS_1_32 + 0x0010 + ((r) & 0x1f) * 0x0020)#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0 (fn) \ (PCIE_CORE_CTRL_MGMT_BASE + 0x0240 + (fn) * 0x0008)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 31/239 PCI: rockchip: Dont advertise MSI-X in PCIe capabilities
In reply to Greg Kroah-HartmanFrom: Rick Wertenbroek <[email protected]>
[ Upstream commit a52587e0bee14cbeeadf48a24013828cb04b8df8 ]
The RK3399 PCIe endpoint controller cannot generate MSI-X IRQs. This is documented in the RK3399 technical reference manual (TRM) section 17.5.9 "Interrupt Support".
MSI-X capability should therefore not be advertised. Remove the MSI-X capability by editing the capability linked-list. The previous entry is the MSI capability, therefore get the next entry from the MSI-X capability entry and set it as next entry for the MSI capability. This in effect removes MSI-X from the list.
Linked list before : MSI cap -> MSI-X cap -> PCIe Device cap -> ... Linked list now : MSI cap -> PCIe Device cap -> ...
--- drivers/pci/controller/pcie-rockchip-ep.c | 24 +++++++++++++++++++++++ drivers/pci/controller/pcie-rockchip.h | 5 +++++ 2 files changed, 29 insertions(+)
drivers/pci/controller/pcie-rockchip-ep.c +24 -0
@@ -508,6 +508,7 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)size_t max_regions;struct pci_epc_mem_window *windows =NULL ;int err, i; +u32 cfg_msi, cfg_msix_cp; ep =devm_kzalloc (dev,sizeof (*ep),GFP_KERNEL );if (!ep)
@@ -583,6 +584,29 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev) ep->irq_pci_addr =ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR ; +/* +* MSI-X is not supported but the controller still advertises the MSI-X +* capability by default, which can lead to the Root Complex side +* allocating MSI-X vectors which cannot be used. Avoid this by skipping +* the MSI-X capability entry in the PCIe capabilities linked-list: get +* the next pointer from the MSI-X entry and set that in the MSI +* capability entry (which is the previous entry). This way the MSI-X +* entry is skipped (left out of the linked-list) and not advertised. +*/ + cfg_msi =rockchip_pcie_read (rockchip,PCIE_EP_CONFIG_BASE + +ROCKCHIP_PCIE_EP_MSI_CTRL_REG ); + + cfg_msi &= ~ROCKCHIP_PCIE_EP_MSI_CP1_MASK ; + + cfg_msix_cp =rockchip_pcie_read (rockchip,PCIE_EP_CONFIG_BASE + +ROCKCHIP_PCIE_EP_MSIX_CAP_REG ) & +ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK ; + + cfg_msi |= cfg_msix_cp; + +rockchip_pcie_write (rockchip, cfg_msi, +PCIE_EP_CONFIG_BASE +ROCKCHIP_PCIE_EP_MSI_CTRL_REG ); +rockchip_pcie_write (rockchip,PCIE_CLIENT_CONF_ENABLE ,PCIE_CLIENT_CONFIG );
drivers/pci/controller/pcie-rockchip.h +5 -0
@@ -227,6 +227,8 @@#define ROCKCHIP_PCIE_EP_CMD_STATUS 0x4#define ROCKCHIP_PCIE_EP_CMD_STATUS_IS BIT(19)#define ROCKCHIP_PCIE_EP_MSI_CTRL_REG 0x90 +#define ROCKCHIP_PCIE_EP_MSI_CP1_OFFSET 8 +#define ROCKCHIP_PCIE_EP_MSI_CP1_MASK GENMASK(15, 8)#define ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET 16#define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET 17#define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK GENMASK(19, 17)
@@ -234,6 +236,9 @@#define ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK GENMASK(22, 20)#define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16)#define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24) +#define ROCKCHIP_PCIE_EP_MSIX_CAP_REG 0xb0 +#define ROCKCHIP_PCIE_EP_MSIX_CAP_CP_OFFSET 8 +#define ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK GENMASK(15, 8)#define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3#define ROCKCHIP_PCIE_EP_FUNC_BASE (fn) \
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 32/239 drm/amd/display: Convert Delaying Aux-I Disable To Monitor Patch
In reply to Greg Kroah-HartmanFrom: Michael Strauss <[email protected]>
[ Upstream commit 9fa8cc0c444562fa19e20ca20f1c70e15b9d8c13 ]
[WHY]
32ms delay was added to resolve issue with a specific sink, however this same delay also introduces erroneous link training failures with certain sink devices.
[HOW]
Only apply the 32ms delay for offending devices instead of globally.
Stable-dep-of: 5a096b73c8fe ("drm/amd/display: Keep disable aux-i delay as 0")
--- drivers/gpu/drm/amd/display/dc/dc.h | 1 - drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + .../link_dp_training_fixed_vs_pe_retimer.c | 17 +++++++++++------ 3 files changed, 12 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/display/dc/dc.h +0 -1
@@ -855,7 +855,6 @@ struct dc_debug_options {bool force_usr_allow;/* uses value at boot and disables switch */ bool disable_dtb_ref_clk_switch; -uint32_t fixed_vs_aux_delay_config_wa;bool extended_blank_optimization;union aux_wake_wa_options aux_wake_wa;uint32_t mst_start_top_delay;
drivers/gpu/drm/amd/display/dc/dc_types.h +1 -0
@@ -196,6 +196,7 @@ struct dc_panel_patch {unsigned int disable_fams;unsigned int skip_avmute;unsigned int mst_start_top_delay; +unsigned int delay_disable_aux_intercept_ms; };struct dc_edid_caps {
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +11 -6
@@ -233,7 +233,8 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( link->dpcd_caps.lttpr_caps.phy_repeater_cnt);const uint8_t vendor_lttpr_write_data_intercept_en[4 ] = {0x1 ,0x55 ,0x63 ,0x0 };const uint8_t vendor_lttpr_write_data_intercept_dis[4 ] = {0x1 ,0x55 ,0x63 ,0x68 }; -uint32_t pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; +uint32_t pre_disable_intercept_delay_ms = + link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms;uint8_t vendor_lttpr_write_data_vs[4 ] = {0x1 ,0x51 ,0x63 ,0x0 };uint8_t vendor_lttpr_write_data_pe[4 ] = {0x1 ,0x52 ,0x63 ,0x0 };uint32_t vendor_lttpr_write_address =0xF004F ;
@@ -259,7 +260,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy(/* Certain display and cable configuration require extra delay */ if (offset >2 ) - pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa *2 ; + pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms *2 ; }/* Vendor specific: Reset lane settings */
@@ -380,7 +381,8 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( 0);/* Vendor specific: Disable intercept */ for (i =0 ; i < max_vendor_dpcd_retries; i++) { -msleep (pre_disable_intercept_delay_ms); +if (pre_disable_intercept_delay_ms !=0 ) +msleep (pre_disable_intercept_delay_ms); dpcd_status = core_link_write_dpcd( link, vendor_lttpr_write_address,
@@ -591,9 +593,11 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence(const uint8_t vendor_lttpr_write_data_adicora_eq1[4 ] = {0x1 ,0x55 ,0x63 ,0x2E };const uint8_t vendor_lttpr_write_data_adicora_eq2[4 ] = {0x1 ,0x55 ,0x63 ,0x01 };const uint8_t vendor_lttpr_write_data_adicora_eq3[4 ] = {0x1 ,0x55 ,0x63 ,0x68 }; -uint32_t pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa;uint8_t vendor_lttpr_write_data_vs[4 ] = {0x1 ,0x51 ,0x63 ,0x0 };uint8_t vendor_lttpr_write_data_pe[4 ] = {0x1 ,0x52 ,0x63 ,0x0 }; +uint32_t pre_disable_intercept_delay_ms = + link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; +uint32_t vendor_lttpr_write_address =0xF004F ;enum link_training_result status =LINK_TRAINING_SUCCESS ;
@@ -618,7 +622,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence(/* Certain display and cable configuration require extra delay */ if (offset >2 ) - pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa *2 ; + pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms *2 ; }/* Vendor specific: Reset lane settings */
@@ -739,7 +743,8 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( 0);/* Vendor specific: Disable intercept */ for (i =0 ; i < max_vendor_dpcd_retries; i++) { -msleep (pre_disable_intercept_delay_ms); +if (pre_disable_intercept_delay_ms !=0 ) +msleep (pre_disable_intercept_delay_ms); dpcd_status = core_link_write_dpcd( link, vendor_lttpr_write_address,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 33/239 drm/amd/display: Keep disable aux-i delay as 0
In reply to Greg Kroah-HartmanFrom: Michael Strauss <[email protected]>
[ Upstream commit 5a096b73c8fed3a9987ba15378285df360e2284b ]
[WHY]
Current Aux-I sequence checks for local_sink which isn't populated on MST links
[HOW]
Leave disable aux-i delay as 0 for MST cases
--- .../link_dp_training_fixed_vs_pe_retimer.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +10 -6
@@ -233,8 +233,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( link->dpcd_caps.lttpr_caps.phy_repeater_cnt);const uint8_t vendor_lttpr_write_data_intercept_en[4 ] = {0x1 ,0x55 ,0x63 ,0x0 };const uint8_t vendor_lttpr_write_data_intercept_dis[4 ] = {0x1 ,0x55 ,0x63 ,0x68 }; -uint32_t pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; +uint32_t pre_disable_intercept_delay_ms =0 ;uint8_t vendor_lttpr_write_data_vs[4 ] = {0x1 ,0x51 ,0x63 ,0x0 };uint8_t vendor_lttpr_write_data_pe[4 ] = {0x1 ,0x52 ,0x63 ,0x0 };uint32_t vendor_lttpr_write_address =0xF004F ;
@@ -245,6 +244,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy(uint8_t toggle_rate;uint8_t rate; +if (link->local_sink) + pre_disable_intercept_delay_ms = + link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; +/* Only 8b/10b is supported */ ASSERT (link_dp_get_encoding_format (<_settings->link_settings) == DP_8b_10b_ENCODING);
@@ -595,10 +598,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence(const uint8_t vendor_lttpr_write_data_adicora_eq3[4 ] = {0x1 ,0x55 ,0x63 ,0x68 };uint8_t vendor_lttpr_write_data_vs[4 ] = {0x1 ,0x51 ,0x63 ,0x0 };uint8_t vendor_lttpr_write_data_pe[4 ] = {0x1 ,0x52 ,0x63 ,0x0 }; -uint32_t pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; - - +uint32_t pre_disable_intercept_delay_ms =0 ;uint32_t vendor_lttpr_write_address =0xF004F ;enum link_training_result status =LINK_TRAINING_SUCCESS ;uint8_t lane =0 ;
@@ -607,6 +607,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence(uint8_t toggle_rate;uint8_t rate; +if (link->local_sink) + pre_disable_intercept_delay_ms = + link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; +/* Only 8b/10b is supported */ ASSERT (link_dp_get_encoding_format (<_settings->link_settings) == DP_8b_10b_ENCODING);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 34/239 drm/amd/display: add pixel rate based CRB allocation support
In reply to Greg Kroah-HartmanFrom: Dmytro Laktyushkin <[email protected]>
[ Upstream commit 9ba90d760e9354c124fa9bbea08017d96699a82c ]
This feature is meant to unblock PSTATE for certain high end display configs on dcn315. This is achieved by allocating CRB to detile buffer based on display requirements to meet pstate latency hiding needs.
Stable-dep-of: 49f26218c344 ("drm/amd/display: fix dcn315 single stream crb allocation")
--- .../drm/amd/display/dc/dcn31/dcn31_hubbub.c | 1 + .../amd/display/dc/dcn315/dcn315_resource.c | 97 ++++++++++++++++++- .../drm/amd/display/dc/dml/dcn31/dcn31_fpu.c | 25 ++++- .../drm/amd/display/dc/dml/dcn31/dcn31_fpu.h | 3 + .../dc/dml/dcn31/display_mode_vba_31.c | 39 +++++--- .../drm/amd/display/dc/dml/display_mode_vba.c | 6 ++ 6 files changed, 154 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c +1 -0
@@ -103,6 +103,7 @@ static void dcn31_program_det_size(struct hubbub *hubbub, int hubp_inst, unsignedefault :break ; } +DC_LOG_DEBUG ("Set DET%d to %d segments\n" , hubp_inst, det_size_segments);/* Should never be hit, if it is we have an erroneous hw config*/ ASSERT (hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size + hubbub2->det3_size + hubbub2->compbuf_size_segments <= hubbub2->crb_size_segs);
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +93 -4
142 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +24 -1
@@ -483,7 +483,7 @@ void dcn31_calculate_wm_and_dlg_fp(int pipe_cnt, int vlevel) { - int i, pipe_idx, active_hubp_count = 0; + int i, pipe_idx, total_det = 0, active_hubp_count = 0;double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];dc_assert_fp_enabled ();
@@ -563,6 +563,18 @@ void dcn31_calculate_wm_and_dlg_fp(if (context->res_ctx.pipe_ctx[i].stream) context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =0 ; } +for (i =0 , pipe_idx =0 ; i < dc->res_pool->pipe_count; i++) { +if (!context->res_ctx.pipe_ctx[i].stream) +continue ; + + context->res_ctx.pipe_ctx[i].det_buffer_size_kb = +get_det_buffer_size_kbytes (&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); +if (context->res_ctx.pipe_ctx[i].det_buffer_size_kb >384 ) + context->res_ctx.pipe_ctx[i].det_buffer_size_kb /=2 ; + total_det += context->res_ctx.pipe_ctx[i].det_buffer_size_kb; + pipe_idx++; + } + context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - total_det; }void dcn31_update_bw_bounding_box (struct dc *dc,struct clk_bw_params *bw_params)
@@ -815,3 +827,14 @@ int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc) {return soc->clock_limits[0 ].dispclk_mhz *10000.0 / (1.0 + soc->dcn_downspread_percent /100.0 ); } + +int dcn_get_approx_det_segs_required_for_pstate ( +struct _vcs_dpi_soc_bounding_box_st *soc, +int pix_clk_100hz,int bpp,int seg_size_kb) +{ +/* Roughly calculate required crb to hide latency. In practice there is slightly +* more buffer available for latency hiding +*/ +return (int )(soc->dram_clock_change_latency_us * pix_clk_100hz * bpp + /10240000 + seg_size_kb -1 ) / seg_size_kb; +}
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h +3 -0
@@ -47,6 +47,9 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_paramsvoid dcn315_update_bw_bounding_box (struct dc *dc,struct clk_bw_params *bw_params);void dcn316_update_bw_bounding_box (struct dc *dc,struct clk_bw_params *bw_params);int dcn_get_max_non_odm_pix_rate_100hz (struct _vcs_dpi_soc_bounding_box_st *soc); +int dcn_get_approx_det_segs_required_for_pstate ( +struct _vcs_dpi_soc_bounding_box_st *soc, +int pix_clk_100hz,int bpp,int seg_size_kb); int dcn31x_populate_dml_pipes_from_context(struct dc *dc, struct dc_state *context,
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +27 -12
@@ -532,7 +532,8 @@ static void CalculateStutterEfficiency( static void CalculateSwathAndDETConfiguration( bool ForceSingleDPP, int NumberOfActivePlanes, - unsigned int DETBufferSizeInKByte, + bool DETSharedByAllDPP, + unsigned int DETBufferSizeInKByte[], double MaximumSwathWidthLuma[], double MaximumSwathWidthChroma[], enum scan_direction_class SourceScan[],
@@ -3118,7 +3119,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman v->SurfaceWidthC[k], v->SurfaceHeightY[k], v->SurfaceHeightC[k], - v->DETBufferSizeInKByte[0 ] *1024 , + v->DETBufferSizeInKByte[k] *1024 , v->BlockHeight256BytesY[k], v->BlockHeight256BytesC[k], v->SurfaceTiling[k],
@@ -3313,7 +3314,8 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) CalculateSwathAndDETConfiguration( false, v->NumberOfActivePlanes, - v->DETBufferSizeInKByte[0], + mode_lib->project == DML_PROJECT_DCN315 && v->DETSizeOverride[0], + v->DETBufferSizeInKByte, dummy1, dummy2, v->SourceScan,
@@ -3779,14 +3781,16 @@ static noinline void CalculatePrefetchSchedulePerPlane( &v->VReadyOffsetPix[k]); } -static void PatchDETBufferSizeInKByte (unsigned int NumberOfActivePlanes,int NoOfDPPThisState[],unsigned int config_return_buffer_size_in_kbytes,unsigned int *DETBufferSizeInKByte) +static void PatchDETBufferSizeInKByte (unsigned int NumberOfActivePlanes,int NoOfDPPThisState[],unsigned int config_return_buffer_size_in_kbytes,unsigned int DETBufferSizeInKByte[]) {int i, total_pipes =0 ;for (i =0 ; i < NumberOfActivePlanes; i++) total_pipes += NoOfDPPThisState[i]; - *DETBufferSizeInKByte = ((config_return_buffer_size_in_kbytes -DCN3_15_MIN_COMPBUF_SIZE_KB ) /64 / total_pipes) *64 ; -if (*DETBufferSizeInKByte >DCN3_15_MAX_DET_SIZE ) - *DETBufferSizeInKByte =DCN3_15_MAX_DET_SIZE ; + DETBufferSizeInKByte[0 ] = ((config_return_buffer_size_in_kbytes -DCN3_15_MIN_COMPBUF_SIZE_KB ) /64 / total_pipes) *64 ; +if (DETBufferSizeInKByte[0 ] >DCN3_15_MAX_DET_SIZE ) + DETBufferSizeInKByte[0 ] =DCN3_15_MAX_DET_SIZE ; +for (i =1 ; i < NumberOfActivePlanes; i++) + DETBufferSizeInKByte[i] = DETBufferSizeInKByte[0 ]; }
@@ -4026,7 +4030,8 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l CalculateSwathAndDETConfiguration( true, v->NumberOfActivePlanes, - v->DETBufferSizeInKByte[0], + mode_lib->project == DML_PROJECT_DCN315 && v->DETSizeOverride[0], + v->DETBufferSizeInKByte, v->MaximumSwathWidthLuma, v->MaximumSwathWidthChroma, v->SourceScan,
@@ -4166,6 +4171,10 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) { v->DISPCLK_DPPCLK_Support[i][j] = false; } +if (mode_lib->project ==DML_PROJECT_DCN315 && v->DETSizeOverride[k] >DCN3_15_MAX_DET_SIZE && v->NoOfDPP[i][j][k] <2 ) { + v->MPCCombine[i][j][k] = true; + v->NoOfDPP[i][j][k] =2 ; + } } v->TotalNumberOfActiveDPP[i][j] =0 ; v->TotalNumberOfSingleDPPPlanes[i][j] =0 ;
@@ -4642,12 +4651,13 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k]; } -if (v->NumberOfActivePlanes >1 && mode_lib->project ==DML_PROJECT_DCN315 ) -PatchDETBufferSizeInKByte (v->NumberOfActivePlanes, v->NoOfDPPThisState, v->ip.config_return_buffer_size_in_kbytes, &v->DETBufferSizeInKByte[0 ]); +if (v->NumberOfActivePlanes >1 && mode_lib->project ==DML_PROJECT_DCN315 && !v->DETSizeOverride[0 ]) +PatchDETBufferSizeInKByte (v->NumberOfActivePlanes, v->NoOfDPPThisState, v->ip.config_return_buffer_size_in_kbytes, v->DETBufferSizeInKByte); CalculateSwathAndDETConfiguration( false, v->NumberOfActivePlanes, - v->DETBufferSizeInKByte[0], + mode_lib->project == DML_PROJECT_DCN315 && v->DETSizeOverride[0], + v->DETBufferSizeInKByte, v->MaximumSwathWidthLuma, v->MaximumSwathWidthChroma, v->SourceScan,
@@ -6611,7 +6621,8 @@ static void CalculateStutterEfficiency( static void CalculateSwathAndDETConfiguration( bool ForceSingleDPP, int NumberOfActivePlanes, - unsigned int DETBufferSizeInKByte, + bool DETSharedByAllDPP, + unsigned int DETBufferSizeInKByteA[], double MaximumSwathWidthLuma[], double MaximumSwathWidthChroma[], enum scan_direction_class SourceScan[],
@@ -6695,6 +6706,10 @@ static void CalculateSwathAndDETConfiguration( *ViewportSizeSupport = true;for (k =0 ; k < NumberOfActivePlanes; ++k) { +unsigned int DETBufferSizeInKByte = DETBufferSizeInKByteA[k]; + +if (DETSharedByAllDPP && DPPPerPlane[k]) + DETBufferSizeInKByte /= DPPPerPlane[k];if ((SourcePixelFormat[k] == dm_444_64 || SourcePixelFormat[k] == dm_444_32 || SourcePixelFormat[k] == dm_444_16 || SourcePixelFormat[k] == dm_mono_16 || SourcePixelFormat[k] == dm_mono_8 || SourcePixelFormat[k] == dm_rgbe)) { if (SurfaceTiling[k] == dm_sw_linear
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +6 -0
@@ -571,6 +571,10 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.OutputLinkDPRate[mode_lib->vba.NumberOfActivePlanes] = dout->dp_rate; mode_lib->vba.ODMUse[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine_policy; mode_lib->vba.DETSizeOverride[mode_lib->vba.NumberOfActivePlanes] = src->det_size_override; +if (src->det_size_override) + mode_lib->vba.DETBufferSizeInKByte[mode_lib->vba.NumberOfActivePlanes] = src->det_size_override; +else + mode_lib->vba.DETBufferSizeInKByte[mode_lib->vba.NumberOfActivePlanes] = ip->det_buffer_size_kbytes;//TODO: Need to assign correct values to dp_multistream vars mode_lib->vba.OutputMultistreamEn[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_en; mode_lib->vba.OutputMultistreamId[mode_lib->vba.NumberOfActiveSurfaces] = dout->dp_multistream_id;
@@ -785,6 +789,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.pipe_plane[k] = mode_lib->vba.NumberOfActivePlanes; mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++; +if (src_k->det_size_override) + mode_lib->vba.DETBufferSizeInKByte[mode_lib->vba.NumberOfActivePlanes] = src_k->det_size_override;if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] == dm_horz) { mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 35/239 drm/amd/display: fix dcn315 single stream crb allocation
In reply to Greg Kroah-HartmanFrom: Dmytro Laktyushkin <[email protected]>
[ Upstream commit 49f26218c344741cb3eaa740b1e44e960551a87f ]
Change to improve avoiding asymetric crb calculations for single stream scenarios.
--- .../drm/amd/display/dc/dcn315/dcn315_resource.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +12 -3
@@ -1662,6 +1662,10 @@ static bool allow_pixel_rate_crb(struct dc *dc, struct dc_state *context)int i;struct resource_context *res_ctx = &context->res_ctx; +/*Don't apply for single stream*/ +if (context->stream_count <2 ) +return false; +for (i =0 ; i < dc->res_pool->pipe_count; i++) {if (!res_ctx->pipe_ctx[i].stream)continue ;
@@ -1748,19 +1752,23 @@ static int dcn315_populate_dml_pipes_from_context( pipe_cnt++; } -/* Spread remaining unreserved crb evenly among all pipes, use default policy if not enough det or single pipe */ +/* Spread remaining unreserved crb evenly among all pipes*/ if (pixel_rate_crb) {for (i =0 , pipe_cnt =0 , crb_idx =0 ; i < dc->res_pool->pipe_count; i++) { pipe = &res_ctx->pipe_ctx[i];if (!pipe->stream)continue ; +/* Do not use asymetric crb if not enough for pstate support */ +if (remaining_det_segs <0 ) { + pipes[pipe_cnt].pipe.src.det_size_override =0 ; +continue ; + } +if (!pipe->top_pipe && !pipe->prev_odm_pipe) {bool split_required = pipe->stream->timing.pix_clk_100hz >=dcn_get_max_non_odm_pix_rate_100hz (&dc->dml.soc) || (pipe->plane_state && pipe->plane_state->src_rect.width >5120 ); -if (remaining_det_segs <0 || crb_pipes ==1 ) - pipes[pipe_cnt].pipe.src.det_size_override =0 ;if (remaining_det_segs >MIN_RESERVED_DET_SEGS ) pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs -MIN_RESERVED_DET_SEGS ) / crb_pipes + (crb_idx < (remaining_det_segs -MIN_RESERVED_DET_SEGS ) % crb_pipes ?1 :0 );
@@ -1776,6 +1784,7 @@ static int dcn315_populate_dml_pipes_from_context( }/* Convert segments into size for DML use */ pipes[pipe_cnt].pipe.src.det_size_override *=DCN3_15_CRB_SEGMENT_SIZE_KB ; + crb_idx++; } pipe_cnt++;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 36/239 drm/amd/display: Update correct DCN314 register header
In reply to Greg Kroah-HartmanFrom: Cruise Hung <[email protected]>
[ Upstream commit 268182606f26434c5d3ebd0e86efcb0418dec487 ]
[Why]
The register header for DCN314 is not correct.
[How]
Update correct DCN314 register header.
Stable-dep-of: cd2e31a9ab93 ("drm/amd/display: Set minimum requirement for using PSR-SU on Phoenix")
--- drivers/gpu/drm/amd/display/dmub/src/Makefile | 2 +- .../drm/amd/display/dmub/src/dmub_dcn314.c | 62 +++++++++++++++++++ .../drm/amd/display/dmub/src/dmub_dcn314.h | 33 ++++++++++ .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 5 +- 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c create mode 100644 drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h
drivers/gpu/drm/amd/display/dmub/src/Makefile +1 -1
@@ -22,7 +22,7 @@ DMUB = dmub_srv.o dmub_srv_stat.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o DMUB += dmub_dcn30.o dmub_dcn301.o dmub_dcn302.o dmub_dcn303.o -DMUB += dmub_dcn31.o dmub_dcn315.o dmub_dcn316.o +DMUB += dmub_dcn31.o dmub_dcn314.o dmub_dcn315.o dmub_dcn316.o DMUB += dmub_dcn32.o AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB))
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c new file +62 -0
62 lines not on this page · raw message
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h new file +33 -0
@@ -0,0 +1,33 @@ +/* +* Copyright 2021 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. +* +* Authors: AMD +* +*/ + +#ifndef _DMUB_DCN314_H_ +#define _DMUB_DCN314_H_ + +#include "dmub_dcn31.h" + +extern const struct dmub_srv_dcn31_regs dmub_srv_dcn314_regs; + +#endif /* _DMUB_DCN314_H_ */
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +4 -1
@@ -32,6 +32,7 @@#include "dmub_dcn302.h" #include "dmub_dcn303.h" #include "dmub_dcn31.h" +#include "dmub_dcn314.h" #include "dmub_dcn315.h" #include "dmub_dcn316.h" #include "dmub_dcn32.h"
@@ -226,7 +227,9 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)case DMUB_ASIC_DCN314 :case DMUB_ASIC_DCN315 :case DMUB_ASIC_DCN316 : -if (asic ==DMUB_ASIC_DCN315 ) +if (asic ==DMUB_ASIC_DCN314 ) + dmub->regs_dcn31 = &dmub_srv_dcn314_regs; +else if (asic ==DMUB_ASIC_DCN315 ) dmub->regs_dcn31 = &dmub_srv_dcn315_regs;else if (asic ==DMUB_ASIC_DCN316 ) dmub->regs_dcn31 = &dmub_srv_dcn316_regs;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 37/239 drm/amd/display: Set minimum requirement for using PSR-SU on Rembrandt
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit c35b6ea8f2ecfa9d775530b70d4e727869099a9c ]
A number of parade TCONs are causing system hangs when utilized with older DMUB firmware and PSR-SU. Some changes have been introduced into DMUB firmware to add resilience against these failures.
Don't allow running PSR-SU unless on the newer firmware.
Stable-dep-of: cd2e31a9ab93 ("drm/amd/display: Set minimum requirement for using PSR-SU on Phoenix")
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 +++++++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 1 + drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 ++ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 5 +++++ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 ++ drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 10 ++++++---- 7 files changed, 25 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +2 -1
@@ -24,6 +24,7 @@*/ #include "amdgpu_dm_psr.h" +#include "dc_dmub_srv.h" #include "dc.h" #include "dm_helpers.h" #include "amdgpu_dm.h"
@@ -50,7 +51,7 @@ static bool link_supports_psrsu(struct dc_link *link) !link->dpcd_caps.psr_info.psr2_su_y_granularity_cap)return false; -return true; +return dc_dmub_check_min_version (dc->ctx->dmub_srv->dmub); }/*
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +7 -0
@@ -1079,3 +1079,10 @@ void dc_send_update_cursor_info_to_dmu(dc_send_cmd_to_dmu (pCtx->stream->ctx->dmub_srv, &cmd); } } + +bool dc_dmub_check_min_version (struct dmub_srv *srv) +{ +if (!srv->hw_funcs.is_psrsu_supported) +return true; +return srv->hw_funcs.is_psrsu_supported (srv); +}
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +1 -0
@@ -89,4 +89,5 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, struct dc_state *context, bvoid dc_dmub_srv_log_diagnostic_data (struct dc_dmub_srv *dc_dmub_srv);void dc_send_update_cursor_info_to_dmu (struct pipe_ctx *pCtx,uint8_t pipe_idx); +bool dc_dmub_check_min_version (struct dmub_srv *srv);#endif /* _DMUB_DC_SRV_H_ */
drivers/gpu/drm/amd/display/dmub/dmub_srv.h +2 -0
@@ -364,6 +364,8 @@ struct dmub_srv_hw_funcs {bool (*is_supported)(struct dmub_srv *dmub); +bool (*is_psrsu_supported)(struct dmub_srv *dmub); +bool (*is_hw_init)(struct dmub_srv *dmub);bool (*is_phy_init)(struct dmub_srv *dmub);
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +5 -0
@@ -297,6 +297,11 @@ bool dmub_dcn31_is_supported(struct dmub_srv *dmub)return supported; } +bool dmub_dcn31_is_psrsu_supported (struct dmub_srv *dmub) +{ +return dmub->fw_version >=DMUB_FW_VERSION (4 ,0 ,59 ); +} +void dmub_dcn31_set_gpint (struct dmub_srv *dmub,union dmub_gpint_data_register reg) {
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +2 -0
@@ -219,6 +219,8 @@ bool dmub_dcn31_is_hw_init(struct dmub_srv *dmub);bool dmub_dcn31_is_supported (struct dmub_srv *dmub); +bool dmub_dcn31_is_psrsu_supported (struct dmub_srv *dmub); +void dmub_dcn31_set_gpint (struct dmub_srv *dmub,union dmub_gpint_data_register reg);
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +6 -4
@@ -227,14 +227,16 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)case DMUB_ASIC_DCN314 :case DMUB_ASIC_DCN315 :case DMUB_ASIC_DCN316 : -if (asic ==DMUB_ASIC_DCN314 ) +if (asic ==DMUB_ASIC_DCN314 ) { dmub->regs_dcn31 = &dmub_srv_dcn314_regs; -else if (asic ==DMUB_ASIC_DCN315 ) + }else if (asic ==DMUB_ASIC_DCN315 ) { dmub->regs_dcn31 = &dmub_srv_dcn315_regs; -else if (asic ==DMUB_ASIC_DCN316 ) + }else if (asic ==DMUB_ASIC_DCN316 ) { dmub->regs_dcn31 = &dmub_srv_dcn316_regs; -else + }else { dmub->regs_dcn31 = &dmub_srv_dcn31_regs; + funcs->is_psrsu_supported = dmub_dcn31_is_psrsu_supported; + } funcs->reset = dmub_dcn31_reset; funcs->reset_release = dmub_dcn31_reset_release; funcs->backdoor_load = dmub_dcn31_backdoor_load;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 38/239 drm/amd/display: Set minimum requirement for using PSR-SU on Phoenix
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit cd2e31a9ab93d13c412a36c6e26811e0f830985b ]
The same parade TCON issue can potentially happen on Phoenix, and the same PSR resilience changes have been ported into the DMUB firmware.
Don't allow running PSR-SU unless on the newer firmware.
--- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c | 5 +++++ drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h | 2 ++ drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 1 + 3 files changed, 8 insertions(+)
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c +5 -0
@@ -60,3 +60,8 @@ const struct dmub_srv_dcn31_regs dmub_srv_dcn314_regs = { { DMUB_DCN31_FIELDS() },#undef DMUB_SF }; + +bool dmub_dcn314_is_psrsu_supported (struct dmub_srv *dmub) +{ +return dmub->fw_version >=DMUB_FW_VERSION (8 ,0 ,16 ); +}
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h +2 -0
@@ -30,4 +30,6 @@extern const struct dmub_srv_dcn31_regs dmub_srv_dcn314_regs; +bool dmub_dcn314_is_psrsu_supported (struct dmub_srv *dmub); +#endif /* _DMUB_DCN314_H_ */
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +1 -0
@@ -229,6 +229,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)case DMUB_ASIC_DCN316 :if (asic ==DMUB_ASIC_DCN314 ) { dmub->regs_dcn31 = &dmub_srv_dcn314_regs; + funcs->is_psrsu_supported = dmub_dcn314_is_psrsu_supported; }else if (asic ==DMUB_ASIC_DCN315 ) { dmub->regs_dcn31 = &dmub_srv_dcn315_regs; }else if (asic ==DMUB_ASIC_DCN316 ) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 39/239 drm/ttm: never consider pinned BOs for eviction&swap
In reply to Greg Kroah-HartmanFrom: Christian König <[email protected]>
[ Upstream commit a2848d08742c8e8494675892c02c0d22acbe3cf8 ]
There is a small window where we have already incremented the pin count but not yet moved the bo from the lru to the pinned list.
--- drivers/gpu/drm/ttm/ttm_bo.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/ttm/ttm_bo.c +6 -0
@@ -517,6 +517,12 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, {bool ret = false; +if (bo->pin_count) { + *locked = false; + *busy = false; +return false; + } +if (bo->base.resv == ctx->resv) {dma_resv_assert_held (bo->base.resv);if (ctx->allow_res_evict)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 40/239 maple_tree: add __init and __exit to test module
In reply to Greg Kroah-HartmanFrom: Liam R. Howlett <[email protected]>
[ Upstream commit eaf9790d3bc6e157a2134c01c7d707a5a712fab1 ]
The test functions are not needed after the module is removed, so mark them as such. Add __exit to the module removal function. Some other variables have been marked as const static as well.
Stable-dep-of: 7a93c71a6714 ("maple_tree: fix 32 bit mas_next testing")
--- lib/test_maple_tree.c | 158 +++++++++++++------------- tools/testing/radix-tree/linux/init.h | 1 + tools/testing/radix-tree/maple.c | 147 ++++++++++++------------ 3 files changed, 155 insertions(+), 151 deletions(-)
lib/test_maple_tree.c +80 -78
@@ -30,54 +30,54 @@#else #define cond_resched () do {} while (0)#endif -static -int mtree_insert_index (struct maple_tree *mt,unsigned long index,gfp_t gfp) +static int __init mtree_insert_index (struct maple_tree *mt, +unsigned long index,gfp_t gfp) {return mtree_insert (mt, index,xa_mk_value (index &LONG_MAX ), gfp); } -static void mtree_erase_index (struct maple_tree *mt,unsigned long index) +static void __init mtree_erase_index (struct maple_tree *mt,unsigned long index) {MT_BUG_ON (mt,mtree_erase (mt, index) !=xa_mk_value (index &LONG_MAX ));MT_BUG_ON (mt,mtree_load (mt, index) !=NULL ); } -static int mtree_test_insert (struct maple_tree *mt,unsigned long index, +static int __init mtree_test_insert (struct maple_tree *mt,unsigned long index,void *ptr) {return mtree_insert (mt, index, ptr,GFP_KERNEL ); } -static int mtree_test_store_range (struct maple_tree *mt,unsigned long start, -unsigned long end,void *ptr) +static int __init mtree_test_store_range (struct maple_tree *mt, +unsigned long start,unsigned long end,void *ptr) {return mtree_store_range (mt, start, end, ptr,GFP_KERNEL ); } -static int mtree_test_store (struct maple_tree *mt,unsigned long start, +static int __init mtree_test_store (struct maple_tree *mt,unsigned long start,void *ptr) {return mtree_test_store_range (mt, start, start, ptr); } -static int mtree_test_insert_range (struct maple_tree *mt,unsigned long start, -unsigned long end,void *ptr) +static int __init mtree_test_insert_range (struct maple_tree *mt, +unsigned long start,unsigned long end,void *ptr) {return mtree_insert_range (mt, start, end, ptr,GFP_KERNEL ); } -static void *mtree_test_load (struct maple_tree *mt,unsigned long index) +static void __init *mtree_test_load (struct maple_tree *mt,unsigned long index) {return mtree_load (mt, index); } -static void *mtree_test_erase (struct maple_tree *mt,unsigned long index) +static void __init *mtree_test_erase (struct maple_tree *mt,unsigned long index) {return mtree_erase (mt, index); }#if defined(CONFIG_64BIT ) -static noinline void check_mtree_alloc_range(struct maple_tree *mt, +static noinline void __init check_mtree_alloc_range(struct maple_tree *mt,unsigned long start,unsigned long end,unsigned long size,unsigned long expected,int eret,void *ptr) {
@@ -94,7 +94,7 @@ static noinline void check_mtree_alloc_range(struct maple_tree *mt,MT_BUG_ON (mt, result != expected); } -static noinline void check_mtree_alloc_rrange(struct maple_tree *mt, +static noinline void __init check_mtree_alloc_rrange(struct maple_tree *mt,unsigned long start,unsigned long end,unsigned long size,unsigned long expected,int eret,void *ptr) {
@@ -112,8 +112,8 @@ static noinline void check_mtree_alloc_rrange(struct maple_tree *mt, }#endif -static noinline void check_load(struct maple_tree *mt, unsigned long index, -void *ptr) +static noinline void __init check_load(struct maple_tree *mt, +unsigned long index,void *ptr) {void *ret =mtree_test_load (mt, index);
@@ -122,7 +122,7 @@ static noinline void check_load(struct maple_tree *mt, unsigned long index,MT_BUG_ON (mt, ret != ptr); } -static noinline void check_store_range(struct maple_tree *mt, +static noinline void __init check_store_range(struct maple_tree *mt,unsigned long start,unsigned long end,void *ptr,int expected) {int ret = -EINVAL ;
@@ -138,7 +138,7 @@ static noinline void check_store_range(struct maple_tree *mt,check_load (mt, i, ptr); } -static noinline void check_insert_range(struct maple_tree *mt, +static noinline void __init check_insert_range(struct maple_tree *mt,unsigned long start,unsigned long end,void *ptr,int expected) {int ret = -EINVAL ;
@@ -154,8 +154,8 @@ static noinline void check_insert_range(struct maple_tree *mt,check_load (mt, i, ptr); } -static noinline void check_insert(struct maple_tree *mt, unsigned long index, -void *ptr) +static noinline void __init check_insert(struct maple_tree *mt, +unsigned long index,void *ptr) {int ret = -EINVAL ;
@@ -163,7 +163,7 @@ static noinline void check_insert(struct maple_tree *mt, unsigned long index,MT_BUG_ON (mt, ret !=0 ); } -static noinline void check_dup_insert(struct maple_tree *mt, +static noinline void __init check_dup_insert(struct maple_tree *mt,unsigned long index,void *ptr) {int ret = -EINVAL ;
@@ -173,13 +173,13 @@ static noinline void check_dup_insert(struct maple_tree *mt, } -static noinline -void check_index_load(struct maple_tree *mt, unsigned long index) +static noinline void __init check_index_load(struct maple_tree *mt, +unsigned long index) {return check_load (mt, index,xa_mk_value (index &LONG_MAX )); } -static inline int not_empty (struct maple_node *node) +static inline __init int not_empty (struct maple_node *node) {int i;
@@ -194,8 +194,8 @@ static inline int not_empty(struct maple_node *node) } -static noinline void check_rev_seq(struct maple_tree *mt, unsigned long max, -bool verbose) +static noinline void __init check_rev_seq(struct maple_tree *mt, +unsigned long max,bool verbose) {unsigned long i = max, j;
@@ -227,7 +227,7 @@ static noinline void check_rev_seq(struct maple_tree *mt, unsigned long max,#endif } -static noinline void check_seq(struct maple_tree *mt, unsigned long max, +static noinline void __init check_seq(struct maple_tree *mt, unsigned long max,bool verbose) {unsigned long i, j;
@@ -256,7 +256,7 @@ static noinline void check_seq(struct maple_tree *mt, unsigned long max,#endif } -static noinline void check_lb_not_empty(struct maple_tree *mt) +static noinline void __init check_lb_not_empty(struct maple_tree *mt) {unsigned long i, j;unsigned long huge =4000UL *1000 *1000 ;
@@ -275,13 +275,13 @@ static noinline void check_lb_not_empty(struct maple_tree *mt)mtree_destroy (mt); } -static noinline void check_lower_bound_split(struct maple_tree *mt) +static noinline void __init check_lower_bound_split(struct maple_tree *mt) {MT_BUG_ON (mt, !mtree_empty (mt));check_lb_not_empty (mt); } -static noinline void check_upper_bound_split(struct maple_tree *mt) +static noinline void __init check_upper_bound_split(struct maple_tree *mt) {unsigned long i, j;unsigned long huge;
@@ -306,7 +306,7 @@ static noinline void check_upper_bound_split(struct maple_tree *mt)mtree_destroy (mt); } -static noinline void check_mid_split(struct maple_tree *mt) +static noinline void __init check_mid_split(struct maple_tree *mt) {unsigned long huge =8000UL *1000 *1000 ;
@@ -315,7 +315,7 @@ static noinline void check_mid_split(struct maple_tree *mt)check_lb_not_empty (mt); } -static noinline void check_rev_find(struct maple_tree *mt) +static noinline void __init check_rev_find(struct maple_tree *mt) {int i, nr_entries =200 ;void *val;
@@ -354,7 +354,7 @@ static noinline void check_rev_find(struct maple_tree *mt)rcu_read_unlock (); } -static noinline void check_find(struct maple_tree *mt) +static noinline void __init check_find(struct maple_tree *mt) {unsigned long val =0 ;unsigned long count;
@@ -571,7 +571,7 @@ static noinline void check_find(struct maple_tree *mt)mtree_destroy (mt); } -static noinline void check_find_2(struct maple_tree *mt) +static noinline void __init check_find_2(struct maple_tree *mt) {unsigned long i, j;void *entry;
@@ -616,7 +616,7 @@ static noinline void check_find_2(struct maple_tree *mt)#if defined(CONFIG_64BIT ) -static noinline void check_alloc_rev_range(struct maple_tree *mt) +static noinline void __init check_alloc_rev_range(struct maple_tree *mt) {/* * Generated by:
@@ -624,7 +624,7 @@ static noinline void check_alloc_rev_range(struct maple_tree *mt)* awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}' */ -unsigned long range[] = { +static const unsigned long range[] = {/* Inclusive , Exclusive. */ 0x565234af2000 ,0x565234af4000 ,0x565234af4000 ,0x565234af9000 ,
@@ -652,7 +652,7 @@ static noinline void check_alloc_rev_range(struct maple_tree *mt) 0x7fff58791000, 0x7fff58793000, }; -unsigned long holes[] = { +static const unsigned long holes[] = {/* * Note: start of hole is INCLUSIVE * end of hole is EXCLUSIVE
@@ -672,7 +672,7 @@ static noinline void check_alloc_rev_range(struct maple_tree *mt)* 4. number that should be returned. * 5. return value */ -unsigned long req_range[] = { +static const unsigned long req_range[] = {0x565234af9000 ,/* Min */ 0x7fff58791000 ,/* Max */ 0x1000 ,/* Size */
@@ -783,7 +783,7 @@ static noinline void check_alloc_rev_range(struct maple_tree *mt)mtree_destroy (mt); } -static noinline void check_alloc_range(struct maple_tree *mt) +static noinline void __init check_alloc_range(struct maple_tree *mt) {/* * Generated by:
@@ -791,7 +791,7 @@ static noinline void check_alloc_range(struct maple_tree *mt)* awk -F "-" '{printf "0x%s, 0x%s, ", $1, $2}' */ -unsigned long range[] = { +static const unsigned long range[] = {/* Inclusive , Exclusive. */ 0x565234af2000 ,0x565234af4000 ,0x565234af4000 ,0x565234af9000 ,
@@ -818,7 +818,7 @@ static noinline void check_alloc_range(struct maple_tree *mt)0x7fff5878e000 ,0x7fff58791000 , 0x7fff58791000, 0x7fff58793000, }; -unsigned long holes[] = { +static const unsigned long holes[] = {/* Start of hole, end of hole, size of hole (+1) */ 0x565234afb000 ,0x565234afc000 ,0x1000 , 0x565234afe000, 0x565235def000, 0x12F1000,
@@ -833,7 +833,7 @@ static noinline void check_alloc_range(struct maple_tree *mt)* 4. number that should be returned. * 5. return value */ -unsigned long req_range[] = { +static const unsigned long req_range[] = {0x565234af9000 ,/* Min */ 0x7fff58791000 ,/* Max */ 0x1000 ,/* Size */
@@ -942,10 +942,10 @@ static noinline void check_alloc_range(struct maple_tree *mt) }#endif -static noinline void check_ranges(struct maple_tree *mt) +static noinline void __init check_ranges(struct maple_tree *mt) {int i, val, val2; -unsigned long r[] = { +static const unsigned long r[] = {10 ,15 ,20 ,25 ,17 ,22 ,/* Overlaps previous range. */
@@ -1210,7 +1210,7 @@ static noinline void check_ranges(struct maple_tree *mt)MT_BUG_ON (mt,mt_height (mt) !=4 ); } -static noinline void check_next_entry(struct maple_tree *mt) +static noinline void __init check_next_entry(struct maple_tree *mt) {void *entry =NULL ;unsigned long limit =30 , i =0 ;
@@ -1234,7 +1234,7 @@ static noinline void check_next_entry(struct maple_tree *mt)mtree_destroy (mt); } -static noinline void check_prev_entry(struct maple_tree *mt) +static noinline void __init check_prev_entry(struct maple_tree *mt) {unsigned long index =16 ;void *value;
@@ -1278,7 +1278,7 @@ static noinline void check_prev_entry(struct maple_tree *mt)mas_unlock (&mas); } -static noinline void check_root_expand(struct maple_tree *mt) +static noinline void __init check_root_expand(struct maple_tree *mt) {MA_STATE (mas, mt,0 ,0 );void *ptr;
@@ -1367,13 +1367,13 @@ static noinline void check_root_expand(struct maple_tree *mt)mas_unlock (&mas); } -static noinline void check_gap_combining(struct maple_tree *mt) +static noinline void __init check_gap_combining(struct maple_tree *mt) {struct maple_enode *mn1, *mn2;void *entry;unsigned long singletons =100 ; -unsigned long *seq100; -unsigned long seq100_64[] = { +static const unsigned long *seq100; +static const unsigned long seq100_64[] = {/* 0-5 */ 74 ,75 ,76 ,50 ,100 ,2 ,
@@ -1387,7 +1387,7 @@ static noinline void check_gap_combining(struct maple_tree *mt) 76, 2, 79, 85, 4, }; -unsigned long seq100_32[] = { +static const unsigned long seq100_32[] = {/* 0-5 */ 61 ,62 ,63 ,50 ,100 ,2 ,
@@ -1401,11 +1401,11 @@ static noinline void check_gap_combining(struct maple_tree *mt) 76, 2, 79, 85, 4, }; -unsigned long seq2000[] = { +static const unsigned long seq2000[] = {1152 ,1151 ,1100 ,1200 ,2 , }; -unsigned long seq400[] = { +static const unsigned long seq400[] = {286 ,318 ,256 ,260 ,266 ,270 ,275 ,280 ,290 ,398 ,286 ,310 ,
@@ -1564,7 +1564,7 @@ static noinline void check_gap_combining(struct maple_tree *mt)mt_set_non_kernel (0 );mtree_destroy (mt); } -static noinline void check_node_overwrite(struct maple_tree *mt) +static noinline void __init check_node_overwrite(struct maple_tree *mt) {int i, max =4000 ;
@@ -1577,7 +1577,7 @@ static noinline void check_node_overwrite(struct maple_tree *mt) }#if defined(BENCH_SLOT_STORE ) -static noinline void bench_slot_store(struct maple_tree *mt) +static noinline void __init bench_slot_store(struct maple_tree *mt) {int i, brk =105 , max =1040 , brk_start =100 , count =20000000 ;
@@ -1593,7 +1593,7 @@ static noinline void bench_slot_store(struct maple_tree *mt)#endif #if defined(BENCH_NODE_STORE ) -static noinline void bench_node_store(struct maple_tree *mt) +static noinline void __init bench_node_store(struct maple_tree *mt) {int i, overwrite =76 , max =240 , count =20000000 ;
@@ -1612,7 +1612,7 @@ static noinline void bench_node_store(struct maple_tree *mt)#endif #if defined(BENCH_AWALK ) -static noinline void bench_awalk(struct maple_tree *mt) +static noinline void __init bench_awalk(struct maple_tree *mt) {int i, max =2500 , count =50000000 ;MA_STATE (mas, mt,1470 ,1470 );
@@ -1629,7 +1629,7 @@ static noinline void bench_awalk(struct maple_tree *mt) }#endif #if defined(BENCH_WALK ) -static noinline void bench_walk(struct maple_tree *mt) +static noinline void __init bench_walk(struct maple_tree *mt) {int i, max =2500 , count =550000000 ;MA_STATE (mas, mt,1470 ,1470 );
@@ -1646,7 +1646,7 @@ static noinline void bench_walk(struct maple_tree *mt)#endif #if defined(BENCH_MT_FOR_EACH ) -static noinline void bench_mt_for_each(struct maple_tree *mt) +static noinline void __init bench_mt_for_each(struct maple_tree *mt) {int i, count =1000000 ;unsigned long max =2500 , index =0 ;
@@ -1670,7 +1670,7 @@ static noinline void bench_mt_for_each(struct maple_tree *mt)#endif /* check_forking - simulate the kernel forking sequence with the tree. */ -static noinline void check_forking(struct maple_tree *mt) +static noinline void __init check_forking(struct maple_tree *mt) {struct maple_tree newmt;
@@ -1709,7 +1709,7 @@ static noinline void check_forking(struct maple_tree *mt)mtree_destroy (&newmt); } -static noinline void check_iteration(struct maple_tree *mt) +static noinline void __init check_iteration(struct maple_tree *mt) {int i, nr_entries =125 ;void *val;
@@ -1777,7 +1777,7 @@ static noinline void check_iteration(struct maple_tree *mt)mt_set_non_kernel (0 ); } -static noinline void check_mas_store_gfp(struct maple_tree *mt) +static noinline void __init check_mas_store_gfp(struct maple_tree *mt) {struct maple_tree newmt;
@@ -1810,7 +1810,7 @@ static noinline void check_mas_store_gfp(struct maple_tree *mt) }#if defined(BENCH_FORK ) -static noinline void bench_forking(struct maple_tree *mt) +static noinline void __init bench_forking(struct maple_tree *mt) {struct maple_tree newmt;
@@ -1852,15 +1852,17 @@ static noinline void bench_forking(struct maple_tree *mt) }#endif -static noinline void next_prev_test(struct maple_tree *mt) +static noinline void __init next_prev_test(struct maple_tree *mt) {int i, nr_entries;void *val;MA_STATE (mas, mt,0 ,0 );struct maple_enode *mn; -unsigned long *level2; -unsigned long level2_64[] = {707 ,1000 ,710 ,715 ,720 ,725 }; -unsigned long level2_32[] = {1747 ,2000 ,1750 ,1755 ,1760 ,1765 }; +static const unsigned long *level2; +static const unsigned long level2_64[] = {707 ,1000 ,710 ,715 ,720 , +725 }; +static const unsigned long level2_32[] = {1747 ,2000 ,1750 ,1755 , +1760 ,1765 };if (MAPLE_32BIT ) { nr_entries =500 ;
@@ -2028,7 +2030,7 @@ static noinline void next_prev_test(struct maple_tree *mt)/* Test spanning writes that require balancing right sibling or right cousin */ -static noinline void check_spanning_relatives(struct maple_tree *mt) +static noinline void __init check_spanning_relatives(struct maple_tree *mt) {unsigned long i, nr_entries =1000 ;
@@ -2041,7 +2043,7 @@ static noinline void check_spanning_relatives(struct maple_tree *mt)mtree_store_range (mt,9365 ,9955 ,NULL ,GFP_KERNEL ); } -static noinline void check_fuzzer(struct maple_tree *mt) +static noinline void __init check_fuzzer(struct maple_tree *mt) {/* * 1. Causes a spanning rebalance of a single root node.
@@ -2438,7 +2440,7 @@ static noinline void check_fuzzer(struct maple_tree *mt) }/* duplicate the tree with a specific gap */ -static noinline void check_dup_gaps(struct maple_tree *mt, +static noinline void __init check_dup_gaps(struct maple_tree *mt,unsigned long nr_entries,bool zero_start,unsigned long gap) {
@@ -2478,7 +2480,7 @@ static noinline void check_dup_gaps(struct maple_tree *mt, }/* Duplicate many sizes of trees. Mainly to test expected entry values */ -static noinline void check_dup(struct maple_tree *mt) +static noinline void __init check_dup(struct maple_tree *mt) {int i;int big_start =100010 ;
@@ -2566,7 +2568,7 @@ static noinline void check_dup(struct maple_tree *mt) } } -static noinline void check_bnode_min_spanning(struct maple_tree *mt) +static noinline void __init check_bnode_min_spanning(struct maple_tree *mt) {int i =50 ;MA_STATE (mas, mt,0 ,0 );
@@ -2585,7 +2587,7 @@ static noinline void check_bnode_min_spanning(struct maple_tree *mt)mt_set_non_kernel (0 ); } -static noinline void check_empty_area_window(struct maple_tree *mt) +static noinline void __init check_empty_area_window(struct maple_tree *mt) {unsigned long i, nr_entries =20 ;MA_STATE (mas, mt,0 ,0 );
@@ -2670,7 +2672,7 @@ static noinline void check_empty_area_window(struct maple_tree *mt)rcu_read_unlock (); } -static noinline void check_empty_area_fill(struct maple_tree *mt) +static noinline void __init check_empty_area_fill(struct maple_tree *mt) {const unsigned long max =0x25D78000 ;unsigned long size;
@@ -2714,11 +2716,11 @@ static noinline void check_empty_area_fill(struct maple_tree *mt) }static DEFINE_MTREE (tree); -static int maple_tree_seed (void ) +static int __init maple_tree_seed (void ) { -unsigned long set[] = {5015 ,5014 ,5017 ,25 ,1000 , -1001 ,1002 ,1003 ,1005 ,0 , -5003 ,5002 }; +unsigned long set[] = {5015 ,5014 ,5017 ,25 ,1000 , +1001 ,1002 ,1003 ,1005 ,0 , +5003 ,5002 };void *ptr = &set;pr_info ("\nTEST STARTING\n\n" );
@@ -2988,7 +2990,7 @@ static int maple_tree_seed(void)return -EINVAL ; } -static void maple_tree_harvest (void ) +static void __exit maple_tree_harvest(void) { }
tools/testing/radix-tree/linux/init.h +1 -0
@@ -1 +1,2 @@#define __init +#define __exit
tools/testing/radix-tree/maple.c +74 -73
487 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 41/239 maple_tree: fix 32 bit mas_next testing
In reply to Greg Kroah-HartmanFrom: Liam R. Howlett <[email protected]>
[ Upstream commit 7a93c71a6714ca1a9c03d70432dac104b0cfb815 ]
The test setup of mas_next is dependent on node entry size to create a 2 level tree, but the tests did not account for this in the expected value when shifting beyond the scope of the tree.
Fix this by setting up the test to succeed depending on the node entries which is dependent on the 32/64 bit setup.
--- lib/test_maple_tree.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
lib/test_maple_tree.c +4 -1
@@ -1863,13 +1863,16 @@ static noinline void __init next_prev_test(struct maple_tree *mt) 725};static const unsigned long level2_32[] = {1747 ,2000 ,1750 ,1755 ,1760 ,1765 }; +unsigned long last_index;if (MAPLE_32BIT ) { nr_entries =500 ; level2 = level2_32; + last_index =0x138e ; }else { nr_entries =200 ; level2 = level2_64; + last_index =0x7d6 ; }for (i =0 ; i <= nr_entries; i++)
@@ -1976,7 +1979,7 @@ static noinline void __init next_prev_test(struct maple_tree *mt) val =mas_next (&mas,ULONG_MAX );MT_BUG_ON (mt, val !=NULL ); -MT_BUG_ON (mt, mas.index !=ULONG_MAX ); +MT_BUG_ON (mt, mas.index != last_index);MT_BUG_ON (mt, mas.last !=ULONG_MAX ); val =mas_prev (&mas,0 );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 42/239 drm/amd/display: Add FAMS validation before trying to use it
In reply to Greg Kroah-HartmanFrom: Rodrigo Siqueira <[email protected]>
[ Upstream commit e3416e872f84086667df21daf166506fab97358d ]
To ensure that FAMS can be used, DC must check if there is VRR support.
This commit adds the required configuration to ensure FAMS can be executed in the target system.
Stable-dep-of: 2a9482e55968 ("drm/amd/display: Prevent vtotal from being set to 0")
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++++++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 7 ++++++- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +6 -0
@@ -2626,6 +2626,12 @@ static enum surface_update_type check_update_surfaces_for_stream(if (stream_update->mst_bw_update) su_flags->bits.mst_bw =1 ; + +if (stream_update->stream && stream_update->stream->freesync_on_desktop && + (stream_update->vrr_infopacket || stream_update->allow_freesync || + stream_update->vrr_active_variable)) + su_flags->bits.fams_changed =1 ; +if (stream_update->crtc_timing_adjust &&dc_extended_blank_supported (dc)) su_flags->bits.crtc_timing_adjust =1 ;
drivers/gpu/drm/amd/display/dc/dc_stream.h +1 -0
@@ -131,6 +131,7 @@ union stream_update_flags { uint32_t dsc_changed : 1; uint32_t mst_bw : 1; uint32_t crtc_timing_adjust : 1; + uint32_t fams_changed : 1; } bits;uint32_t raw;
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +6 -1
@@ -301,7 +301,12 @@ static void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *ovoid optc3_set_vtotal_min_max (struct timing_generator *optc,int vtotal_min,int vtotal_max) { -optc1_set_vtotal_min_max (optc, vtotal_min, vtotal_max); +struct dc *dc = optc->ctx->dc; + +if (dc->caps.dmub_caps.mclk_sw && !dc->debug.disable_fams) +dc_dmub_srv_drr_update_cmd (dc, optc->inst, vtotal_min, vtotal_max); +else +optc1_set_vtotal_min_max (optc, vtotal_min, vtotal_max); }void optc3_tg_init (struct timing_generator *optc)
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +1 -1
@@ -360,7 +360,7 @@ union dmub_fw_boot_status { uint32_t optimized_init_done : 1; /**< 1 if optimized init done */ uint32_t restore_required : 1; /**< 1 if driver should call restore */ uint32_t defer_load : 1; /**< 1 if VBIOS data is deferred programmed */ - uint32_t reserved : 1; + uint32_t fams_enabled : 1; /**< 1 if VBIOS data is deferred programmed */ uint32_t detection_required: 1; /**< if detection need to be triggered by driver */ uint32_t hw_power_init_done: 1; /**< 1 if hw power init is completed */ } bits;/**< status bits */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 43/239 drm/amd/display: update extended blank for dcn314 onwards
In reply to Greg Kroah-HartmanFrom: Gabe Teeger <[email protected]>
[ Upstream commit 469a62938a45ef382c9cb7b9fec6c6c1fcd781c0 ]
[Why]
Flickering and underflow was observed when testing extended blank on dcn314.
[What]
Vstartup is contrainted by vblank_nom, so adjusting it to include non-adjusted vtotal in its calculation during freesync video means that Vstartup is not changed when vtotal changes. This fixed the flickering + underflow.
dc_extended_blank_supported function was removed because extended blank is only relevant to when zstate is supported. The increased vtotal during freesync can be passed to dml regardless of whether extended blank is supported or not, so this function is not needed.
Updates were made recently in dml to the calculation of min_dst_y_next_start. Dml input for dcn314 will now always use the newer calculation for min_dst_y_next_start. Dml input for older dcn versions remains untouched.
The variable optimized_min_dst_y_next_start is replaced everywhere with min_dst_y_next_start, and the updated dml allows min_dst_y_next_start to increase to an optimized value during freesync video, then return to default when freesync is disengaged.
Also removed registry key for controlling
extended blank feature.
Stable-dep-of: 2a9482e55968 ("drm/amd/display: Prevent vtotal from being set to 0")
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 21 ----------------- drivers/gpu/drm/amd/display/dc/dc.h | 2 -- .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++-- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 23 +++++++++---------- .../dc/dml/dcn31/display_rq_dlg_calc_31.c | 3 +-- .../amd/display/dc/dml/dcn314/dcn314_fpu.c | 14 +++++++---- .../dc/dml/dcn314/display_rq_dlg_calc_314.c | 16 ++++--------- .../amd/display/dc/dml/display_mode_structs.h | 3 +-- 8 files changed, 29 insertions(+), 57 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +0 -21
@@ -2632,9 +2632,6 @@ static enum surface_update_type check_update_surfaces_for_stream( stream_update->vrr_active_variable)) su_flags->bits.fams_changed =1 ; -if (stream_update->crtc_timing_adjust &&dc_extended_blank_supported (dc)) - su_flags->bits.crtc_timing_adjust =1 ; -if (su_flags->raw !=0 ) overall_type =UPDATE_TYPE_FULL ;
@@ -4900,21 +4897,3 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, boif (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause) pipe->stream_res.abm->funcs->set_abm_pause (pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst); } - -/** -* dc_extended_blank_supported - Decide whether extended blank is supported -* -* @dc: [in] Current DC state -* -* Extended blank is a freesync optimization feature to be enabled in the -* future. During the extra vblank period gained from freesync, we have the -* ability to enter z9/z10. -* -* Return: -* Indicate whether extended blank is supported (%true or %false) -*/ -bool dc_extended_blank_supported (struct dc *dc) -{ -return dc->debug.extended_blank_optimization && !dc->debug.disable_z10 - && dc->caps.zstate_support && dc->caps.is_apu; -}
drivers/gpu/drm/amd/display/dc/dc.h +0 -2
@@ -2125,8 +2125,6 @@ struct dc_sink_init_data {bool converter_disable_audio; }; -bool dc_extended_blank_supported (struct dc *dc); -struct dc_sink *dc_sink_create (const struct dc_sink_init_data *init_params);/* Newer interfaces */
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +2 -2
@@ -2128,7 +2128,7 @@ void dcn20_optimize_bandwidth( dc->clk_mgr, context, true); -if (dc_extended_blank_supported (dc) && context->bw_ctx.bw.dcn.clk.zstate_support ==DCN_ZSTATE_SUPPORT_ALLOW ) { +if (context->bw_ctx.bw.dcn.clk.zstate_support ==DCN_ZSTATE_SUPPORT_ALLOW ) {for (i =0 ; i < dc->res_pool->pipe_count; ++i) {struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
@@ -2136,7 +2136,7 @@ void dcn20_optimize_bandwidth( && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total) pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp, - pipe_ctx->dlg_regs.optimized_min_dst_y_next_start); + pipe_ctx->dlg_regs.min_dst_y_next_start); } } }
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +11 -12
@@ -948,10 +948,10 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc {int plane_count;int i; -unsigned int optimized_min_dst_y_next_start_us; +unsigned int min_dst_y_next_start_us; plane_count =0 ; - optimized_min_dst_y_next_start_us =0 ; + min_dst_y_next_start_us =0 ;for (i =0 ; i < dc->res_pool->pipe_count; i++) {if (context->res_ctx.pipe_ctx[i].plane_state) plane_count++;
@@ -973,19 +973,18 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, strucelse if (context->stream_count ==1 && context->streams[0 ]->signal ==SIGNAL_TYPE_EDP ) {struct dc_link *link = context->streams[0 ]->sink->link;struct dc_stream_status *stream_status = &context->stream_status[0 ]; +struct dc_stream_state *current_stream = context->streams[0 ];int minmum_z8_residency = dc->debug.minimum_z8_residency_time >0 ? dc->debug.minimum_z8_residency_time :1000 ;bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double )minmum_z8_residency;bool is_pwrseq0 = link->link_index ==0 ; +bool isFreesyncVideo; -if (dc_extended_blank_supported (dc)) { -for (i =0 ; i < dc->res_pool->pipe_count; i++) { -if (context->res_ctx.pipe_ctx[i].stream == context->streams[0 ] - && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min == context->res_ctx.pipe_ctx[i].stream->adjust.v_total_max - && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min > context->res_ctx.pipe_ctx[i].stream->timing.v_total) { - optimized_min_dst_y_next_start_us = - context->res_ctx.pipe_ctx[i].dlg_regs.optimized_min_dst_y_next_start_us; -break ; - } + isFreesyncVideo = current_stream->adjust.v_total_min == current_stream->adjust.v_total_max; + isFreesyncVideo = isFreesyncVideo && current_stream->timing.v_total < current_stream->adjust.v_total_min; +for (i =0 ; i < dc->res_pool->pipe_count; i++) { +if (context->res_ctx.pipe_ctx[i].stream == current_stream && isFreesyncVideo) { + min_dst_y_next_start_us = context->res_ctx.pipe_ctx[i].dlg_regs.min_dst_y_next_start_us; +break ; } }
@@ -993,7 +992,7 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, strucif (stream_status->plane_count >1 )return DCN_ZSTATE_SUPPORT_DISALLOW ; -if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod >5000.0 || optimized_min_dst_y_next_start_us >5000 )) +if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod >5000.0 || min_dst_y_next_start_us >5000 ))return DCN_ZSTATE_SUPPORT_ALLOW ;else if (is_pwrseq0 && link->psr_settings.psr_version ==DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr)return allow_z8 ?DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY :DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY ;
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c +1 -2
@@ -987,8 +987,7 @@ static void dml_rq_dlg_get_dlg_params( dlg_vblank_start = interlaced ? (vblank_start /2 ) : vblank_start; disp_dlg_regs->min_dst_y_next_start = (unsigned int ) (((double ) dlg_vblank_start) *dml_pow (2 ,2 )); - disp_dlg_regs->optimized_min_dst_y_next_start_us =0 ; - disp_dlg_regs->optimized_min_dst_y_next_start = disp_dlg_regs->min_dst_y_next_start; + disp_dlg_regs->min_dst_y_next_start_us =0 ;ASSERT (disp_dlg_regs->min_dst_y_next_start < (unsigned int )dml_pow (2 ,18 ));dml_print ("DML_DLG: %s: min_ttu_vblank (us) = %3.2f\n" , __func__, min_ttu_vblank);
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +10 -4
@@ -286,6 +286,7 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *cstruct resource_context *res_ctx = &context->res_ctx;struct pipe_ctx *pipe;bool upscaled = false; +bool isFreesyncVideo = false;dc_assert_fp_enabled ();
@@ -299,9 +300,16 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe = &res_ctx->pipe_ctx[i]; timing = &pipe->stream->timing; -if (dc_extended_blank_supported (dc) && pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min - && pipe->stream->adjust.v_total_min > timing->v_total) + isFreesyncVideo = pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min; + isFreesyncVideo = isFreesyncVideo && pipe->stream->adjust.v_total_min > timing->v_total; + +if (!isFreesyncVideo) { + pipes[pipe_cnt].pipe.dest.vblank_nom = + dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz /10000.0 )); + }else { pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; + pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; + } if (pipe->plane_state && (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
@@ -323,8 +331,6 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma =0 ; pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma =0 ; pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; - pipes[pipe_cnt].pipe.dest.vblank_nom = - dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz /10000.0 )); pipes[pipe_cnt].pipe.src.dcc_rate =3 ; pipes[pipe_cnt].dout.dsc_input_bpc =0 ;
drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c +4 -12
@@ -1051,7 +1051,6 @@ static void dml_rq_dlg_get_dlg_params(float vba__refcyc_per_req_delivery_pre_l =get_refcyc_per_req_delivery_pre_l_in_us (mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;// From VBA float vba__refcyc_per_req_delivery_l =get_refcyc_per_req_delivery_l_in_us (mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;// From VBA -int blank_lines =0 ;memset (disp_dlg_regs,0 ,sizeof (*disp_dlg_regs));memset (disp_ttu_regs,0 ,sizeof (*disp_ttu_regs));
@@ -1075,17 +1074,10 @@ static void dml_rq_dlg_get_dlg_params( min_ttu_vblank =get_min_ttu_vblank_in_us (mode_lib, e2e_pipe_param, num_pipes, pipe_idx);// From VBA dlg_vblank_start = interlaced ? (vblank_start /2 ) : vblank_start; - disp_dlg_regs->optimized_min_dst_y_next_start = disp_dlg_regs->min_dst_y_next_start; - disp_dlg_regs->optimized_min_dst_y_next_start_us =0 ; - disp_dlg_regs->min_dst_y_next_start = (unsigned int ) (((double ) dlg_vblank_start) *dml_pow (2 ,2 )); - blank_lines = (dst->vblank_end + dst->vtotal_min - dst->vblank_start - dst->vstartup_start -1 ); -if (blank_lines <0 ) - blank_lines =0 ; -if (blank_lines !=0 ) { - disp_dlg_regs->optimized_min_dst_y_next_start = vba__min_dst_y_next_start; - disp_dlg_regs->optimized_min_dst_y_next_start_us = (disp_dlg_regs->optimized_min_dst_y_next_start * dst->hactive) / (unsigned int ) dst->pixel_rate_mhz; - disp_dlg_regs->min_dst_y_next_start = disp_dlg_regs->optimized_min_dst_y_next_start; - } + disp_dlg_regs->min_dst_y_next_start_us = + (vba__min_dst_y_next_start * dst->hactive) / (unsigned int ) dst->pixel_rate_mhz; + disp_dlg_regs->min_dst_y_next_start = vba__min_dst_y_next_start *dml_pow (2 ,2 ); +ASSERT (disp_dlg_regs->min_dst_y_next_start < (unsigned int )dml_pow (2 ,18 ));dml_print ("DML_DLG: %s: min_ttu_vblank (us) = %3.2f\n" , __func__, min_ttu_vblank);
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +1 -2
@@ -619,8 +619,7 @@ struct _vcs_dpi_display_dlg_regs_st {unsigned int refcyc_h_blank_end;unsigned int dlg_vblank_end;unsigned int min_dst_y_next_start; -unsigned int optimized_min_dst_y_next_start; -unsigned int optimized_min_dst_y_next_start_us; +unsigned int min_dst_y_next_start_us;unsigned int refcyc_per_htotal;unsigned int refcyc_x_after_scaler;unsigned int dst_y_after_scaler;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 44/239 drm/amd/display: Fix possible underflow for displays with large vblank
In reply to Greg Kroah-HartmanFrom: Daniel Miess <[email protected]>
[ Upstream commit 1a4bcdbea4319efeb26cc4b05be859a7867e02dc ]
[Why]
Underflow observed when using a display with a large vblank region and low refresh rate
[How]
Simplify calculation of vblank_nom
Increase value for VBlankNomDefaultUS to 800us
Stable-dep-of: 2a9482e55968 ("drm/amd/display: Prevent vtotal from being set to 0")
--- .../amd/display/dc/dml/dcn314/dcn314_fpu.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +7 -12
@@ -33,7 +33,7 @@#include "dml/display_mode_vba.h" struct _vcs_dpi_ip_params_st dcn3_14_ip = { - .VBlankNomDefaultUS =668 , + .VBlankNomDefaultUS =800 , .gpuvm_enable =1 , .gpuvm_max_page_table_levels =1 , .hostvm_enable =1 ,
@@ -286,7 +286,7 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *cstruct resource_context *res_ctx = &context->res_ctx;struct pipe_ctx *pipe;bool upscaled = false; -bool isFreesyncVideo = false; +const unsigned int max_allowed_vblank_nom =1023 ;dc_assert_fp_enabled ();
@@ -300,16 +300,11 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe = &res_ctx->pipe_ctx[i]; timing = &pipe->stream->timing; - isFreesyncVideo = pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min; - isFreesyncVideo = isFreesyncVideo && pipe->stream->adjust.v_total_min > timing->v_total; - -if (!isFreesyncVideo) { - pipes[pipe_cnt].pipe.dest.vblank_nom = - dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz /10000.0 )); - }else { - pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; - pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; - } + pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; + pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; + pipes[pipe_cnt].pipe.dest.vblank_nom =min (pipes[pipe_cnt].pipe.dest.vblank_nom, dcn3_14_ip.VBlankNomDefaultUS); + pipes[pipe_cnt].pipe.dest.vblank_nom =max (pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width); + pipes[pipe_cnt].pipe.dest.vblank_nom =min (pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom); if (pipe->plane_state && (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 45/239 drm/amd/display: Prevent vtotal from being set to 0
In reply to Greg Kroah-HartmanFrom: Daniel Miess <[email protected]>
[ Upstream commit 2a9482e55968ed7368afaa9c2133404069117320 ]
[Why]
In dcn314 DML the destination pipe vtotal was being set to the crtc adjustment vtotal_min value even in cases where that value is 0.
[How]
Only set vtotal to the crtc adjustment vtotal_min value in cases where the value is non-zero.
--- drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +5 -1
@@ -300,7 +300,11 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c pipe = &res_ctx->pipe_ctx[i]; timing = &pipe->stream->timing; - pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; +if (pipe->stream->adjust.v_total_min !=0 ) + pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; +else + pipes[pipe_cnt].pipe.dest.vtotal = timing->v_total; + pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; pipes[pipe_cnt].pipe.dest.vblank_nom =min (pipes[pipe_cnt].pipe.dest.vblank_nom, dcn3_14_ip.VBlankNomDefaultUS); pipes[pipe_cnt].pipe.dest.vblank_nom =max (pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 46/239 jbd2: remove t_checkpoint_io_list
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
[ Upstream commit be22255360f80d3af789daad00025171a65424a5 ]
Since t_checkpoint_io_list was stop using in jbd2_log_do_checkpoint() now, it's time to remove the whole t_checkpoint_io_list logic.
Stable-dep-of: 46f881b5b175 ("jbd2: fix a race when checking checkpoint buffer busy")
--- fs/jbd2/checkpoint.c | 42 ++---------------------------------------- fs/jbd2/commit.c | 3 +-- include/linux/jbd2.h | 6 ------ 3 files changed, 3 insertions(+), 48 deletions(-)
fs/jbd2/checkpoint.c +2 -40
@@ -27,7 +27,7 @@* * Called with j_list_lock held. */ -static inline void __buffer_unlink_first (struct journal_head *jh) +static inline void __buffer_unlink (struct journal_head *jh) {transaction_t *transaction = jh->b_cp_transaction;
@@ -40,23 +40,6 @@ static inline void __buffer_unlink_first(struct journal_head *jh) } } -/* -* Unlink a buffer from a transaction checkpoint(io) list. -* -* Called with j_list_lock held. -*/ -static inline void __buffer_unlink (struct journal_head *jh) -{ -transaction_t *transaction = jh->b_cp_transaction; - -__buffer_unlink_first (jh); -if (transaction->t_checkpoint_io_list == jh) { - transaction->t_checkpoint_io_list = jh->b_cpnext; -if (transaction->t_checkpoint_io_list == jh) - transaction->t_checkpoint_io_list =NULL ; - } -} -/* * Check a checkpoint buffer could be release or not. *
@@ -505,15 +488,6 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,break ;if (need_resched () ||spin_needbreak (&journal->j_list_lock))break ; -if (released) -continue ; - - nr_freed +=journal_shrink_one_cp_list (transaction->t_checkpoint_io_list, - nr_to_scan, &released); -if (*nr_to_scan ==0 ) -break ; -if (need_resched () ||spin_needbreak (&journal->j_list_lock)) -break ; }while (transaction != last_transaction);if (transaction != last_transaction) {
@@ -568,17 +542,6 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)*/ if (need_resched ())return ; -if (ret) -continue ; -/* -* It is essential that we are as careful as in the case of -* t_checkpoint_list with removing the buffer from the list as -* we can possibly see not yet submitted buffers on io_list -*/ - ret =journal_clean_one_cp_list (transaction-> - t_checkpoint_io_list, destroy); -if (need_resched ()) -return ;/* * Stop scanning if we couldn't free the transaction. This * avoids pointless scanning of transactions which still
@@ -663,7 +626,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)jbd2_journal_put_journal_head (jh);/* Is this transaction empty? */ -if (transaction->t_checkpoint_list || transaction->t_checkpoint_io_list) +if (transaction->t_checkpoint_list)return 0 ;/*
@@ -755,7 +718,6 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transactJ_ASSERT (transaction->t_forget ==NULL );J_ASSERT (transaction->t_shadow_list ==NULL );J_ASSERT (transaction->t_checkpoint_list ==NULL ); -J_ASSERT (transaction->t_checkpoint_io_list ==NULL );J_ASSERT (atomic_read (&transaction->t_updates) ==0 );J_ASSERT (journal->j_committing_transaction != transaction);J_ASSERT (journal->j_running_transaction != transaction);
fs/jbd2/commit.c +1 -2
@@ -1141,8 +1141,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)spin_lock (&journal->j_list_lock); commit_transaction->t_state =T_FINISHED ;/* Check if the transaction can be dropped now that we are finished */ -if (commit_transaction->t_checkpoint_list ==NULL && - commit_transaction->t_checkpoint_io_list ==NULL ) { +if (commit_transaction->t_checkpoint_list ==NULL ) {__jbd2_journal_drop_transaction (journal, commit_transaction);jbd2_journal_free_transaction (commit_transaction); }
include/linux/jbd2.h +0 -6
@@ -622,12 +622,6 @@ struct transaction_s*/ struct journal_head *t_checkpoint_list; -/* -* Doubly-linked circular list of all buffers submitted for IO while -* checkpointing. [j_list_lock] -*/ -struct journal_head *t_checkpoint_io_list; -/* * Doubly-linked circular list of metadata buffers being * shadowed by log IO. The IO buffers on the iobuf list and
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 47/239 jbd2: remove journal_clean_one_cp_list()
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
[ Upstream commit b98dba273a0e47dbfade89c9af73c5b012a4eabb ]
journal_clean_one_cp_list() and journal_shrink_one_cp_list() are almost the same, so merge them into journal_shrink_one_cp_list(), remove the nr_to_scan parameter, always scan and try to free the whole checkpoint list.
Stable-dep-of: 46f881b5b175 ("jbd2: fix a race when checking checkpoint buffer busy")
--- fs/jbd2/checkpoint.c | 75 +++++++++---------------------------- include/trace/events/jbd2.h | 12 ++---- 2 files changed, 21 insertions(+), 66 deletions(-)
fs/jbd2/checkpoint.c +17 -58
@@ -349,50 +349,10 @@ int jbd2_cleanup_journal_tail(journal_t *journal)/* Checkpoint list management */ -/* -* journal_clean_one_cp_list -* -* Find all the written-back checkpoint buffers in the given list and -* release them. If 'destroy' is set, clean all buffers unconditionally. -* -* Called with j_list_lock held. -* Returns 1 if we freed the transaction, 0 otherwise. -*/ -static int journal_clean_one_cp_list (struct journal_head *jh,bool destroy) -{ -struct journal_head *last_jh; -struct journal_head *next_jh = jh; - -if (!jh) -return 0 ; - - last_jh = jh->b_cpprev; -do { - jh = next_jh; - next_jh = jh->b_cpnext; - -if (!destroy &&__cp_buffer_busy (jh)) -return 0 ; - -if (__jbd2_journal_remove_checkpoint (jh)) -return 1 ; -/* -* This function only frees up some memory -* if possible so we dont have an obligation -* to finish processing. Bail out if preemption -* requested: -*/ -if (need_resched ()) -return 0 ; - }while (jh != last_jh); - -return 0 ; -} -/* * journal_shrink_one_cp_list * -* Find 'nr_to_scan' written-back checkpoint buffers in the given list +* Find all the written-back checkpoint buffers in the given list * and try to release them. If the whole transaction is released, set * the 'released' parameter. Return the number of released checkpointed * buffers.
@@ -400,15 +360,15 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)* Called with j_list_lock held. */ static unsigned long journal_shrink_one_cp_list (struct journal_head *jh, -unsigned long *nr_to_scan, -bool *released) +bool destroy,bool *released) {struct journal_head *last_jh;struct journal_head *next_jh = jh;unsigned long nr_freed =0 ;int ret; -if (!jh || *nr_to_scan ==0 ) + *released = false; +if (!jh)return 0 ; last_jh = jh->b_cpprev;
@@ -416,8 +376,7 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, jh = next_jh; next_jh = jh->b_cpnext; - (*nr_to_scan)--; -if (__cp_buffer_busy (jh)) +if (!destroy &&__cp_buffer_busy (jh))continue ; nr_freed++;
@@ -429,7 +388,7 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh,if (need_resched ())break ; - }while (jh != last_jh && *nr_to_scan); + }while (jh != last_jh);return nr_freed; }
@@ -447,11 +406,11 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, unsigned long *nr_to_scan) {transaction_t *transaction, *last_transaction, *next_transaction; -bool released; +bool __maybe_unused released;tid_t first_tid =0 , last_tid =0 , next_tid =0 ;tid_t tid =0 ;unsigned long nr_freed =0 ; -unsigned long nr_scanned = *nr_to_scan; +unsigned long freed; again:spin_lock (&journal->j_list_lock);
@@ -480,10 +439,11 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, transaction = next_transaction; next_transaction = transaction->t_cpnext; tid = transaction->t_tid; - released = false; - nr_freed +=journal_shrink_one_cp_list (transaction->t_checkpoint_list, - nr_to_scan, &released); + freed =journal_shrink_one_cp_list (transaction->t_checkpoint_list, + false, &released); + nr_freed += freed; + (*nr_to_scan) -=min (*nr_to_scan, freed);if (*nr_to_scan ==0 )break ;if (need_resched () ||spin_needbreak (&journal->j_list_lock))
@@ -504,9 +464,8 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,if (*nr_to_scan && next_tid) goto again; out: - nr_scanned -= *nr_to_scan;trace_jbd2_shrink_checkpoint_list (journal, first_tid, tid, last_tid, - nr_freed, nr_scanned, next_tid); + nr_freed, next_tid);return nr_freed; }
@@ -522,7 +481,7 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,void __jbd2_journal_clean_checkpoint_list (journal_t *journal,bool destroy) {transaction_t *transaction, *last_transaction, *next_transaction; -int ret; +bool released; transaction = journal->j_checkpoint_transactions;if (!transaction)
@@ -533,8 +492,8 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) do { transaction = next_transaction; next_transaction = transaction->t_cpnext; - ret = journal_clean_one_cp_list(transaction->t_checkpoint_list, - destroy); + journal_shrink_one_cp_list(transaction->t_checkpoint_list, + destroy, &released); /* * This function only frees up some memory if possible so we * dont have an obligation to finish processing. Bail out if
@@ -547,7 +506,7 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)* avoids pointless scanning of transactions which still * weren't checkpointed. */ -if (!ret) +if (!released)return ; }while (transaction != last_transaction); }
include/trace/events/jbd2.h +4 -8
@@ -462,11 +462,9 @@ TRACE_EVENT(jbd2_shrink_scan_exit, TRACE_EVENT(jbd2_shrink_checkpoint_list, TP_PROTO(journal_t *journal, tid_t first_tid, tid_t tid, tid_t last_tid, - unsigned long nr_freed, unsigned long nr_scanned, - tid_t next_tid), + unsigned long nr_freed, tid_t next_tid), - TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, - nr_scanned, next_tid), + TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, next_tid), TP_STRUCT__entry( __field(dev_t, dev)
@@ -474,7 +472,6 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, __field(tid_t, tid) __field(tid_t, last_tid) __field(unsigned long, nr_freed) - __field(unsigned long, nr_scanned) __field(tid_t, next_tid) ),
@@ -484,15 +481,14 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, __entry->tid = tid; __entry->last_tid = last_tid; __entry->nr_freed = nr_freed; - __entry->nr_scanned = nr_scanned; __entry->next_tid = next_tid; ),TP_printk ("dev %d,%d shrink transaction %u-%u(%u) freed %lu " -"scanned %lu next transaction %u" , +"next transaction %u" ,MAJOR (__entry->dev),MINOR (__entry->dev), __entry->first_tid, __entry->tid, __entry->last_tid, - __entry->nr_freed, __entry->nr_scanned, __entry->next_tid) + __entry->nr_freed, __entry->next_tid) );#endif /* _TRACE_JBD2_H */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 48/239 jbd2: fix a race when checking checkpoint buffer busy
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
[ Upstream commit 46f881b5b1758dc4a35fba4a643c10717d0cf427 ]
Before removing checkpoint buffer from the t_checkpoint_list, we have to check both BH_Dirty and BH_Lock bits together to distinguish buffers have not been or were being written back. But __cp_buffer_busy() checks them separately, it first check lock state and then check dirty, the window between these two checks could be raced by writing back procedure, which locks buffer and clears buffer dirty before I/O completes. So it cannot guarantee checkpointing buffers been written back to disk if some error happens later. Finally, it may clean checkpoint transactions and lead to inconsistent filesystem.
jbd2_journal_forget() and __journal_try_to_free_buffer() also have the same problem (journal_unmap_buffer() escape from this issue since it's running under the buffer lock), so fix them through introducing a new helper to try holding the buffer lock and remove really clean buffer.
--- fs/jbd2/checkpoint.c | 38 +++++++++++++++++++++++++++++++++++--- fs/jbd2/transaction.c | 17 +++++------------ include/linux/jbd2.h | 1 + 3 files changed, 41 insertions(+), 15 deletions(-)
fs/jbd2/checkpoint.c +35 -3
@@ -376,11 +376,15 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, jh = next_jh; next_jh = jh->b_cpnext; -if (!destroy &&__cp_buffer_busy (jh)) -continue ; +if (destroy) { + ret =__jbd2_journal_remove_checkpoint (jh); + }else { + ret =jbd2_journal_try_remove_checkpoint (jh); +if (ret <0 ) +continue ; + } nr_freed++; - ret =__jbd2_journal_remove_checkpoint (jh);if (ret) { *released = true;break ;
@@ -616,6 +620,34 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)return 1 ; } +/* +* Check the checkpoint buffer and try to remove it from the checkpoint +* list if it's clean. Returns -EBUSY if it is not clean, returns 1 if +* it frees the transaction, 0 otherwise. +* +* This function is called with j_list_lock held. +*/ +int jbd2_journal_try_remove_checkpoint (struct journal_head *jh) +{ +struct buffer_head *bh =jh2bh (jh); + +if (!trylock_buffer (bh)) +return -EBUSY ; +if (buffer_dirty (bh)) { +unlock_buffer (bh); +return -EBUSY ; + } +unlock_buffer (bh); + +/* +* Buffer is clean and the IO has finished (we held the buffer +* lock) so the checkpoint is done. We can safely remove the +* buffer from this transaction. +*/ +JBUFFER_TRACE (jh,"remove from checkpoint list" ); +return __jbd2_journal_remove_checkpoint (jh); +} +/* * journal_insert_checkpoint: put a committed buffer onto a checkpoint * list so that we know when it is safe to clean the transaction out of
fs/jbd2/transaction.c +5 -12
@@ -1784,8 +1784,7 @@ int jbd2_journal_forget(handle_t *handle, struct buffer_head *bh)* Otherwise, if the buffer has been written to disk, * it is safe to remove the checkpoint and drop it. */ -if (!buffer_dirty (bh)) { -__jbd2_journal_remove_checkpoint (jh); +if (jbd2_journal_try_remove_checkpoint (jh) >=0 ) {spin_unlock (&journal->j_list_lock); goto drop; }
@@ -2112,20 +2111,14 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) jh =bh2jh (bh); -if (buffer_locked (bh) ||buffer_dirty (bh)) - goto out; -if (jh->b_next_transaction !=NULL || jh->b_transaction !=NULL ) - goto out; +return ;spin_lock (&journal->j_list_lock); -if (jh->b_cp_transaction !=NULL ) { -/* written-back checkpointed metadata buffer */ -JBUFFER_TRACE (jh,"remove from checkpoint list" ); -__jbd2_journal_remove_checkpoint (jh); - } +/* Remove written-back checkpointed metadata buffer */ +if (jh->b_cp_transaction !=NULL ) +jbd2_journal_try_remove_checkpoint (jh);spin_unlock (&journal->j_list_lock); -out:return ; }
include/linux/jbd2.h +1 -0
@@ -1443,6 +1443,7 @@ extern void jbd2_journal_commit_transaction(journal_t *);void __jbd2_journal_clean_checkpoint_list (journal_t *journal,bool destroy);unsigned long jbd2_journal_shrink_checkpoint_list (journal_t *journal,unsigned long *nr_to_scan);int __jbd2_journal_remove_checkpoint (struct journal_head *); +int jbd2_journal_try_remove_checkpoint (struct journal_head *jh);void jbd2_journal_destroy_checkpoint (journal_t *journal);void __jbd2_journal_insert_checkpoint (struct journal_head *,transaction_t *);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 49/239 ext4: add EXT4_MB_HINT_GOAL_ONLY test in ext4_mb_use_preallocated
In reply to Greg Kroah-HartmanFrom: Kemeng Shi <[email protected]>
[ Upstream commit 1eff590489a213a213c57d96b86f48b32cdf8c3a ]
ext4_mb_use_preallocated will ignore the demand to alloc goal blocks, although the EXT4_MB_HINT_GOAL_ONLY is requested.
For group pa, ext4_mb_group_or_file will not set EXT4_MB_HINT_GROUP_ALLOC if EXT4_MB_HINT_GOAL_ONLY is set. So we will not alloc goal blocks from group pa if EXT4_MB_HINT_GOAL_ONLY is set.
For inode pa, ext4_mb_pa_goal_check is added to check if free extent in found inode pa meets goal blocks when EXT4_MB_HINT_GOAL_ONLY is set.
Stable-dep-of: 9d3de7ee192a ("ext4: fix rbtree traversal bug in ext4_mb_use_preallocated")
--- fs/ext4/mballoc.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
fs/ext4/mballoc.c +33 -1
@@ -4528,6 +4528,37 @@ ext4_mb_check_group_pa(ext4_fsblk_t goal_block,return pa; } +/* +* check if found pa meets EXT4_MB_HINT_GOAL_ONLY +*/ +static bool +ext4_mb_pa_goal_check (struct ext4_allocation_context *ac, +struct ext4_prealloc_space *pa) +{ +struct ext4_sb_info *sbi =EXT4_SB (ac->ac_sb); +ext4_fsblk_t start; + +if (likely (!(ac->ac_flags &EXT4_MB_HINT_GOAL_ONLY ))) +return true; + +/* +* If EXT4_MB_HINT_GOAL_ONLY is set, ac_g_ex will not be adjusted +* in ext4_mb_normalize_request and will keep same with ac_o_ex +* from ext4_mb_initialize_context. Choose ac_g_ex here to keep +* consistent with ext4_mb_find_by_goal. +*/ + start = pa->pa_pstart + + (ac->ac_g_ex.fe_logical - pa->pa_lstart); +if (ext4_grp_offs_to_block (ac->ac_sb, &ac->ac_g_ex) != start) +return false; + +if (ac->ac_g_ex.fe_len > pa->pa_len - +EXT4_B2C (sbi, ac->ac_g_ex.fe_logical - pa->pa_lstart)) +return false; + +return true; +} +/* * search goal blocks in preallocated space */
@@ -4578,7 +4609,8 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)/* found preallocated blocks, use them */ spin_lock (&tmp_pa->pa_lock); -if (tmp_pa->pa_deleted ==0 && tmp_pa->pa_free) { +if (tmp_pa->pa_deleted ==0 && tmp_pa->pa_free && +likely (ext4_mb_pa_goal_check (ac, tmp_pa))) {atomic_inc (&tmp_pa->pa_count);ext4_mb_use_inode_pa (ac, tmp_pa);spin_unlock (&tmp_pa->pa_lock);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 50/239 ext4: mballoc: Remove useless setting of ac_criteria
In reply to Greg Kroah-HartmanFrom: Ritesh Harjani <[email protected]>
[ Upstream commit 569f196f1e7a14472f21734170411f75a3179db0 ]
There will be changes coming in future patches which will introduce a new criteria for block allocation. This removes the useless setting of ac_criteria. AFAIU, this might be only used to differentiate between whether a preallocated blocks was allocated or was regular allocator called for allocating blocks. Hence this also adds the debug prints to identify what type of block allocation was done in ext4_mb_show_ac().
Stable-dep-of: 9d3de7ee192a ("ext4: fix rbtree traversal bug in ext4_mb_use_preallocated")
--- fs/ext4/mballoc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/mballoc.c +4 -2
@@ -4614,7 +4614,6 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)atomic_inc (&tmp_pa->pa_count);ext4_mb_use_inode_pa (ac, tmp_pa);spin_unlock (&tmp_pa->pa_lock); - ac->ac_criteria =10 ;read_unlock (&ei->i_prealloc_lock);return true; }
@@ -4657,7 +4656,6 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac) }if (cpa) {ext4_mb_use_group_pa (ac, cpa); - ac->ac_criteria =20 ;return true; }return false;
@@ -5431,6 +5429,10 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac) (unsigned long )ac->ac_b_ex.fe_logical, (int)ac->ac_criteria);mb_debug (sb,"%u found" , ac->ac_found); +mb_debug (sb,"used pa: %s, " , ac->ac_pa ?"yes" :"no" ); +if (ac->ac_pa) +mb_debug (sb,"pa_type %s\n" , ac->ac_pa->pa_type ==MB_GROUP_PA ? +"group pa" :"inode pa" ); ext4_mb_show_pa(sb); }#else
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 51/239 ext4: fix rbtree traversal bug in ext4_mb_use_preallocated
In reply to Greg Kroah-HartmanFrom: Ojaswin Mujoo <[email protected]>
[ Upstream commit 9d3de7ee192a6a253f475197fe4d2e2af10a731f ]
During allocations, while looking for preallocations(PA) in the per inode rbtree, we can't do a direct traversal of the tree because ext4_mb_discard_group_preallocation() can paralelly mark the pa deleted and that can cause direct traversal to skip some entries. This was leading to a BUG_ON() being hit [1] when we missed a PA that could satisfy our request and ultimately tried to create a new PA that would overlap with the missed one.
To makes sure we handle that case while still keeping the performance of the rbtree, we make use of the fact that the only pa that could possibly overlap the original goal start is the one that satisfies the below conditions:
1. It must have it's logical start immediately to the left of (ie less than) original logical start.
2. It must not be deleted
To find this pa we use the following traversal method:
1. Descend into the rbtree normally to find the immediate neighboring PA. Here we keep descending irrespective of if the PA is deleted or if it overlaps with our request etc. The goal is to find an immediately adjacent PA.
2. If the found PA is on right of original goal, use rb_prev() to find the left adjacent PA.
3. Check if this PA is deleted and keep moving left with rb_prev() until a non deleted PA is found.
4. This is the PA we are looking for. Now we can check if it can satisfy the original request and proceed accordingly.
This approach also takes care of having deleted PAs in the tree.
(While we are at it, also fix a possible overflow bug in calculating the end of a PA)
--- fs/ext4/mballoc.c | 158 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 131 insertions(+), 27 deletions(-)
fs/ext4/mballoc.c +131 -27
@@ -4569,8 +4569,8 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)int order, i;struct ext4_inode_info *ei =EXT4_I (ac->ac_inode);struct ext4_locality_group *lg; -struct ext4_prealloc_space *tmp_pa, *cpa =NULL ; -ext4_lblk_t tmp_pa_start, tmp_pa_end; +struct ext4_prealloc_space *tmp_pa =NULL , *cpa =NULL ; +loff_t tmp_pa_end;struct rb_node *iter;ext4_fsblk_t goal_block;
@@ -4578,47 +4578,151 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)if (!(ac->ac_flags &EXT4_MB_HINT_DATA ))return false; -/* first, try per-file preallocation */ +/* +* first, try per-file preallocation by searching the inode pa rbtree. +* +* Here, we can't do a direct traversal of the tree because +* ext4_mb_discard_group_preallocation() can paralelly mark the pa +* deleted and that can cause direct traversal to skip some entries. +*/ read_lock (&ei->i_prealloc_lock); + +if (RB_EMPTY_ROOT (&ei->i_prealloc_node)) { + goto try_group_pa; + } + +/* +* Step 1: Find a pa with logical start immediately adjacent to the +* original logical start. This could be on the left or right. +* +* (tmp_pa->pa_lstart never changes so we can skip locking for it). +*/ for (iter = ei->i_prealloc_node.rb_node; iter; iter =ext4_mb_pa_rb_next_iter (ac->ac_o_ex.fe_logical, - tmp_pa_start, iter)) { + tmp_pa->pa_lstart, iter)) { tmp_pa = rb_entry(iter, struct ext4_prealloc_space, pa_node.inode_node); + } -/* all fields in this condition don't change, -* so we can skip locking for them */ - tmp_pa_start = tmp_pa->pa_lstart; - tmp_pa_end = tmp_pa->pa_lstart +EXT4_C2B (sbi, tmp_pa->pa_len); - -/* original request start doesn't lie in this PA */ -if (ac->ac_o_ex.fe_logical < tmp_pa_start || - ac->ac_o_ex.fe_logical >= tmp_pa_end) -continue ; +/* +* Step 2: The adjacent pa might be to the right of logical start, find +* the left adjacent pa. After this step we'd have a valid tmp_pa whose +* logical start is towards the left of original request's logical start +*/ +if (tmp_pa->pa_lstart > ac->ac_o_ex.fe_logical) { +struct rb_node *tmp; + tmp =rb_prev (&tmp_pa->pa_node.inode_node); -/* non-extent files can't have physical blocks past 2^32 */ -if (!(ext4_test_inode_flag (ac->ac_inode,EXT4_INODE_EXTENTS )) && - (tmp_pa->pa_pstart +EXT4_C2B (sbi, tmp_pa->pa_len) > -EXT4_MAX_BLOCK_FILE_PHYS )) { +if (tmp) { + tmp_pa = rb_entry(tmp, struct ext4_prealloc_space, + pa_node.inode_node); + }else {/* -* Since PAs don't overlap, we won't find any -* other PA to satisfy this. +* If there is no adjacent pa to the left then finding +* an overlapping pa is not possible hence stop searching +* inode pa tree */ -break ; + goto try_group_pa; } + } -/* found preallocated blocks, use them */ +BUG_ON (!(tmp_pa && tmp_pa->pa_lstart <= ac->ac_o_ex.fe_logical)); + +/* +* Step 3: If the left adjacent pa is deleted, keep moving left to find +* the first non deleted adjacent pa. After this step we should have a +* valid tmp_pa which is guaranteed to be non deleted. +*/ +for (iter = &tmp_pa->pa_node.inode_node;; iter =rb_prev (iter)) { +if (!iter) { +/* +* no non deleted left adjacent pa, so stop searching +* inode pa tree +*/ + goto try_group_pa; + } + tmp_pa = rb_entry(iter, struct ext4_prealloc_space, + pa_node.inode_node);spin_lock (&tmp_pa->pa_lock); -if (tmp_pa->pa_deleted ==0 && tmp_pa->pa_free && -likely (ext4_mb_pa_goal_check (ac, tmp_pa))) { -atomic_inc (&tmp_pa->pa_count); -ext4_mb_use_inode_pa (ac, tmp_pa); +if (tmp_pa->pa_deleted ==0 ) { +/* +* We will keep holding the pa_lock from +* this point on because we don't want group discard +* to delete this pa underneath us. Since group +* discard is anyways an ENOSPC operation it +* should be okay for it to wait a few more cycles. +*/ +break ; + }else {spin_unlock (&tmp_pa->pa_lock); -read_unlock (&ei->i_prealloc_lock); -return true; } + } + +BUG_ON (!(tmp_pa && tmp_pa->pa_lstart <= ac->ac_o_ex.fe_logical)); +BUG_ON (tmp_pa->pa_deleted ==1 ); + +/* +* Step 4: We now have the non deleted left adjacent pa. Only this +* pa can possibly satisfy the request hence check if it overlaps +* original logical start and stop searching if it doesn't. +*/ + tmp_pa_end = (loff_t )tmp_pa->pa_lstart +EXT4_C2B (sbi, tmp_pa->pa_len); + +if (ac->ac_o_ex.fe_logical >= tmp_pa_end) { +spin_unlock (&tmp_pa->pa_lock); + goto try_group_pa; + } + +/* non-extent files can't have physical blocks past 2^32 */ +if (!(ext4_test_inode_flag (ac->ac_inode,EXT4_INODE_EXTENTS )) && + (tmp_pa->pa_pstart +EXT4_C2B (sbi, tmp_pa->pa_len) > +EXT4_MAX_BLOCK_FILE_PHYS )) { +/* +* Since PAs don't overlap, we won't find any other PA to +* satisfy this. +*/ spin_unlock (&tmp_pa->pa_lock); + goto try_group_pa; + } + +if (tmp_pa->pa_free &&likely (ext4_mb_pa_goal_check (ac, tmp_pa))) { +atomic_inc (&tmp_pa->pa_count); +ext4_mb_use_inode_pa (ac, tmp_pa); +spin_unlock (&tmp_pa->pa_lock); +read_unlock (&ei->i_prealloc_lock); +return true; + }else { +/* +* We found a valid overlapping pa but couldn't use it because +* it had no free blocks. This should ideally never happen +* because: +* +* 1. When a new inode pa is added to rbtree it must have +* pa_free > 0 since otherwise we won't actually need +* preallocation. +* +* 2. An inode pa that is in the rbtree can only have it's +* pa_free become zero when another thread calls: +* ext4_mb_new_blocks +* ext4_mb_use_preallocated +* ext4_mb_use_inode_pa +* +* 3. Further, after the above calls make pa_free == 0, we will +* immediately remove it from the rbtree in: +* ext4_mb_new_blocks +* ext4_mb_release_context +* ext4_mb_put_pa +* +* 4. Since the pa_free becoming 0 and pa_free getting removed +* from tree both happen in ext4_mb_new_blocks, which is always +* called with i_data_sem held for data allocations, we can be +* sure that another process will never see a pa in rbtree with +* pa_free == 0. +*/ +WARN_ON_ONCE (tmp_pa->pa_free ==0 ); } +spin_unlock (&tmp_pa->pa_lock); +try_group_pa:read_unlock (&ei->i_prealloc_lock);/* can we use group allocation? */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 52/239 phy: phy-mtk-dp: Fix an error code in probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5782017cc4d0c8f3425d55b893675bb8a20c33e9 ]
Negative -EINVAL was intended instead of positive EINVAL.
--- drivers/phy/mediatek/phy-mtk-dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/mediatek/phy-mtk-dp.c +1 -1
@@ -169,7 +169,7 @@ static int mtk_dp_phy_probe(struct platform_device *pdev) regs = *(struct regmap **)dev->platform_data;if (!regs) -return dev_err_probe (dev,EINVAL , +return dev_err_probe (dev, -EINVAL ,"No data passed, requires struct regmap**\n" ); dp_phy =devm_kzalloc (dev,sizeof (*dp_phy),GFP_KERNEL );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 53/239 phy: mediatek: hdmi: mt8195: fix prediv bad upper limit test
In reply to Greg Kroah-HartmanFrom: Guillaume Ranquet <[email protected]>
[ Upstream commit 95bd315f0a5ed7d7afe771776272c5b3cdb29bc8 ]
The pll prediv calculus searchs for the smallest prediv that gets the ns_hdmipll_ck in the range of 5 GHz to 12 GHz.
A typo in the upper bound test was testing for 5Ghz to 1Ghz
--- drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c +1 -1
@@ -253,7 +253,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw,for (i =0 ; i <ARRAY_SIZE (txpredivs); i++) { ns_hdmipll_ck =5 * tmds_clk * txposdiv * txpredivs[i];if (ns_hdmipll_ck >=5 *GIGA && - ns_hdmipll_ck <=1 *GIGA ) + ns_hdmipll_ck <=12 *GIGA )break ; } if (i == (ARRAY_SIZE(txpredivs) - 1) &&
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 54/239 phy: qcom-snps-femto-v2: keep cfg_ahb_clk enabled during runtime suspend
In reply to Greg Kroah-HartmanFrom: Adrien Thierry <[email protected]>
[ Upstream commit 45d89a344eb46db9dce851c28e14f5e3c635c251 ]
In the dwc3 core, both system and runtime suspend end up calling dwc3_suspend_common(). From there, what happens for the PHYs depends on the USB mode and whether the controller is entering system or runtime suspend.
HOST mode:
(1) system suspend on a non-wakeup-capable controller
The [1] if branch is taken. dwc3_core_exit() is called, which ends up calling phy_power_off() and phy_exit(). Those two functions decrease the PM runtime count at some point, so they will trigger the PHY runtime sleep (assuming the count is right).
(2) runtime suspend / system suspend on a wakeup-capable controller
The [1] branch is not taken. dwc3_suspend_common() calls phy_pm_runtime_put_sync(). Assuming the ref count is right, the PHY runtime suspend op is called.
DEVICE mode:
dwc3_core_exit() is called on both runtime and system sleep unless the controller is already runtime suspended.
OTG mode:
(1) system suspend : dwc3_core_exit() is called
(2) runtime suspend : do nothing
In host mode, the code seems to make a distinction between 1) runtime sleep / system sleep for wakeup-capable controller, and 2) system sleep for non-wakeup-capable controller, where phy_power_off() and phy_exit() are only called for the latter. This suggests the PHY is not supposed to be in a fully powered-off state for runtime sleep and system sleep for wakeup-capable controller.
Moreover, downstream, cfg_ahb_clk only gets disabled for system suspend. The clocks are disabled by phy->set_suspend() [2] which is only called in the system sleep path through dwc3_core_exit() [3].
With that in mind, don't disable the clocks during the femto PHY runtime suspend callback. The clocks will only be disabled during system suspend for non-wakeup-capable controllers, through dwc3_core_exit().
[1] https://elixir.bootlin.com/linux/v6.4/source/drivers/usb/dwc3/core.c#L1988
[2] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/phy/phy-msm-snps-hs.c#L524
[3] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/dwc3/core.c#L1915
Stable-dep-of: 8a0eb8f9b9a0 ("phy: qcom-snps-femto-v2: properly enable ref clock")
--- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +0 -9
@@ -165,22 +165,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) 0, USB2_AUTO_RESUME); } -clk_disable_unprepare (hsphy->cfg_ahb_clk);return 0 ; }static int qcom_snps_hsphy_resume (struct qcom_snps_hsphy *hsphy) { -int ret; -dev_dbg (&hsphy->phy->dev,"Resume QCOM SNPS PHY, mode\n" ); - ret =clk_prepare_enable (hsphy->cfg_ahb_clk); -if (ret) { -dev_err (&hsphy->phy->dev,"failed to enable cfg ahb clock\n" ); -return ret; - } -return 0 ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 55/239 phy: qcom-snps-femto-v2: properly enable ref clock
In reply to Greg Kroah-HartmanFrom: Adrien Thierry <[email protected]>
[ Upstream commit 8a0eb8f9b9a002291a3934acfd913660b905249e ]
The driver is not enabling the ref clock, which thus gets disabled by the clk_disable_unused() initcall. This leads to the dwc3 controller failing to initialize if probed after clk_disable_unused() is called, for instance when the driver is built as a module.
To fix this, switch to the clk_bulk API to handle both cfg_ahb and ref clocks at the proper places.
Note that the cfg_ahb clock is currently not used by any device tree instantiation of the PHY. Work needs to be done separately to fix this.
--- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-)
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +48 -15
@@ -110,11 +110,13 @@ struct phy_override_seq {/** * struct qcom_snps_hsphy - snps hs phy attributes * +* @dev: device structure +* * @phy: generic phy * @base: iomapped memory space for snps hs phy * -* @cfg_ahb_clk: AHB2PHY interface clock -* @ref_clk: phy reference clock +* @num_clks: number of clocks +* @clks: array of clocks * @phy_reset: phy reset control * @vregs: regulator supplies bulk data * @phy_initialized: if PHY has been initialized correctly
@@ -122,11 +124,13 @@ struct phy_override_seq {* @update_seq_cfg: tuning parameters for phy init */ struct qcom_snps_hsphy { +struct device *dev; +struct phy *phy;void __iomem *base; -struct clk *cfg_ahb_clk; -struct clk *ref_clk; +int num_clks; +struct clk_bulk_data *clks;struct reset_control *phy_reset;struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS ];
@@ -135,6 +139,34 @@ struct qcom_snps_hsphy {struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS ]; }; +static int qcom_snps_hsphy_clk_init (struct qcom_snps_hsphy *hsphy) +{ +struct device *dev = hsphy->dev; + + hsphy->num_clks =2 ; + hsphy->clks =devm_kcalloc (dev, hsphy->num_clks,sizeof (*hsphy->clks),GFP_KERNEL ); +if (!hsphy->clks) +return -ENOMEM ; + +/* +* TODO: Currently no device tree instantiation of the PHY is using the clock. +* This needs to be fixed in order for this code to be able to use devm_clk_bulk_get(). +*/ + hsphy->clks[0 ].id ="cfg_ahb" ; + hsphy->clks[0 ].clk =devm_clk_get_optional (dev,"cfg_ahb" ); +if (IS_ERR (hsphy->clks[0 ].clk)) +return dev_err_probe (dev,PTR_ERR (hsphy->clks[0 ].clk), +"failed to get cfg_ahb clk\n" ); + + hsphy->clks[1 ].id ="ref" ; + hsphy->clks[1 ].clk =devm_clk_get (dev,"ref" ); +if (IS_ERR (hsphy->clks[1 ].clk)) +return dev_err_probe (dev,PTR_ERR (hsphy->clks[1 ].clk), +"failed to get ref clk\n" ); + +return 0 ; +} +static inline void qcom_snps_hsphy_write_mask (void __iomem *base,u32 offset,u32 mask,u32 val) {
@@ -365,16 +397,16 @@ static int qcom_snps_hsphy_init(struct phy *phy)if (ret)return ret; - ret =clk_prepare_enable (hsphy->cfg_ahb_clk); + ret =clk_bulk_prepare_enable (hsphy->num_clks, hsphy->clks);if (ret) { -dev_err (&phy->dev,"failed to enable cfg ahb clock, %d\n" , ret); +dev_err (&phy->dev,"failed to enable clocks, %d\n" , ret); goto poweroff_phy; } ret =reset_control_assert (hsphy->phy_reset);if (ret) {dev_err (&phy->dev,"failed to assert phy_reset, %d\n" , ret); - goto disable_ahb_clk; + goto disable_clks; }usleep_range (100 ,150 );
@@ -382,7 +414,7 @@ static int qcom_snps_hsphy_init(struct phy *phy) ret =reset_control_deassert (hsphy->phy_reset);if (ret) {dev_err (&phy->dev,"failed to de-assert phy_reset, %d\n" , ret); - goto disable_ahb_clk; + goto disable_clks; } qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
@@ -439,8 +471,8 @@ static int qcom_snps_hsphy_init(struct phy *phy)return 0 ; -disable_ahb_clk: -clk_disable_unprepare (hsphy->cfg_ahb_clk); +disable_clks: +clk_bulk_disable_unprepare (hsphy->num_clks, hsphy->clks); poweroff_phy:regulator_bulk_disable (ARRAY_SIZE (hsphy->vregs), hsphy->vregs);
@@ -452,7 +484,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy)struct qcom_snps_hsphy *hsphy =phy_get_drvdata (phy);reset_control_assert (hsphy->phy_reset); -clk_disable_unprepare (hsphy->cfg_ahb_clk); +clk_bulk_disable_unprepare (hsphy->num_clks, hsphy->clks);regulator_bulk_disable (ARRAY_SIZE (hsphy->vregs), hsphy->vregs); hsphy->phy_initialized = false;
@@ -545,14 +577,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)if (!hsphy)return -ENOMEM ; + hsphy->dev = dev; + hsphy->base =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (hsphy->base))return PTR_ERR (hsphy->base); - hsphy->ref_clk =devm_clk_get (dev,"ref" ); -if (IS_ERR (hsphy->ref_clk)) -return dev_err_probe (dev,PTR_ERR (hsphy->ref_clk), -"failed to get ref clk\n" ); + ret =qcom_snps_hsphy_clk_init (hsphy); +if (ret) +return dev_err_probe (dev, ret,"failed to initialize clocks\n" ); hsphy->phy_reset =devm_reset_control_get_exclusive (&pdev->dev,NULL );if (IS_ERR (hsphy->phy_reset)) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 56/239 soundwire: qcom: update status correctly with mask
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit f84d41b2a083b990cbdf70f3b24b6b108b9678ad ]
SoundWire device status can be incorrectly updated without proper mask, fix this by adding a mask before updating the status.
--- drivers/soundwire/qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soundwire/qcom.c +1 -1
@@ -437,7 +437,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl) status = (val >> (dev_num *SWRM_MCP_SLV_STATUS_SZ ));if ((status &SWRM_MCP_SLV_STATUS_MASK ) ==SDW_SLAVE_ALERT ) { - ctrl->status[dev_num] = status; + ctrl->status[dev_num] = status &SWRM_MCP_SLV_STATUS_MASK ;return dev_num; } }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 57/239 soundwire: amd: Fix a check for errors in probe()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 7891d0a5ce6f627132d3068ba925cf86f29008b1 ]
This code has two problems:
1) The devm_ioremap() function returns NULL, not error pointers.
2) It's checking the wrong variable. ->mmio instead of ->acp_mmio.
--- drivers/soundwire/amd_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/soundwire/amd_manager.c +2 -2
@@ -910,9 +910,9 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)return -ENOMEM ; amd_manager->acp_mmio =devm_ioremap (dev, res->start,resource_size (res)); -if (IS_ERR (amd_manager->mmio)) { +if (!amd_manager->acp_mmio) {dev_err (dev,"mmio not found\n" ); -return PTR_ERR (amd_manager->mmio); +return -ENOMEM ; } amd_manager->instance = pdata->instance; amd_manager->mmio = amd_manager->acp_mmio +
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 58/239 media: tc358746: Address compiler warnings
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
[ Upstream commit 9c2dcfc2cf0f2e4e0a0db33bc1a626e35928c475 ]
Address these compiler warnings by initialising the m_best and p_best values to 0 and 1 respectively (as latter is used as a divisor):
drivers/media/i2c/tc358746.c: In function 'tc358746_find_pll_settings':
Quoted 1 line
Quoted 1 line
drivers/media/i2c/tc358746.c:817:13: warning: 'p_best' is used uninitialized
[-Wuninitialized]
817 | u16 p_best, p;
| ^~~~~~Quoted 1 line
Quoted 1 line
drivers/media/i2c/tc358746.c:816:13: warning: 'm_best' is used uninitialized
[-Wuninitialized]
816 | u16 m_best, mul;
| ^~~~~~The warnings may well be a false positive but it is difficult for a compiler to find out whether that truly is the case.
--- drivers/media/i2c/tc358746.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/i2c/tc358746.c +2 -2
@@ -813,8 +813,8 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746,u32 min_delta =0xffffffff ;u16 prediv_max =17 ;u16 prediv_min =1 ; -u16 m_best, mul; -u16 p_best, p; +u16 m_best =0 , mul; +u16 p_best =1 , p;u8 postdiv;if (fout >1000 *HZ_PER_MHZ ) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 59/239 media: staging: atomisp: select V4L2_FWNODE
In reply to Greg Kroah-HartmanFrom: Sakari Ailus <[email protected]>
[ Upstream commit bf4c985707d3168ebb7d87d15830de66949d979c ]
Select V4L2_FWNODE as the driver depends on it.
--- drivers/staging/media/atomisp/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/staging/media/atomisp/Kconfig +1 -0
@@ -13,6 +13,7 @@ config VIDEO_ATOMISP tristate "Intel Atom Image Signal Processor Driver" depends on VIDEO_DEV && INTEL_ATOMISP depends on PMIC_OPREGION + select V4L2_FWNODE select IOSF_MBI select VIDEOBUF2_VMALLOC select VIDEO_V4L2_SUBDEV_API
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 60/239 media: amphion: Fix firmware path to match linux-firmware
In reply to Greg Kroah-HartmanFrom: Nicolas Dufresne <[email protected]>
[ Upstream commit dcff0b56f661b6b42e828012b464d22cc2068c38 ]
The path did not match the one it was submitted into linux-firmware which prevented generic distribution from having working CODEC.
--- drivers/media/platform/amphion/vpu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/platform/amphion/vpu_core.c +2 -2
@@ -826,7 +826,7 @@ static const struct dev_pm_ops vpu_core_pm_ops = {static struct vpu_core_resources imx8q_enc = { .type =VPU_CORE_TYPE_ENC , - .fwname ="vpu/vpu_fw_imx8_enc.bin" , + .fwname ="amphion/vpu/vpu_fw_imx8_enc.bin" , .stride =16 , .max_width =1920 , .max_height =1920 ,
@@ -841,7 +841,7 @@ static struct vpu_core_resources imx8q_enc = {static struct vpu_core_resources imx8q_dec = { .type =VPU_CORE_TYPE_DEC , - .fwname ="vpu/vpu_fw_imx8_dec.bin" , + .fwname ="amphion/vpu/vpu_fw_imx8_dec.bin" , .stride =256 , .max_width =8188 , .max_height =8188 ,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 61/239 media: mtk-jpeg: move data/code inside CONFIG_OF blocks
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit da4ede4b7fd6aa341b69e3a9d2517b8df5e744fd ]
Lots of data and functions here are not needed when CONFIG_OF is not set, so move them inside #ifdef CONFIG_OF blocks to prevent the warnings.
../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1645:29: warning: ‘mtk_jpeg_clocks’ defined but not used [-Wunused-variable]
1645 | static struct clk_bulk_data mtk_jpeg_clocks[] = {../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1640:29: warning: ‘mt8173_jpeg_dec_clocks’ defined but not used [-Wunused-variable]
1640 | static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1481:20: warning: ‘mtk_jpeg_dec_irq’ defined but not used [-Wunused-function]
1481 | static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1461:20: warning: ‘mtk_jpeg_enc_irq’ defined but not used [-Wunused-function]
1461 | static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1180:13: warning: ‘mtk_jpegdec_worker’ defined but not used [-Wunused-function]
1180 | static void mtk_jpegdec_worker(struct work_struct *work)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:986:13: warning: ‘mtk_jpegenc_worker’ defined but not used [-Wunused-function]
986 | static void mtk_jpegenc_worker(struct work_struct *work)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:79:28: warning: ‘mtk_jpeg_dec_formats’ defined but not used [-Wunused-variable]
79 | static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = {../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:31:28: warning: ‘mtk_jpeg_enc_formats’ defined but not used [-Wunused-variable]
31 | static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = {../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1222:20: warning: ‘mtk_jpeg_enc_done’ defined but not used [-Wunused-function]
1222 | static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1072:12: warning: ‘mtk_jpegdec_set_hw_param’ defined but not used [-Wunused-function]
1072 | static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx,../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1060:12: warning: ‘mtk_jpegdec_put_hw’ defined but not used [-Wunused-function]
1060 | static int mtk_jpegdec_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1038:12: warning: ‘mtk_jpegdec_get_hw’ defined but not used [-Wunused-function]
1038 | static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:977:12: warning: ‘mtk_jpegenc_put_hw’ defined but not used [-Wunused-function]
977 | static int mtk_jpegenc_put_hw(struct mtk_jpeg_dev *jpeg, int hw_id)../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:963:12: warning: ‘mtk_jpegenc_set_hw_param’ defined but not used [-Wunused-function]
963 | static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx,../drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:941:12: warning: ‘mtk_jpegenc_get_hw’ defined but not used [-Wunused-function]
941 | static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx)
Stable-dep-of: 20de9fdaf488 ("media: mtk_jpeg_core: avoid unused-variable warning")
--- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 858 +++++++++--------- 1 file changed, 430 insertions(+), 428 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +430 -428
@@ -28,6 +28,7 @@#include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" +#if defined(CONFIG_OF) static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG,
@@ -101,6 +102,7 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { .flags = MTK_JPEG_FMT_FLAG_CAPTURE, }, }; +#endif #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
@@ -936,148 +938,6 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,return 0 ; } -static int mtk_jpegenc_get_hw (struct mtk_jpeg_ctx *ctx) -{ -struct mtk_jpegenc_comp_dev *comp_jpeg; -struct mtk_jpeg_dev *jpeg = ctx->jpeg; -unsigned long flags; -int hw_id =-1 ; -int i; - -spin_lock_irqsave (&jpeg->hw_lock, flags); -for (i =0 ; i <MTK_JPEGENC_HW_MAX ; i++) { - comp_jpeg = jpeg->enc_hw_dev[i]; -if (comp_jpeg->hw_state ==MTK_JPEG_HW_IDLE ) { - hw_id = i; - comp_jpeg->hw_state =MTK_JPEG_HW_BUSY ; -break ; - } - } -spin_unlock_irqrestore (&jpeg->hw_lock, flags); - -return hw_id; -} - -static int mtk_jpegenc_set_hw_param (struct mtk_jpeg_ctx *ctx, -int hw_id, -struct vb2_v4l2_buffer *src_buf, -struct vb2_v4l2_buffer *dst_buf) -{ -struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id]; - - jpeg->hw_param.curr_ctx = ctx; - jpeg->hw_param.src_buffer = src_buf; - jpeg->hw_param.dst_buffer = dst_buf; - -return 0 ; -} - -static int mtk_jpegenc_put_hw (struct mtk_jpeg_dev *jpeg,int hw_id) -{ -unsigned long flags; - -spin_lock_irqsave (&jpeg->hw_lock, flags); - jpeg->enc_hw_dev[hw_id]->hw_state =MTK_JPEG_HW_IDLE ; -spin_unlock_irqrestore (&jpeg->hw_lock, flags); - -return 0 ; -} - -static void mtk_jpegenc_worker (struct work_struct *work) -{ -struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX ]; -enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; -struct mtk_jpeg_src_buf *jpeg_dst_buf; -struct vb2_v4l2_buffer *src_buf, *dst_buf; -int ret, i, hw_id =0 ; -unsigned long flags; - -struct mtk_jpeg_ctx *ctx =container_of (work, - struct mtk_jpeg_ctx, - jpeg_work); -struct mtk_jpeg_dev *jpeg = ctx->jpeg; - -for (i =0 ; i <MTK_JPEGENC_HW_MAX ; i++) - comp_jpeg[i] = jpeg->enc_hw_dev[i]; - i =0 ; - -retry_select: - hw_id =mtk_jpegenc_get_hw (ctx); -if (hw_id <0 ) { - ret =wait_event_interruptible (jpeg->hw_wq, -atomic_read (&jpeg->hw_rdy) >0 ); -if (ret !=0 || (i++ >MTK_JPEG_MAX_RETRY_TIME )) { -dev_err (jpeg->dev,"%s : %d, all HW are busy\n" , - __func__, __LINE__); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -return ; - } - - goto retry_select; - } - -atomic_dec (&jpeg->hw_rdy); - src_buf =v4l2_m2m_next_src_buf (ctx->fh.m2m_ctx); -if (!src_buf) - goto getbuf_fail; - - dst_buf =v4l2_m2m_next_dst_buf (ctx->fh.m2m_ctx); -if (!dst_buf) - goto getbuf_fail; - -v4l2_m2m_buf_copy_metadata (src_buf, dst_buf, true); - -mtk_jpegenc_set_hw_param (ctx, hw_id, src_buf, dst_buf); - ret =pm_runtime_get_sync (comp_jpeg[hw_id]->dev); -if (ret <0 ) { -dev_err (jpeg->dev,"%s : %d, pm_runtime_get_sync fail !!!\n" , - __func__, __LINE__); - goto enc_end; - } - - ret =clk_prepare_enable (comp_jpeg[hw_id]->venc_clk.clks->clk); -if (ret) { -dev_err (jpeg->dev,"%s : %d, jpegenc clk_prepare_enable fail\n" , - __func__, __LINE__); - goto enc_end; - } - -v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); - -schedule_delayed_work (&comp_jpeg[hw_id]->job_timeout_work, -msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); - -spin_lock_irqsave (&comp_jpeg[hw_id]->hw_lock, flags); - jpeg_dst_buf =mtk_jpeg_vb2_to_srcbuf (&dst_buf->vb2_buf); - jpeg_dst_buf->curr_ctx = ctx; - jpeg_dst_buf->frame_num = ctx->total_frame_num; - ctx->total_frame_num++; -mtk_jpeg_enc_reset (comp_jpeg[hw_id]->reg_base); -mtk_jpeg_set_enc_dst (ctx, - comp_jpeg[hw_id]->reg_base, - &dst_buf->vb2_buf); -mtk_jpeg_set_enc_src (ctx, - comp_jpeg[hw_id]->reg_base, - &src_buf->vb2_buf); -mtk_jpeg_set_enc_params (ctx, comp_jpeg[hw_id]->reg_base); -mtk_jpeg_enc_start (comp_jpeg[hw_id]->reg_base); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -spin_unlock_irqrestore (&comp_jpeg[hw_id]->hw_lock, flags); - -return ; - -enc_end: -v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_buf_done (src_buf, buf_state); -v4l2_m2m_buf_done (dst_buf, buf_state); -getbuf_fail: -atomic_inc (&jpeg->hw_rdy); -mtk_jpegenc_put_hw (jpeg, hw_id); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -} -static void mtk_jpeg_enc_device_run (void *priv) {struct mtk_jpeg_ctx *ctx = priv;
@@ -1128,206 +988,39 @@ static void mtk_jpeg_multicore_enc_device_run(void *priv)queue_work (jpeg->workqueue, &ctx->jpeg_work); } -static int mtk_jpegdec_get_hw (struct mtk_jpeg_ctx *ctx) +static void mtk_jpeg_multicore_dec_device_run (void *priv) { -struct mtk_jpegdec_comp_dev *comp_jpeg; +struct mtk_jpeg_ctx *ctx = priv;struct mtk_jpeg_dev *jpeg = ctx->jpeg; -unsigned long flags; -int hw_id =-1 ; -int i; - -spin_lock_irqsave (&jpeg->hw_lock, flags); -for (i =0 ; i <MTK_JPEGDEC_HW_MAX ; i++) { - comp_jpeg = jpeg->dec_hw_dev[i]; -if (comp_jpeg->hw_state ==MTK_JPEG_HW_IDLE ) { - hw_id = i; - comp_jpeg->hw_state =MTK_JPEG_HW_BUSY ; -break ; - } - } -spin_unlock_irqrestore (&jpeg->hw_lock, flags); - -return hw_id; -} - -static int mtk_jpegdec_put_hw (struct mtk_jpeg_dev *jpeg,int hw_id) -{ -unsigned long flags; - -spin_lock_irqsave (&jpeg->hw_lock, flags); - jpeg->dec_hw_dev[hw_id]->hw_state = -MTK_JPEG_HW_IDLE ; -spin_unlock_irqrestore (&jpeg->hw_lock, flags); - -return 0 ; -} - -static int mtk_jpegdec_set_hw_param (struct mtk_jpeg_ctx *ctx, -int hw_id, -struct vb2_v4l2_buffer *src_buf, -struct vb2_v4l2_buffer *dst_buf) -{ -struct mtk_jpegdec_comp_dev *jpeg = - ctx->jpeg->dec_hw_dev[hw_id]; - - jpeg->hw_param.curr_ctx = ctx; - jpeg->hw_param.src_buffer = src_buf; - jpeg->hw_param.dst_buffer = dst_buf; -return 0 ; +queue_work (jpeg->workqueue, &ctx->jpeg_work); } -static void mtk_jpegdec_worker (struct work_struct *work) +static void mtk_jpeg_dec_device_run (void *priv) { - struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx, - jpeg_work); -struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX ]; -enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; -struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf; -struct vb2_v4l2_buffer *src_buf, *dst_buf; +struct mtk_jpeg_ctx *ctx = priv;struct mtk_jpeg_dev *jpeg = ctx->jpeg; -int ret, i, hw_id =0 ; +struct vb2_v4l2_buffer *src_buf, *dst_buf; +enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; +unsigned long flags; +struct mtk_jpeg_src_buf *jpeg_src_buf;struct mtk_jpeg_bs bs;struct mtk_jpeg_fb fb; -unsigned long flags; - -for (i =0 ; i <MTK_JPEGDEC_HW_MAX ; i++) - comp_jpeg[i] = jpeg->dec_hw_dev[i]; - i =0 ; - -retry_select: - hw_id =mtk_jpegdec_get_hw (ctx); -if (hw_id <0 ) { - ret =wait_event_interruptible_timeout (jpeg->hw_wq, -atomic_read (&jpeg->hw_rdy) >0 , -MTK_JPEG_HW_TIMEOUT_MSEC ); -if (ret !=0 || (i++ >MTK_JPEG_MAX_RETRY_TIME )) { -dev_err (jpeg->dev,"%s : %d, all HW are busy\n" , - __func__, __LINE__); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -return ; - } - - goto retry_select; - } +int ret; -atomic_dec (&jpeg->hw_rdy); src_buf =v4l2_m2m_next_src_buf (ctx->fh.m2m_ctx); -if (!src_buf) - goto getbuf_fail; - dst_buf =v4l2_m2m_next_dst_buf (ctx->fh.m2m_ctx); -if (!dst_buf) - goto getbuf_fail; - -v4l2_m2m_buf_copy_metadata (src_buf, dst_buf, true); jpeg_src_buf =mtk_jpeg_vb2_to_srcbuf (&src_buf->vb2_buf); - jpeg_dst_buf =mtk_jpeg_vb2_to_srcbuf (&dst_buf->vb2_buf); -if (mtk_jpeg_check_resolution_change (ctx, - &jpeg_src_buf->dec_param)) { +if (mtk_jpeg_check_resolution_change (ctx, &jpeg_src_buf->dec_param)) {mtk_jpeg_queue_src_chg_event (ctx); ctx->state =MTK_JPEG_SOURCE_CHANGE ; - goto getbuf_fail; +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +return ; } - jpeg_src_buf->curr_ctx = ctx; - jpeg_src_buf->frame_num = ctx->total_frame_num; - jpeg_dst_buf->curr_ctx = ctx; - jpeg_dst_buf->frame_num = ctx->total_frame_num; - -mtk_jpegdec_set_hw_param (ctx, hw_id, src_buf, dst_buf); - ret =pm_runtime_get_sync (comp_jpeg[hw_id]->dev); -if (ret <0 ) { -dev_err (jpeg->dev,"%s : %d, pm_runtime_get_sync fail !!!\n" , - __func__, __LINE__); - goto dec_end; - } - - ret =clk_prepare_enable (comp_jpeg[hw_id]->jdec_clk.clks->clk); -if (ret) { -dev_err (jpeg->dev,"%s : %d, jpegdec clk_prepare_enable fail\n" , - __func__, __LINE__); - goto clk_end; - } - -v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); - -schedule_delayed_work (&comp_jpeg[hw_id]->job_timeout_work, -msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); - -mtk_jpeg_set_dec_src (ctx, &src_buf->vb2_buf, &bs); -if (mtk_jpeg_set_dec_dst (ctx, - &jpeg_src_buf->dec_param, - &dst_buf->vb2_buf, &fb)) { -dev_err (jpeg->dev,"%s : %d, mtk_jpeg_set_dec_dst fail\n" , - __func__, __LINE__); - goto setdst_end; - } - -spin_lock_irqsave (&comp_jpeg[hw_id]->hw_lock, flags); - ctx->total_frame_num++; -mtk_jpeg_dec_reset (comp_jpeg[hw_id]->reg_base); -mtk_jpeg_dec_set_config (comp_jpeg[hw_id]->reg_base, - &jpeg_src_buf->dec_param, - jpeg_src_buf->bs_size, - &bs, - &fb); -mtk_jpeg_dec_start (comp_jpeg[hw_id]->reg_base); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -spin_unlock_irqrestore (&comp_jpeg[hw_id]->hw_lock, flags); - -return ; - -setdst_end: -clk_disable_unprepare (comp_jpeg[hw_id]->jdec_clk.clks->clk); -clk_end: -pm_runtime_put (comp_jpeg[hw_id]->dev); -dec_end: -v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); -v4l2_m2m_buf_done (src_buf, buf_state); -v4l2_m2m_buf_done (dst_buf, buf_state); -getbuf_fail: -atomic_inc (&jpeg->hw_rdy); -mtk_jpegdec_put_hw (jpeg, hw_id); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -} - -static void mtk_jpeg_multicore_dec_device_run (void *priv) -{ -struct mtk_jpeg_ctx *ctx = priv; -struct mtk_jpeg_dev *jpeg = ctx->jpeg; - -queue_work (jpeg->workqueue, &ctx->jpeg_work); -} - -static void mtk_jpeg_dec_device_run (void *priv) -{ -struct mtk_jpeg_ctx *ctx = priv; -struct mtk_jpeg_dev *jpeg = ctx->jpeg; -struct vb2_v4l2_buffer *src_buf, *dst_buf; -enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; -unsigned long flags; -struct mtk_jpeg_src_buf *jpeg_src_buf; -struct mtk_jpeg_bs bs; -struct mtk_jpeg_fb fb; -int ret; - - src_buf =v4l2_m2m_next_src_buf (ctx->fh.m2m_ctx); - dst_buf =v4l2_m2m_next_dst_buf (ctx->fh.m2m_ctx); - jpeg_src_buf =mtk_jpeg_vb2_to_srcbuf (&src_buf->vb2_buf); - -if (mtk_jpeg_check_resolution_change (ctx, &jpeg_src_buf->dec_param)) { -mtk_jpeg_queue_src_chg_event (ctx); - ctx->state =MTK_JPEG_SOURCE_CHANGE ; -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -return ; - } - - ret =pm_runtime_resume_and_get (jpeg->dev); -if (ret <0 ) + ret =pm_runtime_resume_and_get (jpeg->dev); +if (ret <0 ) goto dec_end; schedule_delayed_work(&jpeg->job_timeout_work,
@@ -1430,101 +1123,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) jpeg->variant->clks); } -static irqreturn_t mtk_jpeg_enc_done (struct mtk_jpeg_dev *jpeg) -{ -struct mtk_jpeg_ctx *ctx; -struct vb2_v4l2_buffer *src_buf, *dst_buf; -enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; -u32 result_size; - - ctx =v4l2_m2m_get_curr_priv (jpeg->m2m_dev); -if (!ctx) { -v4l2_err (&jpeg->v4l2_dev,"Context is NULL\n" ); -return IRQ_HANDLED ; - } - - src_buf =v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); - dst_buf =v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); - - result_size =mtk_jpeg_enc_get_file_size (jpeg->reg_base); -vb2_set_plane_payload (&dst_buf->vb2_buf,0 , result_size); - - buf_state =VB2_BUF_STATE_DONE ; - -v4l2_m2m_buf_done (src_buf, buf_state); -v4l2_m2m_buf_done (dst_buf, buf_state); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -pm_runtime_put (ctx->jpeg->dev); -return IRQ_HANDLED ; -} - -static irqreturn_t mtk_jpeg_enc_irq (int irq,void *priv) -{ -struct mtk_jpeg_dev *jpeg = priv; -u32 irq_status; -irqreturn_t ret =IRQ_NONE ; - -cancel_delayed_work (&jpeg->job_timeout_work); - - irq_status =readl (jpeg->reg_base +JPEG_ENC_INT_STS ) & -JPEG_ENC_INT_STATUS_MASK_ALLIRQ ; -if (irq_status) -writel (0 , jpeg->reg_base +JPEG_ENC_INT_STS ); - -if (!(irq_status &JPEG_ENC_INT_STATUS_DONE )) -return ret; - - ret =mtk_jpeg_enc_done (jpeg); -return ret; -} - -static irqreturn_t mtk_jpeg_dec_irq (int irq,void *priv) -{ -struct mtk_jpeg_dev *jpeg = priv; -struct mtk_jpeg_ctx *ctx; -struct vb2_v4l2_buffer *src_buf, *dst_buf; -struct mtk_jpeg_src_buf *jpeg_src_buf; -enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; -u32 dec_irq_ret; -u32 dec_ret; -int i; - -cancel_delayed_work (&jpeg->job_timeout_work); - - dec_ret =mtk_jpeg_dec_get_int_status (jpeg->reg_base); - dec_irq_ret =mtk_jpeg_dec_enum_result (dec_ret); - ctx =v4l2_m2m_get_curr_priv (jpeg->m2m_dev); -if (!ctx) { -v4l2_err (&jpeg->v4l2_dev,"Context is NULL\n" ); -return IRQ_HANDLED ; - } - - src_buf =v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); - dst_buf =v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); - jpeg_src_buf =mtk_jpeg_vb2_to_srcbuf (&src_buf->vb2_buf); - -if (dec_irq_ret >=MTK_JPEG_DEC_RESULT_UNDERFLOW ) -mtk_jpeg_dec_reset (jpeg->reg_base); - -if (dec_irq_ret !=MTK_JPEG_DEC_RESULT_EOF_DONE ) { -dev_err (jpeg->dev,"decode failed\n" ); - goto dec_end; - } - -for (i =0 ; i < dst_buf->vb2_buf.num_planes; i++) -vb2_set_plane_payload (&dst_buf->vb2_buf, i, - jpeg_src_buf->dec_param.comp_size[i]); - - buf_state =VB2_BUF_STATE_DONE ; - -dec_end: -v4l2_m2m_buf_done (src_buf, buf_state); -v4l2_m2m_buf_done (dst_buf, buf_state); -v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); -pm_runtime_put (ctx->jpeg->dev); -return IRQ_HANDLED ; -} -static void mtk_jpeg_set_default_params (struct mtk_jpeg_ctx *ctx) {struct mtk_jpeg_q_data *q = &ctx->out_q;
@@ -1637,15 +1235,6 @@ static const struct v4l2_file_operations mtk_jpeg_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { - { .id ="jpgdec-smi" }, - { .id ="jpgdec" }, -}; - -static struct clk_bulk_data mtk_jpeg_clocks[] = { - { .id ="jpgenc" }, -}; -static void mtk_jpeg_job_timeout_work (struct work_struct *work) { struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
@@ -1867,6 +1456,419 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { };#if defined(CONFIG_OF ) +static int mtk_jpegenc_get_hw (struct mtk_jpeg_ctx *ctx) +{ +struct mtk_jpegenc_comp_dev *comp_jpeg; +struct mtk_jpeg_dev *jpeg = ctx->jpeg; +unsigned long flags; +int hw_id =-1 ; +int i; + +spin_lock_irqsave (&jpeg->hw_lock, flags); +for (i =0 ; i <MTK_JPEGENC_HW_MAX ; i++) { + comp_jpeg = jpeg->enc_hw_dev[i]; +if (comp_jpeg->hw_state ==MTK_JPEG_HW_IDLE ) { + hw_id = i; + comp_jpeg->hw_state =MTK_JPEG_HW_BUSY ; +break ; + } + } +spin_unlock_irqrestore (&jpeg->hw_lock, flags); + +return hw_id; +} + +static int mtk_jpegenc_set_hw_param (struct mtk_jpeg_ctx *ctx, +int hw_id, +struct vb2_v4l2_buffer *src_buf, +struct vb2_v4l2_buffer *dst_buf) +{ +struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg->enc_hw_dev[hw_id]; + + jpeg->hw_param.curr_ctx = ctx; + jpeg->hw_param.src_buffer = src_buf; + jpeg->hw_param.dst_buffer = dst_buf; + +return 0 ; +} + +static int mtk_jpegenc_put_hw (struct mtk_jpeg_dev *jpeg,int hw_id) +{ +unsigned long flags; + +spin_lock_irqsave (&jpeg->hw_lock, flags); + jpeg->enc_hw_dev[hw_id]->hw_state =MTK_JPEG_HW_IDLE ; +spin_unlock_irqrestore (&jpeg->hw_lock, flags); + +return 0 ; +} + +static int mtk_jpegdec_get_hw (struct mtk_jpeg_ctx *ctx) +{ +struct mtk_jpegdec_comp_dev *comp_jpeg; +struct mtk_jpeg_dev *jpeg = ctx->jpeg; +unsigned long flags; +int hw_id =-1 ; +int i; + +spin_lock_irqsave (&jpeg->hw_lock, flags); +for (i =0 ; i <MTK_JPEGDEC_HW_MAX ; i++) { + comp_jpeg = jpeg->dec_hw_dev[i]; +if (comp_jpeg->hw_state ==MTK_JPEG_HW_IDLE ) { + hw_id = i; + comp_jpeg->hw_state =MTK_JPEG_HW_BUSY ; +break ; + } + } +spin_unlock_irqrestore (&jpeg->hw_lock, flags); + +return hw_id; +} + +static int mtk_jpegdec_put_hw (struct mtk_jpeg_dev *jpeg,int hw_id) +{ +unsigned long flags; + +spin_lock_irqsave (&jpeg->hw_lock, flags); + jpeg->dec_hw_dev[hw_id]->hw_state = +MTK_JPEG_HW_IDLE ; +spin_unlock_irqrestore (&jpeg->hw_lock, flags); + +return 0 ; +} + +static int mtk_jpegdec_set_hw_param (struct mtk_jpeg_ctx *ctx, +int hw_id, +struct vb2_v4l2_buffer *src_buf, +struct vb2_v4l2_buffer *dst_buf) +{ +struct mtk_jpegdec_comp_dev *jpeg = + ctx->jpeg->dec_hw_dev[hw_id]; + + jpeg->hw_param.curr_ctx = ctx; + jpeg->hw_param.src_buffer = src_buf; + jpeg->hw_param.dst_buffer = dst_buf; + +return 0 ; +} + +static irqreturn_t mtk_jpeg_enc_done (struct mtk_jpeg_dev *jpeg) +{ +struct mtk_jpeg_ctx *ctx; +struct vb2_v4l2_buffer *src_buf, *dst_buf; +enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; +u32 result_size; + + ctx =v4l2_m2m_get_curr_priv (jpeg->m2m_dev); +if (!ctx) { +v4l2_err (&jpeg->v4l2_dev,"Context is NULL\n" ); +return IRQ_HANDLED ; + } + + src_buf =v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); + dst_buf =v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + + result_size =mtk_jpeg_enc_get_file_size (jpeg->reg_base); +vb2_set_plane_payload (&dst_buf->vb2_buf,0 , result_size); + + buf_state =VB2_BUF_STATE_DONE ; + +v4l2_m2m_buf_done (src_buf, buf_state); +v4l2_m2m_buf_done (dst_buf, buf_state); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +pm_runtime_put (ctx->jpeg->dev); +return IRQ_HANDLED ; +} + +static void mtk_jpegenc_worker (struct work_struct *work) +{ +struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX ]; +enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; +struct mtk_jpeg_src_buf *jpeg_dst_buf; +struct vb2_v4l2_buffer *src_buf, *dst_buf; +int ret, i, hw_id =0 ; +unsigned long flags; + +struct mtk_jpeg_ctx *ctx =container_of (work, + struct mtk_jpeg_ctx, + jpeg_work); +struct mtk_jpeg_dev *jpeg = ctx->jpeg; + +for (i =0 ; i <MTK_JPEGENC_HW_MAX ; i++) + comp_jpeg[i] = jpeg->enc_hw_dev[i]; + i =0 ; + +retry_select: + hw_id =mtk_jpegenc_get_hw (ctx); +if (hw_id <0 ) { + ret =wait_event_interruptible (jpeg->hw_wq, +atomic_read (&jpeg->hw_rdy) >0 ); +if (ret !=0 || (i++ >MTK_JPEG_MAX_RETRY_TIME )) { +dev_err (jpeg->dev,"%s : %d, all HW are busy\n" , + __func__, __LINE__); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +return ; + } + + goto retry_select; + } + +atomic_dec (&jpeg->hw_rdy); + src_buf =v4l2_m2m_next_src_buf (ctx->fh.m2m_ctx); +if (!src_buf) + goto getbuf_fail; + + dst_buf =v4l2_m2m_next_dst_buf (ctx->fh.m2m_ctx); +if (!dst_buf) + goto getbuf_fail; + +v4l2_m2m_buf_copy_metadata (src_buf, dst_buf, true); + +mtk_jpegenc_set_hw_param (ctx, hw_id, src_buf, dst_buf); + ret =pm_runtime_get_sync (comp_jpeg[hw_id]->dev); +if (ret <0 ) { +dev_err (jpeg->dev,"%s : %d, pm_runtime_get_sync fail !!!\n" , + __func__, __LINE__); + goto enc_end; + } + + ret =clk_prepare_enable (comp_jpeg[hw_id]->venc_clk.clks->clk); +if (ret) { +dev_err (jpeg->dev,"%s : %d, jpegenc clk_prepare_enable fail\n" , + __func__, __LINE__); + goto enc_end; + } + +v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + +schedule_delayed_work (&comp_jpeg[hw_id]->job_timeout_work, +msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); + +spin_lock_irqsave (&comp_jpeg[hw_id]->hw_lock, flags); + jpeg_dst_buf =mtk_jpeg_vb2_to_srcbuf (&dst_buf->vb2_buf); + jpeg_dst_buf->curr_ctx = ctx; + jpeg_dst_buf->frame_num = ctx->total_frame_num; + ctx->total_frame_num++; +mtk_jpeg_enc_reset (comp_jpeg[hw_id]->reg_base); +mtk_jpeg_set_enc_dst (ctx, + comp_jpeg[hw_id]->reg_base, + &dst_buf->vb2_buf); +mtk_jpeg_set_enc_src (ctx, + comp_jpeg[hw_id]->reg_base, + &src_buf->vb2_buf); +mtk_jpeg_set_enc_params (ctx, comp_jpeg[hw_id]->reg_base); +mtk_jpeg_enc_start (comp_jpeg[hw_id]->reg_base); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +spin_unlock_irqrestore (&comp_jpeg[hw_id]->hw_lock, flags); + +return ; + +enc_end: +v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_buf_done (src_buf, buf_state); +v4l2_m2m_buf_done (dst_buf, buf_state); +getbuf_fail: +atomic_inc (&jpeg->hw_rdy); +mtk_jpegenc_put_hw (jpeg, hw_id); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static void mtk_jpegdec_worker (struct work_struct *work) +{ + struct mtk_jpeg_ctx *ctx = container_of(work, struct mtk_jpeg_ctx, + jpeg_work); +struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX ]; +enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; +struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf; +struct vb2_v4l2_buffer *src_buf, *dst_buf; +struct mtk_jpeg_dev *jpeg = ctx->jpeg; +int ret, i, hw_id =0 ; +struct mtk_jpeg_bs bs; +struct mtk_jpeg_fb fb; +unsigned long flags; + +for (i =0 ; i <MTK_JPEGDEC_HW_MAX ; i++) + comp_jpeg[i] = jpeg->dec_hw_dev[i]; + i =0 ; + +retry_select: + hw_id =mtk_jpegdec_get_hw (ctx); +if (hw_id <0 ) { + ret =wait_event_interruptible_timeout (jpeg->hw_wq, +atomic_read (&jpeg->hw_rdy) >0 , +MTK_JPEG_HW_TIMEOUT_MSEC ); +if (ret !=0 || (i++ >MTK_JPEG_MAX_RETRY_TIME )) { +dev_err (jpeg->dev,"%s : %d, all HW are busy\n" , + __func__, __LINE__); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +return ; + } + + goto retry_select; + } + +atomic_dec (&jpeg->hw_rdy); + src_buf =v4l2_m2m_next_src_buf (ctx->fh.m2m_ctx); +if (!src_buf) + goto getbuf_fail; + + dst_buf =v4l2_m2m_next_dst_buf (ctx->fh.m2m_ctx); +if (!dst_buf) + goto getbuf_fail; + +v4l2_m2m_buf_copy_metadata (src_buf, dst_buf, true); + jpeg_src_buf =mtk_jpeg_vb2_to_srcbuf (&src_buf->vb2_buf); + jpeg_dst_buf =mtk_jpeg_vb2_to_srcbuf (&dst_buf->vb2_buf); + +if (mtk_jpeg_check_resolution_change (ctx, + &jpeg_src_buf->dec_param)) { +mtk_jpeg_queue_src_chg_event (ctx); + ctx->state =MTK_JPEG_SOURCE_CHANGE ; + goto getbuf_fail; + } + + jpeg_src_buf->curr_ctx = ctx; + jpeg_src_buf->frame_num = ctx->total_frame_num; + jpeg_dst_buf->curr_ctx = ctx; + jpeg_dst_buf->frame_num = ctx->total_frame_num; + +mtk_jpegdec_set_hw_param (ctx, hw_id, src_buf, dst_buf); + ret =pm_runtime_get_sync (comp_jpeg[hw_id]->dev); +if (ret <0 ) { +dev_err (jpeg->dev,"%s : %d, pm_runtime_get_sync fail !!!\n" , + __func__, __LINE__); + goto dec_end; + } + + ret =clk_prepare_enable (comp_jpeg[hw_id]->jdec_clk.clks->clk); +if (ret) { +dev_err (jpeg->dev,"%s : %d, jpegdec clk_prepare_enable fail\n" , + __func__, __LINE__); + goto clk_end; + } + +v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + +schedule_delayed_work (&comp_jpeg[hw_id]->job_timeout_work, +msecs_to_jiffies (MTK_JPEG_HW_TIMEOUT_MSEC )); + +mtk_jpeg_set_dec_src (ctx, &src_buf->vb2_buf, &bs); +if (mtk_jpeg_set_dec_dst (ctx, + &jpeg_src_buf->dec_param, + &dst_buf->vb2_buf, &fb)) { +dev_err (jpeg->dev,"%s : %d, mtk_jpeg_set_dec_dst fail\n" , + __func__, __LINE__); + goto setdst_end; + } + +spin_lock_irqsave (&comp_jpeg[hw_id]->hw_lock, flags); + ctx->total_frame_num++; +mtk_jpeg_dec_reset (comp_jpeg[hw_id]->reg_base); +mtk_jpeg_dec_set_config (comp_jpeg[hw_id]->reg_base, + &jpeg_src_buf->dec_param, + jpeg_src_buf->bs_size, + &bs, + &fb); +mtk_jpeg_dec_start (comp_jpeg[hw_id]->reg_base); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +spin_unlock_irqrestore (&comp_jpeg[hw_id]->hw_lock, flags); + +return ; + +setdst_end: +clk_disable_unprepare (comp_jpeg[hw_id]->jdec_clk.clks->clk); +clk_end: +pm_runtime_put (comp_jpeg[hw_id]->dev); +dec_end: +v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); +v4l2_m2m_buf_done (src_buf, buf_state); +v4l2_m2m_buf_done (dst_buf, buf_state); +getbuf_fail: +atomic_inc (&jpeg->hw_rdy); +mtk_jpegdec_put_hw (jpeg, hw_id); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static irqreturn_t mtk_jpeg_enc_irq (int irq,void *priv) +{ +struct mtk_jpeg_dev *jpeg = priv; +u32 irq_status; +irqreturn_t ret =IRQ_NONE ; + +cancel_delayed_work (&jpeg->job_timeout_work); + + irq_status =readl (jpeg->reg_base +JPEG_ENC_INT_STS ) & +JPEG_ENC_INT_STATUS_MASK_ALLIRQ ; +if (irq_status) +writel (0 , jpeg->reg_base +JPEG_ENC_INT_STS ); + +if (!(irq_status &JPEG_ENC_INT_STATUS_DONE )) +return ret; + + ret =mtk_jpeg_enc_done (jpeg); +return ret; +} + +static irqreturn_t mtk_jpeg_dec_irq (int irq,void *priv) +{ +struct mtk_jpeg_dev *jpeg = priv; +struct mtk_jpeg_ctx *ctx; +struct vb2_v4l2_buffer *src_buf, *dst_buf; +struct mtk_jpeg_src_buf *jpeg_src_buf; +enum vb2_buffer_state buf_state =VB2_BUF_STATE_ERROR ; +u32 dec_irq_ret; +u32 dec_ret; +int i; + +cancel_delayed_work (&jpeg->job_timeout_work); + + dec_ret =mtk_jpeg_dec_get_int_status (jpeg->reg_base); + dec_irq_ret =mtk_jpeg_dec_enum_result (dec_ret); + ctx =v4l2_m2m_get_curr_priv (jpeg->m2m_dev); +if (!ctx) { +v4l2_err (&jpeg->v4l2_dev,"Context is NULL\n" ); +return IRQ_HANDLED ; + } + + src_buf =v4l2_m2m_src_buf_remove (ctx->fh.m2m_ctx); + dst_buf =v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + jpeg_src_buf =mtk_jpeg_vb2_to_srcbuf (&src_buf->vb2_buf); + +if (dec_irq_ret >=MTK_JPEG_DEC_RESULT_UNDERFLOW ) +mtk_jpeg_dec_reset (jpeg->reg_base); + +if (dec_irq_ret !=MTK_JPEG_DEC_RESULT_EOF_DONE ) { +dev_err (jpeg->dev,"decode failed\n" ); + goto dec_end; + } + +for (i =0 ; i < dst_buf->vb2_buf.num_planes; i++) +vb2_set_plane_payload (&dst_buf->vb2_buf, i, + jpeg_src_buf->dec_param.comp_size[i]); + + buf_state =VB2_BUF_STATE_DONE ; + +dec_end: +v4l2_m2m_buf_done (src_buf, buf_state); +v4l2_m2m_buf_done (dst_buf, buf_state); +v4l2_m2m_job_finish (jpeg->m2m_dev, ctx->fh.m2m_ctx); +pm_runtime_put (ctx->jpeg->dev); +return IRQ_HANDLED ; +} + +static struct clk_bulk_data mtk_jpeg_clocks[] = { + { .id ="jpgenc" }, +}; + +static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = { + { .id ="jpgdec-smi" }, + { .id ="jpgdec" }, +}; +static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = { .clks = mt8173_jpeg_dec_clocks, .num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 62/239 media: mtk_jpeg_core: avoid unused-variable warning
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 20de9fdaf4883deffb0138eef28e9cbbead32cfd ]
The mtk8195_jpegenc_drvdata object was added outside of an #ifdef causing a harmless build warning.
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1879:32: error: 'mtk8195_jpegenc_drvdata' defined but not used [-Werror=unused-variable]
1879 | static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = {
| ^~~~~~~~~~~~~~~~~~~~~~~A follow-up patch moved it inside of an #ifdef, which caused more warnings, and a third patch ended up adding even more #ifdefs. These were all bogus, since the actual problem here is the incorrect use of of_ptr(). Since the driver (like any other modern platform driver) only works in combination with CONFIG_OF, there is no point in hiding the reference, so just remove that along with all the pointless #ifdef checks in the driver.
This improves build coverage and avoids running into the same problem again when another part of the driver gets changed that relies on the #ifdef blocks to be completely matched.
--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +----- drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 4 +--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 4 +--- 3 files changed, 3 insertions(+), 11 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +1 -5
@@ -28,7 +28,6 @@#include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" -#if defined(CONFIG_OF)static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { { .fourcc =V4L2_PIX_FMT_JPEG ,
@@ -102,7 +101,6 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { .flags = MTK_JPEG_FMT_FLAG_CAPTURE, }, }; -#endif #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
@@ -1455,7 +1453,6 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) }; -#if defined(CONFIG_OF )static int mtk_jpegenc_get_hw (struct mtk_jpeg_ctx *ctx) {struct mtk_jpegenc_comp_dev *comp_jpeg;
@@ -1951,14 +1948,13 @@ static const struct of_device_id mtk_jpeg_match[] = { };MODULE_DEVICE_TABLE (of, mtk_jpeg_match); -#endif static struct platform_driver mtk_jpeg_driver = { .probe = mtk_jpeg_probe, .remove_new = mtk_jpeg_remove, .driver = { .name =MTK_JPEG_NAME , - .of_match_table =of_match_ptr (mtk_jpeg_match), + .of_match_table = mtk_jpeg_match, .pm = &mtk_jpeg_pm_ops, }, };
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +1 -3
@@ -39,7 +39,6 @@ enum mtk_jpeg_color {MTK_JPEG_COLOR_400 =0x00110000 }; -#if defined(CONFIG_OF)static const struct of_device_id mtk_jpegdec_hw_ids[] = { { .compatible ="mediatek,mt8195-jpgdec-hw" ,
@@ -47,7 +46,6 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = { {}, };MODULE_DEVICE_TABLE (of, mtk_jpegdec_hw_ids); -#endif static inline int mtk_jpeg_verify_align (u32 val,int align,u32 reg) {
@@ -653,7 +651,7 @@ static struct platform_driver mtk_jpegdec_hw_driver = { .probe = mtk_jpegdec_hw_probe, .driver = { .name = "mtk-jpegdec-hw", - .of_match_table = of_match_ptr(mtk_jpegdec_hw_ids), + .of_match_table = mtk_jpegdec_hw_ids, }, };
drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +1 -3
@@ -46,7 +46,6 @@ static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, }; -#if defined(CONFIG_OF) static const struct of_device_id mtk_jpegenc_drv_ids[] = { { .compatible = "mediatek,mt8195-jpgenc-hw",
@@ -54,7 +53,6 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = { {}, };MODULE_DEVICE_TABLE (of, mtk_jpegenc_drv_ids); -#endif void mtk_jpeg_enc_reset (void __iomem *base) {
@@ -377,7 +375,7 @@ static struct platform_driver mtk_jpegenc_hw_driver = { .probe = mtk_jpegenc_hw_probe, .driver = { .name = "mtk-jpegenc-hw", - .of_match_table = of_match_ptr(mtk_jpegenc_drv_ids), + .of_match_table = mtk_jpegenc_drv_ids, }, };
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 63/239 i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir()
In reply to Greg Kroah-HartmanFrom: Wang Ming <[email protected]>
[ Upstream commit 043b1f185fb0f3939b7427f634787706f45411c4 ]
The debugfs_create_dir() function returns error pointers. It never returns NULL. Most incorrect error checks were fixed, but the one in i40e_dbg_init() was forgotten.
Fix the remaining error check.
--- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e_debugfs.c +1 -1
@@ -1839,7 +1839,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf)void i40e_dbg_init (void ) { i40e_dbg_root =debugfs_create_dir (i40e_driver_name,NULL ); -if (!i40e_dbg_root) +if (IS_ERR (i40e_dbg_root))pr_info ("init of debugfs failed\n" ); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 64/239 iavf: fix potential deadlock on allocation failure
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit a2f054c10bef0b54600ec9cb776508443e941343 ]
In iavf_adminq_task(), if kzalloc() fails to allocate the event.msg_buf, the function will exit without releasing the adapter->crit_lock.
This is unlikely, but if it happens, the next access to that mutex will deadlock.
Fix this by moving the unlock to the end of the function, and adding a new label to allow jumping to the unlock portion of the function exit flow.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +3 -2
@@ -3300,7 +3300,7 @@ static void iavf_adminq_task(struct work_struct *work) event.buf_len =IAVF_MAX_AQ_BUF_SIZE ; event.msg_buf =kzalloc (event.buf_len,GFP_KERNEL );if (!event.msg_buf) - goto out; + goto unlock; do { ret = iavf_clean_arq_element(hw, &event, &pending);
@@ -3315,7 +3315,6 @@ static void iavf_adminq_task(struct work_struct *work)if (pending !=0 )memset (event.msg_buf,0 ,IAVF_MAX_AQ_BUF_SIZE ); }while (pending); -mutex_unlock (&adapter->crit_lock);if (iavf_is_reset_in_progress (adapter)) goto freedom;
@@ -3359,6 +3358,8 @@ static void iavf_adminq_task(struct work_struct *work) freedom:kfree (event.msg_buf); +unlock: +mutex_unlock (&adapter->crit_lock); out:/* re-enable Admin queue interrupt cause */ iavf_misc_irq_enable (adapter);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 65/239 iavf: check for removal state before IAVF_FLAG_PF_COMMS_FAILED
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit 91896c8acce23d33ed078cffd46a9534b1f82be5 ]
In iavf_adminq_task(), if the function can't acquire the adapter->crit_lock, it checks if the driver is removing. If so, it simply exits without re-enabling the interrupt. This is done to ensure that the task stops processing as soon as possible once the driver is being removed.
However, if the IAVF_FLAG_PF_COMMS_FAILED is set, the function checks this before attempting to acquire the lock. In this case, the function exits early and re-enables the interrupt. This will happen even if the driver is already removing.
Avoid this, by moving the check to after the adapter->crit_lock is acquired. This way, if the driver is removing, we will not re-enable the interrupt.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +3 -3
@@ -3286,9 +3286,6 @@ static void iavf_adminq_task(struct work_struct *work)u32 val, oldval;u16 pending; -if (adapter->flags &IAVF_FLAG_PF_COMMS_FAILED ) - goto out; -if (!mutex_trylock (&adapter->crit_lock)) {if (adapter->state == __IAVF_REMOVE)return ;
@@ -3297,6 +3294,9 @@ static void iavf_adminq_task(struct work_struct *work) goto out; } +if (adapter->flags &IAVF_FLAG_PF_COMMS_FAILED ) + goto unlock; + event.buf_len =IAVF_MAX_AQ_BUF_SIZE ; event.msg_buf =kzalloc (event.buf_len,GFP_KERNEL );if (!event.msg_buf)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 66/239 net: phy: marvell10g: fix 88x3310 power up
In reply to Greg Kroah-HartmanFrom: Jiawen Wu <[email protected]>
[ Upstream commit c7b75bea853daeb64fc831dbf39a6bbabcc402ac ]
Clear MV_V2_PORT_CTRL_PWRDOWN bit to set power up for 88x3310 PHY, it sometimes does not take effect immediately. And a read of this register causes the bit not to clear. This will cause mv3310_reset() to time out, which will fail the config initialization. So add a delay before the next access.
--- drivers/net/phy/marvell10g.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/phy/marvell10g.c +7 -0
@@ -328,6 +328,13 @@ static int mv3310_power_up(struct phy_device *phydev) ret =phy_clear_bits_mmd (phydev,MDIO_MMD_VEND2 ,MV_V2_PORT_CTRL ,MV_V2_PORT_CTRL_PWRDOWN ); +/* Sometimes, the power down bit doesn't clear immediately, and +* a read of this register causes the bit not to clear. Delay +* 100us to allow the PHY to come out of power down mode before +* the next access. +*/ +udelay (100 ); +if (phydev->drv->phy_id !=MARVELL_PHY_ID_88X3310 || priv->firmware_ver <0x00030000 )return ret;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 67/239 net: hns3: fix the imp capability bit cannot exceed 32 bits issue
In reply to Greg Kroah-HartmanFrom: Hao Lan <[email protected]>
[ Upstream commit b27d0232e8897f7c896dc8ad80c9907dd57fd3f3 ]
Current only the first 32 bits of the capability flag bit are considered. When the matching capability flag bit is greater than 31 bits, it will get an error bit.This patch use bitmap to solve this issue. It can handle each capability bit whitout bit width limit.
--- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 ++- .../hns3/hns3_common/hclge_comm_cmd.c | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hnae3.h +2 -1
@@ -31,6 +31,7 @@#include <linux/pci.h> #include <linux/pkt_sched.h> #include <linux/types.h> +#include <linux/bitmap.h> #include <net/pkt_cls.h> #include <net/pkt_sched.h>
@@ -407,7 +408,7 @@ struct hnae3_ae_dev {unsigned long hw_err_reset_req;struct hnae3_dev_specs dev_specs;u32 dev_version; -unsigned long caps[BITS_TO_LONGS (HNAE3_DEV_CAPS_MAX_NUM )]; +DECLARE_BITMAP (caps,HNAE3_DEV_CAPS_MAX_NUM );void *priv; };
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +18 -3
@@ -171,6 +171,20 @@ static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { {HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B}, }; +static void +hclge_comm_capability_to_bitmap (unsigned long *bitmap,__le32 *caps) +{ +const unsigned int words =HCLGE_COMM_QUERY_CAP_LENGTH ; +u32 val[HCLGE_COMM_QUERY_CAP_LENGTH ]; +unsigned int i; + +for (i =0 ; i < words; i++) + val[i] =__le32_to_cpu (caps[i]); + +bitmap_from_arr32 (bitmap, val, +HCLGE_COMM_QUERY_CAP_LENGTH *BITS_PER_TYPE (u32)); +} +static void hclge_comm_parse_capability (struct hnae3_ae_dev *ae_dev,bool is_pf,struct hclge_comm_query_version_cmd *cmd)
@@ -179,11 +193,12 @@ hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf, is_pf ? hclge_pf_cmd_caps : hclge_vf_cmd_caps;u32 size = is_pf ?ARRAY_SIZE (hclge_pf_cmd_caps) :ARRAY_SIZE (hclge_vf_cmd_caps); -u32 caps, i; +DECLARE_BITMAP (caps,HCLGE_COMM_QUERY_CAP_LENGTH *BITS_PER_TYPE (u32)); +u32 i; - caps =__le32_to_cpu (cmd->caps[0 ]); +hclge_comm_capability_to_bitmap (caps, cmd->caps);for (i =0 ; i < size; i++) -if (hnae3_get_bit (caps, caps_map[i].imp_bit)) +if (test_bit (caps_map[i].imp_bit, caps))set_bit (caps_map[i].local_bit, ae_dev->caps); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 68/239 net: hns3: fix wrong tc bandwidth weight data issue
In reply to Greg Kroah-HartmanFrom: Jijie Shao <[email protected]>
[ Upstream commit 116d9f732eef634abbd871f2c6f613a5b4677742 ]
Currently, the weight saved by the driver is used as the query result, which may be different from the actual weight in the register. Therefore, the register value read from the firmware is used as the query result
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +1 -2
@@ -693,8 +693,7 @@ static int hclge_dbg_dump_tc(struct hclge_dev *hdev, char *buf, int len)for (i =0 ; i <HNAE3_MAX_TC ; i++) { sch_mode_str = ets_weight->tc_weight[i] ?"dwrr" :"sp" ; pos +=scnprintf (buf + pos, len - pos,"%u %4s %3u\n" , - i, sch_mode_str, - hdev->tm_info.pg_info[0 ].tc_dwrr[i]); + i, sch_mode_str, ets_weight->tc_weight[i]); }return 0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 69/239 net: hns3: fix wrong bw weight of disabled tc issue
In reply to Greg Kroah-HartmanFrom: Jijie Shao <[email protected]>
[ Upstream commit 882481b1c55fc44861d7e2d54b4e0936b1b39f2c ]
In dwrr mode, the default bandwidth weight of disabled tc is set to 0. If the bandwidth weight is 0, the mode will change to sp. Therefore, disabled tc default bandwidth weight need changed to 1, and 0 is returned when query the bandwidth weight of disabled tc. In addition, driver need stop configure bandwidth weight if tc is disabled.
--- .../ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 17 ++++++++++++++--- .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +14 -3
@@ -52,7 +52,10 @@ static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev,for (i =0 ; i <HNAE3_MAX_TC ; i++) { ets->prio_tc[i] = hdev->tm_info.prio_tc[i]; - ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0 ].tc_dwrr[i]; +if (i < hdev->tm_info.num_tc) + ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0 ].tc_dwrr[i]; +else + ets->tc_tx_bw[i] =0 ;if (hdev->tm_info.tc_info[i].tc_sch_mode ==HCLGE_SCH_MODE_SP )
@@ -123,7 +126,8 @@ static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets, }static int hclge_ets_sch_mode_validate (struct hclge_dev *hdev, -struct ieee_ets *ets,bool *changed) +struct ieee_ets *ets,bool *changed, +u8 tc_num) {bool has_ets_tc = false;u32 total_ets_bw =0 ;
@@ -137,6 +141,13 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, *changed = true;break ;case IEEE_8021QAZ_TSA_ETS : +if (i >= tc_num) { +dev_err (&hdev->pdev->dev, +"tc%u is disabled, cannot set ets bw\n" , + i); +return -EINVAL ; + } +/* The hardware will switch to sp mode if bandwidth is * 0, so limit ets bandwidth must be greater than 0. */
@@ -176,7 +187,7 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,if (ret)return ret; - ret =hclge_ets_sch_mode_validate (hdev, ets, changed); + ret =hclge_ets_sch_mode_validate (hdev, ets, changed, tc_num);if (ret)return ret;
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +2 -1
@@ -785,6 +785,7 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)static void hclge_tm_pg_info_init (struct hclge_dev *hdev) {#define BW_PERCENT 100 +#define DEFAULT_BW_WEIGHT 1u8 i;
@@ -806,7 +807,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)for (k =0 ; k < hdev->tm_info.num_tc; k++) hdev->tm_info.pg_info[i].tc_dwrr[k] =BW_PERCENT ;for (; k <HNAE3_MAX_TC ; k++) - hdev->tm_info.pg_info[i].tc_dwrr[k] =0 ; + hdev->tm_info.pg_info[i].tc_dwrr[k] =DEFAULT_BW_WEIGHT ; } }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 70/239 vxlan: calculate correct header length for GPE
In reply to Greg Kroah-HartmanFrom: Jiri Benc <[email protected]>
[ Upstream commit 94d166c5318c6edd1e079df8552233443e909c33 ]
VXLAN-GPE does not add an extra inner Ethernet header. Take that into account when calculating header length.
This causes problems in skb_tunnel_check_pmtu, where incorrect PMTU is cached.
In the collect_md mode (which is the only mode that VXLAN-GPE supports), there's no magic auto-setting of the tunnel interface MTU. It can't be, since the destination and thus the underlying interface may be different for each packet.
So, the administrator is responsible for setting the correct tunnel interface MTU. Apparently, the administrators are capable enough to calculate that the maximum MTU for VXLAN-GPE is (their_lower_MTU - 36). They set the tunnel interface MTU to 1464. If you run a TCP stream over such interface, it's then segmented according to the MTU 1464, i.e. producing 1514 bytes frames. Which is okay, this still fits the lower MTU.
However, skb_tunnel_check_pmtu (called from vxlan_xmit_one) uses 50 as the header size and thus incorrectly calculates the frame size to be 1528. This leads to ICMP too big message being generated (locally), PMTU of 1450 to be cached and the TCP stream to be resegmented.
The fix is to use the correct actual header size, especially for skb_tunnel_check_pmtu calculation.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/vxlan/vxlan_core.c | 23 ++++++++----------- include/net/vxlan.h | 13 +++++++---- 3 files changed, 20 insertions(+), 18 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1 -1
@@ -8479,7 +8479,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,struct ixgbe_adapter *adapter = q_vector->adapter;if (unlikely (skb_tail_pointer (skb) < hdr.network + -VXLAN_HEADROOM )) +vxlan_headroom (0 )))return ;/* verify the port is recognized as VXLAN */
drivers/net/vxlan/vxlan_core.c +10 -13
@@ -2515,7 +2515,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, } ndst = &rt->dst; - err =skb_tunnel_check_pmtu (skb, ndst,VXLAN_HEADROOM , + err =skb_tunnel_check_pmtu (skb, ndst,vxlan_headroom (flags &VXLAN_F_GPE ),netif_is_any_bridge_port (dev));if (err <0 ) { goto tx_error;
@@ -2576,7 +2576,8 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto out_unlock; } - err =skb_tunnel_check_pmtu (skb, ndst,VXLAN6_HEADROOM , + err =skb_tunnel_check_pmtu (skb, ndst, +vxlan_headroom ((flags &VXLAN_F_GPE ) |VXLAN_F_IPV6 ),netif_is_any_bridge_port (dev));if (err <0 ) { goto tx_error;
@@ -2988,14 +2989,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu)struct vxlan_rdst *dst = &vxlan->default_dst;struct net_device *lowerdev =__dev_get_by_index (vxlan->net, dst->remote_ifindex); -bool use_ipv6 = !!(vxlan->cfg.flags &VXLAN_F_IPV6 );/* This check is different than dev->max_mtu, because it looks at * the lowerdev->mtu, rather than the static dev->max_mtu */ if (lowerdev) { -int max_mtu = lowerdev->mtu - - (use_ipv6 ?VXLAN6_HEADROOM :VXLAN_HEADROOM ); +int max_mtu = lowerdev->mtu -vxlan_headroom (vxlan->cfg.flags);if (new_mtu > max_mtu)return -EINVAL ; }
@@ -3641,11 +3640,11 @@ static void vxlan_config_apply(struct net_device *dev,struct vxlan_dev *vxlan =netdev_priv (dev);struct vxlan_rdst *dst = &vxlan->default_dst;unsigned short needed_headroom =ETH_HLEN ; -bool use_ipv6 = !!(conf->flags &VXLAN_F_IPV6 );int max_mtu =ETH_MAX_MTU ; +u32 flags = conf->flags;if (!changelink) { -if (conf->flags &VXLAN_F_GPE ) +if (flags &VXLAN_F_GPE )vxlan_raw_setup (dev);else vxlan_ether_setup (dev);
@@ -3670,8 +3669,7 @@ static void vxlan_config_apply(struct net_device *dev, dev->needed_tailroom = lowerdev->needed_tailroom; - max_mtu = lowerdev->mtu - (use_ipv6 ?VXLAN6_HEADROOM : -VXLAN_HEADROOM ); + max_mtu = lowerdev->mtu -vxlan_headroom (flags);if (max_mtu <ETH_MIN_MTU ) max_mtu =ETH_MIN_MTU ;
@@ -3682,10 +3680,9 @@ static void vxlan_config_apply(struct net_device *dev,if (dev->mtu > max_mtu) dev->mtu = max_mtu; -if (use_ipv6 || conf->flags &VXLAN_F_COLLECT_METADATA ) - needed_headroom +=VXLAN6_HEADROOM ; -else - needed_headroom +=VXLAN_HEADROOM ; +if (flags &VXLAN_F_COLLECT_METADATA ) + flags |=VXLAN_F_IPV6 ; + needed_headroom +=vxlan_headroom (flags); dev->needed_headroom = needed_headroom;memcpy (&vxlan->cfg, conf,sizeof (*conf));
include/net/vxlan.h +9 -4
@@ -384,10 +384,15 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,return features; } -/* IP header + UDP + VXLAN + Ethernet header */ -#define VXLAN_HEADROOM (20 + 8 + 8 + 14) -/* IPv6 header + UDP + VXLAN + Ethernet header */ -#define VXLAN6_HEADROOM (40 + 8 + 8 + 14) +static inline int vxlan_headroom (u32 flags) +{ +/* VXLAN: IP4/6 header + UDP + VXLAN + Ethernet header */ +/* VXLAN-GPE: IP4/6 header + UDP + VXLAN */ +return (flags &VXLAN_F_IPV6 ?sizeof (struct ipv6hdr ) : +sizeof (struct iphdr )) + +sizeof (struct udphdr ) +sizeof (struct vxlanhdr ) + + (flags &VXLAN_F_GPE ?0 :ETH_HLEN ); +}static inline struct vxlanhdr *vxlan_hdr (struct sk_buff *skb) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 71/239 vxlan: generalize vxlan_parse_gpe_hdr and remove unused args
In reply to Greg Kroah-HartmanFrom: Jiri Benc <[email protected]>
[ Upstream commit 17a0a64448b568442a101de09575f81ffdc45d15 ]
The vxlan_parse_gpe_hdr function extracts the next protocol value from the GPE header and marks GPE bits as parsed.
In order to be used in the next patch, split the function into protocol extraction and bit marking. The bit marking is meaningful only in vxlan_rcv; move it directly there.
Rename the function to vxlan_parse_gpe_proto to reflect what it now does. Remove unused arguments skb and vxflags. Move the function earlier in the file to allow it to be called from more places in the next patch.
Stable-dep-of: b0b672c4d095 ("vxlan: fix GRO with VXLAN-GPE")
--- drivers/net/vxlan/vxlan_core.c | 58 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 30 deletions(-)
drivers/net/vxlan/vxlan_core.c +28 -30
@@ -623,6 +623,32 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,return 1 ; } +static bool vxlan_parse_gpe_proto (struct vxlanhdr *hdr,__be16 *protocol) +{ +struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr; + +/* Need to have Next Protocol set for interfaces in GPE mode. */ +if (!gpe->np_applied) +return false; +/* "The initial version is 0. If a receiver does not support the +* version indicated it MUST drop the packet. +*/ +if (gpe->version !=0 ) +return false; +/* "When the O bit is set to 1, the packet is an OAM packet and OAM +* processing MUST occur." However, we don't implement OAM +* processing, thus drop the packet. +*/ +if (gpe->oam_flag) +return false; + + *protocol =tun_p_to_eth_p (gpe->next_protocol); +if (!*protocol) +return false; + +return true; +} + static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, unsigned int off, struct vxlanhdr *vh, size_t hdrlen,
@@ -1525,35 +1551,6 @@ static void vxlan_parse_gbp_hdr(struct vxlanhdr *unparsed, unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS ; } -static bool vxlan_parse_gpe_hdr (struct vxlanhdr *unparsed, -__be16 *protocol, -struct sk_buff *skb,u32 vxflags) -{ -struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed; - -/* Need to have Next Protocol set for interfaces in GPE mode. */ -if (!gpe->np_applied) -return false; -/* "The initial version is 0. If a receiver does not support the -* version indicated it MUST drop the packet. -*/ -if (gpe->version !=0 ) -return false; -/* "When the O bit is set to 1, the packet is an OAM packet and OAM -* processing MUST occur." However, we don't implement OAM -* processing, thus drop the packet. -*/ -if (gpe->oam_flag) -return false; - - *protocol =tun_p_to_eth_p (gpe->next_protocol); -if (!*protocol) -return false; - - unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS ; -return true; -} -static bool vxlan_set_mac (struct vxlan_dev *vxlan,struct vxlan_sock *vs,struct sk_buff *skb,__be32 vni)
@@ -1655,8 +1652,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)* used by VXLAN extensions if explicitly requested. */ if (vs->flags &VXLAN_F_GPE ) { -if (!vxlan_parse_gpe_hdr (&unparsed, &protocol, skb, vs->flags)) +if (!vxlan_parse_gpe_proto (&unparsed, &protocol)) goto drop; + unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS ; raw_proto = true; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 72/239 vxlan: fix GRO with VXLAN-GPE
In reply to Greg Kroah-HartmanFrom: Jiri Benc <[email protected]>
[ Upstream commit b0b672c4d0957e5897685667fc848132b8bd2d71 ]
In VXLAN-GPE, there may not be an Ethernet header following the VXLAN header. But in GRO, the vxlan driver calls eth_gro_receive unconditionally, which means the following header is incorrectly parsed as Ethernet.
Introduce GPE specific GRO handling.
For better performance, do not check for GPE during GRO but rather install a different set of functions at setup time.
--- drivers/net/vxlan/vxlan_core.c | 84 ++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 15 deletions(-)
drivers/net/vxlan/vxlan_core.c +69 -15
@@ -675,26 +675,24 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,return vh; } -static struct sk_buff *vxlan_gro_receive (struct sock *sk, -struct list_head *head, -struct sk_buff *skb) +static struct vxlanhdr *vxlan_gro_prepare_receive (struct sock *sk, +struct list_head *head, +struct sk_buff *skb, +struct gro_remcsum *grc) { -struct sk_buff *pp =NULL ;struct sk_buff *p;struct vxlanhdr *vh, *vh2;unsigned int hlen, off_vx; -int flush =1 ;struct vxlan_sock *vs =rcu_dereference_sk_user_data (sk);__be32 flags; -struct gro_remcsum grc; -skb_gro_remcsum_init (&grc); +skb_gro_remcsum_init (grc); off_vx =skb_gro_offset (skb); hlen = off_vx +sizeof (*vh); vh =skb_gro_header (skb, hlen, off_vx);if (unlikely (!vh)) - goto out; +return NULL ;skb_gro_postpull_rcsum (skb, vh,sizeof (struct vxlanhdr ));
@@ -702,12 +700,12 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,if ((flags &VXLAN_HF_RCO ) && (vs->flags &VXLAN_F_REMCSUM_RX )) { vh =vxlan_gro_remcsum (skb, off_vx, vh,sizeof (struct vxlanhdr ), - vh->vx_vni, &grc, + vh->vx_vni, grc, !!(vs->flags &VXLAN_F_REMCSUM_NOPARTIAL ));if (!vh) - goto out; +return NULL ; }skb_gro_pull (skb,sizeof (struct vxlanhdr ));/* pull vxlan header */
@@ -724,12 +722,48 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, } } - pp =call_gro_receive (eth_gro_receive, head, skb); - flush =0 ; +return vh; +} + +static struct sk_buff *vxlan_gro_receive (struct sock *sk, +struct list_head *head, +struct sk_buff *skb) +{ +struct sk_buff *pp =NULL ; +struct gro_remcsum grc; +int flush =1 ; -out: +if (vxlan_gro_prepare_receive (sk, head, skb, &grc)) { + pp =call_gro_receive (eth_gro_receive, head, skb); + flush =0 ; + }skb_gro_flush_final_remcsum (skb, pp, flush, &grc); +return pp; +} +static struct sk_buff *vxlan_gpe_gro_receive (struct sock *sk, +struct list_head *head, +struct sk_buff *skb) +{ +const struct packet_offload *ptype; +struct sk_buff *pp =NULL ; +struct gro_remcsum grc; +struct vxlanhdr *vh; +__be16 protocol; +int flush =1 ; + + vh =vxlan_gro_prepare_receive (sk, head, skb, &grc); +if (vh) { +if (!vxlan_parse_gpe_proto (vh, &protocol)) + goto out; + ptype =gro_find_receive_by_type (protocol); +if (!ptype) + goto out; + pp =call_gro_receive (ptype->callbacks.gro_receive, head, skb); + flush =0 ; + } +out: +skb_gro_flush_final_remcsum (skb, pp, flush, &grc);return pp; }
@@ -741,6 +775,21 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)return eth_gro_complete (skb, nhoff +sizeof (struct vxlanhdr )); } +static int vxlan_gpe_gro_complete (struct sock *sk,struct sk_buff *skb,int nhoff) +{ +struct vxlanhdr *vh = (struct vxlanhdr *)(skb->data + nhoff); +const struct packet_offload *ptype; +int err = -ENOSYS ; +__be16 protocol; + +if (!vxlan_parse_gpe_proto (vh, &protocol)) +return err; + ptype =gro_find_complete_by_type (protocol); +if (ptype) + err = ptype->callbacks.gro_complete (skb, nhoff +sizeof (struct vxlanhdr )); +return err; +} +static struct vxlan_fdb *vxlan_fdb_alloc (struct vxlan_dev *vxlan,const u8 *mac,__u16 state,__be32 src_vni,__u16 ndm_flags)
@@ -3373,8 +3422,13 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6, tunnel_cfg.encap_rcv = vxlan_rcv; tunnel_cfg.encap_err_lookup = vxlan_err_lookup; tunnel_cfg.encap_destroy =NULL ; - tunnel_cfg.gro_receive = vxlan_gro_receive; - tunnel_cfg.gro_complete = vxlan_gro_complete; +if (vs->flags &VXLAN_F_GPE ) { + tunnel_cfg.gro_receive = vxlan_gpe_gro_receive; + tunnel_cfg.gro_complete = vxlan_gpe_gro_complete; + }else { + tunnel_cfg.gro_receive = vxlan_gro_receive; + tunnel_cfg.gro_complete = vxlan_gro_complete; + }setup_udp_tunnel_sock (net, sock, &tunnel_cfg);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 73/239 phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe()
In reply to Greg Kroah-HartmanFrom: Harshit Mogalapalli <[email protected]>
[ Upstream commit 13c088cf3657d70893d75cf116be937f1509cc0f ]
The size of array 'priv->ports[]' is INNO_PHY_PORT_NUM.
In the for loop, 'i' is used as the index for array 'priv->ports[]' with a check (i > INNO_PHY_PORT_NUM) which indicates that INNO_PHY_PORT_NUM is allowed value for 'i' in the same loop.
This > comparison needs to be changed to >=, otherwise it potentially leads to an out of bounds write on the next iteration through the loop
--- drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/hisilicon/phy-hisi-inno-usb2.c +1 -1
@@ -158,7 +158,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev)phy_set_drvdata (phy, &priv->ports[i]); i++; -if (i >INNO_PHY_PORT_NUM ) { +if (i >=INNO_PHY_PORT_NUM ) {dev_warn (dev,"Support %d ports in maximum\n" , i);of_node_put (child);break ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 74/239 atheros: fix return value check in atl1_tso()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit ed96824b71ed67664390890441b229423a25317f ]
in atl1_tso(), it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim().
--- drivers/net/ethernet/atheros/atlx/atl1.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/atheros/atlx/atl1.c +5 -2
@@ -2113,8 +2113,11 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, real_len = (((unsigned char *)iph - skb->data) +ntohs (iph->tot_len)); -if (real_len < skb->len) -pskb_trim (skb, real_len); +if (real_len < skb->len) { + err =pskb_trim (skb, real_len); +if (err) +return err; + } hdr_len =skb_tcp_all_headers (skb);if (skb->len == hdr_len) { iph->check =0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 75/239 ethernet: atheros: fix return value check in atl1e_tso_csum()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit 69a184f7a372aac588babfb0bd681aaed9779f5b ]
in atl1e_tso_csum, it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim().
--- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/atheros/atl1e/atl1e_main.c +5 -2
@@ -1641,8 +1641,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter, real_len = (((unsigned char *)ip_hdr (skb) - skb->data) +ntohs (ip_hdr (skb)->tot_len)); -if (real_len < skb->len) -pskb_trim (skb, real_len); +if (real_len < skb->len) { + err =pskb_trim (skb, real_len); +if (err) +return err; + } hdr_len =skb_tcp_all_headers (skb);if (unlikely (skb->len == hdr_len)) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 76/239 ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new temporary address
In reply to Greg Kroah-HartmanFrom: Maciej Żenczykowski <[email protected]>
[ Upstream commit 69172f0bcb6a09110c5d2a6d792627f5095a9018 ]
currently on 6.4 net/main:
# ip link add dummy1 type dummy # echo 1 > /proc/sys/net/ipv6/conf/dummy1/use_tempaddr # ip link set dummy1 up # ip -6 addr add 2000::1/64 mngtmpaddr dev dummy1 # ip -6 addr show dev dummy1
11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet6 2000::44f3:581c:8ca:3983/64 scope global temporary dynamic
valid_lft 604800sec preferred_lft 86172sec
inet6 2000::1/64 scope global mngtmpaddr
valid_lft forever preferred_lft forever
inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
valid_lft forever preferred_lft forever# ip -6 addr del 2000::44f3:581c:8ca:3983/64 dev dummy1
(can wait a few seconds if you want to, the above delete isn't [directly] the problem)
# ip -6 addr show dev dummy1
11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet6 2000::1/64 scope global mngtmpaddr
valid_lft forever preferred_lft forever
inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
valid_lft forever preferred_lft forever
# ip -6 addr del 2000::1/64 mngtmpaddr dev dummy1 # ip -6 addr show dev dummy1
11: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet6 2000::81c9:56b7:f51a:b98f/64 scope global temporary dynamic
valid_lft 604797sec preferred_lft 86169sec
inet6 fe80::e8a8:a6ff:fed5:56d4/64 scope link
valid_lft forever preferred_lft foreverThis patch prevents this new 'global temporary dynamic' address from being created by the deletion of the related (same subnet prefix) 'mngtmpaddr' (which is triggered by there already being no temporary addresses).
--- net/ipv6/addrconf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/ipv6/addrconf.c +10 -4
@@ -2561,12 +2561,18 @@ static void manage_tempaddrs(struct inet6_dev *idev,ipv6_ifa_notify (0 , ift); } -if ((create ||list_empty (&idev->tempaddr_list)) && - idev->cnf.use_tempaddr >0 ) { +/* Also create a temporary address if it's enabled but no temporary +* address currently exists. +* However, we get called with valid_lft == 0, prefered_lft == 0, create == false +* as part of cleanup (ie. deleting the mngtmpaddr). +* We don't want that to result in creating a new temporary ip address. +*/ +if (list_empty (&idev->tempaddr_list) && (valid_lft || prefered_lft)) + create = true; + +if (create && idev->cnf.use_tempaddr >0 ) {/* When a new public address is created as described * in [ADDRCONF], also create a new temporary address. -* Also create a temporary address if it's enabled but -* no temporary address currently exists. */ read_unlock_bh (&idev->lock);ipv6_create_tempaddr (ifp, false);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 77/239 net: fec: avoid tx queue timeout when XDP is enabled
In reply to Greg Kroah-HartmanFrom: Wei Fang <[email protected]>
[ Upstream commit bb7a0156365dffe2fcd63e2051145fbe4f8908b4 ]
According to the implementation of XDP of FEC driver, the XDP path shares the transmit queues with the kernel network stack, so it is possible to lead to a tx timeout event when XDP uses the tx queue pretty much exclusively. And this event will cause the reset of the FEC hardware.
To avoid timeout in this case, we use the txq_trans_cond_update() interface to update txq->trans_start to jiffies so that watchdog won't generate a transmit timeout warning.
--- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/freescale/fec_main.c +2 -0
@@ -3908,6 +3908,8 @@ static int fec_enet_xdp_xmit(struct net_device *dev,__netif_tx_lock (nq, cpu); +/* Avoid tx timeout as XDP shares the queue with kernel stack */ +txq_trans_cond_update (nq);for (i =0 ; i < num_frames; i++) {if (fec_enet_txq_xmit_frame (fep, txq, frames[i]) !=0 )break ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 78/239 tcp: Reduce chance of collisions in inet6_hashfn().
In reply to Greg Kroah-HartmanFrom: Stewart Smith <[email protected]>
[ Upstream commit d11b0df7ddf1831f3e170972f43186dad520bfcc ]
For both IPv4 and IPv6 incoming TCP connections are tracked in a hash table with a hash over the source & destination addresses and ports. However, the IPv6 hash is insufficient and can lead to a high rate of collisions.
The IPv6 hash used an XOR to fit everything into the 96 bits for the fast jenkins hash, meaning it is possible for an external entity to ensure the hash collides, thus falling back to a linear search in the bucket, which is slow.
We take the approach of hash the full length of IPv6 address in __ipv6_addr_jhash() so that all users can benefit from a more secure version.
While this may look like it adds overhead, the reality of modern CPUs means that this is unmeasurable in real world scenarios.
In simulating with llvm-mca, the increase in cycles for the hashing code was ~16 cycles on Skylake (from a base of ~155), and an extra ~9 on Nehalem (base of ~173).
In commit dd6d2910c5e0 ("netfilter: conntrack: switch to siphash") netfilter switched from a jenkins hash to a siphash, but even the faster hsiphash is a more significant overhead (~20-30%) in some preliminary testing. So, in this patch, we keep to the more conservative approach to ensure we don't add much overhead per SYN.
In testing, this results in a consistently even spread across the connection buckets. In both testing and real-world scenarios, we have not found any measurable performance impact.
--- include/net/ipv6.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
include/net/ipv6.h +2 -6
@@ -752,12 +752,8 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a)/* more secured version of ipv6_addr_hash() */ static inline u32 __ipv6_addr_jhash (const struct in6_addr *a,const u32 initval) { -u32 v = (__force u32 )a->s6_addr32[0 ] ^ (__force u32 )a->s6_addr32[1 ]; - -return jhash_3words (v, - (__force u32 )a->s6_addr32[2 ], - (__force u32 )a->s6_addr32[3 ], - initval); +return jhash2 ((__force const u32 *)a->s6_addr32, +ARRAY_SIZE (a->s6_addr32), initval); }static inline bool ipv6_addr_loopback (const struct in6_addr *a)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 79/239 ice: Fix memory management in ice_ethtool_fdir.c
In reply to Greg Kroah-HartmanFrom: Jedrzej Jagielski <[email protected]>
[ Upstream commit a3336056504d780590ac6d6ac94fbba829994594 ]
Fix ethtool FDIR logic to not use memory after its release. In the ice_ethtool_fdir.c file there are 2 spots where code can refer to pointers which may be missing.
In the ice_cfg_fdir_xtrct_seq() function seg may be freed but even then may be still used by memcpy(&tun_seg[1], seg, sizeof(*seg)).
In the ice_add_fdir_ethtool() function struct ice_fdir_fltr *input may first fail to be added via ice_fdir_update_list_entry() but then may be deleted by ice_fdir_update_list_entry.
Terminate in both cases when the returned value of the previous operation is other than 0, free memory and don't use it anymore.
--- .../net/ethernet/intel/ice/ice_ethtool_fdir.c | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +14 -12
@@ -1281,16 +1281,21 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp, ICE_FLOW_FLD_OFF_INVAL); } -/* add filter for outer headers */ fltr_idx =ice_ethtool_flow_to_fltr (fsp->flow_type & ~FLOW_EXT ); + +assign_bit (fltr_idx, hw->fdir_perfect_fltr, perfect_filter); + +/* add filter for outer headers */ ret =ice_fdir_set_hw_fltr_rule (pf, seg, fltr_idx,ICE_FD_HW_SEG_NON_TUN ); -if (ret == -EEXIST ) -/* Rule already exists, free memory and continue */ -devm_kfree (dev, seg); -else if (ret) +if (ret == -EEXIST ) { +/* Rule already exists, free memory and count as success */ + ret =0 ; + goto err_exit; + }else if (ret) {/* could not write filter, free memory */ goto err_exit; + }/* make tunneled filter HW entries if possible */ memcpy (&tun_seg[1 ], seg,sizeof (*seg));
@@ -1305,18 +1310,13 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,devm_kfree (dev, tun_seg); } -if (perfect_filter) -set_bit (fltr_idx, hw->fdir_perfect_fltr); -else -clear_bit (fltr_idx, hw->fdir_perfect_fltr); -return ret; err_exit:devm_kfree (dev, tun_seg);devm_kfree (dev, seg); -return -EOPNOTSUPP ; +return ret; }/**
@@ -1914,7 +1914,9 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd) input->comp_report =ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL ;/* input struct is added to the HW filter list */ -ice_fdir_update_list_entry (pf, input, fsp->location); + ret =ice_fdir_update_list_entry (pf, input, fsp->location); +if (ret) + goto release_lock; ret =ice_fdir_write_all_fltr (pf, input, true);if (ret)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 80/239 bonding: reset bonds flags when down link is P2P device
In reply to Greg Kroah-HartmanFrom: Hangbin Liu <[email protected]>
[ Upstream commit da19a2b967cf1e2c426f50d28550d1915214a81d ]
When adding a point to point downlink to the bond, we neglected to reset the bond's flags, which were still using flags like BROADCAST and MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink interfaces, such as when adding a GRE device to the bonding.
To address this issue, let's reset the bond's flags for P2P interfaces.
Before fix:
7: gre0@NONE: <POINTOPOINT,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UNKNOWN group default qlen 1000
link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr 167f:18:f188::
8: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/gre6 2006:70:10::1 brd 2006:70:10::2
inet6 fe80::200:ff:fe00:0/64 scope link
valid_lft forever preferred_lft foreverAfter fix:
7: gre0@NONE: <POINTOPOINT,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond2 state UNKNOWN group default qlen 1000
link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr c29e:557a:e9d9::
8: bond0: <POINTOPOINT,NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/gre6 2006:70:10::1 peer 2006:70:10::2
inet6 fe80::1/64 scope link
valid_lft forever preferred_lft forever--- drivers/net/bonding/bond_main.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/bonding/bond_main.c +5 -0
@@ -1507,6 +1507,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev,memcpy (bond_dev->broadcast, slave_dev->broadcast, slave_dev->addr_len); + +if (slave_dev->flags &IFF_POINTOPOINT ) { + bond_dev->flags &= ~(IFF_BROADCAST |IFF_MULTICAST ); + bond_dev->flags |= (IFF_POINTOPOINT |IFF_NOARP ); + } }/* On bonding slaves other than the currently active slave, suppress
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 81/239 team: reset teams flags when down link is P2P device
In reply to Greg Kroah-HartmanFrom: Hangbin Liu <[email protected]>
[ Upstream commit fa532bee17d15acf8bba4bc8e2062b7a093ba801 ]
When adding a point to point downlink to team device, we neglected to reset the team's flags, which were still using flags like BROADCAST and MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink interfaces, such as when adding a GRE device to team device. Fix this by remove multicast/broadcast flags and add p2p and noarp flags.
After removing the none ethernet interface and adding an ethernet interface to team, we need to reset team interface flags. Unlike bonding interface, team do not need restore IFF_MASTER, IFF_SLAVE flags.
--- drivers/net/team/team.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/team/team.c +9 -0
@@ -2135,6 +2135,15 @@ static void team_setup_by_port(struct net_device *dev, dev->mtu = port_dev->mtu;memcpy (dev->broadcast, port_dev->broadcast, port_dev->addr_len);eth_hw_addr_inherit (dev, port_dev); + +if (port_dev->flags &IFF_POINTOPOINT ) { + dev->flags &= ~(IFF_BROADCAST |IFF_MULTICAST ); + dev->flags |= (IFF_POINTOPOINT |IFF_NOARP ); + }else if ((port_dev->flags & (IFF_BROADCAST |IFF_MULTICAST )) == + (IFF_BROADCAST |IFF_MULTICAST )) { + dev->flags |= (IFF_BROADCAST |IFF_MULTICAST ); + dev->flags &= ~(IFF_POINTOPOINT |IFF_NOARP ); + } } static int team_dev_type_check_change(struct net_device *dev,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 82/239 octeontx2-af: Fix hash extraction enable configuration
In reply to Greg Kroah-HartmanFrom: Suman Ghosh <[email protected]>
[ Upstream commit 4e62c99d71e56817c934caa2a709a775c8cee078 ]
As of today, hash extraction support is enabled for all the silicons. Because of which we are facing initialization issues when the silicon does not support hash extraction. During creation of the hardware parsing table for IPv6 address, we need to consider if hash extraction is enabled then extract only 32 bit, otherwise 128 bit needs to be extracted. This patch fixes the issue and configures the hardware parser based on the availability of the feature.
--- .../marvell/octeontx2/af/rvu_npc_hash.c | 43 ++++++++++++++++++- .../marvell/octeontx2/af/rvu_npc_hash.h | 8 ++-- 2 files changed, 46 insertions(+), 5 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c +42 -1
@@ -218,13 +218,54 @@ void npc_config_secret_key(struct rvu *rvu, int blkaddr)void npc_program_mkex_hash (struct rvu *rvu,int blkaddr) { +struct npc_mcam_kex_hash *mh = rvu->kpu.mkex_hash;struct hw_cap *hwcap = &rvu->hw->cap; +u8 intf, ld, hdr_offset, byte_len;struct rvu_hwinfo *hw = rvu->hw; -u8 intf; +u64 cfg; +/* Check if hardware supports hash extraction */ if (!hwcap->npc_hash_extract)return ; +/* Check if IPv6 source/destination address +* should be hash enabled. +* Hashing reduces 128bit SIP/DIP fields to 32bit +* so that 224 bit X2 key can be used for IPv6 based filters as well, +* which in turn results in more number of MCAM entries available for +* use. +* +* Hashing of IPV6 SIP/DIP is enabled in below scenarios +* 1. If the silicon variant supports hashing feature +* 2. If the number of bytes of IP addr being extracted is 4 bytes ie +* 32bit. The assumption here is that if user wants 8bytes of LSB of +* IP addr or full 16 bytes then his intention is not to use 32bit +* hash. +*/ +for (intf =0 ; intf < hw->npc_intfs; intf++) { +for (ld =0 ; ld <NPC_MAX_LD ; ld++) { + cfg =rvu_read64 (rvu, blkaddr, +NPC_AF_INTFX_LIDX_LTX_LDX_CFG (intf, +NPC_LID_LC , +NPC_LT_LC_IP6 , + ld)); + hdr_offset =FIELD_GET (NPC_HDR_OFFSET , cfg); + byte_len =FIELD_GET (NPC_BYTESM , cfg); +/* Hashing of IPv6 source/destination address should be +* enabled if, +* hdr_offset == 8 (offset of source IPv6 address) or +* hdr_offset == 24 (offset of destination IPv6) +* address) and the number of byte to be +* extracted is 4. As per hardware configuration +* byte_len should be == actual byte_len - 1. +* Hence byte_len is checked against 3 but nor 4. +*/ +if ((hdr_offset ==8 || hdr_offset ==24 ) && byte_len ==3 ) + mh->lid_lt_ld_hash_en[intf][NPC_LID_LC ][NPC_LT_LC_IP6 ][ld] = true; + } + } + +/* Update hash configuration if the field is hash enabled */ for (intf =0 ; intf < hw->npc_intfs; intf++) {npc_program_mkex_hash_rx (rvu, blkaddr, intf);npc_program_mkex_hash_tx (rvu, blkaddr, intf);
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h +4 -4
@@ -70,8 +70,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { [NIX_INTF_RX] = { [NPC_LID_LC] = { [NPC_LT_LC_IP6] = { - true, - true, + false, + false, }, }, },
@@ -79,8 +79,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { [NIX_INTF_TX] = { [NPC_LID_LC] = { [NPC_LT_LC_IP6] = { - true, - true, + false, + false, }, }, },
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 83/239 net: stmmac: Apply redundant write work around on 4.xx too
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit 284779dbf4e98753458708783af8c35630674a21 ]
commit a3a57bf07de23fe1ff779e0fdf710aa581c3ff73 ("net: stmmac: work around sporadic tx issue on link-up") worked around a problem with TX sometimes not working after a link-up by avoiding a redundant write to MAC_CTRL_REG (aka GMAC_CONFIG), since the IP appeared to have problems with handling multiple writes to that register in some cases.
That commit however only added the work around to dwmac_lib.c (apart from the common code in stmmac_main.c), but my systems with version 4.21a of the IP exhibit the same problem, so add the work around to dwmac4_lib.c too.
--- drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +3 -1
@@ -240,13 +240,15 @@ void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, const u8 addr[6],void stmmac_dwmac4_set_mac (void __iomem *ioaddr,bool enable) {u32 value =readl (ioaddr +GMAC_CONFIG ); +u32 old_val = value;if (enable) value |=GMAC_CONFIG_RE |GMAC_CONFIG_TE ;else value &= ~(GMAC_CONFIG_TE |GMAC_CONFIG_RE ); -writel (value, ioaddr +GMAC_CONFIG ); +if (value != old_val) +writel (value, ioaddr +GMAC_CONFIG ); } void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 84/239 platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit ad084a6d99bc182bf109c190c808e2ea073ec57b ]
Only the HW rfkill state is toggled on laptops with quirks->ec_read_only (so far only MSI Wind U90/U100). There are, however, a few issues with the implementation:
1. The initial HW state is always unblocked, regardless of the actual state on boot, because msi_init_rfkill only sets the SW state, regardless of ec_read_only.
2. The initial SW state corresponds to the actual state on boot, but it can't be changed afterwards, because set_device_state returns -EOPNOTSUPP. It confuses the userspace, making Wi-Fi and/or Bluetooth unusable if it was blocked on boot, and breaking the airplane mode if the rfkill was unblocked on boot.
Address the above issues by properly initializing the HW state on ec_read_only laptops and by allowing the userspace to toggle the SW state. Don't set the SW state ourselves and let the userspace fully control it. Toggling the SW state is a no-op, however, it allows the userspace to properly toggle the airplane mode. The actual SW radio disablement is handled by the corresponding rtl818x_pci and btusb drivers that have their own rfkills.
Tested on MSI Wind U100 Plus, BIOS ver 1.0G, EC ver 130.
--- drivers/platform/x86/msi-laptop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/platform/x86/msi-laptop.c +4 -4
@@ -208,7 +208,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask)return -EINVAL ;if (quirks->ec_read_only) -return -EOPNOTSUPP ; +return 0 ;/* read current device state */ result =ec_read (MSI_STANDARD_EC_COMMAND_ADDRESS , &rdata);
@@ -838,15 +838,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,static void msi_init_rfkill (struct work_struct *ignored) {if (rfk_wlan) { -rfkill_set_sw_state (rfk_wlan, !wlan_s); +msi_rfkill_set_state (rfk_wlan, !wlan_s);rfkill_wlan_set (NULL , !wlan_s); }if (rfk_bluetooth) { -rfkill_set_sw_state (rfk_bluetooth, !bluetooth_s); +msi_rfkill_set_state (rfk_bluetooth, !bluetooth_s);rfkill_bluetooth_set (NULL , !bluetooth_s); }if (rfk_threeg) { -rfkill_set_sw_state (rfk_threeg, !threeg_s); +msi_rfkill_set_state (rfk_threeg, !threeg_s);rfkill_threeg_set (NULL , !threeg_s); } }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 85/239 x86/traps: Fix load_unaligned_zeropad() handling for shared TDX memory
In reply to Greg Kroah-HartmanFrom: Kirill A. Shutemov <[email protected]>
[ Upstream commit 9f9116406120638b4d8db3831ffbc430dd2e1e95 ]
Commit c4e34dd99f2e ("x86: simplify load_unaligned_zeropad() implementation") changes how exceptions around load_unaligned_zeropad() handled. The kernel now uses the fault_address in fixup_exception() to verify the address calculations for the load_unaligned_zeropad().
It works fine for #PF, but breaks on #VE since no fault address is passed down to fixup_exception().
Propagating ve_info.gla down to fixup_exception() resolves the issue.
See commit 1e7769653b06 ("x86/tdx: Handle load_unaligned_zeropad() page-cross to a shared page") for more context.
--- arch/x86/kernel/traps.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
arch/x86/kernel/traps.c +11 -7
@@ -697,9 +697,10 @@ static bool try_fixup_enqcmd_gp(void) }static bool gp_try_fixup_and_notify (struct pt_regs *regs,int trapnr, -unsigned long error_code,const char *str) +unsigned long error_code,const char *str, +unsigned long address) { -if (fixup_exception (regs, trapnr, error_code,0 )) +if (fixup_exception (regs, trapnr, error_code, address))return true; current->thread.error_code = error_code;
@@ -759,7 +760,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) goto exit; } -if (gp_try_fixup_and_notify (regs,X86_TRAP_GP , error_code, desc)) +if (gp_try_fixup_and_notify (regs,X86_TRAP_GP , error_code, desc,0 )) goto exit;if (error_code)
@@ -1357,17 +1358,20 @@ DEFINE_IDTENTRY(exc_device_not_available)#define VE_FAULT_STR "VE fault" -static void ve_raise_fault (struct pt_regs *regs,long error_code) +static void ve_raise_fault (struct pt_regs *regs,long error_code, +unsigned long address) {if (user_mode (regs)) {gp_user_force_sig_segv (regs,X86_TRAP_VE , error_code,VE_FAULT_STR );return ; } -if (gp_try_fixup_and_notify (regs,X86_TRAP_VE , error_code,VE_FAULT_STR )) +if (gp_try_fixup_and_notify (regs,X86_TRAP_VE , error_code, +VE_FAULT_STR , address)) {return ; + } -die_addr (VE_FAULT_STR , regs, error_code,0 ); +die_addr (VE_FAULT_STR , regs, error_code, address); }/*
@@ -1431,7 +1435,7 @@ DEFINE_IDTENTRY(exc_virtualization_exception)* it successfully, treat it as #GP(0) and handle it. */ if (!tdx_handle_virt_exception (regs, &ve)) -ve_raise_fault (regs,0 ); +ve_raise_fault (regs,0 , ve.gla);cond_local_irq_disable (regs); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 86/239 macvlan: add forgotten nla_policy for IFLA_MACVLAN_BC_CUTOFF
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
[ Upstream commit 55cef78c244d0d076f5a75a35530ca63c92f4426 ]
The previous commit 954d1fa1ac93 ("macvlan: Add netlink attribute for broadcast cutoff") added one additional attribute named IFLA_MACVLAN_BC_CUTOFF to allow broadcast cutfoff.
However, it forgot to describe the nla_policy at macvlan_policy (drivers/net/macvlan.c). Hence, this suppose NLA_S32 (4 bytes) integer can be faked as empty (0 bytes) by a malicious user, which could leads to OOB in heap just like CVE-2023-3773.
To fix it, this commit just completes the nla_policy description for IFLA_MACVLAN_BC_CUTOFF. This enforces the length check and avoids the potential OOB read.
--- drivers/net/macvlan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/macvlan.c +1 -0
@@ -1746,6 +1746,7 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 }, [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NLA_U32 }, [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NLA_REJECT }, + [IFLA_MACVLAN_BC_CUTOFF] = { .type = NLA_S32 }, };int macvlan_link_register (struct rtnl_link_ops *ops)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 87/239 igc: Fix Kernel Panic during ndo_tx_timeout callback
In reply to Greg Kroah-HartmanFrom: Muhammad Husaini Zulkifli <[email protected]>
[ Upstream commit d4a7ce642100765119a872d4aba1bf63e3a22c8a ]
The Xeon validation group has been carrying out some loaded tests with various HW configurations, and they have seen some transmit queue time out happening during the test. This will cause the reset adapter function to be called by igc_tx_timeout(). Similar race conditions may arise when the interface is being brought down and up in igc_reinit_locked(), an interrupt being generated, and igc_clean_tx_irq() being called to complete the TX.
When the igc_tx_timeout() function is invoked, this patch will turn off all TX ring HW queues during igc_down() process. TX ring HW queues will be activated again during the igc_configure_tx_ring() process when performing the igc_up() procedure later.
This patch also moved existing igc_disable_tx_ring_hw() to avoid using forward declaration.
Kernel trace:
[ 7678.747813] ------------[ cut here ]------------ [ 7678.757914] NETDEV WATCHDOG: enp1s0 (igc): transmit queue 2 timed out [ 7678.770117] WARNING: CPU: 0 PID: 13 at net/sched/sch_generic.c:525 dev_watchdog+0x1ae/0x1f0 [ 7678.784459] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype nft_compat
nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci
[ 7678.784496] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm fuse backlight
configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core
[ 7679.200403] RIP: 0010:dev_watchdog+0x1ae/0x1f0 [ 7679.210201] Code: 28 e9 53 ff ff ff 4c 89 e7 c6 05 06 42 b9 00 01 e8 17 d1 fb ff 44 89 e9 4c 89 e6 48 c7 c7 40 ad fb 81 48 89 c2 e8 52 62 82 ff <0f> 0b e9 72 ff ff ff 65 8b 05 80 7d 7c 7e 89 c0 48 0f a3 05 0a c1 [ 7679.245438] RSP: 0018:ffa00000001f7d90 EFLAGS: 00010282 [ 7679.256021] RAX: 0000000000000000 RBX: ff11000109938440 RCX: 0000000000000000 [ 7679.268710] RDX: ff11000361e26cd8 RSI: ff11000361e1b880 RDI: ff11000361e1b880 [ 7679.281314] RBP: ffa00000001f7da8 R08: ff1100035f8fffe8 R09: 0000000000027ffb [ 7679.293840] R10: 0000000000001f0a R11: ff1100035f840000 R12: ff11000109938000 [ 7679.306276] R13: 0000000000000002 R14: dead000000000122 R15: ffa00000001f7e18 [ 7679.318648] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 7679.332064] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7679.342757] CR2: 00007ffff7fca168 CR3: 000000013b08a006 CR4: 0000000000471ef8 [ 7679.354984] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 7679.367207] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 7679.379370] PKRU: 55555554 [ 7679.386446] Call Trace: [ 7679.393152] <TASK> [ 7679.399363] ? __pfx_dev_watchdog+0x10/0x10 [ 7679.407870] call_timer_fn+0x31/0x110 [ 7679.415698] expire_timers+0xb2/0x120 [ 7679.423403] run_timer_softirq+0x179/0x1e0 [ 7679.431532] ? __schedule+0x2b1/0x820 [ 7679.439078] __do_softirq+0xd1/0x295 [ 7679.446426] ? __pfx_smpboot_thread_fn+0x10/0x10 [ 7679.454867] run_ksoftirqd+0x22/0x30 [ 7679.462058] smpboot_thread_fn+0xb7/0x160 [ 7679.469670] kthread+0xcd/0xf0 [ 7679.476097] ? __pfx_kthread+0x10/0x10 [ 7679.483211] ret_from_fork+0x29/0x50 [ 7679.490047] </TASK> [ 7679.495204] ---[ end trace 0000000000000000 ]--- [ 7679.503179] igc 0000:01:00.0 enp1s0: Register Dump [ 7679.511230] igc 0000:01:00.0 enp1s0: Register Name Value [ 7679.519892] igc 0000:01:00.0 enp1s0: CTRL 181c0641 [ 7679.528782] igc 0000:01:00.0 enp1s0: STATUS 40280683 [ 7679.537551] igc 0000:01:00.0 enp1s0: CTRL_EXT 10000040 [ 7679.546284] igc 0000:01:00.0 enp1s0: MDIC 180a3800 [ 7679.554942] igc 0000:01:00.0 enp1s0: ICR 00000081 [ 7679.563503] igc 0000:01:00.0 enp1s0: RCTL 04408022 [ 7679.571963] igc 0000:01:00.0 enp1s0: RDLEN[0-3] 00001000 00001000 00001000 00001000 [ 7679.583075] igc 0000:01:00.0 enp1s0: RDH[0-3] 00000068 000000b6 0000000f 00000031 [ 7679.594162] igc 0000:01:00.0 enp1s0: RDT[0-3] 00000066 000000b2 0000000e 00000030 [ 7679.605174] igc 0000:01:00.0 enp1s0: RXDCTL[0-3] 02040808 02040808 02040808 02040808 [ 7679.616196] igc 0000:01:00.0 enp1s0: RDBAL[0-3] 1bb7c000 1bb7f000 1bb82000 0ef33000 [ 7679.627242] igc 0000:01:00.0 enp1s0: RDBAH[0-3] 00000001 00000001 00000001 00000001 [ 7679.638256] igc 0000:01:00.0 enp1s0: TCTL a503f0fa [ 7679.646607] igc 0000:01:00.0 enp1s0: TDBAL[0-3] 2ba4a000 1bb6f000 1bb74000 1bb79000 [ 7679.657609] igc 0000:01:00.0 enp1s0: TDBAH[0-3] 00000001 00000001 00000001 00000001 [ 7679.668551] igc 0000:01:00.0 enp1s0: TDLEN[0-3] 00001000 00001000 00001000 00001000 [ 7679.679470] igc 0000:01:00.0 enp1s0: TDH[0-3] 000000a7 0000002d 000000bf 000000d9 [ 7679.690406] igc 0000:01:00.0 enp1s0: TDT[0-3] 000000a7 0000002d 000000bf 000000d9 [ 7679.701264] igc 0000:01:00.0 enp1s0: TXDCTL[0-3] 02100108 02100108 02100108 02100108 [ 7679.712123] igc 0000:01:00.0 enp1s0: Reset adapter [ 7683.085967] igc 0000:01:00.0 enp1s0: NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX [ 8086.945561] ------------[ cut here ]------------ Entering kdb (current=0xffffffff8220b200, pid 0) on processor 0 Oops: (null) due to oops @ 0xffffffff81573888 RIP: 0010:dql_completed+0x148/0x160 Code: c9 00 48 89 57 58 e9 46 ff ff ff 45 85 e4 41 0f 95 c4 41 39 db 0f 95 c1 41 84 cc 74 05 45 85 ed 78 0a 44 89 c1 e9 27 ff ff ff <0f> 0b 01 f6 44 89 c1 29 f1 0f 48 ca eb 8c cc cc cc cc cc cc cc cc RSP: 0018:ffa0000000003e00 EFLAGS: 00010287 RAX: 000000000000006c RBX: ffa0000003eb0f78 RCX: ff11000109938000 RDX: 0000000000000003 RSI: 0000000000000160 RDI: ff110001002e9480 RBP: ffa0000000003ed8 R08: ff110001002e93c0 R09: ffa0000000003d28 R10: 0000000000007cc0 R11: 0000000000007c54 R12: 00000000ffffffd9 R13: ff1100037039cb00 R14: 00000000ffffffd9 R15: ff1100037039c048 FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <IRQ> ? igc_poll+0x1a9/0x14d0 [igc] __napi_poll+0x2e/0x1b0 net_rx_action+0x126/0x250 __do_softirq+0xd1/0x295 irq_exit_rcu+0xc5/0xf0 common_interrupt+0x86/0xa0 </IRQ> <TASK> asm_common_interrupt+0x27/0x40 RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b
de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d
RSP: 0018:ffffffff82203df0 EFLAGS: 00000202
RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f
RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000
RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018
R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000
R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002
cpuidle_enter+0x2e/0x50 call_cpuidle+0x23/0x40 do_idle+0x1be/0x220 cpu_startup_entry+0x20/0x30 rest_init+0xb5/0xc0 arch_call_rest_init+0xe/0x30 start_kernel+0x448/0x760 x86_64_start_kernel+0x109/0x150 secondary_startup_64_no_verify+0xe0/0xeb </TASK>
more>
[0]kdb>
[0]kdb>
[0]kdb> go
Catastrophic error detected
kdb_continue_catastrophic=0, type go a second time if you really want to continue
[0]kdb> go
Catastrophic error detected
kdb_continue_catastrophic=0, attempting to continue
[ 8086.955689] refcount_t: underflow; use-after-free. [ 8086.955697] WARNING: CPU: 0 PID: 0 at lib/refcount.c:28 refcount_warn_saturate+0xc2/0x110 [ 8086.955706] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype nft_compat
nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci
[ 8086.955751] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm
fuse backlight configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core
[ 8086.955784] RIP: 0010:refcount_warn_saturate+0xc2/0x110 [ 8086.955788] Code: 01 e8 82 e7 b4 ff 0f 0b 5d c3 cc cc cc cc 80 3d 68 c6 eb 00 00 75 81 48 c7 c7 a0 87 f6 81 c6 05 58 c6 eb 00 01 e8 5e e7 b4 ff <0f> 0b 5d c3 cc cc cc cc 80 3d 42 c6 eb 00 00 0f 85 59 ff ff ff 48 [ 8086.955790] RSP: 0018:ffa0000000003da0 EFLAGS: 00010286 [ 8086.955793] RAX: 0000000000000000 RBX: ff1100011da40ee0 RCX: ff11000361e1b888 [ 8086.955794] RDX: 00000000ffffffd8 RSI: 0000000000000027 RDI: ff11000361e1b880 [ 8086.955795] RBP: ffa0000000003da0 R08: 80000000ffff9f45 R09: ffa0000000003d28 [ 8086.955796] R10: ff1100035f840000 R11: 0000000000000028 R12: ff11000319ff8000 [ 8086.955797] R13: ff1100011bb79d60 R14: 00000000ffffffd6 R15: ff1100037039cb00 [ 8086.955798] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 8086.955800] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8086.955801] CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 [ 8086.955803] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 8086.955803] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 8086.955804] PKRU: 55555554 [ 8086.955805] Call Trace: [ 8086.955806] <IRQ> [ 8086.955808] tcp_wfree+0x112/0x130 [ 8086.955814] skb_release_head_state+0x24/0xa0 [ 8086.955818] napi_consume_skb+0x9c/0x160 [ 8086.955821] igc_poll+0x5d8/0x14d0 [igc] [ 8086.955835] __napi_poll+0x2e/0x1b0 [ 8086.955839] net_rx_action+0x126/0x250 [ 8086.955843] __do_softirq+0xd1/0x295 [ 8086.955846] irq_exit_rcu+0xc5/0xf0 [ 8086.955851] common_interrupt+0x86/0xa0 [ 8086.955857] </IRQ> [ 8086.955857] <TASK> [ 8086.955858] asm_common_interrupt+0x27/0x40 [ 8086.955862] RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 [ 8086.955866] Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d [ 8086.955867] RSP: 0018:ffffffff82203df0 EFLAGS: 00000202 [ 8086.955869] RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f [ 8086.955870] RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000 [ 8086.955871] RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018 [ 8086.955872] R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000 [ 8086.955873] R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002 [ 8086.955875] cpuidle_enter+0x2e/0x50 [ 8086.955880] call_cpuidle+0x23/0x40 [ 8086.955884] do_idle+0x1be/0x220 [ 8086.955887] cpu_startup_entry+0x20/0x30 [ 8086.955889] rest_init+0xb5/0xc0 [ 8086.955892] arch_call_rest_init+0xe/0x30 [ 8086.955895] start_kernel+0x448/0x760 [ 8086.955898] x86_64_start_kernel+0x109/0x150 [ 8086.955900] secondary_startup_64_no_verify+0xe0/0xeb [ 8086.955904] </TASK> [ 8086.955904] ---[ end trace 0000000000000000 ]--- [ 8086.955912] ------------[ cut here ]------------ [ 8086.955913] kernel BUG at lib/dynamic_queue_limits.c:27! [ 8086.955918] invalid opcode: 0000 [#1] SMP [ 8086.955922] RIP: 0010:dql_completed+0x148/0x160 [ 8086.955925] Code: c9 00 48 89 57 58 e9 46 ff ff ff 45 85 e4 41 0f 95 c4 41 39 db 0f 95 c1 41 84 cc 74 05 45 85 ed 78 0a 44 89 c1 e9 27 ff ff ff <0f> 0b 01 f6 44 89 c1 29 f1 0f 48 ca eb 8c cc cc cc cc cc cc cc cc [ 8086.955927] RSP: 0018:ffa0000000003e00 EFLAGS: 00010287 [ 8086.955928] RAX: 000000000000006c RBX: ffa0000003eb0f78 RCX: ff11000109938000 [ 8086.955929] RDX: 0000000000000003 RSI: 0000000000000160 RDI: ff110001002e9480 [ 8086.955930] RBP: ffa0000000003ed8 R08: ff110001002e93c0 R09: ffa0000000003d28 [ 8086.955931] R10: 0000000000007cc0 R11: 0000000000007c54 R12: 00000000ffffffd9 [ 8086.955932] R13: ff1100037039cb00 R14: 00000000ffffffd9 R15: ff1100037039c048 [ 8086.955933] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 8086.955934] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8086.955935] CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 [ 8086.955936] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 8086.955937] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 8086.955938] PKRU: 55555554 [ 8086.955939] Call Trace: [ 8086.955939] <IRQ> [ 8086.955940] ? igc_poll+0x1a9/0x14d0 [igc] [ 8086.955949] __napi_poll+0x2e/0x1b0 [ 8086.955952] net_rx_action+0x126/0x250 [ 8086.955956] __do_softirq+0xd1/0x295 [ 8086.955958] irq_exit_rcu+0xc5/0xf0 [ 8086.955961] common_interrupt+0x86/0xa0 [ 8086.955964] </IRQ> [ 8086.955965] <TASK> [ 8086.955965] asm_common_interrupt+0x27/0x40 [ 8086.955968] RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 [ 8086.955971] Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d [ 8086.955972] RSP: 0018:ffffffff82203df0 EFLAGS: 00000202 [ 8086.955973] RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f [ 8086.955974] RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000 [ 8086.955974] RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018 [ 8086.955975] R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000 [ 8086.955976] R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002 [ 8086.955978] cpuidle_enter+0x2e/0x50 [ 8086.955981] call_cpuidle+0x23/0x40 [ 8086.955984] do_idle+0x1be/0x220 [ 8086.955985] cpu_startup_entry+0x20/0x30 [ 8086.955987] rest_init+0xb5/0xc0 [ 8086.955990] arch_call_rest_init+0xe/0x30 [ 8086.955992] start_kernel+0x448/0x760 [ 8086.955994] x86_64_start_kernel+0x109/0x150 [ 8086.955996] secondary_startup_64_no_verify+0xe0/0xeb [ 8086.955998] </TASK> [ 8086.955999] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype
nft_compat nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci
[ 8086.956029] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm
fuse backlight configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core
[16762.543675] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.593 msecs [16762.543678] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.595 msecs [16762.543673] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.495 msecs [16762.543679] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.599 msecs [16762.543678] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.598 msecs [16762.543690] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.605 msecs [16762.543684] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.599 msecs [16762.543693] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.613 msecs [16762.543784] ---[ end trace 0000000000000000 ]--- [16762.849099] RIP: 0010:dql_completed+0x148/0x160
PANIC: Fatal exception in interrupt
--- drivers/net/ethernet/intel/igc/igc_main.c | 40 ++++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/igc/igc_main.c +28 -12
@@ -316,6 +316,33 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter)igc_clean_tx_ring (adapter->tx_ring[i]); } +static void igc_disable_tx_ring_hw (struct igc_ring *ring) +{ +struct igc_hw *hw = &ring->q_vector->adapter->hw; +u8 idx = ring->reg_idx; +u32 txdctl; + + txdctl =rd32 (IGC_TXDCTL (idx)); + txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE ; + txdctl |=IGC_TXDCTL_SWFLUSH ; +wr32 (IGC_TXDCTL (idx), txdctl); +} + +/** +* igc_disable_all_tx_rings_hw - Disable all transmit queue operation +* @adapter: board private structure +*/ +static void igc_disable_all_tx_rings_hw (struct igc_adapter *adapter) +{ +int i; + +for (i =0 ; i < adapter->num_tx_queues; i++) { +struct igc_ring *tx_ring = adapter->tx_ring[i]; + +igc_disable_tx_ring_hw (tx_ring); + } +} +/** * igc_setup_tx_resources - allocate Tx resources (Descriptors) * @tx_ring: tx descriptor ring (for a specific queue) to setup
@@ -5056,6 +5083,7 @@ void igc_down(struct igc_adapter *adapter)/* clear VLAN promisc flag so VFTA will be updated if necessary */ adapter->flags &= ~IGC_FLAG_VLAN_PROMISC ; +igc_disable_all_tx_rings_hw (adapter);igc_clean_all_tx_rings (adapter);igc_clean_all_rx_rings (adapter); }
@@ -7274,18 +7302,6 @@ void igc_enable_rx_ring(struct igc_ring *ring)igc_alloc_rx_buffers (ring,igc_desc_unused (ring)); } -static void igc_disable_tx_ring_hw (struct igc_ring *ring) -{ -struct igc_hw *hw = &ring->q_vector->adapter->hw; -u8 idx = ring->reg_idx; -u32 txdctl; - - txdctl =rd32 (IGC_TXDCTL (idx)); - txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE ; - txdctl |=IGC_TXDCTL_SWFLUSH ; -wr32 (IGC_TXDCTL (idx), txdctl); -} -void igc_disable_tx_ring (struct igc_ring *ring) {igc_disable_tx_ring_hw (ring);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 88/239 netfilter: nft_set_rbtree: fix overlap expiration walk
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit f718863aca469a109895cb855e6b81fff4827d71 ]
The lazy gc on insert that should remove timed-out entries fails to release the other half of the interval, if any.
Can be reproduced with tests/shell/testcases/sets/0044interval_overlap_0 in nftables.git and kmemleak enabled kernel.
Second bug is the use of rbe_prev vs. prev pointer.
If rbe_prev() returns NULL after at least one iteration, rbe_prev points to element that is not an end interval, hence it should not be removed.
Lastly, check the genmask of the end interval if this is active in the current generation.
--- net/netfilter/nft_set_rbtree.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
net/netfilter/nft_set_rbtree.c +14 -6
@@ -217,29 +217,37 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set,static int nft_rbtree_gc_elem (const struct nft_set *__set,struct nft_rbtree *priv, -struct nft_rbtree_elem *rbe) +struct nft_rbtree_elem *rbe, +u8 genmask) {struct nft_set *set = (struct nft_set *)__set;struct rb_node *prev =rb_prev (&rbe->node); -struct nft_rbtree_elem *rbe_prev =NULL ; +struct nft_rbtree_elem *rbe_prev;struct nft_set_gc_batch *gcb; gcb =nft_set_gc_batch_check (set,NULL ,GFP_ATOMIC );if (!gcb)return -ENOMEM ; -/* search for expired end interval coming before this element. */ +/* search for end interval coming before this element. +* end intervals don't carry a timeout extension, they +* are coupled with the interval start element. +*/ while (prev) { rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); -if (nft_rbtree_interval_end (rbe_prev)) +if (nft_rbtree_interval_end (rbe_prev) && +nft_set_elem_active (&rbe_prev->ext, genmask))break ; prev =rb_prev (prev); } -if (rbe_prev) { +if (prev) { + rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); +rb_erase (&rbe_prev->node, &priv->root);atomic_dec (&set->nelems); +nft_set_gc_batch_add (gcb, rbe_prev); }rb_erase (&rbe->node, &priv->root);
@@ -321,7 +329,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,/* perform garbage collection to avoid bogus overlap reports. */ if (nft_set_elem_expired (&rbe->ext)) { - err =nft_rbtree_gc_elem (set, priv, rbe); + err =nft_rbtree_gc_elem (set, priv, rbe, genmask);if (err <0 )return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 89/239 netfilter: nf_tables: skip immediate deactivate in _PREPARE_ERROR
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 0a771f7b266b02d262900c75f1e175c7fe76fec2 ]
On error when building the rule, the immediate expression unbinds the chain, hence objects can be deactivated by the transaction records.
Otherwise, it is possible to trigger the following warning:
WARNING: CPU: 3 PID: 915 at net/netfilter/nf_tables_api.c:2013 nf_tables_chain_destroy+0x1f7/0x210 [nf_tables] CPU: 3 PID: 915 Comm: chain-bind-err- Not tainted 6.1.39 #1 RIP: 0010:nf_tables_chain_destroy+0x1f7/0x210 [nf_tables]
--- net/netfilter/nft_immediate.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
net/netfilter/nft_immediate.c +18 -9
@@ -125,15 +125,27 @@ static void nft_immediate_activate(const struct nft_ctx *ctx,return nft_data_hold (&priv->data,nft_dreg_to_type (priv->dreg)); } +static void nft_immediate_chain_deactivate (const struct nft_ctx *ctx, +struct nft_chain *chain, +enum nft_trans_phase phase) +{ +struct nft_ctx chain_ctx; +struct nft_rule *rule; + + chain_ctx = *ctx; + chain_ctx.chain = chain; + +list_for_each_entry (rule, &chain->rules, list) +nft_rule_expr_deactivate (&chain_ctx, rule, phase); +} +static void nft_immediate_deactivate (const struct nft_ctx *ctx,const struct nft_expr *expr,enum nft_trans_phase phase) {const struct nft_immediate_expr *priv =nft_expr_priv (expr);const struct nft_data *data = &priv->data; -struct nft_ctx chain_ctx;struct nft_chain *chain; -struct nft_rule *rule;if (priv->dreg ==NFT_REG_VERDICT ) {switch (data->verdict.code) {
@@ -143,20 +155,17 @@ static void nft_immediate_deactivate(const struct nft_ctx *ctx,if (!nft_chain_binding (chain))break ; - chain_ctx = *ctx; - chain_ctx.chain = chain; - -list_for_each_entry (rule, &chain->rules, list) -nft_rule_expr_deactivate (&chain_ctx, rule, phase); -switch (phase) {case NFT_TRANS_PREPARE_ERROR :nf_tables_unbind_chain (ctx, chain); - fallthrough; +nft_deactivate_next (ctx->net, chain); +break ;case NFT_TRANS_PREPARE : +nft_immediate_chain_deactivate (ctx, chain, phase);nft_deactivate_next (ctx->net, chain);break ;default : +nft_immediate_chain_deactivate (ctx, chain, phase);nft_chain_del (chain); chain->bound = false;nft_use_dec (&chain->table->use);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 90/239 netfilter: nf_tables: disallow rule addition to bound chain via NFTA_RULE_CHAIN_ID
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 0ebc1064e4874d5987722a2ddbc18f94aa53b211 ]
Bail out with EOPNOTSUPP when adding rule to bound chain via NFTA_RULE_CHAIN_ID. The following warning splat is shown when adding a rule to a deleted bound chain:
WARNING: CPU: 2 PID: 13692 at net/netfilter/nf_tables_api.c:2013 nf_tables_chain_destroy+0x1f7/0x210 [nf_tables] CPU: 2 PID: 13692 Comm: chain-bound-rul Not tainted 6.1.39 #1 RIP: 0010:nf_tables_chain_destroy+0x1f7/0x210 [nf_tables]
--- net/netfilter/nf_tables_api.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/netfilter/nf_tables_api.c +3 -2
@@ -3810,8 +3810,6 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,NL_SET_BAD_ATTR (extack, nla[NFTA_RULE_CHAIN ]);return PTR_ERR (chain); } -if (nft_chain_is_bound (chain)) -return -EOPNOTSUPP ; }else if (nla[NFTA_RULE_CHAIN_ID ]) { chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID],
@@ -3824,6 +3822,9 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,return -EINVAL ; } +if (nft_chain_is_bound (chain)) +return -EOPNOTSUPP ; +if (nla[NFTA_RULE_HANDLE ]) { handle =be64_to_cpu (nla_get_be64 (nla[NFTA_RULE_HANDLE ])); rule =__nft_rule_lookup (chain, handle);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 91/239 mm: suppress mm fault logging if fatal signal already pending
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit 5f0bc0b042fc77ff70e14c790abdec960cde4ec1 ]
Commit eda0047296a1 ("mm: make the page fault mmap locking killable") intentionally made it much easier to trigger the "page fault fails because a fatal signal is pending" situation, by having the mmap locking fail early in that case.
We have long aborted page faults in other fatal cases when the actual IO for a page is interrupted by SIGKILL - which is particularly useful for the traditional case of NFS hanging due to network issues, but local filesystems could cause it too if you happened to get the SIGKILL while waiting for a page to be faulted in (eg lock_folio_maybe_drop_mmap()).
So aborting the page fault wasn't a new condition - but it now triggers earlier, before we even get to 'handle_mm_fault()'. And as a result the error doesn't go through our 'fault_signal_pending()' logic, and doesn't get filtered away there.
Normally you'd never even notice, because if a fatal signal is pending, the new SIGSEGV we send ends up being ignored anyway.
But it turns out that there is one very noticeable exception: if you enable 'show_unhandled_signals', the aborted page fault will be logged in the kernel messages, and you'll get a scary line looking something like this in your logs:
pverados[2183248]: segfault at 55e5a00f9ae0 ip 000055e5a00f9ae0 sp 00007ffc0720bea8 error 14 in perl[55e5a00d4000+195000] likely on CPU 10 (core 4, socket 0)
which is rather misleading. It's not really a segfault at all, it's just "the thread was killed before the page fault completed, so we aborted the page fault".
Fix this by just making it clear that a pending fatal signal means that any new signal coming in after that is implicitly handled. This will avoid the misleading logging, since now the signal isn't 'unhandled' any more.
--- kernel/signal.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/signal.c +4 -0
@@ -561,6 +561,10 @@ bool unhandled_signal(struct task_struct *tsk, int sig)if (handler !=SIG_IGN && handler !=SIG_DFL )return false; +/* If dying, we handle all new signals by ignoring them */ +if (fatal_signal_pending (tsk)) +return false; +/* if ptraced, let the tracer determine */ return !tsk->ptrace; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 92/239 tools: ynl-gen: fix enum index in _decode_enum(..)
In reply to Greg Kroah-HartmanFrom: Arkadiusz Kubalewski <[email protected]>
[ Upstream commit d7ddf5f4269fcaf19aafe971e635d91897423a3a ]
Remove wrong index adjustment, which is leftover from adding support for sparse enums.enum.entries_by_val() function shall not subtract the start-value, as it is indexed with real enum value.
--- tools/net/ynl/lib/ynl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/net/ynl/lib/ynl.py +2 -2
@@ -405,8 +405,8 @@ class YnlFamily(SpecFamily): def _decode_enum(self, rsp, attr_spec): raw = rsp[attr_spec['name']] enum = self.consts[attr_spec['enum']] - i = attr_spec.get('value-start', 0) if 'enum-as-flags' in attr_spec and attr_spec['enum-as-flags']: + i = 0 value = set() while raw: if raw & 1:
@@ -414,7 +414,7 @@ class YnlFamily(SpecFamily): raw >>= 1 i += 1 else: - value = enum.entries_by_val[raw - i].name + value = enum.entries_by_val[raw].name rsp[attr_spec['name']] = value def _decode_binary(self, attr, attr_spec):
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 93/239 net: fec: tx processing does not call XDP APIs if budget is 0
In reply to Greg Kroah-HartmanFrom: Wei Fang <[email protected]>
[ Upstream commit 15cec633fc7bfe4cd69aa012c3b35b31acfc86f2 ]
According to the clarification [1] in the latest napi.rst, the tx processing cannot call any XDP (or page pool) APIs if the "budget" is 0. Because NAPI is called with the budget of 0 (such as netpoll) indicates we may be in an IRQ context, however, we cannot use the page pool from IRQ context.
[1] https://lore.kernel.org/all/[email protected]/
--- drivers/net/ethernet/freescale/fec_main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/net/ethernet/freescale/fec_main.c +12 -4
@@ -1372,7 +1372,7 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts, }static void -fec_enet_tx_queue (struct net_device *ndev,u16 queue_id) +fec_enet_tx_queue (struct net_device *ndev,u16 queue_id,int budget) {struct fec_enet_private *fep;struct xdp_frame *xdpf;
@@ -1416,6 +1416,14 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)if (!skb) goto tx_buf_done; }else { +/* Tx processing cannot call any XDP (or page pool) APIs if +* the "budget" is 0. Because NAPI is called with budget of +* 0 (such as netpoll) indicates we may be in an IRQ context, +* however, we can't use the page pool from IRQ context. +*/ +if (unlikely (!budget)) +break ; + xdpf = txq->tx_buf[index].xdp;if (bdp->cbd_bufaddr) dma_unmap_single(&fep->pdev->dev,
@@ -1508,14 +1516,14 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)writel (0 , txq->bd.reg_desc_active); } -static void fec_enet_tx (struct net_device *ndev) +static void fec_enet_tx (struct net_device *ndev,int budget) {struct fec_enet_private *fep =netdev_priv (ndev);int i;/* Make sure that AVB queues are processed first. */ for (i = fep->num_tx_queues -1 ; i >=0 ; i--) -fec_enet_tx_queue (ndev, i); +fec_enet_tx_queue (ndev, i, budget); } static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
@@ -1858,7 +1866,7 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)do { done +=fec_enet_rx (ndev, budget - done); -fec_enet_tx (ndev); +fec_enet_tx (ndev, budget); }while ((done < budget) &&fec_enet_collect_events (fep));if (done < budget) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 94/239 net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
[ Upstream commit 6c58c8816abb7b93b21fa3b1d0c1726402e5e568 ]
The nla_for_each_nested parsing in function mqprio_parse_nlattr() does not check the length of the nested attribute. This can lead to an out-of-attribute read and allow a malformed nlattr (e.g., length 0) to be viewed as 8 byte integer and passed to priv->max_rate/min_rate.
This patch adds the check based on nla_len() when check the nla_type(), which ensures that the length of these two attribute must equals sizeof(u64).
--- net/sched/sch_mqprio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
net/sched/sch_mqprio.c +14 -0
@@ -290,6 +290,13 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt, "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");return -EINVAL ; } + +if (nla_len (attr) !=sizeof (u64)) { +NL_SET_ERR_MSG_ATTR (extack, attr, +"Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length" ); +return -EINVAL ; + } +if (i >= qopt->num_tc)break ; priv->min_rate[i] =nla_get_u64 (attr);
@@ -312,6 +319,13 @@ static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt, "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");return -EINVAL ; } + +if (nla_len (attr) !=sizeof (u64)) { +NL_SET_ERR_MSG_ATTR (extack, attr, +"Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length" ); +return -EINVAL ; + } +if (i >= qopt->num_tc)break ; priv->max_rate[i] =nla_get_u64 (attr);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 95/239 benet: fix return value check in be_lancer_xmit_workarounds()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit 5c85f7065718a949902b238a6abd8fc907c5d3e0 ]
in be_lancer_xmit_workarounds(), it should go to label 'tx_drop' if an unexpected value is returned by pskb_trim().
--- drivers/net/ethernet/emulex/benet/be_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/emulex/benet/be_main.c +2 -1
@@ -1138,7 +1138,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, (lancer_chip(adapter) || BE3_chip(adapter) || skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { ip = (struct iphdr *)ip_hdr (skb); -pskb_trim (skb, eth_hdr_len +ntohs (ip->tot_len)); +if (unlikely (pskb_trim (skb, eth_hdr_len +ntohs (ip->tot_len)))) + goto tx_drop; }/* If vlan tag is already inlined in the packet, skip HW VLAN
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 96/239 tipc: check return value of pskb_trim()
In reply to Greg Kroah-HartmanFrom: Yuanjun Gong <[email protected]>
[ Upstream commit e46e06ffc6d667a89b979701288e2264f45e6a7b ]
goto free_skb if an unexpected result is returned by pskb_tirm() in tipc_crypto_rcv_complete().
--- net/tipc/crypto.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/tipc/crypto.c +2 -1
@@ -1960,7 +1960,8 @@ static void tipc_crypto_rcv_complete(struct net *net, struct tipc_aead *aead,skb_reset_network_header (*skb);skb_pull (*skb,tipc_ehdr_size (ehdr)); -pskb_trim (*skb, (*skb)->len - aead->authsize); +if (pskb_trim (*skb, (*skb)->len - aead->authsize)) + goto free_skb;/* Validate TIPCv2 message */ if (unlikely (!tipc_msg_validate (skb))) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 97/239 tipc: stop tipc crypto on failure in tipc_node_create
In reply to Greg Kroah-HartmanFrom: Fedor Pchelkin <[email protected]>
[ Upstream commit de52e17326c3e9a719c9ead4adb03467b8fae0ef ]
If tipc_link_bc_create() fails inside tipc_node_create() for a newly allocated tipc node then we should stop its tipc crypto and free the resources allocated with a call to tipc_crypto_start().
As the node ref is initialized to one to that point, just put the ref on tipc_link_bc_create() error case that would lead to tipc_node_free() be eventually executed and properly clean the node and its crypto resources.
Found by Linux Verification Center (linuxtesting.org).
--- net/tipc/node.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/node.c +1 -1
@@ -583,7 +583,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id, n->capabilities, &n->bc_entry.inputq1, &n->bc_entry.namedq, snd_l, &n->bc_entry.link)) {pr_warn ("Broadcast rcv link creation failed, no memory\n" ); -kfree (n); +tipc_node_put (n); n =NULL ; goto exit; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 98/239 fs/9p: Fix a datatype used with V9FS_DIRECT_IO
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 95f41d87810083d8b3dedcce46a4e356cf4a9673 ]
The commit in Fixes has introduced some "enum p9_session_flags" values larger than a char.
Such values are stored in "v9fs_session_info->flags" which is a char only.
Turn it into an int so that the "enum p9_session_flags" values can fit in it.
--- fs/9p/v9fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/9p/v9fs.h +1 -1
@@ -108,7 +108,7 @@ enum p9_cache_bits {struct v9fs_session_info {/* options */ -unsigned char flags; +unsigned int flags;unsigned char nodev;unsigned short debug;unsigned int afid;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 99/239 RDMA/mlx4: Make check for invalid flags stricter
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit d64b1ee12a168030fbb3e0aebf7bce49e9a07589 ]
This code is trying to ensure that only the flags specified in the list are allowed. The problem is that ucmd->rx_hash_fields_mask is a u64 and the flags are an enum which is treated as a u32 in this context. That means the test doesn't check whether the highest 32 bits are zero.
--- drivers/infiniband/hw/mlx4/qp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/infiniband/hw/mlx4/qp.c +9 -9
@@ -565,15 +565,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx,return (-EOPNOTSUPP ); } -if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | -MLX4_IB_RX_HASH_DST_IPV4 | -MLX4_IB_RX_HASH_SRC_IPV6 | -MLX4_IB_RX_HASH_DST_IPV6 | -MLX4_IB_RX_HASH_SRC_PORT_TCP | -MLX4_IB_RX_HASH_DST_PORT_TCP | -MLX4_IB_RX_HASH_SRC_PORT_UDP | -MLX4_IB_RX_HASH_DST_PORT_UDP | -MLX4_IB_RX_HASH_INNER )) { +if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | +MLX4_IB_RX_HASH_DST_IPV4 | +MLX4_IB_RX_HASH_SRC_IPV6 | +MLX4_IB_RX_HASH_DST_IPV6 | +MLX4_IB_RX_HASH_SRC_PORT_TCP | +MLX4_IB_RX_HASH_DST_PORT_TCP | +MLX4_IB_RX_HASH_SRC_PORT_UDP | +MLX4_IB_RX_HASH_DST_PORT_UDP | +MLX4_IB_RX_HASH_INNER )) {pr_debug ("RX Hash fields_mask has unsupported mask (0x%llx)\n" , ucmd->rx_hash_fields_mask);return (-EOPNOTSUPP );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 100/239 drm/msm/mdss: correct UBWC programming for SM8550
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit a85c238c5ccd64f8d4c4560702c65cb25dee791c ]
The SM8550 platform employs newer UBWC decoder, which requires slightly different programming.
Patchwork: https://patchwork.freedesktop.org/patch/546934/
--- drivers/gpu/drm/msm/msm_mdss.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/msm_mdss.c +17 -2
@@ -189,6 +189,7 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)#define UBWC_2_0 0x20000000#define UBWC_3_0 0x30000000#define UBWC_4_0 0x40000000 +#define UBWC_4_3 0x40030000static void msm_mdss_setup_ubwc_dec_20 (struct msm_mdss *msm_mdss) {
@@ -227,7 +228,10 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)writel_relaxed (1 , msm_mdss->mmio +UBWC_CTRL_2 );writel_relaxed (0 , msm_mdss->mmio +UBWC_PREDICTION_MODE ); }else { -writel_relaxed (2 , msm_mdss->mmio +UBWC_CTRL_2 ); +if (data->ubwc_dec_version ==UBWC_4_3 ) +writel_relaxed (3 , msm_mdss->mmio +UBWC_CTRL_2 ); +else +writel_relaxed (2 , msm_mdss->mmio +UBWC_CTRL_2 );writel_relaxed (1 , msm_mdss->mmio +UBWC_PREDICTION_MODE ); } }
@@ -271,6 +275,7 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)msm_mdss_setup_ubwc_dec_30 (msm_mdss);break ;case UBWC_4_0 : +case UBWC_4_3 :msm_mdss_setup_ubwc_dec_40 (msm_mdss);break ;default :
@@ -561,6 +566,16 @@ static const struct msm_mdss_data sm8250_data = { .macrotile_mode = 1, }; +static const struct msm_mdss_data sm8550_data = { + .ubwc_version =UBWC_4_0 , + .ubwc_dec_version =UBWC_4_3 , + .ubwc_swizzle =6 , + .ubwc_static =1 , +/* TODO: highest_bank_bit = 2 for LP_DDR4 */ + .highest_bank_bit =3 , + .macrotile_mode =1 , +}; +static const struct of_device_id mdss_dt_match[] = { { .compatible ="qcom,mdss" }, { .compatible ="qcom,msm8998-mdss" },
@@ -575,7 +590,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data }, - { .compatible = "qcom,sm8550-mdss", .data = &sm8250_data }, + { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, {} };MODULE_DEVICE_TABLE (of, mdss_dt_match);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 101/239 drm/msm/dpu: add missing flush and fetch bits for DMA4/DMA5 planes
In reply to Greg Kroah-HartmanFrom: Jonathan Marek <[email protected]>
[ Upstream commit ba7a94ea73120e3f72c4a9b7ed6fd5598d29c069 ]
Note that with this, DMA4/DMA5 are still non-functional, but at least display *something* in modetest instead of nothing or underflow.
Patchwork: https://patchwork.freedesktop.org/patch/545548/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +7 -1
@@ -51,7 +51,7 @@static const u32 fetch_tbl[SSPP_MAX ] = {CTL_INVALID_BIT ,16 ,17 ,18 ,19 ,CTL_INVALID_BIT ,CTL_INVALID_BIT ,CTL_INVALID_BIT ,CTL_INVALID_BIT ,0 , -1 ,2 ,3 ,CTL_INVALID_BIT ,CTL_INVALID_BIT }; +1 ,2 ,3 ,4 ,5 }; static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl, const struct dpu_mdss_cfg *m,
@@ -209,6 +209,12 @@ static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,case SSPP_DMA3 : ctx->pending_flush_mask |=BIT (25 );break ; +case SSPP_DMA4 : + ctx->pending_flush_mask |=BIT (13 ); +break ; +case SSPP_DMA5 : + ctx->pending_flush_mask |=BIT (14 ); +break ;case SSPP_CURSOR0 : ctx->pending_flush_mask |=BIT (22 );break ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 102/239 drm/msm/dpu: drop enum dpu_core_perf_data_bus_id
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit e8383f5cf1b3573ce140a80bfbfd809278ab16d6 ]
Drop the leftover of bus-client -> interconnect conversion, the enum dpu_core_perf_data_bus_id.
Patchwork: https://patchwork.freedesktop.org/patch/546048/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 13 ------------- 1 file changed, 13 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +0 -13
@@ -14,19 +14,6 @@#define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 -/** -* enum dpu_core_perf_data_bus_id - data bus identifier -* @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus -* @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus -* @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus -*/ -enum dpu_core_perf_data_bus_id { -DPU_CORE_PERF_DATA_BUS_ID_MNOC , -DPU_CORE_PERF_DATA_BUS_ID_LLCC , -DPU_CORE_PERF_DATA_BUS_ID_EBI , -DPU_CORE_PERF_DATA_BUS_ID_MAX , -}; -/** * struct dpu_core_perf_params - definition of performance parameters * @max_per_pipe_ib: maximum instantaneous bandwidth request
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 103/239 drm/msm/dsi: Drop unused regulators from QCM2290 14nm DSI PHY config
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 97368254a08e2ca4766e7f84a45840230fe77fa3 ]
The regulator setup was likely copied from other SoCs by mistake. Just like SM6125 the DSI PHY on this platform is not getting power from a regulator but from the MX power domain.
Patchwork: https://patchwork.freedesktop.org/patch/544536/
--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +0 -2
@@ -1087,8 +1087,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = {const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = { .has_phy_lane = true, - .regulator_data = dsi_phy_14nm_17mA_regulators, - .num_regulators =ARRAY_SIZE (dsi_phy_14nm_17mA_regulators), .ops = { .enable = dsi_14nm_phy_enable, .disable = dsi_14nm_phy_disable,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 104/239 drm/msm/adreno: Fix snapshot BINDLESS_DATA size
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit bd846ceee9c478d0397428f02696602ba5eb264a ]
The incorrect size was causing "CP | AHB bus error" when snapshotting the GPU state on a6xx gen4 (a660 family).
Patchwork: https://patchwork.freedesktop.org/patch/546763/
--- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +1 -1
@@ -206,7 +206,7 @@ static const struct a6xx_shader_block {SHADER (A6XX_SP_LB_3_DATA ,0x800 ),SHADER (A6XX_SP_LB_4_DATA ,0x800 ),SHADER (A6XX_SP_LB_5_DATA ,0x200 ), -SHADER (A6XX_SP_CB_BINDLESS_DATA ,0x2000 ), +SHADER (A6XX_SP_CB_BINDLESS_DATA ,0x800 ),SHADER (A6XX_SP_CB_LEGACY_DATA ,0x280 ),SHADER (A6XX_SP_UAV_DATA ,0x80 ), SHADER(A6XX_SP_INST_TAG, 0x80),
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 105/239 RDMA/irdma: Add missing read barriers
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit 4984eb51453ff7eddee9e5ce816145be39c0ec5c ]
On code inspection, there are many instances in the driver where CEQE and AEQE fields written to by HW are read without guaranteeing that the polarity bit has been read and checked first.
Add a read barrier to avoid reordering of loads on the CEQE/AEQE fields prior to checking the polarity bit.
--- drivers/infiniband/hw/irdma/ctrl.c | 9 ++++++++- drivers/infiniband/hw/irdma/puda.c | 6 ++++++ drivers/infiniband/hw/irdma/uk.c | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-)
drivers/infiniband/hw/irdma/ctrl.c +8 -1
@@ -3363,6 +3363,9 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,if (polarity != ccq->cq_uk.polarity)return -ENOENT ; +/* Ensure CEQE contents are read after valid bit is checked */ +dma_rmb (); +get_64bit_val (cqe,8 , &qp_ctx); cqp = (struct irdma_sc_cqp *)(unsigned long )qp_ctx; info->error = (bool )FIELD_GET (IRDMA_CQ_ERROR , temp);
@@ -4009,13 +4012,17 @@ int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,u8 polarity; aeqe =IRDMA_GET_CURRENT_AEQ_ELEM (aeq); -get_64bit_val (aeqe,0 , &compl_ctx);get_64bit_val (aeqe,8 , &temp); polarity = (u8 )FIELD_GET (IRDMA_AEQE_VALID , temp);if (aeq->polarity != polarity)return -ENOENT ; +/* Ensure AEQE contents are read after valid bit is checked */ +dma_rmb (); + +get_64bit_val (aeqe,0 , &compl_ctx); +print_hex_dump_debug ("WQE: AEQ_ENTRY WQE" ,DUMP_PREFIX_OFFSET ,16 ,8 , aeqe,16 , false);
drivers/infiniband/hw/irdma/puda.c +6 -0
@@ -230,6 +230,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,if (valid_bit != cq_uk->polarity)return -ENOENT ; +/* Ensure CQE contents are read after valid bit is checked */ +dma_rmb (); +if (cq->dev->hw_attrs.uk_attrs.hw_rev >=IRDMA_GEN_2 ) ext_valid = (bool )FIELD_GET (IRDMA_CQ_EXTCQE , qword3);
@@ -243,6 +246,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,if (polarity != cq_uk->polarity)return -ENOENT ; +/* Ensure ext CQE contents are read after ext valid bit is checked */ +dma_rmb (); +IRDMA_RING_MOVE_HEAD_NOCHECK (cq_uk->cq_ring);if (!IRDMA_RING_CURRENT_HEAD (cq_uk->cq_ring)) cq_uk->polarity = !cq_uk->polarity;
drivers/infiniband/hw/irdma/uk.c +3 -0
@@ -1527,6 +1527,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)if (polarity != temp)break ; +/* Ensure CQE contents are read after valid bit is checked */ +dma_rmb (); +get_64bit_val (cqe,8 , &comp_ctx);if ((void *)(unsigned long )comp_ctx == q)set_64bit_val (cqe,8 ,0 );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 106/239 RDMA/irdma: Fix data race on CQP completion stats
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit f2c3037811381f9149243828c7eb9a1631df9f9c ]
CQP completion statistics is read lockesly in irdma_wait_event and irdma_check_cqp_progress while it can be updated in the completion thread irdma_sc_ccq_get_cqe_info on another CPU as KCSAN reports.
Make completion statistics an atomic variable to reflect coherent updates to it. This will also avoid load/store tearing logic bug potentially possible by compiler optimizations.
[77346.170861] BUG: KCSAN: data-race in irdma_handle_cqp_op [irdma] / irdma_sc_ccq_get_cqe_info [irdma]
[77346.171383] write to 0xffff8a3250b108e0 of 8 bytes by task 9544 on cpu 4: [77346.171483] irdma_sc_ccq_get_cqe_info+0x27a/0x370 [irdma] [77346.171658] irdma_cqp_ce_handler+0x164/0x270 [irdma] [77346.171835] cqp_compl_worker+0x1b/0x20 [irdma] [77346.172009] process_one_work+0x4d1/0xa40 [77346.172024] worker_thread+0x319/0x700 [77346.172037] kthread+0x180/0x1b0 [77346.172054] ret_from_fork+0x22/0x30
[77346.172136] read to 0xffff8a3250b108e0 of 8 bytes by task 9838 on cpu 2: [77346.172234] irdma_handle_cqp_op+0xf4/0x4b0 [irdma] [77346.172413] irdma_cqp_aeq_cmd+0x75/0xa0 [irdma] [77346.172592] irdma_create_aeq+0x390/0x45a [irdma] [77346.172769] irdma_rt_init_hw.cold+0x212/0x85d [irdma] [77346.172944] irdma_probe+0x54f/0x620 [irdma] [77346.173122] auxiliary_bus_probe+0x66/0xa0 [77346.173137] really_probe+0x140/0x540 [77346.173154] __driver_probe_device+0xc7/0x220 [77346.173173] driver_probe_device+0x5f/0x140 [77346.173190] __driver_attach+0xf0/0x2c0 [77346.173208] bus_for_each_dev+0xa8/0xf0 [77346.173225] driver_attach+0x29/0x30 [77346.173240] bus_add_driver+0x29c/0x2f0 [77346.173255] driver_register+0x10f/0x1a0 [77346.173272] __auxiliary_driver_register+0xbc/0x140 [77346.173287] irdma_init_module+0x55/0x1000 [irdma] [77346.173460] do_one_initcall+0x7d/0x410 [77346.173475] do_init_module+0x81/0x2c0 [77346.173491] load_module+0x1232/0x12c0 [77346.173506] __do_sys_finit_module+0x101/0x180 [77346.173522] __x64_sys_finit_module+0x3c/0x50 [77346.173538] do_syscall_64+0x39/0x90 [77346.173553] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[77346.173634] value changed: 0x0000000000000094 -> 0x0000000000000095
--- drivers/infiniband/hw/irdma/ctrl.c | 22 +++++++------- drivers/infiniband/hw/irdma/defs.h | 46 ++++++++++++++--------------- drivers/infiniband/hw/irdma/type.h | 2 ++ drivers/infiniband/hw/irdma/utils.c | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-)
drivers/infiniband/hw/irdma/ctrl.c +11 -11
@@ -2712,13 +2712,13 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq,*/ void irdma_check_cqp_progress (struct irdma_cqp_timeout *timeout,struct irdma_sc_dev *dev) { -if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]) { - timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]; +u64 completed_ops =atomic64_read (&dev->cqp->completed_ops); + +if (timeout->compl_cqp_cmds != completed_ops) { + timeout->compl_cqp_cmds = completed_ops; timeout->count =0 ; - }else { -if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ] != - timeout->compl_cqp_cmds) - timeout->count++; + }else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) { + timeout->count++; } }
@@ -2761,7 +2761,7 @@ static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail,if (newtail != tail) {/* SUCCESS */ IRDMA_RING_MOVE_TAIL (cqp->sq_ring); - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]++; +atomic64_inc (&cqp->completed_ops);return 0 ; }udelay (cqp->dev->hw_attrs.max_sleep_count);
@@ -3121,8 +3121,8 @@ int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp, info->dev->cqp = cqp;IRDMA_RING_INIT (cqp->sq_ring, cqp->sq_size); - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ] =0 ; - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ] =0 ; + cqp->requested_ops =0 ; +atomic64_set (&cqp->completed_ops,0 );/* for the cqp commands backlog. */ INIT_LIST_HEAD (&cqp->dev->cqp_cmd_head);
@@ -3274,7 +3274,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratchif (ret_code)return NULL ; - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ]++; + cqp->requested_ops++;if (!*wqe_idx) cqp->polarity = !cqp->polarity; wqe = cqp->sq_base[*wqe_idx].elem;
@@ -3400,7 +3400,7 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,dma_wmb ();/* make sure shadow area is updated before moving tail */ IRDMA_RING_MOVE_TAIL (cqp->sq_ring); - ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]++; +atomic64_inc (&cqp->completed_ops);return ret_code; }
drivers/infiniband/hw/irdma/defs.h +22 -24
54 lines not on this page · raw message
drivers/infiniband/hw/irdma/type.h +2 -0
@@ -365,6 +365,8 @@ struct irdma_sc_cqp {struct irdma_dcqcn_cc_params dcqcn_params;__le64 *host_ctx;u64 *scratch_array; +u64 requested_ops; +atomic64_t completed_ops;u32 cqp_id;u32 sq_size;u32 hw_sq_size;
drivers/infiniband/hw/irdma/utils.c +1 -1
@@ -567,7 +567,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf,bool cqp_error = false;int err_code =0 ; - cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]; + cqp_timeout.compl_cqp_cmds =atomic64_read (&rf->sc_dev.cqp->completed_ops); do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 107/239 RDMA/irdma: Fix data race on CQP request done
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit f0842bb3d38863777e3454da5653d80b5fde6321 ]
KCSAN detects a data race on cqp_request->request_done memory location which is accessed locklessly in irdma_handle_cqp_op while being updated in irdma_cqp_ce_handler.
Annotate lockless intent with READ_ONCE/WRITE_ONCE to avoid any compiler optimizations like load fusing and/or KCSAN warning.
[222808.417128] BUG: KCSAN: data-race in irdma_cqp_ce_handler [irdma] / irdma_wait_event [irdma]
[222808.417532] write to 0xffff8e44107019dc of 1 bytes by task 29658 on cpu 5: [222808.417610] irdma_cqp_ce_handler+0x21e/0x270 [irdma] [222808.417725] cqp_compl_worker+0x1b/0x20 [irdma] [222808.417827] process_one_work+0x4d1/0xa40 [222808.417835] worker_thread+0x319/0x700 [222808.417842] kthread+0x180/0x1b0 [222808.417852] ret_from_fork+0x22/0x30
[222808.417918] read to 0xffff8e44107019dc of 1 bytes by task 29688 on cpu 1: [222808.417995] irdma_wait_event+0x1e2/0x2c0 [irdma] [222808.418099] irdma_handle_cqp_op+0xae/0x170 [irdma] [222808.418202] irdma_cqp_cq_destroy_cmd+0x70/0x90 [irdma] [222808.418308] irdma_puda_dele_rsrc+0x46d/0x4d0 [irdma] [222808.418411] irdma_rt_deinit_hw+0x179/0x1d0 [irdma] [222808.418514] irdma_ib_dealloc_device+0x11/0x40 [irdma] [222808.418618] ib_dealloc_device+0x2a/0x120 [ib_core] [222808.418823] __ib_unregister_device+0xde/0x100 [ib_core] [222808.418981] ib_unregister_device+0x22/0x40 [ib_core] [222808.419142] irdma_ib_unregister_device+0x70/0x90 [irdma] [222808.419248] i40iw_close+0x6f/0xc0 [irdma] [222808.419352] i40e_client_device_unregister+0x14a/0x180 [i40e] [222808.419450] i40iw_remove+0x21/0x30 [irdma] [222808.419554] auxiliary_bus_remove+0x31/0x50 [222808.419563] device_remove+0x69/0xb0 [222808.419572] device_release_driver_internal+0x293/0x360 [222808.419582] driver_detach+0x7c/0xf0 [222808.419592] bus_remove_driver+0x8c/0x150 [222808.419600] driver_unregister+0x45/0x70 [222808.419610] auxiliary_driver_unregister+0x16/0x30 [222808.419618] irdma_exit_module+0x18/0x1e [irdma] [222808.419733] __do_sys_delete_module.constprop.0+0x1e2/0x310 [222808.419745] __x64_sys_delete_module+0x1b/0x30 [222808.419755] do_syscall_64+0x39/0x90 [222808.419763] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[222808.419829] value changed: 0x01 -> 0x03
--- drivers/infiniband/hw/irdma/hw.c | 2 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/utils.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/infiniband/hw/irdma/hw.c +1 -1
@@ -2075,7 +2075,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq) cqp_request->compl_info.error = info.error;if (cqp_request->waiting) { - cqp_request->request_done = true; +WRITE_ONCE (cqp_request->request_done, true);wake_up (&cqp_request->waitq);irdma_put_cqp_request (&rf->cqp, cqp_request); }else {
drivers/infiniband/hw/irdma/main.h +1 -1
@@ -161,8 +161,8 @@ struct irdma_cqp_request {void (*callback_fcn)(struct irdma_cqp_request *cqp_request);void *param;struct irdma_cqp_compl_info compl_info; +bool request_done;/* READ/WRITE_ONCE macros operate on it */ bool waiting:1; - bool request_done:1; bool dynamic:1; };
drivers/infiniband/hw/irdma/utils.c +3 -3
@@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp,if (cqp_request->dynamic) {kfree (cqp_request); }else { - cqp_request->request_done = false; +WRITE_ONCE (cqp_request->request_done, false); cqp_request->callback_fcn =NULL ; cqp_request->waiting = false;
@@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp, {if (cqp_request->waiting) { cqp_request->compl_info.error = true; - cqp_request->request_done = true; +WRITE_ONCE (cqp_request->request_done, true);wake_up (&cqp_request->waitq); } wait_event_timeout(cqp->remove_wq,
@@ -571,7 +571,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf, do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq, - cqp_request->request_done, + READ_ONCE(cqp_request->request_done), msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS))) break;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 108/239 RDMA/core: Update CMA destination address on rdma_resolve_addr
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit 0e15863015d97c1ee2cc29d599abcc7fa2dc3e95 ]
8d037973d48c ("RDMA/core: Refactor rdma_bind_addr") intoduces as regression on irdma devices on certain tests which uses rdma CM, such as cmtime.
No connections can be established with the MAD QP experiences a fatal error on the active side.
The cma destination address is not updated with the dst_addr when ULP on active side calls rdma_bind_addr followed by rdma_resolve_addr. The id_priv state is 'bound' in resolve_prepare_src and update is skipped.
This leaves the dgid passed into irdma driver to create an Address Handle (AH) for the MAD QP at 0. The create AH descriptor as well as the ARP cache entry is invalid and HW throws an asynchronous events as result.
[ 1207.656888] resolve_prepare_src caller: ucma_resolve_addr+0xff/0x170 [rdma_ucm] daddr=200.0.4.28 id_priv->state=7 [....] [ 1207.680362] ice 0000:07:00.1 rocep7s0f1: caller: irdma_create_ah+0x3e/0x70 [irdma] ah_id=0 arp_idx=0 dest_ip=0.0.0.0 destMAC=00:00:64:ca:b7:52 ipvalid=1 raw=0000:0000:0000:0000:0000:ffff:0000:0000 [ 1207.682077] ice 0000:07:00.1 rocep7s0f1: abnormal ae_id = 0x401 bool qp=1 qp_id = 1, ae_src=5 [ 1207.691657] infiniband rocep7s0f1: Fatal error (1) on MAD QP (1)
Fix this by updating the CMA destination address when the ULP calls a resolve address with the CM state already bound.
--- drivers/infiniband/core/cma.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/core/cma.c +2 -0
@@ -4062,6 +4062,8 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv, RDMA_CM_ADDR_QUERY)))return -EINVAL ; + }else { +memcpy (cma_dst_addr (id_priv), dst_addr,rdma_addr_size (dst_addr)); }if (cma_family (id_priv) != dst_addr->sa_family) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 109/239 RDMA/mthca: Fix crash when polling CQ for shared QPs
In reply to Greg Kroah-HartmanFrom: Thomas Bogendoerfer <[email protected]>
[ Upstream commit dc52aadbc1849cbe3fcf6bc54d35f6baa396e0a1 ]
Commit 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP") introduced a new struct mthca_sqp which doesn't contain struct mthca_qp any longer. Placing a pointer of this new struct into qptable leads to crashes, because mthca_poll_one() expects a qp pointer. Fix this by putting the correct pointer into qptable.
--- drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mthca/mthca_qp.c +1 -1
@@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,if (mthca_array_get (&dev->qp_table.qp, mqpn)) err = -EBUSY ;else -mthca_array_set (&dev->qp_table.qp, mqpn, qp->sqp); +mthca_array_set (&dev->qp_table.qp, mqpn, qp);spin_unlock_irq (&dev->qp_table.lock);if (err)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 110/239 RDMA/bnxt_re: Prevent handling any completions after qp destroy
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit b5bbc6551297447d3cca55cf907079e206e9cd82 ]
HW may generate completions that indicates QP is destroyed. Driver should not be scheduling any more completion handlers for this QP, after the QP is destroyed. Since CQs are active during the QP destroy, driver may still schedule completion handlers. This can cause a race where the destroy_cq and poll_cq running simultaneously.
Snippet of kernel panic while doing bnxt_re driver load unload in loop. This indicates a poll after the CQ is freed.
[77786.481636] Call Trace: [77786.481640] <TASK> [77786.481644] bnxt_re_poll_cq+0x14a/0x620 [bnxt_re] [77786.481658] ? kvm_clock_read+0x14/0x30 [77786.481693] __ib_process_cq+0x57/0x190 [ib_core] [77786.481728] ib_cq_poll_work+0x26/0x80 [ib_core] [77786.481761] process_one_work+0x1e5/0x3f0 [77786.481768] worker_thread+0x50/0x3a0 [77786.481785] ? __pfx_worker_thread+0x10/0x10 [77786.481790] kthread+0xe2/0x110 [77786.481794] ? __pfx_kthread+0x10/0x10 [77786.481797] ret_from_fork+0x2c/0x50
To avoid this, complete all completion handlers before returning the destroy QP. If free_cq is called soon after destroy_qp, IB stack will cancel the CQ work before invoking the destroy_cq verb and this will prevent any race mentioned.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 ++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 18 ++++++++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 + 3 files changed, 31 insertions(+)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +12 -0
@@ -797,7 +797,10 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)int bnxt_re_destroy_qp (struct ib_qp *ib_qp,struct ib_udata *udata) { struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); +struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;struct bnxt_re_dev *rdev = qp->rdev; +struct bnxt_qplib_nq *scq_nq =NULL ; +struct bnxt_qplib_nq *rcq_nq =NULL ;unsigned int flags;int rc;
@@ -831,6 +834,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)ib_umem_release (qp->rumem);ib_umem_release (qp->sumem); +/* Flush all the entries of notification queue associated with +* given qp. +*/ + scq_nq = qplib_qp->scq->nq; + rcq_nq = qplib_qp->rcq->nq; +bnxt_re_synchronize_nq (scq_nq); +if (scq_nq != rcq_nq) +bnxt_re_synchronize_nq (rcq_nq); +return 0 ; }
drivers/infiniband/hw/bnxt_re/qplib_fp.c +18 -0
@@ -381,6 +381,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)spin_unlock_bh (&hwq->lock); } +/* bnxt_re_synchronize_nq - self polling notification queue. +* @nq - notification queue pointer +* +* This function will start polling entries of a given notification queue +* for all pending entries. +* This function is useful to synchronize notification entries while resources +* are going away. +*/ + +void bnxt_re_synchronize_nq (struct bnxt_qplib_nq *nq) +{ +int budget = nq->budget; + + nq->budget = nq->hwq.max_elements; +bnxt_qplib_service_nq (&nq->nq_tasklet); + nq->budget = budget; +} +static irqreturn_t bnxt_qplib_nq_irq (int irq,void *dev_instance) {struct bnxt_qplib_nq *nq = dev_instance;
drivers/infiniband/hw/bnxt_re/qplib_fp.h +1 -0
@@ -553,6 +553,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,struct bnxt_qplib_cqe *cqe, int num_cqes);void bnxt_qplib_flush_cqn_wq (struct bnxt_qplib_qp *qp); +void bnxt_re_synchronize_nq (struct bnxt_qplib_nq *nq);static inline void *bnxt_qplib_get_swqe (struct bnxt_qplib_q *que,u32 *swq_idx) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 111/239 RDMA/bnxt_re: Enhance the existing functions that wait for FW responses
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit 8cf1d12ad56beb73d2439ccf334b7148e71de58e ]
Use jiffies based timewait instead of counting iteration for commands that block for FW response.
Also add a poll routine for control path commands. This is for polling completion if the waiting commands timeout. This avoids cases where the driver misses completion interrupts.
Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 65 +++++++++++++++++----- 1 file changed, 51 insertions(+), 14 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +51 -14
@@ -53,37 +53,74 @@static void bnxt_qplib_service_creq (struct tasklet_struct *t); -/* Hardware communication channel */ +/** +* __wait_for_resp - Don't hold the cpu context and wait for response +* @rcfw - rcfw channel instance of rdev +* @cookie - cookie to track the command +* +* Wait for command completion in sleepable context. +* +* Returns: +* 0 if command is completed by firmware. +* Non zero error code for rest of the case. +*/ static int __wait_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie) {struct bnxt_qplib_cmdq_ctx *cmdq;u16 cbit; -int rc; +int ret; cmdq = &rcfw->cmdq; cbit = cookie % rcfw->cmdq_depth; - rc =wait_event_timeout (cmdq->waitq, - !test_bit (cbit, cmdq->cmdq_bitmap), -msecs_to_jiffies (RCFW_CMD_WAIT_TIME_MS )); -return rc ?0 : -ETIMEDOUT ; + +do { +/* Non zero means command completed */ + ret =wait_event_timeout (cmdq->waitq, + !test_bit (cbit, cmdq->cmdq_bitmap), +msecs_to_jiffies (10000 )); + +if (!test_bit (cbit, cmdq->cmdq_bitmap)) +return 0 ; + +bnxt_qplib_service_creq (&rcfw->creq.creq_tasklet); + +if (!test_bit (cbit, cmdq->cmdq_bitmap)) +return 0 ; + + }while (true); }; +/** +* __block_for_resp - hold the cpu context and wait for response +* @rcfw - rcfw channel instance of rdev +* @cookie - cookie to track the command +* +* This function will hold the cpu (non-sleepable context) and +* wait for command completion. Maximum holding interval is 8 second. +* +* Returns: +* -ETIMEOUT if command is not completed in specific time interval. +* 0 if command is completed by firmware. +*/ static int __block_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie) { -u32 count =RCFW_BLOCKED_CMD_WAIT_COUNT ; -struct bnxt_qplib_cmdq_ctx *cmdq; +struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq; +unsigned long issue_time =0 ;u16 cbit; - cmdq = &rcfw->cmdq; cbit = cookie % rcfw->cmdq_depth; -if (!test_bit (cbit, cmdq->cmdq_bitmap)) - goto done; + issue_time = jiffies; +do {udelay (1 ); +bnxt_qplib_service_creq (&rcfw->creq.creq_tasklet); - }while (test_bit (cbit, cmdq->cmdq_bitmap) && --count); -done: -return count ?0 : -ETIMEDOUT ; +if (!test_bit (cbit, cmdq->cmdq_bitmap)) +return 0 ; + + }while (time_before (jiffies, issue_time + (8 *HZ ))); + +return -ETIMEDOUT ; }; static int __send_message(struct bnxt_qplib_rcfw *rcfw,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 112/239 RDMA/bnxt_re: Avoid the command wait if firmware is inactive
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit 3022cc15119733cebaef05feddb5d87b9e401c0e ]
Add a check to avoid waiting if driver already detects a FW timeout. Return success for resource destroy in case the device is detached. Add helper function to map timeout error code to success.
Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 52 ++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +48 -4
@@ -53,10 +53,47 @@static void bnxt_qplib_service_creq (struct tasklet_struct *t); +/** +* bnxt_qplib_map_rc - map return type based on opcode +* @opcode - roce slow path opcode +* +* In some cases like firmware halt is detected, the driver is supposed to +* remap the error code of the timed out command. +* +* It is not safe to assume hardware is really inactive so certain opcodes +* like destroy qp etc are not safe to be returned success, but this function +* will be called when FW already reports a timeout. This would be possible +* only when FW crashes and resets. This will clear all the HW resources. +* +* Returns: +* 0 to communicate success to caller. +* Non zero error code to communicate failure to caller. +*/ +static int bnxt_qplib_map_rc (u8 opcode) +{ +switch (opcode) { +case CMDQ_BASE_OPCODE_DESTROY_QP : +case CMDQ_BASE_OPCODE_DESTROY_SRQ : +case CMDQ_BASE_OPCODE_DESTROY_CQ : +case CMDQ_BASE_OPCODE_DEALLOCATE_KEY : +case CMDQ_BASE_OPCODE_DEREGISTER_MR : +case CMDQ_BASE_OPCODE_DELETE_GID : +case CMDQ_BASE_OPCODE_DESTROY_QP1 : +case CMDQ_BASE_OPCODE_DESTROY_AH : +case CMDQ_BASE_OPCODE_DEINITIALIZE_FW : +case CMDQ_BASE_OPCODE_MODIFY_ROCE_CC : +case CMDQ_BASE_OPCODE_SET_LINK_AGGR_MODE : +return 0 ; +default : +return -ETIMEDOUT ; + } +} +/** * __wait_for_resp - Don't hold the cpu context and wait for response * @rcfw - rcfw channel instance of rdev * @cookie - cookie to track the command +* @opcode - rcfw submitted for given opcode * * Wait for command completion in sleepable context. *
@@ -64,7 +101,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t);* 0 if command is completed by firmware. * Non zero error code for rest of the case. */ -static int __wait_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie) +static int __wait_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie,u8 opcode) {struct bnxt_qplib_cmdq_ctx *cmdq;u16 cbit;
@@ -74,6 +111,9 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) cbit = cookie % rcfw->cmdq_depth; do { + if (test_bit(ERR_DEVICE_DETACHED, &cmdq->flags)) + return bnxt_qplib_map_rc(opcode); + /* Non zero means command completed */ ret = wait_event_timeout(cmdq->waitq, !test_bit(cbit, cmdq->cmdq_bitmap),
@@ -94,6 +134,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)* __block_for_resp - hold the cpu context and wait for response * @rcfw - rcfw channel instance of rdev * @cookie - cookie to track the command +* @opcode - rcfw submitted for given opcode * * This function will hold the cpu (non-sleepable context) and * wait for command completion. Maximum holding interval is 8 second.
@@ -102,7 +143,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)* -ETIMEOUT if command is not completed in specific time interval. * 0 if command is completed by firmware. */ -static int __block_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie) +static int __block_for_resp (struct bnxt_qplib_rcfw *rcfw,u16 cookie,u8 opcode) {struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;unsigned long issue_time =0 ;
@@ -112,6 +153,9 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) issue_time = jiffies; do { + if (test_bit(ERR_DEVICE_DETACHED, &cmdq->flags)) + return bnxt_qplib_map_rc(opcode); + udelay(1); bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
@@ -267,9 +311,9 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, }while (retry_cnt--);if (msg->block) - rc =__block_for_resp (rcfw, cookie); + rc =__block_for_resp (rcfw, cookie, opcode);else - rc =__wait_for_resp (rcfw, cookie); + rc =__wait_for_resp (rcfw, cookie, opcode);if (rc) {/* timed out */ dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n",
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 113/239 RDMA/bnxt_re: use shadow qd while posting non blocking rcfw command
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit 65288a22ddd81422a2a2a10c15df976a5332e41b ]
Whenever there is a fast path IO and create/destroy resources from the slow path is happening in parallel, we may notice high latency of slow path command completion.
Introduces a shadow queue depth to prevent the outstanding requests to the FW. Driver will not allow more than #RCFW_CMD_NON_BLOCKING_SHADOW_QD non-blocking commands to the Firmware.
Shadow queue depth is a soft limit only for non-blocking commands. Blocking commands will be posted to the firmware as long as there is a free slot.
Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 60 +++++++++++++++++++++- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 3 ++ 2 files changed, 61 insertions(+), 2 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +58 -2
@@ -281,8 +281,21 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,return 0 ; } -int bnxt_qplib_rcfw_send_message (struct bnxt_qplib_rcfw *rcfw, -struct bnxt_qplib_cmdqmsg *msg) +/** +* __bnxt_qplib_rcfw_send_message - qplib interface to send +* and complete rcfw command. +* @rcfw - rcfw channel instance of rdev +* @msg - qplib message internal +* +* This function does not account shadow queue depth. It will send +* all the command unconditionally as long as send queue is not full. +* +* Returns: +* 0 if command completed by firmware. +* Non zero if the command is not completed by firmware. +*/ +static int __bnxt_qplib_rcfw_send_message (struct bnxt_qplib_rcfw *rcfw, +struct bnxt_qplib_cmdqmsg *msg) {struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;u16 cookie;
@@ -331,6 +344,48 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,return rc; } + +/** +* bnxt_qplib_rcfw_send_message - qplib interface to send +* and complete rcfw command. +* @rcfw - rcfw channel instance of rdev +* @msg - qplib message internal +* +* Driver interact with Firmware through rcfw channel/slow path in two ways. +* a. Blocking rcfw command send. In this path, driver cannot hold +* the context for longer period since it is holding cpu until +* command is not completed. +* b. Non-blocking rcfw command send. In this path, driver can hold the +* context for longer period. There may be many pending command waiting +* for completion because of non-blocking nature. +* +* Driver will use shadow queue depth. Current queue depth of 8K +* (due to size of rcfw message there can be actual ~4K rcfw outstanding) +* is not optimal for rcfw command processing in firmware. +* +* Restrict at max #RCFW_CMD_NON_BLOCKING_SHADOW_QD Non-Blocking rcfw commands. +* Allow all blocking commands until there is no queue full. +* +* Returns: +* 0 if command completed by firmware. +* Non zero if the command is not completed by firmware. +*/ +int bnxt_qplib_rcfw_send_message (struct bnxt_qplib_rcfw *rcfw, +struct bnxt_qplib_cmdqmsg *msg) +{ +int ret; + +if (!msg->block) { +down (&rcfw->rcfw_inflight); + ret =__bnxt_qplib_rcfw_send_message (rcfw, msg); +up (&rcfw->rcfw_inflight); + }else { + ret =__bnxt_qplib_rcfw_send_message (rcfw, msg); + } + +return ret; +} +/* Completions */ static int bnxt_qplib_process_func_event (struct bnxt_qplib_rcfw *rcfw,struct creq_func_event *func_event)
@@ -937,6 +992,7 @@ int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,return rc; } +sema_init (&rcfw->rcfw_inflight,RCFW_CMD_NON_BLOCKING_SHADOW_QD );bnxt_qplib_start_rcfw (rcfw);return 0 ;
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +3 -0
@@ -67,6 +67,8 @@ static inline void bnxt_qplib_rcfw_cmd_prep(struct cmdq_base *req, req->cmd_size = cmd_size; } +/* Shadow queue depth for non blocking command */ +#define RCFW_CMD_NON_BLOCKING_SHADOW_QD 64#define RCFW_CMD_WAIT_TIME_MS 20000/* 20 Seconds timeout */ /* CMDQ elements */
@@ -201,6 +203,7 @@ struct bnxt_qplib_rcfw {u64 oos_prev;u32 init_oos_stats;u32 cmdq_depth; +struct semaphore rcfw_inflight; };struct bnxt_qplib_cmdqmsg {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 114/239 RDMA/bnxt_re: Simplify the function that sends the FW commands
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit 159cf95e42a7ca7375646fab82c0056cbb71f9e9 ]
- Use __send_message_basic_sanity helper function.
- Do not retry posting same command if there is a queue full detection.
- ENXIO is used to indicate controller recovery.
- In the case of ERR_DEVICE_DETACHED state, the driver should not post commands to the firmware, but also return fabricated written code.
Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 125 +++++++++++---------- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 22 ++++ 2 files changed, 86 insertions(+), 61 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +64 -61
@@ -170,34 +170,22 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie, u8 opcode)static int __send_message (struct bnxt_qplib_rcfw *rcfw,struct bnxt_qplib_cmdqmsg *msg) { -struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq; -struct bnxt_qplib_hwq *hwq = &cmdq->hwq; +u32 bsize, opcode, free_slots, required_slots; +struct bnxt_qplib_cmdq_ctx *cmdq;struct bnxt_qplib_crsqe *crsqe;struct bnxt_qplib_cmdqe *cmdqe; +struct bnxt_qplib_hwq *hwq;u32 sw_prod, cmdq_prod;struct pci_dev *pdev;unsigned long flags; -u32 bsize, opcode;u16 cookie, cbit;u8 *preq; + cmdq = &rcfw->cmdq; + hwq = &cmdq->hwq; pdev = rcfw->pdev; opcode =__get_cmdq_base_opcode (msg->req, msg->req_sz); -if (!test_bit (FIRMWARE_INITIALIZED_FLAG , &cmdq->flags) && - (opcode !=CMDQ_BASE_OPCODE_QUERY_FUNC && - opcode !=CMDQ_BASE_OPCODE_INITIALIZE_FW && - opcode !=CMDQ_BASE_OPCODE_QUERY_VERSION )) { -dev_err (&pdev->dev, -"RCFW not initialized, reject opcode 0x%x\n" , opcode); -return -EINVAL ; - } - -if (test_bit (FIRMWARE_INITIALIZED_FLAG , &cmdq->flags) && - opcode ==CMDQ_BASE_OPCODE_INITIALIZE_FW ) { -dev_err (&pdev->dev,"RCFW already initialized!\n" ); -return -EINVAL ; - }if (test_bit (FIRMWARE_TIMED_OUT , &cmdq->flags))return -ETIMEDOUT ;
@@ -206,40 +194,37 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,* cmdqe */ spin_lock_irqsave (&hwq->lock, flags); -if (msg->req->cmd_size >=HWQ_FREE_SLOTS (hwq)) { -dev_err (&pdev->dev,"RCFW: CMDQ is full!\n" ); + required_slots =bnxt_qplib_get_cmd_slots (msg->req); + free_slots =HWQ_FREE_SLOTS (hwq); + cookie = cmdq->seq_num &RCFW_MAX_COOKIE_VALUE ; + cbit = cookie % rcfw->cmdq_depth; + +if (required_slots >= free_slots || +test_bit (cbit, cmdq->cmdq_bitmap)) { +dev_info_ratelimited (&pdev->dev, +"CMDQ is full req/free %d/%d!" , + required_slots, free_slots);spin_unlock_irqrestore (&hwq->lock, flags);return -EAGAIN ; } - - - cookie = cmdq->seq_num &RCFW_MAX_COOKIE_VALUE ; - cbit = cookie % rcfw->cmdq_depth;if (msg->block) cookie |=RCFW_CMD_IS_BLOCKING ; -set_bit (cbit, cmdq->cmdq_bitmap);__set_cmdq_base_cookie (msg->req, msg->req_sz,cpu_to_le16 (cookie)); crsqe = &rcfw->crsqe_tbl[cbit]; -if (crsqe->resp) { -spin_unlock_irqrestore (&hwq->lock, flags); -return -EBUSY ; - } - -/* change the cmd_size to the number of 16byte cmdq unit. -* req->cmd_size is modified here -*/ bsize =bnxt_qplib_set_cmd_slots (msg->req); - -memset (msg->resp,0 ,sizeof (*msg->resp)); + crsqe->free_slots = free_slots; crsqe->resp = (struct creq_qp_event *)msg->resp; crsqe->resp->cookie =cpu_to_le16 (cookie); crsqe->req_size =__get_cmdq_base_cmd_size (msg->req, msg->req_sz);if (__get_cmdq_base_resp_size (msg->req, msg->req_sz) && msg->sb) {struct bnxt_qplib_rcfw_sbuf *sbuf = msg->sb; -__set_cmdq_base_resp_addr (msg->req, msg->req_sz,cpu_to_le64 (sbuf->dma_addr)); + +__set_cmdq_base_resp_addr (msg->req, msg->req_sz, +cpu_to_le64 (sbuf->dma_addr));__set_cmdq_base_resp_size (msg->req, msg->req_sz, -ALIGN (sbuf->size,BNXT_QPLIB_CMDQE_UNITS )); +ALIGN (sbuf->size, +BNXT_QPLIB_CMDQE_UNITS )); } preq = (u8 *)msg->req;
@@ -247,11 +232,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,/* Locate the next cmdq slot */ sw_prod =HWQ_CMP (hwq->prod, hwq); cmdqe =bnxt_qplib_get_qe (hwq, sw_prod,NULL ); -if (!cmdqe) { -dev_err (&pdev->dev, -"RCFW request failed with no cmdqe!\n" ); - goto done; - }/* Copy a segment of the req cmd to the cmdq */ memset (cmdqe,0 ,sizeof (*cmdqe));memcpy (cmdqe, preq,min_t (u32, bsize,sizeof (*cmdqe)));
@@ -275,12 +255,43 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,wmb ();writel (cmdq_prod, cmdq->cmdq_mbox.prod);writel (RCFW_CMDQ_TRIG_VAL , cmdq->cmdq_mbox.db); -done:spin_unlock_irqrestore (&hwq->lock, flags);/* Return the CREQ response pointer */ return 0 ; } +static int __send_message_basic_sanity (struct bnxt_qplib_rcfw *rcfw, +struct bnxt_qplib_cmdqmsg *msg) +{ +struct bnxt_qplib_cmdq_ctx *cmdq; +u32 opcode; + + cmdq = &rcfw->cmdq; + opcode =__get_cmdq_base_opcode (msg->req, msg->req_sz); + +/* Prevent posting if f/w is not in a state to process */ +if (test_bit (ERR_DEVICE_DETACHED , &rcfw->cmdq.flags)) +return -ENXIO ; + +if (test_bit (FIRMWARE_INITIALIZED_FLAG , &cmdq->flags) && + opcode ==CMDQ_BASE_OPCODE_INITIALIZE_FW ) { +dev_err (&rcfw->pdev->dev,"QPLIB: RCFW already initialized!" ); +return -EINVAL ; + } + +if (!test_bit (FIRMWARE_INITIALIZED_FLAG , &cmdq->flags) && + (opcode !=CMDQ_BASE_OPCODE_QUERY_FUNC && + opcode !=CMDQ_BASE_OPCODE_INITIALIZE_FW && + opcode !=CMDQ_BASE_OPCODE_QUERY_VERSION )) { +dev_err (&rcfw->pdev->dev, +"QPLIB: RCFW not initialized, reject opcode 0x%x" , + opcode); +return -EOPNOTSUPP ; + } + +return 0 ; +} +/** * __bnxt_qplib_rcfw_send_message - qplib interface to send * and complete rcfw command.
@@ -299,29 +310,21 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, {struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;u16 cookie; -u8 opcode, retry_cnt =0xFF ;int rc =0 ; +u8 opcode; -/* Prevent posting if f/w is not in a state to process */ -if (test_bit (ERR_DEVICE_DETACHED , &rcfw->cmdq.flags)) -return 0 ; + opcode =__get_cmdq_base_opcode (msg->req, msg->req_sz); -do { - opcode =__get_cmdq_base_opcode (msg->req, msg->req_sz); - rc =__send_message (rcfw, msg); - cookie =le16_to_cpu (__get_cmdq_base_cookie (msg->req, msg->req_sz)) & -RCFW_MAX_COOKIE_VALUE ; -if (!rc) -break ; -if (!retry_cnt || (rc != -EAGAIN && rc != -EBUSY )) { -/* send failed */ -dev_err (&rcfw->pdev->dev,"cmdq[%#x]=%#x send failed\n" , - cookie, opcode); -return rc; - } - msg->block ?mdelay (1 ) :usleep_range (500 ,1000 ); + rc =__send_message_basic_sanity (rcfw, msg); +if (rc) +return rc == -ENXIO ?bnxt_qplib_map_rc (opcode) : rc; + + rc =__send_message (rcfw, msg); +if (rc) +return rc; - }while (retry_cnt--); + cookie =le16_to_cpu (__get_cmdq_base_cookie (msg->req, msg->req_sz)) + &RCFW_MAX_COOKIE_VALUE ;if (msg->block) rc =__block_for_resp (rcfw, cookie, opcode);
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +22 -0
@@ -91,6 +91,26 @@ static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)return (bnxt_qplib_cmdqe_npages (depth) *PAGE_SIZE ); } +/* Get the number of command units required for the req. The +* function returns correct value only if called before +* setting using bnxt_qplib_set_cmd_slots +*/ +static inline u32 bnxt_qplib_get_cmd_slots (struct cmdq_base *req) +{ +u32 cmd_units =0 ; + +if (HAS_TLV_HEADER (req)) { +struct roce_tlv *tlv_req = (struct roce_tlv *)req; + + cmd_units = tlv_req->total_size; + }else { + cmd_units = (req->cmd_size +BNXT_QPLIB_CMDQE_UNITS -1 ) / +BNXT_QPLIB_CMDQE_UNITS ; + } + +return cmd_units; +} +static inline u32 bnxt_qplib_set_cmd_slots (struct cmdq_base *req) {u32 cmd_byte =0 ;
@@ -134,6 +154,8 @@ typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *);struct bnxt_qplib_crsqe {struct creq_qp_event *resp;u32 req_size; +/* Free slots at the time of submission */ +u32 free_slots; };struct bnxt_qplib_rcfw_sbuf {
Signature · 1 line
2.40.1