From 0ef3f4258c9ce8afad145a98b99b2009baa314f2 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 15 Jan 2023 18:58:56 -0500 Subject: [PATCH] Fixes for 6.1 Signed-off-by: Sasha Levin --- ...-fix-the-size-of-the-parameter-to-co.patch | 58 ++ ...ix-possible-null-pointer-dereference.patch | 44 ++ ...ake-sure-to-stop-endpoints-before-cl.patch | 45 ++ ...elax-hw-constraints-for-implicit-fb-.patch | 55 ++ ...c-intel-fix-sof-nau8825-link-failure.patch | 40 ++ ...of-nau8825-fix-module-alias-overflow.patch | 119 ++++ ...au8825-support-rt1015p-speaker-ampli.patch | 110 +++ ...ilding-apq8016-machine-driver-withou.patch | 486 +++++++++++++ ...wrong-outputs-volume-after-power-rea.patch | 69 ++ ...a-gendisk-to-blk_crypto_sysfs_-un-re.patch | 109 +++ ...srcu_struct-used-for-quiescing-to-th.patch | 358 ++++++++++ ...rious-might_sleep-from-blk_put_queue.patch | 62 ++ ...ctor-out-a-blk_debugfs_remove-helper.patch | 61 ++ ...rror-unwinding-in-blk_register_queue.patch | 101 +++ ...lk_put_queue-as-potentially-blocking.patch | 52 ++ ...request_queue-refcounting-from-sysfs.patch | 400 +++++++++++ ...ake-sure-we-return-pages-to-the-pool.patch | 52 ++ ...mdgpu-fix-potential-null-dereference.patch | 48 ++ ...memory-leak-in-msm_mdss_parse_data_b.patch | 52 ++ ...msm-dpu-fix-some-kernel-doc-comments.patch | 54 ++ ...tor-resource-manager-s-hashtable-to-.patch | 203 ++++++ ...tor-resource-validation-hashtable-to.patch | 382 ++++++++++ ...tor-ttm-reference-object-hashtable-t.patch | 324 +++++++++ ...remove-rcu-locks-from-user-resources.patch | 592 ++++++++++++++++ ...m-vmwgfx-remove-ttm-object-hashtable.patch | 161 +++++ .../drm-vmwgfx-remove-vmwgfx_hashtab.patch | 462 ++++++++++++ ...vmwgfx-write-the-driver-id-registers.patch | 102 +++ ...fi-fix-null-deref-in-init-error-path.patch | 56 ++ ...o-avoid-checking-for-a-failed-search.patch | 112 +++ .../gro-take-care-of-dodgy-packets.patch | 48 ++ .../hvc-xen-lock-console-list-traversal.patch | 186 +++++ queue-6.1/ice-add-check-for-kzalloc.patch | 73 ++ ...al-memory-leak-in-ice_gnss_tty_write.patch | 39 + ...a-between-two-synchronized-end-point.patch | 97 +++ ...io_uring-lock-overflowing-for-iopoll.patch | 63 ++ ...tempt-request-issue-after-racy-poll-.patch | 119 ++++ ...-allow-building-spi-intel-standalone.patch | 61 ++ ...part-fix-__udivdi3-undefined-on-mips.patch | 47 ++ ...ng-use-of-rss-size-during-vf-rss-con.patch | 42 ++ ...k-for-ptp-to-be-enabled-in-lan966x_p.patch | 42 ++ ...ttr-pointer-validity-before-derefere.patch | 38 + ...-fix-command-stats-access-after-free.patch | 108 +++ ...x-ptp-max-frequency-adjustment-range.patch | 41 ++ ...-support-encap-rules-with-gbp-option.patch | 40 ++ ...csec-possible-null-dereference-when-.patch | 57 ++ ...csec-ssci-attribute-handling-in-offl.patch | 73 ++ ...block-pkey-interfaces-with-less-rx-q.patch | 55 ++ ...block-queue-count-configuration-when.patch | 184 +++++ ...fix-child-pkey-interface-stats-on-rx.patch | 43 ++ ...p-mod-hdr-actions-after-mod-hdr-allo.patch | 56 ++ ...-dev-is-present-for-fix-features-ndo.patch | 40 ++ ...ls-fix-warning-during-failed-attribu.patch | 109 +++ ...or-out_urb-s-completion-in-pn533_usb.patch | 129 ++++ ...sd-add-an-nfsd_file_fsync-tracepoint.patch | 93 +++ ..._file_gc-flag-to-enable-nfsd_file-ga.patch | 266 +++++++ ...g-of-cached-open-files-in-nfsd4_open.patch | 273 +++++++ ...-the-target-nfsd_file-to-nfsd_commit.patch | 153 ++++ ...pages_flushed-statistic-from-filecac.patch | 76 ++ queue-6.1/nfsd-reorganize-filecache.c.patch | 240 +++++++ ...-nfsv4-close-should-release-an-nfsd_.patch | 96 +++ ...nfsd-rework-refcounting-in-filecache.patch | 669 ++++++++++++++++++ ...-lmac-config-in-cgx_lmac_rx_tx_enabl.patch | 57 ++ ...-resource-leakage-in-vf-driver-unbin.patch | 39 + ...build-properly-guard-libbpf-includes.patch | 80 +++ ...t-field-node-in-evsel__process_alloc.patch | 111 +++ ...perf-kmem-support-legacy-tracepoints.patch | 106 +++ ...-aggregator-add-missing-call-to-ssam.patch | 43 ++ ...d-fix-refcount-leak-in-amd_pmc_probe.patch | 40 ++ ...or-da9211-use-irq-handler-when-ready.patch | 66 ++ ...disable-detection-of-chip-version-36.patch | 43 ++ ...rch_scale_freq_tick-on-tickless-syst.patch | 56 ++ ...refer-config_scsi_mpi3mr-in-makefile.patch | 44 ++ ...-swiotlb-bounce-buffer-leak-in-confi.patch | 51 ++ ...un-suspend-ssu-enter-hibern8-fail-re.patch | 79 +++ ..._tos_ttl_inherit.sh-ensure-environme.patch | 113 +++ ..._tos_ttl_inherit.sh-run-tests-in-the.patch | 309 ++++++++ ..._tos_ttl_inherit.sh-set-ipv6-address.patch | 52 ++ queue-6.1/series | 81 +++ ...iatek-remove-the-dwmac_fix_mac_speed.patch | 81 +++ ...ted-link-reset-due-to-discovery-mess.patch | 111 +++ ...-the-o_-fcntl-open-macro-definitions.patch | 49 ++ ...tore-mips-branch-ordering-in-the-_st.patch | 80 +++ 82 files changed, 10116 insertions(+) create mode 100644 queue-6.1/af_unix-selftest-fix-the-size-of-the-parameter-to-co.patch create mode 100644 queue-6.1/alsa-usb-audio-fix-possible-null-pointer-dereference.patch create mode 100644 queue-6.1/alsa-usb-audio-make-sure-to-stop-endpoints-before-cl.patch create mode 100644 queue-6.1/alsa-usb-audio-relax-hw-constraints-for-implicit-fb-.patch create mode 100644 queue-6.1/asoc-intel-fix-sof-nau8825-link-failure.patch create mode 100644 queue-6.1/asoc-intel-sof-nau8825-fix-module-alias-overflow.patch create mode 100644 queue-6.1/asoc-intel-sof_nau8825-support-rt1015p-speaker-ampli.patch create mode 100644 queue-6.1/asoc-qcom-fix-building-apq8016-machine-driver-withou.patch create mode 100644 queue-6.1/asoc-wm8904-fix-wrong-outputs-volume-after-power-rea.patch create mode 100644 queue-6.1/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch create mode 100644 queue-6.1/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch create mode 100644 queue-6.1/block-drop-spurious-might_sleep-from-blk_put_queue.patch create mode 100644 queue-6.1/block-factor-out-a-blk_debugfs_remove-helper.patch create mode 100644 queue-6.1/block-fix-error-unwinding-in-blk_register_queue.patch create mode 100644 queue-6.1/block-mark-blk_put_queue-as-potentially-blocking.patch create mode 100644 queue-6.1/block-untangle-request_queue-refcounting-from-sysfs.patch create mode 100644 queue-6.1/bnxt-make-sure-we-return-pages-to-the-pool.patch create mode 100644 queue-6.1/drm-amdgpu-fix-potential-null-dereference.patch create mode 100644 queue-6.1/drm-msm-dpu-fix-memory-leak-in-msm_mdss_parse_data_b.patch create mode 100644 queue-6.1/drm-msm-dpu-fix-some-kernel-doc-comments.patch create mode 100644 queue-6.1/drm-vmwgfx-refactor-resource-manager-s-hashtable-to-.patch create mode 100644 queue-6.1/drm-vmwgfx-refactor-resource-validation-hashtable-to.patch create mode 100644 queue-6.1/drm-vmwgfx-refactor-ttm-reference-object-hashtable-t.patch create mode 100644 queue-6.1/drm-vmwgfx-remove-rcu-locks-from-user-resources.patch create mode 100644 queue-6.1/drm-vmwgfx-remove-ttm-object-hashtable.patch create mode 100644 queue-6.1/drm-vmwgfx-remove-vmwgfx_hashtab.patch create mode 100644 queue-6.1/drm-vmwgfx-write-the-driver-id-registers.patch create mode 100644 queue-6.1/efi-fix-null-deref-in-init-error-path.patch create mode 100644 queue-6.1/gro-avoid-checking-for-a-failed-search.patch create mode 100644 queue-6.1/gro-take-care-of-dodgy-packets.patch create mode 100644 queue-6.1/hvc-xen-lock-console-list-traversal.patch create mode 100644 queue-6.1/ice-add-check-for-kzalloc.patch create mode 100644 queue-6.1/ice-fix-potential-memory-leak-in-ice_gnss_tty_write.patch create mode 100644 queue-6.1/igc-fix-pps-delta-between-two-synchronized-end-point.patch create mode 100644 queue-6.1/io_uring-lock-overflowing-for-iopoll.patch create mode 100644 queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch create mode 100644 queue-6.1/mtd-cfi-allow-building-spi-intel-standalone.patch create mode 100644 queue-6.1/mtd-parsers-scpart-fix-__udivdi3-undefined-on-mips.patch create mode 100644 queue-6.1/net-hns3-fix-wrong-use-of-rss-size-during-vf-rss-con.patch create mode 100644 queue-6.1/net-lan966x-check-for-ptp-to-be-enabled-in-lan966x_p.patch create mode 100644 queue-6.1/net-mlx5-check-attr-pointer-validity-before-derefere.patch create mode 100644 queue-6.1/net-mlx5-fix-command-stats-access-after-free.patch create mode 100644 queue-6.1/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch create mode 100644 queue-6.1/net-mlx5e-don-t-support-encap-rules-with-gbp-option.patch create mode 100644 queue-6.1/net-mlx5e-fix-macsec-possible-null-dereference-when-.patch create mode 100644 queue-6.1/net-mlx5e-fix-macsec-ssci-attribute-handling-in-offl.patch create mode 100644 queue-6.1/net-mlx5e-ipoib-block-pkey-interfaces-with-less-rx-q.patch create mode 100644 queue-6.1/net-mlx5e-ipoib-block-queue-count-configuration-when.patch create mode 100644 queue-6.1/net-mlx5e-ipoib-fix-child-pkey-interface-stats-on-rx.patch create mode 100644 queue-6.1/net-mlx5e-tc-keep-mod-hdr-actions-after-mod-hdr-allo.patch create mode 100644 queue-6.1/net-mlx5e-verify-dev-is-present-for-fix-features-ndo.patch create mode 100644 queue-6.1/net-sched-act_mpls-fix-warning-during-failed-attribu.patch create mode 100644 queue-6.1/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch create mode 100644 queue-6.1/nfsd-add-an-nfsd_file_fsync-tracepoint.patch create mode 100644 queue-6.1/nfsd-add-an-nfsd_file_gc-flag-to-enable-nfsd_file-ga.patch create mode 100644 queue-6.1/nfsd-fix-handling-of-cached-open-files-in-nfsd4_open.patch create mode 100644 queue-6.1/nfsd-pass-the-target-nfsd_file-to-nfsd_commit.patch create mode 100644 queue-6.1/nfsd-remove-the-pages_flushed-statistic-from-filecac.patch create mode 100644 queue-6.1/nfsd-reorganize-filecache.c.patch create mode 100644 queue-6.1/nfsd-revert-nfsd-nfsv4-close-should-release-an-nfsd_.patch create mode 100644 queue-6.1/nfsd-rework-refcounting-in-filecache.patch create mode 100644 queue-6.1/octeontx2-af-fix-lmac-config-in-cgx_lmac_rx_tx_enabl.patch create mode 100644 queue-6.1/octeontx2-pf-fix-resource-leakage-in-vf-driver-unbin.patch create mode 100644 queue-6.1/perf-build-properly-guard-libbpf-includes.patch create mode 100644 queue-6.1/perf-kmem-support-field-node-in-evsel__process_alloc.patch create mode 100644 queue-6.1/perf-kmem-support-legacy-tracepoints.patch create mode 100644 queue-6.1/platform-surface-aggregator-add-missing-call-to-ssam.patch create mode 100644 queue-6.1/platform-x86-amd-fix-refcount-leak-in-amd_pmc_probe.patch create mode 100644 queue-6.1/regulator-da9211-use-irq-handler-when-ready.patch create mode 100644 queue-6.1/revert-r8169-disable-detection-of-chip-version-36.patch create mode 100644 queue-6.1/sched-core-fix-arch_scale_freq_tick-on-tickless-syst.patch create mode 100644 queue-6.1/scsi-mpi3mr-refer-config_scsi_mpi3mr-in-makefile.patch create mode 100644 queue-6.1/scsi-storvsc-fix-swiotlb-bounce-buffer-leak-in-confi.patch create mode 100644 queue-6.1/scsi-ufs-core-wlun-suspend-ssu-enter-hibern8-fail-re.patch create mode 100644 queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-ensure-environme.patch create mode 100644 queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-run-tests-in-the.patch create mode 100644 queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-set-ipv6-address.patch create mode 100644 queue-6.1/stmmac-dwmac-mediatek-remove-the-dwmac_fix_mac_speed.patch create mode 100644 queue-6.1/tipc-fix-unexpected-link-reset-due-to-discovery-mess.patch create mode 100644 queue-6.1/tools-nolibc-fix-the-o_-fcntl-open-macro-definitions.patch create mode 100644 queue-6.1/tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch diff --git a/queue-6.1/af_unix-selftest-fix-the-size-of-the-parameter-to-co.patch b/queue-6.1/af_unix-selftest-fix-the-size-of-the-parameter-to-co.patch new file mode 100644 index 00000000000..71ffd2ccc10 --- /dev/null +++ b/queue-6.1/af_unix-selftest-fix-the-size-of-the-parameter-to-co.patch @@ -0,0 +1,58 @@ +From 9802dc7ce4d550936c03edeb0db440c1bfb8a961 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Jan 2023 04:40:20 +0100 +Subject: af_unix: selftest: Fix the size of the parameter to connect() + +From: Mirsad Goran Todorovac + +[ Upstream commit 7d6ceeb1875cc08dc3d1e558e191434d94840cd5 ] + +Adjust size parameter in connect() to match the type of the parameter, to +fix "No such file or directory" error in selftests/net/af_unix/ +test_oob_unix.c:127. + +The existing code happens to work provided that the autogenerated pathname +is shorter than sizeof (struct sockaddr), which is why it hasn't been +noticed earlier. + +Visible from the trace excerpt: + +bind(3, {sa_family=AF_UNIX, sun_path="unix_oob_453059"}, 110) = 0 +clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa6a6577a10) = 453060 +[pid ] connect(6, {sa_family=AF_UNIX, sun_path="unix_oob_45305"}, 16) = -1 ENOENT (No such file or directory) + +BUG: The filename is trimmed to sizeof (struct sockaddr). + +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: Shuah Khan +Cc: Kuniyuki Iwashima +Cc: Florian Westphal +Reviewed-by: Florian Westphal +Fixes: 314001f0bf92 ("af_unix: Add OOB support") +Signed-off-by: Mirsad Goran Todorovac +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/af_unix/test_unix_oob.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/af_unix/test_unix_oob.c b/tools/testing/selftests/net/af_unix/test_unix_oob.c +index b57e91e1c3f2..532459a15067 100644 +--- a/tools/testing/selftests/net/af_unix/test_unix_oob.c ++++ b/tools/testing/selftests/net/af_unix/test_unix_oob.c +@@ -124,7 +124,7 @@ void producer(struct sockaddr_un *consumer_addr) + + wait_for_signal(pipefd[0]); + if (connect(cfd, (struct sockaddr *)consumer_addr, +- sizeof(struct sockaddr)) != 0) { ++ sizeof(*consumer_addr)) != 0) { + perror("Connect failed"); + kill(0, SIGTERM); + exit(1); +-- +2.35.1 + diff --git a/queue-6.1/alsa-usb-audio-fix-possible-null-pointer-dereference.patch b/queue-6.1/alsa-usb-audio-fix-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..7c3fe91cfe8 --- /dev/null +++ b/queue-6.1/alsa-usb-audio-fix-possible-null-pointer-dereference.patch @@ -0,0 +1,44 @@ +From c60d4354b6e26ceef976bd3769e84c49c7b8da46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Jan 2023 09:53:11 +0100 +Subject: ALSA: usb-audio: Fix possible NULL pointer dereference in + snd_usb_pcm_has_fixed_rate() + +From: Jaroslav Kysela + +[ Upstream commit 92a9c0ad86d47ff4cce899012e355c400f02cfb8 ] + +The subs function argument may be NULL, so do not use it before the NULL check. + +Fixes: 291e9da91403 ("ALSA: usb-audio: Always initialize fixed_rate in snd_usb_find_implicit_fb_sync_format()") +Reported-by: coverity-bot +Link: https://lore.kernel.org/alsa-devel/202301121424.4A79A485@keescook/ +Signed-off-by: Jaroslav Kysela +Link: https://lore.kernel.org/r/20230113085311.623325-1-perex@perex.cz +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/pcm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index 29838000eee0..2c5765cbed2d 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -160,11 +160,12 @@ find_substream_format(struct snd_usb_substream *subs, + bool snd_usb_pcm_has_fixed_rate(struct snd_usb_substream *subs) + { + const struct audioformat *fp; +- struct snd_usb_audio *chip = subs->stream->chip; ++ struct snd_usb_audio *chip; + int rate = -1; + + if (!subs) + return false; ++ chip = subs->stream->chip; + if (!(chip->quirk_flags & QUIRK_FLAG_FIXED_RATE)) + return false; + list_for_each_entry(fp, &subs->fmt_list, list) { +-- +2.35.1 + diff --git a/queue-6.1/alsa-usb-audio-make-sure-to-stop-endpoints-before-cl.patch b/queue-6.1/alsa-usb-audio-make-sure-to-stop-endpoints-before-cl.patch new file mode 100644 index 00000000000..c2bf9bd84b6 --- /dev/null +++ b/queue-6.1/alsa-usb-audio-make-sure-to-stop-endpoints-before-cl.patch @@ -0,0 +1,45 @@ +From e8d205471cae10707410a4d306416a31ac1497d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Jan 2023 18:07:57 +0100 +Subject: ALSA: usb-audio: Make sure to stop endpoints before closing EPs + +From: Takashi Iwai + +[ Upstream commit 0599313e26666e79f6e7fe1450588431b8cb25d5 ] + +At the PCM hw params, we may re-configure the endpoints and it's done +by a temporary EP close followed by re-open. A potential problem +there is that the EP might be already running internally at the PCM +prepare stage; it's seen typically in the playback stream with the +implicit feedback sync. As this stream start isn't tracked by the +core PCM layer, we'd need to stop it explicitly, and that's the +missing piece. + +This patch adds the stop_endpoints() call at snd_usb_hw_params() to +assure the stream stop before closing the EPs. + +Fixes: bf6313a0ff76 ("ALSA: usb-audio: Refactor endpoint management") +Link: https://lore.kernel.org/r/4e509aea-e563-e592-e652-ba44af6733fe@veniogames.com +Link: https://lore.kernel.org/r/20230102170759.29610-2-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/pcm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index d2c652aa1385..535eb95bc9ee 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -527,6 +527,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + if (snd_usb_endpoint_compatible(chip, subs->data_endpoint, + fmt, hw_params)) + goto unlock; ++ if (stop_endpoints(subs, false)) ++ sync_pending_stops(subs); + close_endpoints(chip, subs); + } + +-- +2.35.1 + diff --git a/queue-6.1/alsa-usb-audio-relax-hw-constraints-for-implicit-fb-.patch b/queue-6.1/alsa-usb-audio-relax-hw-constraints-for-implicit-fb-.patch new file mode 100644 index 00000000000..e6bf104580e --- /dev/null +++ b/queue-6.1/alsa-usb-audio-relax-hw-constraints-for-implicit-fb-.patch @@ -0,0 +1,55 @@ +From 50ae6e718898d4d28086dc799abe0741bb634ccd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Jan 2023 18:07:58 +0100 +Subject: ALSA: usb-audio: Relax hw constraints for implicit fb sync + +From: Takashi Iwai + +[ Upstream commit d463ac1acb454fafed58f695cb3067fbf489f3a0 ] + +The fix commit the commit e4ea77f8e53f ("ALSA: usb-audio: Always apply +the hw constraints for implicit fb sync") tried to address the bug +where an incorrect PCM parameter is chosen when two (implicit fb) +streams are set up at the same time. This change had, however, some +side effect: once when the sync endpoint is chosen and set up, this +restriction is applied at the next hw params unless it's freed via hw +free explicitly. + +This patch is a workaround for the problem by relaxing the hw +constraints a bit for the implicit fb sync. We still keep applying +the hw constraints for implicit fb sync, but only when the matching +sync EP is being used by other streams. + +Fixes: e4ea77f8e53f ("ALSA: usb-audio: Always apply the hw constraints for implicit fb sync") +Reported-by: Ruud van Asseldonk +Link: https://lore.kernel.org/r/4e509aea-e563-e592-e652-ba44af6733fe@veniogames.com +Link: https://lore.kernel.org/r/20230102170759.29610-3-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/pcm.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index 535eb95bc9ee..29838000eee0 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -939,8 +939,13 @@ get_sync_ep_from_substream(struct snd_usb_substream *subs) + continue; + /* for the implicit fb, check the sync ep as well */ + ep = snd_usb_get_endpoint(chip, fp->sync_ep); +- if (ep && ep->cur_audiofmt) +- return ep; ++ if (ep && ep->cur_audiofmt) { ++ /* ditto, if the sync (data) ep is used by others, ++ * this stream is restricted by the sync ep ++ */ ++ if (ep != subs->sync_endpoint || ep->opened > 1) ++ return ep; ++ } + } + return NULL; + } +-- +2.35.1 + diff --git a/queue-6.1/asoc-intel-fix-sof-nau8825-link-failure.patch b/queue-6.1/asoc-intel-fix-sof-nau8825-link-failure.patch new file mode 100644 index 00000000000..bd2e1d43448 --- /dev/null +++ b/queue-6.1/asoc-intel-fix-sof-nau8825-link-failure.patch @@ -0,0 +1,40 @@ +From 53462d345b7d8dabe94ee7dc7702730518175b32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Dec 2022 14:25:48 +0100 +Subject: ASoC: Intel: fix sof-nau8825 link failure + +From: Arnd Bergmann + +[ Upstream commit 63f3d99b7efe4c5404a9388c05780917099cecf4 ] + +The snd-soc-sof_nau8825.ko module fails to link unless the +sof_realtek_common support is also enabled: + +ERROR: modpost: "sof_rt1015p_codec_conf" [sound/soc/intel/boards/snd-soc-sof_nau8825.ko] undefined! +ERROR: modpost: "sof_rt1015p_dai_link" [sound/soc/intel/boards/snd-soc-sof_nau8825.ko] undefined! + +Fixes: 8d0872f6239f ("ASoC: Intel: add sof-nau8825 machine driver") +Signed-off-by: Arnd Bergmann +Acked-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20221221132559.2402341-1-arnd@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig +index aa12d7e3dd2f..ca49cc49c378 100644 +--- a/sound/soc/intel/boards/Kconfig ++++ b/sound/soc/intel/boards/Kconfig +@@ -558,6 +558,7 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH + select SND_SOC_HDAC_HDMI + select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_MAXIM_COMMON ++ select SND_SOC_INTEL_SOF_REALTEK_COMMON + help + This adds support for ASoC machine driver for SOF platforms + with nau8825 codec. +-- +2.35.1 + diff --git a/queue-6.1/asoc-intel-sof-nau8825-fix-module-alias-overflow.patch b/queue-6.1/asoc-intel-sof-nau8825-fix-module-alias-overflow.patch new file mode 100644 index 00000000000..2671a9cd939 --- /dev/null +++ b/queue-6.1/asoc-intel-sof-nau8825-fix-module-alias-overflow.patch @@ -0,0 +1,119 @@ +From 81868dc7b6e837be9c3739f80b615864f8d11758 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Dec 2022 14:24:56 +0100 +Subject: ASoC: Intel: sof-nau8825: fix module alias overflow + +From: Arnd Bergmann + +[ Upstream commit 3e78986a840d59dd27e636eae3f52dc11125c835 ] + +The maximum name length for a platform_device_id entry is 20 characters +including the trailing NUL byte. The sof_nau8825.c file exceeds that, +which causes an obscure error message: + +sound/soc/intel/boards/snd-soc-sof_nau8825.mod.c:35:45: error: illegal character encoding in string literal [-Werror,-Winvalid-source-encoding] +MODULE_ALIAS("platform:adl_max98373_nau8825"); + ^~~~ +include/linux/module.h:168:49: note: expanded from macro 'MODULE_ALIAS' + ^~~~~~ +include/linux/module.h:165:56: note: expanded from macro 'MODULE_INFO' + ^~~~ +include/linux/moduleparam.h:26:47: note: expanded from macro '__MODULE_INFO' + = __MODULE_INFO_PREFIX __stringify(tag) "=" info + +I could not figure out how to make the module handling robust enough +to handle this better, but as a quick fix, using slightly shorter +names that are still unique avoids the build issue. + +Fixes: 8d0872f6239f ("ASoC: Intel: add sof-nau8825 machine driver") +Signed-off-by: Arnd Bergmann +Acked-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20221221132515.2363276-1-arnd@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_nau8825.c | 8 ++++---- + sound/soc/intel/common/soc-acpi-intel-adl-match.c | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c +index 27880224359d..009a41fbefa1 100644 +--- a/sound/soc/intel/boards/sof_nau8825.c ++++ b/sound/soc/intel/boards/sof_nau8825.c +@@ -618,7 +618,7 @@ static const struct platform_device_id board_ids[] = { + + }, + { +- .name = "adl_rt1019p_nau8825", ++ .name = "adl_rt1019p_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1019P_SPEAKER_AMP_PRESENT | +@@ -626,7 +626,7 @@ static const struct platform_device_id board_ids[] = { + SOF_NAU8825_NUM_HDMIDEV(4)), + }, + { +- .name = "adl_max98373_nau8825", ++ .name = "adl_max98373_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_MAX98373_SPEAKER_AMP_PRESENT | +@@ -637,7 +637,7 @@ static const struct platform_device_id board_ids[] = { + }, + { + /* The limitation of length of char array, shorten the name */ +- .name = "adl_mx98360a_nau8825", ++ .name = "adl_mx98360a_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_MAX98360A_SPEAKER_AMP_PRESENT | +@@ -648,7 +648,7 @@ static const struct platform_device_id board_ids[] = { + + }, + { +- .name = "adl_rt1015p_nau8825", ++ .name = "adl_rt1015p_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1015P_SPEAKER_AMP_PRESENT | +diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c +index ce4d8ec86f2c..68b4fa352354 100644 +--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c ++++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c +@@ -474,21 +474,21 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { + }, + { + .id = "10508825", +- .drv_name = "adl_rt1019p_nau8825", ++ .drv_name = "adl_rt1019p_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_rt1019p_amp, + .sof_tplg_filename = "sof-adl-rt1019-nau8825.tplg", + }, + { + .id = "10508825", +- .drv_name = "adl_max98373_nau8825", ++ .drv_name = "adl_max98373_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_max98373_amp, + .sof_tplg_filename = "sof-adl-max98373-nau8825.tplg", + }, + { + .id = "10508825", +- .drv_name = "adl_mx98360a_nau8825", ++ .drv_name = "adl_mx98360a_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_max98360a_amp, + .sof_tplg_filename = "sof-adl-max98360a-nau8825.tplg", +@@ -502,7 +502,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { + }, + { + .id = "10508825", +- .drv_name = "adl_rt1015p_nau8825", ++ .drv_name = "adl_rt1015p_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_rt1015p_amp, + .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg", +-- +2.35.1 + diff --git a/queue-6.1/asoc-intel-sof_nau8825-support-rt1015p-speaker-ampli.patch b/queue-6.1/asoc-intel-sof_nau8825-support-rt1015p-speaker-ampli.patch new file mode 100644 index 00000000000..5b60d8be371 --- /dev/null +++ b/queue-6.1/asoc-intel-sof_nau8825-support-rt1015p-speaker-ampli.patch @@ -0,0 +1,110 @@ +From e3ee72117d71e8c30a11c2d7d425dfbb22b10bd5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 17:19:19 -0600 +Subject: ASoC: Intel: sof_nau8825: support rt1015p speaker amplifier + +From: Brent Lu + +[ Upstream commit 13c459fa37c9f26e9bf884a832dd67598b5c4d3e ] + +Add rt1015p speaker amplifier support with a new board info +'adl_rt1015p_nau8825' which supports NAU8825 on SSP0 and ALC1015Q on +SSP1. + +Reviewed-by: Bard Liao +Signed-off-by: Brent Lu +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20221117231919.112483-1-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Stable-dep-of: 3e78986a840d ("ASoC: Intel: sof-nau8825: fix module alias overflow") +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_nau8825.c | 16 ++++++++++++++++ + .../soc/intel/common/soc-acpi-intel-adl-match.c | 12 ++++++++++++ + 2 files changed, 28 insertions(+) + +diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c +index 5585c217f78d..27880224359d 100644 +--- a/sound/soc/intel/boards/sof_nau8825.c ++++ b/sound/soc/intel/boards/sof_nau8825.c +@@ -47,6 +47,7 @@ + #define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) + #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) + #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) ++#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) + + static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); + +@@ -483,6 +484,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, + } else if (sof_nau8825_quirk & + SOF_MAX98360A_SPEAKER_AMP_PRESENT) { + max_98360a_dai_link(&links[id]); ++ } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { ++ sof_rt1015p_dai_link(&links[id]); + } else { + goto devm_err; + } +@@ -576,6 +579,8 @@ static int sof_audio_probe(struct platform_device *pdev) + + if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) + max_98373_set_codec_conf(&sof_audio_card_nau8825); ++ else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) ++ sof_rt1015p_codec_conf(&sof_audio_card_nau8825); + + if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) + sof_audio_card_nau8825.num_links++; +@@ -642,6 +647,16 @@ static const struct platform_device_id board_ids[] = { + SOF_SSP_BT_OFFLOAD_PRESENT), + + }, ++ { ++ .name = "adl_rt1015p_nau8825", ++ .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | ++ SOF_SPEAKER_AMP_PRESENT | ++ SOF_RT1015P_SPEAKER_AMP_PRESENT | ++ SOF_NAU8825_SSP_AMP(1) | ++ SOF_NAU8825_NUM_HDMIDEV(4) | ++ SOF_BT_OFFLOAD_SSP(2) | ++ SOF_SSP_BT_OFFLOAD_PRESENT), ++ }, + { } + }; + MODULE_DEVICE_TABLE(platform, board_ids); +@@ -663,3 +678,4 @@ MODULE_AUTHOR("Mac Chiang "); + MODULE_LICENSE("GPL"); + MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); + MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); ++MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c +index 9990d5502d26..ce4d8ec86f2c 100644 +--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c ++++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c +@@ -430,6 +430,11 @@ static const struct snd_soc_acpi_codecs adl_rt5682_rt5682s_hp = { + .codecs = {"10EC5682", "RTL5682"}, + }; + ++static const struct snd_soc_acpi_codecs adl_rt1015p_amp = { ++ .num_codecs = 1, ++ .codecs = {"RTL1015"} ++}; ++ + static const struct snd_soc_acpi_codecs adl_rt1019p_amp = { + .num_codecs = 1, + .codecs = {"RTL1019"} +@@ -495,6 +500,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { + .quirk_data = &adl_rt1019p_amp, + .sof_tplg_filename = "sof-adl-rt1019-rt5682.tplg", + }, ++ { ++ .id = "10508825", ++ .drv_name = "adl_rt1015p_nau8825", ++ .machine_quirk = snd_soc_acpi_codec_list, ++ .quirk_data = &adl_rt1015p_amp, ++ .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg", ++ }, + { + .id = "10508825", + .drv_name = "sof_nau8825", +-- +2.35.1 + diff --git a/queue-6.1/asoc-qcom-fix-building-apq8016-machine-driver-withou.patch b/queue-6.1/asoc-qcom-fix-building-apq8016-machine-driver-withou.patch new file mode 100644 index 00000000000..a9410478411 --- /dev/null +++ b/queue-6.1/asoc-qcom-fix-building-apq8016-machine-driver-withou.patch @@ -0,0 +1,486 @@ +From 0aff577b36aaac9c14b90d822d0fda26993b3d65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 31 Dec 2022 12:55:06 +0100 +Subject: ASoC: qcom: Fix building APQ8016 machine driver without SOUNDWIRE + +From: Stephan Gerhold + +[ Upstream commit 0cbf1ecd8c4801ec7566231491f7ad9cec31098b ] + +Older Qualcomm platforms like APQ8016 do not have hardware support for +SoundWire, so kernel configurations made specifically for those platforms +will usually not have CONFIG_SOUNDWIRE enabled. + +Unfortunately commit 8d89cf6ff229 ("ASoC: qcom: cleanup and fix +dependency of QCOM_COMMON") breaks those kernel configurations, because +SOUNDWIRE is now a required dependency for SND_SOC_QCOM_COMMON (and in +turn also SND_SOC_APQ8016_SBC). Trying to migrate such a kernel config +silently disables SND_SOC_APQ8016_SBC and breaks audio functionality. + +The soundwire helpers in common.c are only used by two of the Qualcomm +audio machine drivers, so building and requiring CONFIG_SOUNDWIRE for +all platforms is unnecessary. + +There is no need to stuff all common code into a single module. Fix the +issue by moving the soundwire helpers to a separate SND_SOC_QCOM_SDW +module/option that is selected only by the machine drivers that make +use of them. This also allows reverting the imply/depends changes from +the previous fix because both SM8250 and SC8280XP already depend on +SOUNDWIRE, so the soundwire helpers will be only built if SOUNDWIRE +is really enabled. + +Cc: Srinivas Kandagatla +Fixes: 8d89cf6ff229 ("ASoC: qcom: cleanup and fix dependency of QCOM_COMMON") +Signed-off-by: Stephan Gerhold +Link: https://lore.kernel.org/r/20221231115506.82991-1-stephan@gerhold.net +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/qcom/Kconfig | 21 ++++--- + sound/soc/qcom/Makefile | 2 + + sound/soc/qcom/common.c | 114 ----------------------------------- + sound/soc/qcom/common.h | 10 ---- + sound/soc/qcom/sc8280xp.c | 1 + + sound/soc/qcom/sdw.c | 123 ++++++++++++++++++++++++++++++++++++++ + sound/soc/qcom/sdw.h | 18 ++++++ + sound/soc/qcom/sm8250.c | 1 + + 8 files changed, 157 insertions(+), 133 deletions(-) + create mode 100644 sound/soc/qcom/sdw.c + create mode 100644 sound/soc/qcom/sdw.h + +diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig +index 96a6d4731e6f..e7b00d1d9e99 100644 +--- a/sound/soc/qcom/Kconfig ++++ b/sound/soc/qcom/Kconfig +@@ -2,7 +2,6 @@ + menuconfig SND_SOC_QCOM + tristate "ASoC support for QCOM platforms" + depends on ARCH_QCOM || COMPILE_TEST +- imply SND_SOC_QCOM_COMMON + help + Say Y or M if you want to add support to use audio devices + in Qualcomm Technologies SOC-based platforms. +@@ -60,14 +59,16 @@ config SND_SOC_STORM + config SND_SOC_APQ8016_SBC + tristate "SoC Audio support for APQ8016 SBC platforms" + select SND_SOC_LPASS_APQ8016 +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON + help + Support for Qualcomm Technologies LPASS audio block in + APQ8016 SOC-based systems. + Say Y if you want to use audio devices on MI2S. + + config SND_SOC_QCOM_COMMON +- depends on SOUNDWIRE ++ tristate ++ ++config SND_SOC_QCOM_SDW + tristate + + config SND_SOC_QDSP6_COMMON +@@ -144,7 +145,7 @@ config SND_SOC_MSM8996 + depends on QCOM_APR + depends on COMMON_CLK + select SND_SOC_QDSP6 +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON + help + Support for Qualcomm Technologies LPASS audio block in + APQ8096 SoC-based systems. +@@ -155,7 +156,7 @@ config SND_SOC_SDM845 + depends on QCOM_APR && I2C && SOUNDWIRE + depends on COMMON_CLK + select SND_SOC_QDSP6 +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON + select SND_SOC_RT5663 + select SND_SOC_MAX98927 + imply SND_SOC_CROS_EC_CODEC +@@ -169,7 +170,8 @@ config SND_SOC_SM8250 + depends on QCOM_APR && SOUNDWIRE + depends on COMMON_CLK + select SND_SOC_QDSP6 +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_SDW + help + To add support for audio on Qualcomm Technologies Inc. + SM8250 SoC-based systems. +@@ -180,7 +182,8 @@ config SND_SOC_SC8280XP + depends on QCOM_APR && SOUNDWIRE + depends on COMMON_CLK + select SND_SOC_QDSP6 +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_SDW + help + To add support for audio on Qualcomm Technologies Inc. + SC8280XP SoC-based systems. +@@ -190,7 +193,7 @@ config SND_SOC_SC7180 + tristate "SoC Machine driver for SC7180 boards" + depends on I2C && GPIOLIB + depends on SOUNDWIRE || SOUNDWIRE=n +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON + select SND_SOC_LPASS_SC7180 + select SND_SOC_MAX98357A + select SND_SOC_RT5682_I2C +@@ -204,7 +207,7 @@ config SND_SOC_SC7180 + config SND_SOC_SC7280 + tristate "SoC Machine driver for SC7280 boards" + depends on I2C && SOUNDWIRE +- depends on SND_SOC_QCOM_COMMON ++ select SND_SOC_QCOM_COMMON + select SND_SOC_LPASS_SC7280 + select SND_SOC_MAX98357A + select SND_SOC_WCD938X_SDW +diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile +index 8b97172cf990..254350d9dc06 100644 +--- a/sound/soc/qcom/Makefile ++++ b/sound/soc/qcom/Makefile +@@ -28,6 +28,7 @@ snd-soc-sdm845-objs := sdm845.o + snd-soc-sm8250-objs := sm8250.o + snd-soc-sc8280xp-objs := sc8280xp.o + snd-soc-qcom-common-objs := common.o ++snd-soc-qcom-sdw-objs := sdw.o + + obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o + obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o +@@ -38,6 +39,7 @@ obj-$(CONFIG_SND_SOC_SC8280XP) += snd-soc-sc8280xp.o + obj-$(CONFIG_SND_SOC_SDM845) += snd-soc-sdm845.o + obj-$(CONFIG_SND_SOC_SM8250) += snd-soc-sm8250.o + obj-$(CONFIG_SND_SOC_QCOM_COMMON) += snd-soc-qcom-common.o ++obj-$(CONFIG_SND_SOC_QCOM_SDW) += snd-soc-qcom-sdw.o + + #DSP lib + obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/ +diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c +index 49c74c1662a3..96fe80241fb4 100644 +--- a/sound/soc/qcom/common.c ++++ b/sound/soc/qcom/common.c +@@ -180,120 +180,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card) + } + EXPORT_SYMBOL_GPL(qcom_snd_parse_of); + +-int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, +- struct sdw_stream_runtime *sruntime, +- bool *stream_prepared) +-{ +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); +- int ret; +- +- if (!sruntime) +- return 0; +- +- switch (cpu_dai->id) { +- case WSA_CODEC_DMA_RX_0: +- case WSA_CODEC_DMA_RX_1: +- case RX_CODEC_DMA_RX_0: +- case RX_CODEC_DMA_RX_1: +- case TX_CODEC_DMA_TX_0: +- case TX_CODEC_DMA_TX_1: +- case TX_CODEC_DMA_TX_2: +- case TX_CODEC_DMA_TX_3: +- break; +- default: +- return 0; +- } +- +- if (*stream_prepared) { +- sdw_disable_stream(sruntime); +- sdw_deprepare_stream(sruntime); +- *stream_prepared = false; +- } +- +- ret = sdw_prepare_stream(sruntime); +- if (ret) +- return ret; +- +- /** +- * NOTE: there is a strict hw requirement about the ordering of port +- * enables and actual WSA881x PA enable. PA enable should only happen +- * after soundwire ports are enabled if not DC on the line is +- * accumulated resulting in Click/Pop Noise +- * PA enable/mute are handled as part of codec DAPM and digital mute. +- */ +- +- ret = sdw_enable_stream(sruntime); +- if (ret) { +- sdw_deprepare_stream(sruntime); +- return ret; +- } +- *stream_prepared = true; +- +- return ret; +-} +-EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); +- +-int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct sdw_stream_runtime **psruntime) +-{ +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct snd_soc_dai *codec_dai; +- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); +- struct sdw_stream_runtime *sruntime; +- int i; +- +- switch (cpu_dai->id) { +- case WSA_CODEC_DMA_RX_0: +- case RX_CODEC_DMA_RX_0: +- case RX_CODEC_DMA_RX_1: +- case TX_CODEC_DMA_TX_0: +- case TX_CODEC_DMA_TX_1: +- case TX_CODEC_DMA_TX_2: +- case TX_CODEC_DMA_TX_3: +- for_each_rtd_codec_dais(rtd, i, codec_dai) { +- sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); +- if (sruntime != ERR_PTR(-ENOTSUPP)) +- *psruntime = sruntime; +- } +- break; +- } +- +- return 0; +- +-} +-EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params); +- +-int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, +- struct sdw_stream_runtime *sruntime, bool *stream_prepared) +-{ +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); +- +- switch (cpu_dai->id) { +- case WSA_CODEC_DMA_RX_0: +- case WSA_CODEC_DMA_RX_1: +- case RX_CODEC_DMA_RX_0: +- case RX_CODEC_DMA_RX_1: +- case TX_CODEC_DMA_TX_0: +- case TX_CODEC_DMA_TX_1: +- case TX_CODEC_DMA_TX_2: +- case TX_CODEC_DMA_TX_3: +- if (sruntime && *stream_prepared) { +- sdw_disable_stream(sruntime); +- sdw_deprepare_stream(sruntime); +- *stream_prepared = false; +- } +- break; +- default: +- break; +- } +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free); +- + int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_jack *jack, bool *jack_setup) + { +diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h +index 3ef5bb6d12df..d7f80ee5ae26 100644 +--- a/sound/soc/qcom/common.h ++++ b/sound/soc/qcom/common.h +@@ -5,19 +5,9 @@ + #define __QCOM_SND_COMMON_H__ + + #include +-#include + + int qcom_snd_parse_of(struct snd_soc_card *card); + int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_jack *jack, bool *jack_setup); + +-int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, +- struct sdw_stream_runtime *runtime, +- bool *stream_prepared); +-int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct sdw_stream_runtime **psruntime); +-int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, +- struct sdw_stream_runtime *sruntime, +- bool *stream_prepared); + #endif +diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c +index ade44ad7c585..14d9fea33d16 100644 +--- a/sound/soc/qcom/sc8280xp.c ++++ b/sound/soc/qcom/sc8280xp.c +@@ -12,6 +12,7 @@ + #include + #include "qdsp6/q6afe.h" + #include "common.h" ++#include "sdw.h" + + #define DRIVER_NAME "sc8280xp" + +diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c +new file mode 100644 +index 000000000000..10249519a39e +--- /dev/null ++++ b/sound/soc/qcom/sdw.c +@@ -0,0 +1,123 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018, Linaro Limited. ++// Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ ++#include ++#include ++#include "qdsp6/q6afe.h" ++#include "sdw.h" ++ ++int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, ++ struct sdw_stream_runtime *sruntime, ++ bool *stream_prepared) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); ++ int ret; ++ ++ if (!sruntime) ++ return 0; ++ ++ switch (cpu_dai->id) { ++ case WSA_CODEC_DMA_RX_0: ++ case WSA_CODEC_DMA_RX_1: ++ case RX_CODEC_DMA_RX_0: ++ case RX_CODEC_DMA_RX_1: ++ case TX_CODEC_DMA_TX_0: ++ case TX_CODEC_DMA_TX_1: ++ case TX_CODEC_DMA_TX_2: ++ case TX_CODEC_DMA_TX_3: ++ break; ++ default: ++ return 0; ++ } ++ ++ if (*stream_prepared) { ++ sdw_disable_stream(sruntime); ++ sdw_deprepare_stream(sruntime); ++ *stream_prepared = false; ++ } ++ ++ ret = sdw_prepare_stream(sruntime); ++ if (ret) ++ return ret; ++ ++ /** ++ * NOTE: there is a strict hw requirement about the ordering of port ++ * enables and actual WSA881x PA enable. PA enable should only happen ++ * after soundwire ports are enabled if not DC on the line is ++ * accumulated resulting in Click/Pop Noise ++ * PA enable/mute are handled as part of codec DAPM and digital mute. ++ */ ++ ++ ret = sdw_enable_stream(sruntime); ++ if (ret) { ++ sdw_deprepare_stream(sruntime); ++ return ret; ++ } ++ *stream_prepared = true; ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); ++ ++int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct sdw_stream_runtime **psruntime) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai; ++ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); ++ struct sdw_stream_runtime *sruntime; ++ int i; ++ ++ switch (cpu_dai->id) { ++ case WSA_CODEC_DMA_RX_0: ++ case RX_CODEC_DMA_RX_0: ++ case RX_CODEC_DMA_RX_1: ++ case TX_CODEC_DMA_TX_0: ++ case TX_CODEC_DMA_TX_1: ++ case TX_CODEC_DMA_TX_2: ++ case TX_CODEC_DMA_TX_3: ++ for_each_rtd_codec_dais(rtd, i, codec_dai) { ++ sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); ++ if (sruntime != ERR_PTR(-ENOTSUPP)) ++ *psruntime = sruntime; ++ } ++ break; ++ } ++ ++ return 0; ++ ++} ++EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params); ++ ++int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, ++ struct sdw_stream_runtime *sruntime, bool *stream_prepared) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); ++ ++ switch (cpu_dai->id) { ++ case WSA_CODEC_DMA_RX_0: ++ case WSA_CODEC_DMA_RX_1: ++ case RX_CODEC_DMA_RX_0: ++ case RX_CODEC_DMA_RX_1: ++ case TX_CODEC_DMA_TX_0: ++ case TX_CODEC_DMA_TX_1: ++ case TX_CODEC_DMA_TX_2: ++ case TX_CODEC_DMA_TX_3: ++ if (sruntime && *stream_prepared) { ++ sdw_disable_stream(sruntime); ++ sdw_deprepare_stream(sruntime); ++ *stream_prepared = false; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/qcom/sdw.h b/sound/soc/qcom/sdw.h +new file mode 100644 +index 000000000000..d74cbb84da13 +--- /dev/null ++++ b/sound/soc/qcom/sdw.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++// Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ ++#ifndef __QCOM_SND_SDW_H__ ++#define __QCOM_SND_SDW_H__ ++ ++#include ++ ++int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, ++ struct sdw_stream_runtime *runtime, ++ bool *stream_prepared); ++int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct sdw_stream_runtime **psruntime); ++int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, ++ struct sdw_stream_runtime *sruntime, ++ bool *stream_prepared); ++#endif +diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c +index 8dbe9ef41b1c..9626a9ef78c2 100644 +--- a/sound/soc/qcom/sm8250.c ++++ b/sound/soc/qcom/sm8250.c +@@ -12,6 +12,7 @@ + #include + #include "qdsp6/q6afe.h" + #include "common.h" ++#include "sdw.h" + + #define DRIVER_NAME "sm8250" + #define MI2S_BCLK_RATE 1536000 +-- +2.35.1 + diff --git a/queue-6.1/asoc-wm8904-fix-wrong-outputs-volume-after-power-rea.patch b/queue-6.1/asoc-wm8904-fix-wrong-outputs-volume-after-power-rea.patch new file mode 100644 index 00000000000..711972ee0e0 --- /dev/null +++ b/queue-6.1/asoc-wm8904-fix-wrong-outputs-volume-after-power-rea.patch @@ -0,0 +1,69 @@ +From 74bc053eac1426389fb579efd7f2b0910f306f08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Dec 2022 09:02:47 +0100 +Subject: ASoC: wm8904: fix wrong outputs volume after power reactivation + +From: Emanuele Ghidoli + +[ Upstream commit 472a6309c6467af89dbf660a8310369cc9cb041f ] + +Restore volume after charge pump and PGA activation to ensure +that volume settings are correctly applied when re-enabling codec +from SND_SOC_BIAS_OFF state. +CLASS_W, CHARGE_PUMP and POWER_MANAGEMENT_2 register configuration +affect how the volume register are applied and must be configured first. + +Fixes: a91eb199e4dc ("ASoC: Initial WM8904 CODEC driver") +Link: https://lore.kernel.org/all/c7864c35-738c-a867-a6a6-ddf9f98df7e7@gmail.com/ +Signed-off-by: Emanuele Ghidoli +Signed-off-by: Francesco Dolcini +Acked-by: Charles Keepax +Link: https://lore.kernel.org/r/20221223080247.7258-1-francesco@dolcini.it +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wm8904.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c +index ca6a01a230af..791d8738d1c0 100644 +--- a/sound/soc/codecs/wm8904.c ++++ b/sound/soc/codecs/wm8904.c +@@ -697,6 +697,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, + int dcs_mask; + int dcs_l, dcs_r; + int dcs_l_reg, dcs_r_reg; ++ int an_out_reg; + int timeout; + int pwr_reg; + +@@ -712,6 +713,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, + dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1; + dcs_r_reg = WM8904_DC_SERVO_8; + dcs_l_reg = WM8904_DC_SERVO_9; ++ an_out_reg = WM8904_ANALOGUE_OUT1_LEFT; + dcs_l = 0; + dcs_r = 1; + break; +@@ -720,6 +722,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, + dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3; + dcs_r_reg = WM8904_DC_SERVO_6; + dcs_l_reg = WM8904_DC_SERVO_7; ++ an_out_reg = WM8904_ANALOGUE_OUT2_LEFT; + dcs_l = 2; + dcs_r = 3; + break; +@@ -792,6 +795,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, + snd_soc_component_update_bits(component, reg, + WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP, + WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP); ++ ++ /* Update volume, requires PGA to be powered */ ++ val = snd_soc_component_read(component, an_out_reg); ++ snd_soc_component_write(component, an_out_reg, val); + break; + + case SND_SOC_DAPM_POST_PMU: +-- +2.35.1 + diff --git a/queue-6.1/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch b/queue-6.1/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch new file mode 100644 index 00000000000..fd7fe4547e4 --- /dev/null +++ b/queue-6.1/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch @@ -0,0 +1,109 @@ +From 01ffed5915ac9f8a369fd9cfacb27a20bdddafc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:33 +0100 +Subject: blk-crypto: pass a gendisk to blk_crypto_sysfs_{,un}register + +From: Christoph Hellwig + +[ Upstream commit 450deb93df7d457cdd93594a1987f9650c749b96 ] + +Prepare for changes to the block layer sysfs handling by passing the +readily available gendisk to blk_crypto_sysfs_{,un}register. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Eric Biggers +Link: https://lore.kernel.org/r/20221114042637.1009333-2-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-crypto-internal.h | 10 ++++++---- + block/blk-crypto-sysfs.c | 7 ++++--- + block/blk-sysfs.c | 4 ++-- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h +index e6818ffaddbf..b8a00847171f 100644 +--- a/block/blk-crypto-internal.h ++++ b/block/blk-crypto-internal.h +@@ -21,9 +21,9 @@ extern const struct blk_crypto_mode blk_crypto_modes[]; + + #ifdef CONFIG_BLK_INLINE_ENCRYPTION + +-int blk_crypto_sysfs_register(struct request_queue *q); ++int blk_crypto_sysfs_register(struct gendisk *disk); + +-void blk_crypto_sysfs_unregister(struct request_queue *q); ++void blk_crypto_sysfs_unregister(struct gendisk *disk); + + void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], + unsigned int inc); +@@ -67,12 +67,14 @@ static inline bool blk_crypto_rq_is_encrypted(struct request *rq) + + #else /* CONFIG_BLK_INLINE_ENCRYPTION */ + +-static inline int blk_crypto_sysfs_register(struct request_queue *q) ++static inline int blk_crypto_sysfs_register(struct gendisk *disk) + { + return 0; + } + +-static inline void blk_crypto_sysfs_unregister(struct request_queue *q) { } ++static inline void blk_crypto_sysfs_unregister(struct gendisk *disk) ++{ ++} + + static inline bool bio_crypt_rq_ctx_compatible(struct request *rq, + struct bio *bio) +diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c +index fd93bd2f33b7..e05f145cd797 100644 +--- a/block/blk-crypto-sysfs.c ++++ b/block/blk-crypto-sysfs.c +@@ -126,8 +126,9 @@ static struct kobj_type blk_crypto_ktype = { + * If the request_queue has a blk_crypto_profile, create the "crypto" + * subdirectory in sysfs (/sys/block/$disk/queue/crypto/). + */ +-int blk_crypto_sysfs_register(struct request_queue *q) ++int blk_crypto_sysfs_register(struct gendisk *disk) + { ++ struct request_queue *q = disk->queue; + struct blk_crypto_kobj *obj; + int err; + +@@ -149,9 +150,9 @@ int blk_crypto_sysfs_register(struct request_queue *q) + return 0; + } + +-void blk_crypto_sysfs_unregister(struct request_queue *q) ++void blk_crypto_sysfs_unregister(struct gendisk *disk) + { +- kobject_put(q->crypto_kobject); ++ kobject_put(disk->queue->crypto_kobject); + } + + static int __init blk_crypto_sysfs_init(void) +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index e7871665825a..2b1cf0b2a5c7 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -833,7 +833,7 @@ int blk_register_queue(struct gendisk *disk) + goto put_dev; + } + +- ret = blk_crypto_sysfs_register(q); ++ ret = blk_crypto_sysfs_register(disk); + if (ret) + goto put_dev; + +@@ -910,7 +910,7 @@ void blk_unregister_queue(struct gendisk *disk) + */ + if (queue_is_mq(q)) + blk_mq_sysfs_unregister(disk); +- blk_crypto_sysfs_unregister(q); ++ blk_crypto_sysfs_unregister(disk); + + mutex_lock(&q->sysfs_lock); + elv_unregister_queue(q); +-- +2.35.1 + diff --git a/queue-6.1/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch b/queue-6.1/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch new file mode 100644 index 00000000000..37bf58b3696 --- /dev/null +++ b/queue-6.1/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch @@ -0,0 +1,358 @@ +From bd9c3b70ef2f102bb8f8fdc9f9965b8078e21b8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:00:47 +0100 +Subject: blk-mq: move the srcu_struct used for quiescing to the tagset + +From: Christoph Hellwig + +[ Upstream commit 80bd4a7aab4c9ce59bf5e35fdf52aa23d8a3c9f5 ] + +All I/O submissions have fairly similar latencies, and a tagset-wide +quiesce is a fairly common operation. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Ming Lei +Reviewed-by: Chao Leng +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Reviewed-by: Chaitanya Kulkarni +Link: https://lore.kernel.org/r/20221101150050.3510-12-hch@lst.de +[axboe: fix whitespace] +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 27 +++++---------------------- + block/blk-mq.c | 33 +++++++++++++++++++++++++-------- + block/blk-mq.h | 14 +++++++------- + block/blk-sysfs.c | 9 ++------- + block/blk.h | 9 +-------- + block/genhd.c | 2 +- + include/linux/blk-mq.h | 4 ++++ + include/linux/blkdev.h | 9 --------- + 8 files changed, 45 insertions(+), 62 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 5487912befe8..9d6a947024ea 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -65,7 +65,6 @@ DEFINE_IDA(blk_queue_ida); + * For queue allocation + */ + struct kmem_cache *blk_requestq_cachep; +-struct kmem_cache *blk_requestq_srcu_cachep; + + /* + * Controlling structure to kblockd +@@ -373,26 +372,20 @@ static void blk_timeout_work(struct work_struct *work) + { + } + +-struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu) ++struct request_queue *blk_alloc_queue(int node_id) + { + struct request_queue *q; + +- q = kmem_cache_alloc_node(blk_get_queue_kmem_cache(alloc_srcu), +- GFP_KERNEL | __GFP_ZERO, node_id); ++ q = kmem_cache_alloc_node(blk_requestq_cachep, GFP_KERNEL | __GFP_ZERO, ++ node_id); + if (!q) + return NULL; + +- if (alloc_srcu) { +- blk_queue_flag_set(QUEUE_FLAG_HAS_SRCU, q); +- if (init_srcu_struct(q->srcu) != 0) +- goto fail_q; +- } +- + q->last_merge = NULL; + + q->id = ida_alloc(&blk_queue_ida, GFP_KERNEL); + if (q->id < 0) +- goto fail_srcu; ++ goto fail_q; + + q->stats = blk_alloc_queue_stats(); + if (!q->stats) +@@ -434,11 +427,8 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu) + blk_free_queue_stats(q->stats); + fail_id: + ida_free(&blk_queue_ida, q->id); +-fail_srcu: +- if (alloc_srcu) +- cleanup_srcu_struct(q->srcu); + fail_q: +- kmem_cache_free(blk_get_queue_kmem_cache(alloc_srcu), q); ++ kmem_cache_free(blk_requestq_cachep, q); + return NULL; + } + +@@ -1183,9 +1173,6 @@ int __init blk_dev_init(void) + sizeof_field(struct request, cmd_flags)); + BUILD_BUG_ON(REQ_OP_BITS + REQ_FLAG_BITS > 8 * + sizeof_field(struct bio, bi_opf)); +- BUILD_BUG_ON(ALIGN(offsetof(struct request_queue, srcu), +- __alignof__(struct request_queue)) != +- sizeof(struct request_queue)); + + /* used for unplugging and affects IO latency/throughput - HIGHPRI */ + kblockd_workqueue = alloc_workqueue("kblockd", +@@ -1196,10 +1183,6 @@ int __init blk_dev_init(void) + blk_requestq_cachep = kmem_cache_create("request_queue", + sizeof(struct request_queue), 0, SLAB_PANIC, NULL); + +- blk_requestq_srcu_cachep = kmem_cache_create("request_queue_srcu", +- sizeof(struct request_queue) + +- sizeof(struct srcu_struct), 0, SLAB_PANIC, NULL); +- + blk_debugfs_root = debugfs_create_dir("block", NULL); + + return 0; +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 0b855e033a83..a23026099284 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -261,8 +261,8 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait); + */ + void blk_mq_wait_quiesce_done(struct request_queue *q) + { +- if (blk_queue_has_srcu(q)) +- synchronize_srcu(q->srcu); ++ if (q->tag_set->flags & BLK_MQ_F_BLOCKING) ++ synchronize_srcu(q->tag_set->srcu); + else + synchronize_rcu(); + } +@@ -4007,7 +4007,7 @@ static struct request_queue *blk_mq_init_queue_data(struct blk_mq_tag_set *set, + struct request_queue *q; + int ret; + +- q = blk_alloc_queue(set->numa_node, set->flags & BLK_MQ_F_BLOCKING); ++ q = blk_alloc_queue(set->numa_node); + if (!q) + return ERR_PTR(-ENOMEM); + q->queuedata = queuedata; +@@ -4179,9 +4179,6 @@ static void blk_mq_update_poll_flag(struct request_queue *q) + int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, + struct request_queue *q) + { +- WARN_ON_ONCE(blk_queue_has_srcu(q) != +- !!(set->flags & BLK_MQ_F_BLOCKING)); +- + /* mark the queue as mq asap */ + q->mq_ops = set->ops; + +@@ -4438,8 +4435,18 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) + if (set->nr_maps == 1 && set->nr_hw_queues > nr_cpu_ids) + set->nr_hw_queues = nr_cpu_ids; + +- if (blk_mq_alloc_tag_set_tags(set, set->nr_hw_queues) < 0) +- return -ENOMEM; ++ if (set->flags & BLK_MQ_F_BLOCKING) { ++ set->srcu = kmalloc(sizeof(*set->srcu), GFP_KERNEL); ++ if (!set->srcu) ++ return -ENOMEM; ++ ret = init_srcu_struct(set->srcu); ++ if (ret) ++ goto out_free_srcu; ++ } ++ ++ ret = blk_mq_alloc_tag_set_tags(set, set->nr_hw_queues); ++ if (ret) ++ goto out_cleanup_srcu; + + ret = -ENOMEM; + for (i = 0; i < set->nr_maps; i++) { +@@ -4469,6 +4476,12 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) + } + kfree(set->tags); + set->tags = NULL; ++out_cleanup_srcu: ++ if (set->flags & BLK_MQ_F_BLOCKING) ++ cleanup_srcu_struct(set->srcu); ++out_free_srcu: ++ if (set->flags & BLK_MQ_F_BLOCKING) ++ kfree(set->srcu); + return ret; + } + EXPORT_SYMBOL(blk_mq_alloc_tag_set); +@@ -4508,6 +4521,10 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set) + + kfree(set->tags); + set->tags = NULL; ++ if (set->flags & BLK_MQ_F_BLOCKING) { ++ cleanup_srcu_struct(set->srcu); ++ kfree(set->srcu); ++ } + } + EXPORT_SYMBOL(blk_mq_free_tag_set); + +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 0b2870839cdd..ef59fee62780 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -377,17 +377,17 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx, + /* run the code block in @dispatch_ops with rcu/srcu read lock held */ + #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \ + do { \ +- if (!blk_queue_has_srcu(q)) { \ +- rcu_read_lock(); \ +- (dispatch_ops); \ +- rcu_read_unlock(); \ +- } else { \ ++ if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \ + int srcu_idx; \ + \ + might_sleep_if(check_sleep); \ +- srcu_idx = srcu_read_lock((q)->srcu); \ ++ srcu_idx = srcu_read_lock((q)->tag_set->srcu); \ + (dispatch_ops); \ +- srcu_read_unlock((q)->srcu, srcu_idx); \ ++ srcu_read_unlock((q)->tag_set->srcu, srcu_idx); \ ++ } else { \ ++ rcu_read_lock(); \ ++ (dispatch_ops); \ ++ rcu_read_unlock(); \ + } \ + } while (0) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index e71b3b43927c..e7871665825a 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -739,10 +739,8 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, + + static void blk_free_queue_rcu(struct rcu_head *rcu_head) + { +- struct request_queue *q = container_of(rcu_head, struct request_queue, +- rcu_head); +- +- kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q); ++ kmem_cache_free(blk_requestq_cachep, ++ container_of(rcu_head, struct request_queue, rcu_head)); + } + + /** +@@ -779,9 +777,6 @@ static void blk_release_queue(struct kobject *kobj) + if (queue_is_mq(q)) + blk_mq_release(q); + +- if (blk_queue_has_srcu(q)) +- cleanup_srcu_struct(q->srcu); +- + ida_free(&blk_queue_ida, q->id); + call_rcu(&q->rcu_head, blk_free_queue_rcu); + } +diff --git a/block/blk.h b/block/blk.h +index 8b75a95b28d6..0661fa4b3a4d 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -27,7 +27,6 @@ struct blk_flush_queue { + }; + + extern struct kmem_cache *blk_requestq_cachep; +-extern struct kmem_cache *blk_requestq_srcu_cachep; + extern struct kobj_type blk_queue_ktype; + extern struct ida blk_queue_ida; + +@@ -428,13 +427,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio, + struct page *page, unsigned int len, unsigned int offset, + unsigned int max_sectors, bool *same_page); + +-static inline struct kmem_cache *blk_get_queue_kmem_cache(bool srcu) +-{ +- if (srcu) +- return blk_requestq_srcu_cachep; +- return blk_requestq_cachep; +-} +-struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu); ++struct request_queue *blk_alloc_queue(int node_id); + + int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner); + +diff --git a/block/genhd.c b/block/genhd.c +index c4765681a8b4..f4f3f3b55634 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -1417,7 +1417,7 @@ struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass) + struct request_queue *q; + struct gendisk *disk; + +- q = blk_alloc_queue(node, false); ++ q = blk_alloc_queue(node); + if (!q) + return NULL; + +diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h +index d6119c5d1069..2952c28410e3 100644 +--- a/include/linux/blk-mq.h ++++ b/include/linux/blk-mq.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + struct blk_mq_tags; + struct blk_flush_queue; +@@ -501,6 +502,8 @@ enum hctx_type { + * @tag_list_lock: Serializes tag_list accesses. + * @tag_list: List of the request queues that use this tag set. See also + * request_queue.tag_set_list. ++ * @srcu: Use as lock when type of the request queue is blocking ++ * (BLK_MQ_F_BLOCKING). + */ + struct blk_mq_tag_set { + struct blk_mq_queue_map map[HCTX_MAX_TYPES]; +@@ -521,6 +524,7 @@ struct blk_mq_tag_set { + + struct mutex tag_list_lock; + struct list_head tag_list; ++ struct srcu_struct *srcu; + }; + + /** +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 891f8cbcd043..36c286d22fb2 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -544,18 +543,11 @@ struct request_queue { + struct mutex debugfs_mutex; + + bool mq_sysfs_init_done; +- +- /** +- * @srcu: Sleepable RCU. Use as lock when type of the request queue +- * is blocking (BLK_MQ_F_BLOCKING). Must be the last member +- */ +- struct srcu_struct srcu[]; + }; + + /* Keep blk_queue_flag_name[] in sync with the definitions below */ + #define QUEUE_FLAG_STOPPED 0 /* queue is stopped */ + #define QUEUE_FLAG_DYING 1 /* queue being torn down */ +-#define QUEUE_FLAG_HAS_SRCU 2 /* SRCU is allocated */ + #define QUEUE_FLAG_NOMERGES 3 /* disable merge attempts */ + #define QUEUE_FLAG_SAME_COMP 4 /* complete on same CPU-group */ + #define QUEUE_FLAG_FAIL_IO 5 /* fake timeout */ +@@ -591,7 +583,6 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q); + + #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) + #define blk_queue_dying(q) test_bit(QUEUE_FLAG_DYING, &(q)->queue_flags) +-#define blk_queue_has_srcu(q) test_bit(QUEUE_FLAG_HAS_SRCU, &(q)->queue_flags) + #define blk_queue_init_done(q) test_bit(QUEUE_FLAG_INIT_DONE, &(q)->queue_flags) + #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) + #define blk_queue_noxmerges(q) \ +-- +2.35.1 + diff --git a/queue-6.1/block-drop-spurious-might_sleep-from-blk_put_queue.patch b/queue-6.1/block-drop-spurious-might_sleep-from-blk_put_queue.patch new file mode 100644 index 00000000000..78c39bc9a55 --- /dev/null +++ b/queue-6.1/block-drop-spurious-might_sleep-from-blk_put_queue.patch @@ -0,0 +1,62 @@ +From dd1460786ec68b9d790823779b75d4ec8e8a118a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 10:34:10 -1000 +Subject: block: Drop spurious might_sleep() from blk_put_queue() + +From: Tejun Heo + +[ Upstream commit 49e4d04f0486117ac57a97890eb1db6d52bf82b3 ] + +Dan reports the following smatch detected the following: + + block/blk-cgroup.c:1863 blkcg_schedule_throttle() warn: sleeping in atomic context + +caused by blkcg_schedule_throttle() calling blk_put_queue() in an +non-sleepable context. + +blk_put_queue() acquired might_sleep() in 63f93fd6fa57 ("block: mark +blk_put_queue as potentially blocking") which transferred the might_sleep() +from blk_free_queue(). + +blk_free_queue() acquired might_sleep() in e8c7d14ac6c3 ("block: revert back +to synchronous request_queue removal") while turning request_queue removal +synchronous. However, this isn't necessary as nothing in the free path +actually requires sleeping. + +It's pretty unusual to require a sleeping context in a put operation and +it's not needed in the first place. Let's drop it. + +Signed-off-by: Tejun Heo +Reported-by: Dan Carpenter +Link: https://lkml.kernel.org/r/Y7g3L6fntnTtOm63@kili +Cc: Christoph Hellwig +Cc: Luis Chamberlain +Fixes: e8c7d14ac6c3 ("block: revert back to synchronous request_queue removal") # v5.9+ +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/Y7iFwjN+XzWvLv3y@slm.duckdns.org +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 815ffce6b988..f5ae527fb0c3 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -282,12 +282,9 @@ static void blk_free_queue(struct request_queue *q) + * + * Decrements the refcount of the request_queue and free it when the refcount + * reaches 0. +- * +- * Context: Can sleep. + */ + void blk_put_queue(struct request_queue *q) + { +- might_sleep(); + if (refcount_dec_and_test(&q->refs)) + blk_free_queue(q); + } +-- +2.35.1 + diff --git a/queue-6.1/block-factor-out-a-blk_debugfs_remove-helper.patch b/queue-6.1/block-factor-out-a-blk_debugfs_remove-helper.patch new file mode 100644 index 00000000000..9a5dc1c6248 --- /dev/null +++ b/queue-6.1/block-factor-out-a-blk_debugfs_remove-helper.patch @@ -0,0 +1,61 @@ +From a470755911a1d91ec554013211b835d0032051ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:34 +0100 +Subject: block: factor out a blk_debugfs_remove helper + +From: Christoph Hellwig + +[ Upstream commit 6fc75f309d291d328b4ea2f91bef0ff56e4bc7c2 ] + +Split the debugfs removal from blk_unregister_queue into a helper so that +the it can be reused for blk_register_queue error handling. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-3-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-sysfs.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 2b1cf0b2a5c7..3d6951a0b4e7 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -797,6 +797,19 @@ struct kobj_type blk_queue_ktype = { + .release = blk_release_queue, + }; + ++static void blk_debugfs_remove(struct gendisk *disk) ++{ ++ struct request_queue *q = disk->queue; ++ ++ mutex_lock(&q->debugfs_mutex); ++ blk_trace_shutdown(q); ++ debugfs_remove_recursive(q->debugfs_dir); ++ q->debugfs_dir = NULL; ++ q->sched_debugfs_dir = NULL; ++ q->rqos_debugfs_dir = NULL; ++ mutex_unlock(&q->debugfs_mutex); ++} ++ + /** + * blk_register_queue - register a block layer queue with sysfs + * @disk: Disk of which the request queue should be registered with sysfs. +@@ -922,11 +935,5 @@ void blk_unregister_queue(struct gendisk *disk) + kobject_del(&q->kobj); + mutex_unlock(&q->sysfs_dir_lock); + +- mutex_lock(&q->debugfs_mutex); +- blk_trace_shutdown(q); +- debugfs_remove_recursive(q->debugfs_dir); +- q->debugfs_dir = NULL; +- q->sched_debugfs_dir = NULL; +- q->rqos_debugfs_dir = NULL; +- mutex_unlock(&q->debugfs_mutex); ++ blk_debugfs_remove(disk); + } +-- +2.35.1 + diff --git a/queue-6.1/block-fix-error-unwinding-in-blk_register_queue.patch b/queue-6.1/block-fix-error-unwinding-in-blk_register_queue.patch new file mode 100644 index 00000000000..f5d83faec31 --- /dev/null +++ b/queue-6.1/block-fix-error-unwinding-in-blk_register_queue.patch @@ -0,0 +1,101 @@ +From 92de18c2eb61fd698c0eb9163a508e1be7e7aea3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:35 +0100 +Subject: block: fix error unwinding in blk_register_queue + +From: Christoph Hellwig + +[ Upstream commit 40602997be26887bdfa3d58659c3acb4579099e9 ] + +blk_register_queue fails to handle errors from blk_mq_sysfs_register, +leaks various resources on errors and accidentally sets queue refs percpu +refcount to percpu mode on kobject_add failure. Fix all that by +properly unwinding on errors. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-4-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-sysfs.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 3d6951a0b4e7..1631ba2f7259 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -820,13 +820,15 @@ int blk_register_queue(struct gendisk *disk) + int ret; + + mutex_lock(&q->sysfs_dir_lock); +- + ret = kobject_add(&q->kobj, &disk_to_dev(disk)->kobj, "queue"); + if (ret < 0) +- goto unlock; ++ goto out_unlock_dir; + +- if (queue_is_mq(q)) +- blk_mq_sysfs_register(disk); ++ if (queue_is_mq(q)) { ++ ret = blk_mq_sysfs_register(disk); ++ if (ret) ++ goto out_del_queue_kobj; ++ } + mutex_lock(&q->sysfs_lock); + + mutex_lock(&q->debugfs_mutex); +@@ -838,17 +840,17 @@ int blk_register_queue(struct gendisk *disk) + + ret = disk_register_independent_access_ranges(disk); + if (ret) +- goto put_dev; ++ goto out_debugfs_remove; + + if (q->elevator) { + ret = elv_register_queue(q, false); + if (ret) +- goto put_dev; ++ goto out_unregister_ia_ranges; + } + + ret = blk_crypto_sysfs_register(disk); + if (ret) +- goto put_dev; ++ goto out_elv_unregister; + + blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q); + wbt_enable_default(q); +@@ -859,8 +861,6 @@ int blk_register_queue(struct gendisk *disk) + if (q->elevator) + kobject_uevent(&q->elevator->kobj, KOBJ_ADD); + mutex_unlock(&q->sysfs_lock); +- +-unlock: + mutex_unlock(&q->sysfs_dir_lock); + + /* +@@ -879,13 +879,17 @@ int blk_register_queue(struct gendisk *disk) + + return ret; + +-put_dev: ++out_elv_unregister: + elv_unregister_queue(q); ++out_unregister_ia_ranges: + disk_unregister_independent_access_ranges(disk); ++out_debugfs_remove: ++ blk_debugfs_remove(disk); + mutex_unlock(&q->sysfs_lock); +- mutex_unlock(&q->sysfs_dir_lock); ++out_del_queue_kobj: + kobject_del(&q->kobj); +- ++out_unlock_dir: ++ mutex_unlock(&q->sysfs_dir_lock); + return ret; + } + +-- +2.35.1 + diff --git a/queue-6.1/block-mark-blk_put_queue-as-potentially-blocking.patch b/queue-6.1/block-mark-blk_put_queue-as-potentially-blocking.patch new file mode 100644 index 00000000000..6957d4a5ae2 --- /dev/null +++ b/queue-6.1/block-mark-blk_put_queue-as-potentially-blocking.patch @@ -0,0 +1,52 @@ +From 1ec7de36d3a9c53347ce5a07ffdfabc14ebed66b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:37 +0100 +Subject: block: mark blk_put_queue as potentially blocking + +From: Christoph Hellwig + +[ Upstream commit 63f93fd6fa5717769a78d6d7bea6f7f9a1ccca8e ] + +We can't just say that the last reference release may block, as any +reference dropped could be the last one. So move the might_sleep() from +blk_free_queue to blk_put_queue and update the documentation. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-6-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 7de1bb16e9a7..815ffce6b988 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -260,8 +260,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head) + + static void blk_free_queue(struct request_queue *q) + { +- might_sleep(); +- + percpu_ref_exit(&q->q_usage_counter); + + if (q->poll_stat) +@@ -285,11 +283,11 @@ static void blk_free_queue(struct request_queue *q) + * Decrements the refcount of the request_queue and free it when the refcount + * reaches 0. + * +- * Context: Any context, but the last reference must not be dropped from +- * atomic context. ++ * Context: Can sleep. + */ + void blk_put_queue(struct request_queue *q) + { ++ might_sleep(); + if (refcount_dec_and_test(&q->refs)) + blk_free_queue(q); + } +-- +2.35.1 + diff --git a/queue-6.1/block-untangle-request_queue-refcounting-from-sysfs.patch b/queue-6.1/block-untangle-request_queue-refcounting-from-sysfs.patch new file mode 100644 index 00000000000..082e6f6cf61 --- /dev/null +++ b/queue-6.1/block-untangle-request_queue-refcounting-from-sysfs.patch @@ -0,0 +1,400 @@ +From 8f978e86b17108d8f596f9b036e512b38e67a1de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:36 +0100 +Subject: block: untangle request_queue refcounting from sysfs + +From: Christoph Hellwig + +[ Upstream commit 2bd85221a625b316114bafaab527770b607095d3 ] + +The kobject embedded into the request_queue is used for the queue +directory in sysfs, but that is a child of the gendisks directory and is +intimately tied to it. Move this kobject to the gendisk and use a +refcount_t in the request_queue for the actual request_queue refcounting +that is completely unrelated to the device model. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-5-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 49e4d04f0486 ("block: Drop spurious might_sleep() from blk_put_queue()") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 42 ++++++++++++++++---- + block/blk-crypto-sysfs.c | 4 +- + block/blk-ia-ranges.c | 3 +- + block/blk-sysfs.c | 86 +++++++++++----------------------------- + block/blk.h | 4 -- + block/bsg.c | 11 +++-- + block/elevator.c | 2 +- + include/linux/blkdev.h | 6 +-- + 8 files changed, 71 insertions(+), 87 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 9d6a947024ea..7de1bb16e9a7 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -59,12 +59,12 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_split); + EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); + EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_insert); + +-DEFINE_IDA(blk_queue_ida); ++static DEFINE_IDA(blk_queue_ida); + + /* + * For queue allocation + */ +-struct kmem_cache *blk_requestq_cachep; ++static struct kmem_cache *blk_requestq_cachep; + + /* + * Controlling structure to kblockd +@@ -252,19 +252,46 @@ void blk_clear_pm_only(struct request_queue *q) + } + EXPORT_SYMBOL_GPL(blk_clear_pm_only); + ++static void blk_free_queue_rcu(struct rcu_head *rcu_head) ++{ ++ kmem_cache_free(blk_requestq_cachep, ++ container_of(rcu_head, struct request_queue, rcu_head)); ++} ++ ++static void blk_free_queue(struct request_queue *q) ++{ ++ might_sleep(); ++ ++ percpu_ref_exit(&q->q_usage_counter); ++ ++ if (q->poll_stat) ++ blk_stat_remove_callback(q, q->poll_cb); ++ blk_stat_free_callback(q->poll_cb); ++ ++ blk_free_queue_stats(q->stats); ++ kfree(q->poll_stat); ++ ++ if (queue_is_mq(q)) ++ blk_mq_release(q); ++ ++ ida_free(&blk_queue_ida, q->id); ++ call_rcu(&q->rcu_head, blk_free_queue_rcu); ++} ++ + /** + * blk_put_queue - decrement the request_queue refcount + * @q: the request_queue structure to decrement the refcount for + * +- * Decrements the refcount of the request_queue kobject. When this reaches 0 +- * we'll have blk_release_queue() called. ++ * Decrements the refcount of the request_queue and free it when the refcount ++ * reaches 0. + * + * Context: Any context, but the last reference must not be dropped from + * atomic context. + */ + void blk_put_queue(struct request_queue *q) + { +- kobject_put(&q->kobj); ++ if (refcount_dec_and_test(&q->refs)) ++ blk_free_queue(q); + } + EXPORT_SYMBOL(blk_put_queue); + +@@ -399,8 +426,7 @@ struct request_queue *blk_alloc_queue(int node_id) + INIT_WORK(&q->timeout_work, blk_timeout_work); + INIT_LIST_HEAD(&q->icq_list); + +- kobject_init(&q->kobj, &blk_queue_ktype); +- ++ refcount_set(&q->refs, 1); + mutex_init(&q->debugfs_mutex); + mutex_init(&q->sysfs_lock); + mutex_init(&q->sysfs_dir_lock); +@@ -444,7 +470,7 @@ bool blk_get_queue(struct request_queue *q) + { + if (unlikely(blk_queue_dying(q))) + return false; +- kobject_get(&q->kobj); ++ refcount_inc(&q->refs); + return true; + } + EXPORT_SYMBOL(blk_get_queue); +diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c +index e05f145cd797..55268edc0625 100644 +--- a/block/blk-crypto-sysfs.c ++++ b/block/blk-crypto-sysfs.c +@@ -140,8 +140,8 @@ int blk_crypto_sysfs_register(struct gendisk *disk) + return -ENOMEM; + obj->profile = q->crypto_profile; + +- err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, &q->kobj, +- "crypto"); ++ err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, ++ &disk->queue_kobj, "crypto"); + if (err) { + kobject_put(&obj->kobj); + return err; +diff --git a/block/blk-ia-ranges.c b/block/blk-ia-ranges.c +index 2bd1d311033b..2141931ddd37 100644 +--- a/block/blk-ia-ranges.c ++++ b/block/blk-ia-ranges.c +@@ -123,7 +123,8 @@ int disk_register_independent_access_ranges(struct gendisk *disk) + */ + WARN_ON(iars->sysfs_registered); + ret = kobject_init_and_add(&iars->kobj, &blk_ia_ranges_ktype, +- &q->kobj, "%s", "independent_access_ranges"); ++ &disk->queue_kobj, "%s", ++ "independent_access_ranges"); + if (ret) { + disk->ia_ranges = NULL; + kobject_put(&iars->kobj); +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 1631ba2f7259..35e854bb6e0c 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -680,8 +680,8 @@ static struct attribute *queue_attrs[] = { + static umode_t queue_attr_visible(struct kobject *kobj, struct attribute *attr, + int n) + { +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + + if (attr == &queue_io_timeout_entry.attr && + (!q->mq_ops || !q->mq_ops->timeout)) +@@ -707,8 +707,8 @@ static ssize_t + queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) + { + struct queue_sysfs_entry *entry = to_queue(attr); +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + ssize_t res; + + if (!entry->show) +@@ -724,63 +724,19 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, + const char *page, size_t length) + { + struct queue_sysfs_entry *entry = to_queue(attr); +- struct request_queue *q; ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + ssize_t res; + + if (!entry->store) + return -EIO; + +- q = container_of(kobj, struct request_queue, kobj); + mutex_lock(&q->sysfs_lock); + res = entry->store(q, page, length); + mutex_unlock(&q->sysfs_lock); + return res; + } + +-static void blk_free_queue_rcu(struct rcu_head *rcu_head) +-{ +- kmem_cache_free(blk_requestq_cachep, +- container_of(rcu_head, struct request_queue, rcu_head)); +-} +- +-/** +- * blk_release_queue - releases all allocated resources of the request_queue +- * @kobj: pointer to a kobject, whose container is a request_queue +- * +- * This function releases all allocated resources of the request queue. +- * +- * The struct request_queue refcount is incremented with blk_get_queue() and +- * decremented with blk_put_queue(). Once the refcount reaches 0 this function +- * is called. +- * +- * Drivers exist which depend on the release of the request_queue to be +- * synchronous, it should not be deferred. +- * +- * Context: can sleep +- */ +-static void blk_release_queue(struct kobject *kobj) +-{ +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); +- +- might_sleep(); +- +- percpu_ref_exit(&q->q_usage_counter); +- +- if (q->poll_stat) +- blk_stat_remove_callback(q, q->poll_cb); +- blk_stat_free_callback(q->poll_cb); +- +- blk_free_queue_stats(q->stats); +- kfree(q->poll_stat); +- +- if (queue_is_mq(q)) +- blk_mq_release(q); +- +- ida_free(&blk_queue_ida, q->id); +- call_rcu(&q->rcu_head, blk_free_queue_rcu); +-} +- + static const struct sysfs_ops queue_sysfs_ops = { + .show = queue_attr_show, + .store = queue_attr_store, +@@ -791,10 +747,15 @@ static const struct attribute_group *blk_queue_attr_groups[] = { + NULL + }; + +-struct kobj_type blk_queue_ktype = { ++static void blk_queue_release(struct kobject *kobj) ++{ ++ /* nothing to do here, all data is associated with the parent gendisk */ ++} ++ ++static struct kobj_type blk_queue_ktype = { + .default_groups = blk_queue_attr_groups, + .sysfs_ops = &queue_sysfs_ops, +- .release = blk_release_queue, ++ .release = blk_queue_release, + }; + + static void blk_debugfs_remove(struct gendisk *disk) +@@ -820,20 +781,20 @@ int blk_register_queue(struct gendisk *disk) + int ret; + + mutex_lock(&q->sysfs_dir_lock); +- ret = kobject_add(&q->kobj, &disk_to_dev(disk)->kobj, "queue"); ++ kobject_init(&disk->queue_kobj, &blk_queue_ktype); ++ ret = kobject_add(&disk->queue_kobj, &disk_to_dev(disk)->kobj, "queue"); + if (ret < 0) +- goto out_unlock_dir; ++ goto out_put_queue_kobj; + + if (queue_is_mq(q)) { + ret = blk_mq_sysfs_register(disk); + if (ret) +- goto out_del_queue_kobj; ++ goto out_put_queue_kobj; + } + mutex_lock(&q->sysfs_lock); + + mutex_lock(&q->debugfs_mutex); +- q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), +- blk_debugfs_root); ++ q->debugfs_dir = debugfs_create_dir(disk->disk_name, blk_debugfs_root); + if (queue_is_mq(q)) + blk_mq_debugfs_register(q); + mutex_unlock(&q->debugfs_mutex); +@@ -857,7 +818,7 @@ int blk_register_queue(struct gendisk *disk) + blk_throtl_register(disk); + + /* Now everything is ready and send out KOBJ_ADD uevent */ +- kobject_uevent(&q->kobj, KOBJ_ADD); ++ kobject_uevent(&disk->queue_kobj, KOBJ_ADD); + if (q->elevator) + kobject_uevent(&q->elevator->kobj, KOBJ_ADD); + mutex_unlock(&q->sysfs_lock); +@@ -886,9 +847,8 @@ int blk_register_queue(struct gendisk *disk) + out_debugfs_remove: + blk_debugfs_remove(disk); + mutex_unlock(&q->sysfs_lock); +-out_del_queue_kobj: +- kobject_del(&q->kobj); +-out_unlock_dir: ++out_put_queue_kobj: ++ kobject_put(&disk->queue_kobj); + mutex_unlock(&q->sysfs_dir_lock); + return ret; + } +@@ -935,8 +895,8 @@ void blk_unregister_queue(struct gendisk *disk) + mutex_unlock(&q->sysfs_lock); + + /* Now that we've deleted all child objects, we can delete the queue. */ +- kobject_uevent(&q->kobj, KOBJ_REMOVE); +- kobject_del(&q->kobj); ++ kobject_uevent(&disk->queue_kobj, KOBJ_REMOVE); ++ kobject_del(&disk->queue_kobj); + mutex_unlock(&q->sysfs_dir_lock); + + blk_debugfs_remove(disk); +diff --git a/block/blk.h b/block/blk.h +index 0661fa4b3a4d..6fe583dd6e3b 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -26,10 +26,6 @@ struct blk_flush_queue { + spinlock_t mq_flush_lock; + }; + +-extern struct kmem_cache *blk_requestq_cachep; +-extern struct kobj_type blk_queue_ktype; +-extern struct ida blk_queue_ida; +- + bool is_flush_rq(struct request *req); + + struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size, +diff --git a/block/bsg.c b/block/bsg.c +index 2ab1351eb082..8eba57b9bb46 100644 +--- a/block/bsg.c ++++ b/block/bsg.c +@@ -175,8 +175,10 @@ static void bsg_device_release(struct device *dev) + + void bsg_unregister_queue(struct bsg_device *bd) + { +- if (bd->queue->kobj.sd) +- sysfs_remove_link(&bd->queue->kobj, "bsg"); ++ struct gendisk *disk = bd->queue->disk; ++ ++ if (disk && disk->queue_kobj.sd) ++ sysfs_remove_link(&disk->queue_kobj, "bsg"); + cdev_device_del(&bd->cdev, &bd->device); + put_device(&bd->device); + } +@@ -216,8 +218,9 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, + if (ret) + goto out_put_device; + +- if (q->kobj.sd) { +- ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg"); ++ if (q->disk && q->disk->queue_kobj.sd) { ++ ret = sysfs_create_link(&q->disk->queue_kobj, &bd->device.kobj, ++ "bsg"); + if (ret) + goto out_device_del; + } +diff --git a/block/elevator.c b/block/elevator.c +index bd71f0fc4e4b..ac096f494911 100644 +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -499,7 +499,7 @@ int elv_register_queue(struct request_queue *q, bool uevent) + + lockdep_assert_held(&q->sysfs_lock); + +- error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched"); ++ error = kobject_add(&e->kobj, &q->disk->queue_kobj, "iosched"); + if (!error) { + struct elv_fs_entry *attr = e->type->elevator_attrs; + if (attr) { +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 36c286d22fb2..17dc59c5aa90 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -155,6 +155,7 @@ struct gendisk { + unsigned open_partitions; /* number of open partitions */ + + struct backing_dev_info *bdi; ++ struct kobject queue_kobj; /* the queue/ directory */ + struct kobject *slave_dir; + #ifdef CONFIG_BLOCK_HOLDER_DEPRECATED + struct list_head slave_bdevs; +@@ -437,10 +438,7 @@ struct request_queue { + + struct gendisk *disk; + +- /* +- * queue kobject +- */ +- struct kobject kobj; ++ refcount_t refs; + + /* + * mq queue kobject +-- +2.35.1 + diff --git a/queue-6.1/bnxt-make-sure-we-return-pages-to-the-pool.patch b/queue-6.1/bnxt-make-sure-we-return-pages-to-the-pool.patch new file mode 100644 index 00000000000..b732a0932ea --- /dev/null +++ b/queue-6.1/bnxt-make-sure-we-return-pages-to-the-pool.patch @@ -0,0 +1,52 @@ +From 55174d10e4cfab4b9ed03b61aef0d9f127b45a3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jan 2023 20:25:47 -0800 +Subject: bnxt: make sure we return pages to the pool + +From: Jakub Kicinski + +[ Upstream commit 97f5e03a4a27d27ee4fed0cdb1658c81cf2784db ] + +Before the commit under Fixes the page would have been released +from the pool before the napi_alloc_skb() call, so normal page +freeing was fine (released page == no longer in the pool). + +After the change we just mark the page for recycling so it's still +in the pool if the skb alloc fails, we need to recycle. + +Same commit added the same bug in the new bnxt_rx_multi_page_skb(). + +Fixes: 1dc4c557bfed ("bnxt: adding bnxt_xdp_build_skb to build skb from multibuffer xdp_buff") +Reviewed-by: Andy Gospodarek +Link: https://lore.kernel.org/r/20230111042547.987749-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index f5a8bae8d79a..edca16b5f9e3 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -990,7 +990,7 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp, + DMA_ATTR_WEAK_ORDERING); + skb = build_skb(page_address(page), PAGE_SIZE); + if (!skb) { +- __free_page(page); ++ page_pool_recycle_direct(rxr->page_pool, page); + return NULL; + } + skb_mark_for_recycle(skb); +@@ -1028,7 +1028,7 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp, + + skb = napi_alloc_skb(&rxr->bnapi->napi, payload); + if (!skb) { +- __free_page(page); ++ page_pool_recycle_direct(rxr->page_pool, page); + return NULL; + } + +-- +2.35.1 + diff --git a/queue-6.1/drm-amdgpu-fix-potential-null-dereference.patch b/queue-6.1/drm-amdgpu-fix-potential-null-dereference.patch new file mode 100644 index 00000000000..73aa60a1bfa --- /dev/null +++ b/queue-6.1/drm-amdgpu-fix-potential-null-dereference.patch @@ -0,0 +1,48 @@ +From 1cbce5ec8e6ce678d060ef683b45499b2972704b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 17:09:02 -0500 +Subject: drm/amdgpu: Fix potential NULL dereference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Luben Tuikov + +[ Upstream commit 0be7ed8e7eb15282b5d0f6fdfea884db594ea9bf ] + +Fix potential NULL dereference, in the case when "man", the resource manager +might be NULL, when/if we print debug information. + +Cc: Alex Deucher +Cc: Christian König +Cc: AMD Graphics +Cc: Dan Carpenter +Cc: kernel test robot +Fixes: 7554886daa31ea ("drm/amdgpu: Fix size validation for non-exclusive domains (v4)") +Signed-off-by: Luben Tuikov +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +index 3be3cba3a16d..cfd78c4a45ba 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -468,8 +468,9 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev, + return true; + + fail: +- DRM_DEBUG("BO size %lu > total memory in domain: %llu\n", size, +- man->size); ++ if (man) ++ DRM_DEBUG("BO size %lu > total memory in domain: %llu\n", size, ++ man->size); + return false; + } + +-- +2.35.1 + diff --git a/queue-6.1/drm-msm-dpu-fix-memory-leak-in-msm_mdss_parse_data_b.patch b/queue-6.1/drm-msm-dpu-fix-memory-leak-in-msm_mdss_parse_data_b.patch new file mode 100644 index 00000000000..301beda0b3e --- /dev/null +++ b/queue-6.1/drm-msm-dpu-fix-memory-leak-in-msm_mdss_parse_data_b.patch @@ -0,0 +1,52 @@ +From 3c3debecffc9122efce64174d9841f64bb7aeb25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:59:22 +0400 +Subject: drm/msm/dpu: Fix memory leak in msm_mdss_parse_data_bus_icc_path + +From: Miaoqian Lin + +[ Upstream commit 45dac1352b55b1d8cb17f218936b2bc2bc1fb4ee ] + +of_icc_get() alloc resources for path1, we should release it when not +need anymore. Early return when IS_ERR_OR_NULL(path0) may leak path1. +Defer getting path1 to fix this. + +Fixes: b9364eed9232 ("drm/msm/dpu: Move min BW request and full BW disable back to mdss") +Signed-off-by: Miaoqian Lin +Reviewed-by: Douglas Anderson +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/514264/ +Link: https://lore.kernel.org/r/20221207065922.2086368-1-linmq006@gmail.com +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_mdss.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c +index e13c5c12b775..3b8d6991b04e 100644 +--- a/drivers/gpu/drm/msm/msm_mdss.c ++++ b/drivers/gpu/drm/msm/msm_mdss.c +@@ -46,15 +46,17 @@ struct msm_mdss { + static int msm_mdss_parse_data_bus_icc_path(struct device *dev, + struct msm_mdss *msm_mdss) + { +- struct icc_path *path0 = of_icc_get(dev, "mdp0-mem"); +- struct icc_path *path1 = of_icc_get(dev, "mdp1-mem"); ++ struct icc_path *path0; ++ struct icc_path *path1; + ++ path0 = of_icc_get(dev, "mdp0-mem"); + if (IS_ERR_OR_NULL(path0)) + return PTR_ERR_OR_ZERO(path0); + + msm_mdss->path[0] = path0; + msm_mdss->num_paths = 1; + ++ path1 = of_icc_get(dev, "mdp1-mem"); + if (!IS_ERR_OR_NULL(path1)) { + msm_mdss->path[1] = path1; + msm_mdss->num_paths++; +-- +2.35.1 + diff --git a/queue-6.1/drm-msm-dpu-fix-some-kernel-doc-comments.patch b/queue-6.1/drm-msm-dpu-fix-some-kernel-doc-comments.patch new file mode 100644 index 00000000000..b09ff2ef188 --- /dev/null +++ b/queue-6.1/drm-msm-dpu-fix-some-kernel-doc-comments.patch @@ -0,0 +1,54 @@ +From d9af0a8f4b170f972d9240218e251b2760a86a9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 09:49:02 +0800 +Subject: drm/msm/dpu: Fix some kernel-doc comments + +From: Yang Li + +[ Upstream commit 1bdeb321d1f856346fe0078af09c9e7ffbd2ca7a ] + +Make the description of @init to @p in dpu_encoder_phys_wb_init() +and remove @wb_roi in dpu_encoder_phys_wb_setup_fb() to clear the below +warnings: + +drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c:139: warning: Excess function parameter 'wb_roi' description in 'dpu_encoder_phys_wb_setup_fb' +drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c:699: warning: Function parameter or member 'p' not described in 'dpu_encoder_phys_wb_init' +drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c:699: warning: Excess function parameter 'init' description in 'dpu_encoder_phys_wb_init' + +Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3067 +Reported-by: Abaci Robot +Signed-off-by: Yang Li +Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback") +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/511605/ +Link: https://lore.kernel.org/r/20221115014902.45240-1-yang.lee@linux.alibaba.com +Signed-off-by: Abhinav Kumar +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +index 7cbcef6efe17..62f6ff6abf41 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +@@ -132,7 +132,6 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc) + * dpu_encoder_phys_wb_setup_fb - setup output framebuffer + * @phys_enc: Pointer to physical encoder + * @fb: Pointer to output framebuffer +- * @wb_roi: Pointer to output region of interest + */ + static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, + struct drm_framebuffer *fb) +@@ -692,7 +691,7 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) + + /** + * dpu_encoder_phys_wb_init - initialize writeback encoder +- * @init: Pointer to init info structure with initialization params ++ * @p: Pointer to init info structure with initialization params + */ + struct dpu_encoder_phys *dpu_encoder_phys_wb_init( + struct dpu_enc_phys_init_params *p) +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-refactor-resource-manager-s-hashtable-to-.patch b/queue-6.1/drm-vmwgfx-refactor-resource-manager-s-hashtable-to-.patch new file mode 100644 index 00000000000..0544db1d53f --- /dev/null +++ b/queue-6.1/drm-vmwgfx-refactor-resource-manager-s-hashtable-to-.patch @@ -0,0 +1,203 @@ +From 9ee285c12d8374ed6c57615766c1e1b4ddf8152f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:22 -0400 +Subject: drm/vmwgfx: Refactor resource manager's hashtable to use + linux/hashtable implementation. + +From: Maaz Mombasawala + +[ Upstream commit 43531dc661b7fb6be249c023bf25847b38215545 ] + +Vmwgfx's hashtab implementation needs to be replaced with linux/hashtable +to reduce maintenance burden. +Refactor cmdbuf resource manager to use linux/hashtable.h implementation +as part of this effort. + +Signed-off-by: Maaz Mombasawala +Reviewed-by: Zack Rusin +Reviewed-by: Martin Krastev +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-4-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 62 +++++++++------------- + 1 file changed, 26 insertions(+), 36 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +index 82ef58ccdd42..142aef686fcd 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 OR MIT + /************************************************************************** + * +- * Copyright 2014-2015 VMware, Inc., Palo Alto, CA., USA ++ * Copyright 2014-2022 VMware, Inc., Palo Alto, CA., USA + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the +@@ -28,6 +28,8 @@ + #include "vmwgfx_drv.h" + #include "vmwgfx_resource_priv.h" + ++#include ++ + #define VMW_CMDBUF_RES_MAN_HT_ORDER 12 + + /** +@@ -59,7 +61,7 @@ struct vmw_cmdbuf_res { + * @resources and @list are protected by the cmdbuf mutex for now. + */ + struct vmw_cmdbuf_res_manager { +- struct vmwgfx_open_hash resources; ++ DECLARE_HASHTABLE(resources, VMW_CMDBUF_RES_MAN_HT_ORDER); + struct list_head list; + struct vmw_private *dev_priv; + }; +@@ -82,14 +84,13 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man, + u32 user_key) + { + struct vmwgfx_hash_item *hash; +- int ret; + unsigned long key = user_key | (res_type << 24); + +- ret = vmwgfx_ht_find_item(&man->resources, key, &hash); +- if (unlikely(ret != 0)) +- return ERR_PTR(ret); +- +- return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res; ++ hash_for_each_possible_rcu(man->resources, hash, head, key) { ++ if (hash->key == key) ++ return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res; ++ } ++ return ERR_PTR(-EINVAL); + } + + /** +@@ -105,7 +106,7 @@ static void vmw_cmdbuf_res_free(struct vmw_cmdbuf_res_manager *man, + struct vmw_cmdbuf_res *entry) + { + list_del(&entry->head); +- WARN_ON(vmwgfx_ht_remove_item(&man->resources, &entry->hash)); ++ hash_del_rcu(&entry->hash.head); + vmw_resource_unreference(&entry->res); + kfree(entry); + } +@@ -159,7 +160,6 @@ void vmw_cmdbuf_res_commit(struct list_head *list) + void vmw_cmdbuf_res_revert(struct list_head *list) + { + struct vmw_cmdbuf_res *entry, *next; +- int ret; + + list_for_each_entry_safe(entry, next, list, head) { + switch (entry->state) { +@@ -167,8 +167,8 @@ void vmw_cmdbuf_res_revert(struct list_head *list) + vmw_cmdbuf_res_free(entry->man, entry); + break; + case VMW_CMDBUF_RES_DEL: +- ret = vmwgfx_ht_insert_item(&entry->man->resources, &entry->hash); +- BUG_ON(ret); ++ hash_add_rcu(entry->man->resources, &entry->hash.head, ++ entry->hash.key); + list_move_tail(&entry->head, &entry->man->list); + entry->state = VMW_CMDBUF_RES_COMMITTED; + break; +@@ -199,26 +199,20 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man, + struct list_head *list) + { + struct vmw_cmdbuf_res *cres; +- int ret; + + cres = kzalloc(sizeof(*cres), GFP_KERNEL); + if (unlikely(!cres)) + return -ENOMEM; + + cres->hash.key = user_key | (res_type << 24); +- ret = vmwgfx_ht_insert_item(&man->resources, &cres->hash); +- if (unlikely(ret != 0)) { +- kfree(cres); +- goto out_invalid_key; +- } ++ hash_add_rcu(man->resources, &cres->hash.head, cres->hash.key); + + cres->state = VMW_CMDBUF_RES_ADD; + cres->res = vmw_resource_reference(res); + cres->man = man; + list_add_tail(&cres->head, list); + +-out_invalid_key: +- return ret; ++ return 0; + } + + /** +@@ -243,24 +237,26 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, + struct list_head *list, + struct vmw_resource **res_p) + { +- struct vmw_cmdbuf_res *entry; ++ struct vmw_cmdbuf_res *entry = NULL; + struct vmwgfx_hash_item *hash; +- int ret; ++ unsigned long key = user_key | (res_type << 24); + +- ret = vmwgfx_ht_find_item(&man->resources, user_key | (res_type << 24), +- &hash); +- if (likely(ret != 0)) ++ hash_for_each_possible_rcu(man->resources, hash, head, key) { ++ if (hash->key == key) { ++ entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash); ++ break; ++ } ++ } ++ if (unlikely(!entry)) + return -EINVAL; + +- entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash); +- + switch (entry->state) { + case VMW_CMDBUF_RES_ADD: + vmw_cmdbuf_res_free(man, entry); + *res_p = NULL; + break; + case VMW_CMDBUF_RES_COMMITTED: +- (void) vmwgfx_ht_remove_item(&man->resources, &entry->hash); ++ hash_del_rcu(&entry->hash.head); + list_del(&entry->head); + entry->state = VMW_CMDBUF_RES_DEL; + list_add_tail(&entry->head, list); +@@ -287,7 +283,6 @@ struct vmw_cmdbuf_res_manager * + vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv) + { + struct vmw_cmdbuf_res_manager *man; +- int ret; + + man = kzalloc(sizeof(*man), GFP_KERNEL); + if (!man) +@@ -295,12 +290,8 @@ vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv) + + man->dev_priv = dev_priv; + INIT_LIST_HEAD(&man->list); +- ret = vmwgfx_ht_create(&man->resources, VMW_CMDBUF_RES_MAN_HT_ORDER); +- if (ret == 0) +- return man; +- +- kfree(man); +- return ERR_PTR(ret); ++ hash_init(man->resources); ++ return man; + } + + /** +@@ -320,7 +311,6 @@ void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man) + list_for_each_entry_safe(entry, next, &man->list, head) + vmw_cmdbuf_res_free(man, entry); + +- vmwgfx_ht_remove(&man->resources); + kfree(man); + } + +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-refactor-resource-validation-hashtable-to.patch b/queue-6.1/drm-vmwgfx-refactor-resource-validation-hashtable-to.patch new file mode 100644 index 00000000000..9d764a8c15d --- /dev/null +++ b/queue-6.1/drm-vmwgfx-refactor-resource-validation-hashtable-to.patch @@ -0,0 +1,382 @@ +From d8260b86aa4503b7be4800e358ea5bf589b71e52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:24 -0400 +Subject: drm/vmwgfx: Refactor resource validation hashtable to use + linux/hashtable implementation. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maaz Mombasawala + +[ Upstream commit 9e931f2e09701e25744f3d186a4ba13b5342b136 ] + +Vmwgfx's hashtab implementation needs to be replaced with linux/hashtable +to reduce maintenence burden. +As part of this effort, refactor the res_ht hashtable used for resource +validation during execbuf execution to use linux/hashtable implementation. +This also refactors vmw_validation_context to use vmw_sw_context as the +container for the hashtable, whereas before it used a vmwgfx_open_hash +directly. This makes vmw_validation_context less generic, but there is +no functional change since res_ht is the only instance where validation +context used a hashtable in vmwgfx driver. + +Signed-off-by: Maaz Mombasawala +Reviewed-by: Thomas Hellström +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-6-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 24 ++++++++-- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 +- + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 14 ++---- + drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 55 +++++++++++----------- + drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 26 +++------- + 5 files changed, 58 insertions(+), 66 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 13b90273eb77..8d77e79bd904 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -830,6 +830,22 @@ static void vmw_write_driver_id(struct vmw_private *dev) + } + } + ++static void vmw_sw_context_init(struct vmw_private *dev_priv) ++{ ++ struct vmw_sw_context *sw_context = &dev_priv->ctx; ++ ++ hash_init(sw_context->res_ht); ++} ++ ++static void vmw_sw_context_fini(struct vmw_private *dev_priv) ++{ ++ struct vmw_sw_context *sw_context = &dev_priv->ctx; ++ ++ vfree(sw_context->cmd_bounce); ++ if (sw_context->staged_bindings) ++ vmw_binding_state_free(sw_context->staged_bindings); ++} ++ + static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + { + int ret; +@@ -839,6 +855,8 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + + dev_priv->drm.dev_private = dev_priv; + ++ vmw_sw_context_init(dev_priv); ++ + mutex_init(&dev_priv->cmdbuf_mutex); + mutex_init(&dev_priv->binding_mutex); + spin_lock_init(&dev_priv->resource_lock); +@@ -1168,9 +1186,7 @@ static void vmw_driver_unload(struct drm_device *dev) + + unregister_pm_notifier(&dev_priv->pm_nb); + +- if (dev_priv->ctx.res_ht_initialized) +- vmwgfx_ht_remove(&dev_priv->ctx.res_ht); +- vfree(dev_priv->ctx.cmd_bounce); ++ vmw_sw_context_fini(dev_priv); + if (dev_priv->enable_fb) { + vmw_fb_off(dev_priv); + vmw_fb_close(dev_priv); +@@ -1198,8 +1214,6 @@ static void vmw_driver_unload(struct drm_device *dev) + vmw_irq_uninstall(&dev_priv->drm); + + ttm_object_device_release(&dev_priv->tdev); +- if (dev_priv->ctx.staged_bindings) +- vmw_binding_state_free(dev_priv->ctx.staged_bindings); + + for (i = vmw_res_context; i < vmw_res_max; ++i) + idr_destroy(&dev_priv->res_idr[i]); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +index 09e2d738aa87..d87aeedb78d0 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +@@ -30,6 +30,7 @@ + + #include + #include ++#include + + #include + #include +@@ -93,6 +94,7 @@ + #define VMW_RES_STREAM ttm_driver_type2 + #define VMW_RES_FENCE ttm_driver_type3 + #define VMW_RES_SHADER ttm_driver_type4 ++#define VMW_RES_HT_ORDER 12 + + #define MKSSTAT_CAPACITY_LOG2 5U + #define MKSSTAT_CAPACITY (1U << MKSSTAT_CAPACITY_LOG2) +@@ -425,8 +427,7 @@ struct vmw_ctx_validation_info; + * @ctx: The validation context + */ + struct vmw_sw_context{ +- struct vmwgfx_open_hash res_ht; +- bool res_ht_initialized; ++ DECLARE_HASHTABLE(res_ht, VMW_RES_HT_ORDER); + bool kernel; + struct vmw_fpriv *fp; + struct drm_file *filp; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index f085dbd4736d..c943ab801ca7 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 OR MIT + /************************************************************************** + * +- * Copyright 2009 - 2015 VMware, Inc., Palo Alto, CA., USA ++ * Copyright 2009 - 2022 VMware, Inc., Palo Alto, CA., USA + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the +@@ -25,6 +25,7 @@ + * + **************************************************************************/ + #include ++#include + + #include "vmwgfx_drv.h" + #include "vmwgfx_reg.h" +@@ -34,7 +35,6 @@ + #include "vmwgfx_binding.h" + #include "vmwgfx_mksstat.h" + +-#define VMW_RES_HT_ORDER 12 + + /* + * Helper macro to get dx_ctx_node if available otherwise print an error +@@ -4101,7 +4101,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, + int ret; + int32_t out_fence_fd = -1; + struct sync_file *sync_file = NULL; +- DECLARE_VAL_CONTEXT(val_ctx, &sw_context->res_ht, 1); ++ DECLARE_VAL_CONTEXT(val_ctx, sw_context, 1); + + if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { + out_fence_fd = get_unused_fd_flags(O_CLOEXEC); +@@ -4164,14 +4164,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, + if (sw_context->staged_bindings) + vmw_binding_state_reset(sw_context->staged_bindings); + +- if (!sw_context->res_ht_initialized) { +- ret = vmwgfx_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER); +- if (unlikely(ret != 0)) +- goto out_unlock; +- +- sw_context->res_ht_initialized = true; +- } +- + INIT_LIST_HEAD(&sw_context->staged_cmd_res); + sw_context->ctx = &val_ctx; + ret = vmw_execbuf_tie_context(dev_priv, sw_context, dx_context_handle); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +index f46891012be3..f5c4a40fb16d 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 OR MIT + /************************************************************************** + * +- * Copyright © 2018 VMware, Inc., Palo Alto, CA., USA ++ * Copyright © 2018 - 2022 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a +@@ -180,11 +180,16 @@ vmw_validation_find_bo_dup(struct vmw_validation_context *ctx, + if (!ctx->merge_dups) + return NULL; + +- if (ctx->ht) { ++ if (ctx->sw_context) { + struct vmwgfx_hash_item *hash; ++ unsigned long key = (unsigned long) vbo; + +- if (!vmwgfx_ht_find_item(ctx->ht, (unsigned long) vbo, &hash)) +- bo_node = container_of(hash, typeof(*bo_node), hash); ++ hash_for_each_possible_rcu(ctx->sw_context->res_ht, hash, head, key) { ++ if (hash->key == key) { ++ bo_node = container_of(hash, typeof(*bo_node), hash); ++ break; ++ } ++ } + } else { + struct vmw_validation_bo_node *entry; + +@@ -217,11 +222,16 @@ vmw_validation_find_res_dup(struct vmw_validation_context *ctx, + if (!ctx->merge_dups) + return NULL; + +- if (ctx->ht) { ++ if (ctx->sw_context) { + struct vmwgfx_hash_item *hash; ++ unsigned long key = (unsigned long) res; + +- if (!vmwgfx_ht_find_item(ctx->ht, (unsigned long) res, &hash)) +- res_node = container_of(hash, typeof(*res_node), hash); ++ hash_for_each_possible_rcu(ctx->sw_context->res_ht, hash, head, key) { ++ if (hash->key == key) { ++ res_node = container_of(hash, typeof(*res_node), hash); ++ break; ++ } ++ } + } else { + struct vmw_validation_res_node *entry; + +@@ -269,20 +279,15 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, + } + } else { + struct ttm_validate_buffer *val_buf; +- int ret; + + bo_node = vmw_validation_mem_alloc(ctx, sizeof(*bo_node)); + if (!bo_node) + return -ENOMEM; + +- if (ctx->ht) { ++ if (ctx->sw_context) { + bo_node->hash.key = (unsigned long) vbo; +- ret = vmwgfx_ht_insert_item(ctx->ht, &bo_node->hash); +- if (ret) { +- DRM_ERROR("Failed to initialize a buffer " +- "validation entry.\n"); +- return ret; +- } ++ hash_add_rcu(ctx->sw_context->res_ht, &bo_node->hash.head, ++ bo_node->hash.key); + } + val_buf = &bo_node->base; + val_buf->bo = ttm_bo_get_unless_zero(&vbo->base); +@@ -316,7 +321,6 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, + bool *first_usage) + { + struct vmw_validation_res_node *node; +- int ret; + + node = vmw_validation_find_res_dup(ctx, res); + if (node) { +@@ -330,14 +334,9 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, + return -ENOMEM; + } + +- if (ctx->ht) { ++ if (ctx->sw_context) { + node->hash.key = (unsigned long) res; +- ret = vmwgfx_ht_insert_item(ctx->ht, &node->hash); +- if (ret) { +- DRM_ERROR("Failed to initialize a resource validation " +- "entry.\n"); +- return ret; +- } ++ hash_add_rcu(ctx->sw_context->res_ht, &node->hash.head, node->hash.key); + } + node->res = vmw_resource_reference_unless_doomed(res); + if (!node->res) +@@ -681,19 +680,19 @@ void vmw_validation_drop_ht(struct vmw_validation_context *ctx) + struct vmw_validation_bo_node *entry; + struct vmw_validation_res_node *val; + +- if (!ctx->ht) ++ if (!ctx->sw_context) + return; + + list_for_each_entry(entry, &ctx->bo_list, base.head) +- (void) vmwgfx_ht_remove_item(ctx->ht, &entry->hash); ++ hash_del_rcu(&entry->hash.head); + + list_for_each_entry(val, &ctx->resource_list, head) +- (void) vmwgfx_ht_remove_item(ctx->ht, &val->hash); ++ hash_del_rcu(&val->hash.head); + + list_for_each_entry(val, &ctx->resource_ctx_list, head) +- (void) vmwgfx_ht_remove_item(ctx->ht, &val->hash); ++ hash_del_rcu(&entry->hash.head); + +- ctx->ht = NULL; ++ ctx->sw_context = NULL; + } + + /** +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h +index f21df053882b..ab9ec226f433 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ + /************************************************************************** + * +- * Copyright © 2018 VMware, Inc., Palo Alto, CA., USA ++ * Copyright © 2018 - 2022 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a +@@ -29,12 +29,11 @@ + #define _VMWGFX_VALIDATION_H_ + + #include ++#include + #include + + #include + +-#include "vmwgfx_hashtab.h" +- + #define VMW_RES_DIRTY_NONE 0 + #define VMW_RES_DIRTY_SET BIT(0) + #define VMW_RES_DIRTY_CLEAR BIT(1) +@@ -59,7 +58,7 @@ + * @total_mem: Amount of reserved memory. + */ + struct vmw_validation_context { +- struct vmwgfx_open_hash *ht; ++ struct vmw_sw_context *sw_context; + struct list_head resource_list; + struct list_head resource_ctx_list; + struct list_head bo_list; +@@ -82,16 +81,16 @@ struct vmw_fence_obj; + /** + * DECLARE_VAL_CONTEXT - Declare a validation context with initialization + * @_name: The name of the variable +- * @_ht: The hash table used to find dups or NULL if none ++ * @_sw_context: Contains the hash table used to find dups or NULL if none + * @_merge_dups: Whether to merge duplicate buffer object- or resource + * entries. If set to true, ideally a hash table pointer should be supplied + * as well unless the number of resources and buffer objects per validation + * is known to be very small + */ + #endif +-#define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ ++#define DECLARE_VAL_CONTEXT(_name, _sw_context, _merge_dups) \ + struct vmw_validation_context _name = \ +- { .ht = _ht, \ ++ { .sw_context = _sw_context, \ + .resource_list = LIST_HEAD_INIT((_name).resource_list), \ + .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ + .bo_list = LIST_HEAD_INIT((_name).bo_list), \ +@@ -114,19 +113,6 @@ vmw_validation_has_bos(struct vmw_validation_context *ctx) + return !list_empty(&ctx->bo_list); + } + +-/** +- * vmw_validation_set_ht - Register a hash table for duplicate finding +- * @ctx: The validation context +- * @ht: Pointer to a hash table to use for duplicate finding +- * This function is intended to be used if the hash table wasn't +- * available at validation context declaration time +- */ +-static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, +- struct vmwgfx_open_hash *ht) +-{ +- ctx->ht = ht; +-} +- + /** + * vmw_validation_bo_reserve - Reserve buffer objects registered with a + * validation context +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-refactor-ttm-reference-object-hashtable-t.patch b/queue-6.1/drm-vmwgfx-refactor-ttm-reference-object-hashtable-t.patch new file mode 100644 index 00000000000..5e77a3e98f6 --- /dev/null +++ b/queue-6.1/drm-vmwgfx-refactor-ttm-reference-object-hashtable-t.patch @@ -0,0 +1,324 @@ +From 59ec46a84315d9b16c024bb045be0e48785c49b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:29 -0400 +Subject: drm/vmwgfx: Refactor ttm reference object hashtable to use + linux/hashtable. + +From: Maaz Mombasawala + +[ Upstream commit 76a9e07f270cf5fb556ac237dbf11f5dacd61fef ] + +This is part of an effort to move from the vmwgfx_open_hash hashtable to +linux/hashtable implementation. +Refactor the ref_hash hashtable, used for fast lookup of reference objects +associated with a ttm file. +This also exposed a problem related to inconsistently using 32-bit and +64-bit keys with this hashtable. The hash function used changes depending +on the size of the type, and results are not consistent across numbers, +for example, hash_32(329) = 329, but hash_long(329) = 328. This would +cause the lookup to fail for objects already in the hashtable, since keys +of different sizes were being passed during adding and lookup. This was +not an issue before because vmwgfx_open_hash always used hash_long. +Fix this by always using 64-bit keys for this hashtable, which means that +hash_long is always used. + +Signed-off-by: Maaz Mombasawala +Reviewed-by: Zack Rusin +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-11-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/ttm_object.c | 91 ++++++++++++++++------------- + drivers/gpu/drm/vmwgfx/ttm_object.h | 12 ++-- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- + 3 files changed, 56 insertions(+), 49 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c +index 9546b121bc22..c07b81fbc495 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.c ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.c +@@ -52,9 +52,12 @@ + #include + #include + #include ++#include + + MODULE_IMPORT_NS(DMA_BUF); + ++#define VMW_TTM_OBJECT_REF_HT_ORDER 10 ++ + /** + * struct ttm_object_file + * +@@ -75,7 +78,7 @@ struct ttm_object_file { + struct ttm_object_device *tdev; + spinlock_t lock; + struct list_head ref_list; +- struct vmwgfx_open_hash ref_hash; ++ DECLARE_HASHTABLE(ref_hash, VMW_TTM_OBJECT_REF_HT_ORDER); + struct kref refcount; + }; + +@@ -136,6 +139,36 @@ ttm_object_file_ref(struct ttm_object_file *tfile) + return tfile; + } + ++static int ttm_tfile_find_ref_rcu(struct ttm_object_file *tfile, ++ uint64_t key, ++ struct vmwgfx_hash_item **p_hash) ++{ ++ struct vmwgfx_hash_item *hash; ++ ++ hash_for_each_possible_rcu(tfile->ref_hash, hash, head, key) { ++ if (hash->key == key) { ++ *p_hash = hash; ++ return 0; ++ } ++ } ++ return -EINVAL; ++} ++ ++static int ttm_tfile_find_ref(struct ttm_object_file *tfile, ++ uint64_t key, ++ struct vmwgfx_hash_item **p_hash) ++{ ++ struct vmwgfx_hash_item *hash; ++ ++ hash_for_each_possible(tfile->ref_hash, hash, head, key) { ++ if (hash->key == key) { ++ *p_hash = hash; ++ return 0; ++ } ++ } ++ return -EINVAL; ++} ++ + static void ttm_object_file_destroy(struct kref *kref) + { + struct ttm_object_file *tfile = +@@ -238,14 +271,13 @@ void ttm_base_object_unref(struct ttm_base_object **p_base) + * Return: A pointer to the object if successful or NULL otherwise. + */ + struct ttm_base_object * +-ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key) ++ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key) + { + struct vmwgfx_hash_item *hash; +- struct vmwgfx_open_hash *ht = &tfile->ref_hash; + int ret; + + rcu_read_lock(); +- ret = vmwgfx_ht_find_item_rcu(ht, key, &hash); ++ ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); + if (ret) { + rcu_read_unlock(); + return NULL; +@@ -257,15 +289,14 @@ ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key) + EXPORT_SYMBOL(ttm_base_object_noref_lookup); + + struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, +- uint32_t key) ++ uint64_t key) + { + struct ttm_base_object *base = NULL; + struct vmwgfx_hash_item *hash; +- struct vmwgfx_open_hash *ht = &tfile->ref_hash; + int ret; + + rcu_read_lock(); +- ret = vmwgfx_ht_find_item_rcu(ht, key, &hash); ++ ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); + + if (likely(ret == 0)) { + base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; +@@ -278,7 +309,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, + } + + struct ttm_base_object * +-ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key) ++ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint64_t key) + { + struct ttm_base_object *base; + +@@ -297,7 +328,6 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + bool *existed, + bool require_existed) + { +- struct vmwgfx_open_hash *ht = &tfile->ref_hash; + struct ttm_ref_object *ref; + struct vmwgfx_hash_item *hash; + int ret = -EINVAL; +@@ -310,7 +340,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + + while (ret == -EINVAL) { + rcu_read_lock(); +- ret = vmwgfx_ht_find_item_rcu(ht, base->handle, &hash); ++ ret = ttm_tfile_find_ref_rcu(tfile, base->handle, &hash); + + if (ret == 0) { + ref = drm_hash_entry(hash, struct ttm_ref_object, hash); +@@ -335,21 +365,14 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + kref_init(&ref->kref); + + spin_lock(&tfile->lock); +- ret = vmwgfx_ht_insert_item_rcu(ht, &ref->hash); +- +- if (likely(ret == 0)) { +- list_add_tail(&ref->head, &tfile->ref_list); +- kref_get(&base->refcount); +- spin_unlock(&tfile->lock); +- if (existed != NULL) +- *existed = false; +- break; +- } ++ hash_add_rcu(tfile->ref_hash, &ref->hash.head, ref->hash.key); ++ ret = 0; + ++ list_add_tail(&ref->head, &tfile->ref_list); ++ kref_get(&base->refcount); + spin_unlock(&tfile->lock); +- BUG_ON(ret != -EINVAL); +- +- kfree(ref); ++ if (existed != NULL) ++ *existed = false; + } + + return ret; +@@ -361,10 +384,8 @@ ttm_ref_object_release(struct kref *kref) + struct ttm_ref_object *ref = + container_of(kref, struct ttm_ref_object, kref); + struct ttm_object_file *tfile = ref->tfile; +- struct vmwgfx_open_hash *ht; + +- ht = &tfile->ref_hash; +- (void)vmwgfx_ht_remove_item_rcu(ht, &ref->hash); ++ hash_del_rcu(&ref->hash.head); + list_del(&ref->head); + spin_unlock(&tfile->lock); + +@@ -376,13 +397,12 @@ ttm_ref_object_release(struct kref *kref) + int ttm_ref_object_base_unref(struct ttm_object_file *tfile, + unsigned long key) + { +- struct vmwgfx_open_hash *ht = &tfile->ref_hash; + struct ttm_ref_object *ref; + struct vmwgfx_hash_item *hash; + int ret; + + spin_lock(&tfile->lock); +- ret = vmwgfx_ht_find_item(ht, key, &hash); ++ ret = ttm_tfile_find_ref(tfile, key, &hash); + if (unlikely(ret != 0)) { + spin_unlock(&tfile->lock); + return -EINVAL; +@@ -414,16 +434,13 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile) + } + + spin_unlock(&tfile->lock); +- vmwgfx_ht_remove(&tfile->ref_hash); + + ttm_object_file_unref(&tfile); + } + +-struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev, +- unsigned int hash_order) ++struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev) + { + struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); +- int ret; + + if (unlikely(tfile == NULL)) + return NULL; +@@ -433,17 +450,9 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev, + kref_init(&tfile->refcount); + INIT_LIST_HEAD(&tfile->ref_list); + +- ret = vmwgfx_ht_create(&tfile->ref_hash, hash_order); +- if (ret) +- goto out_err; ++ hash_init(tfile->ref_hash); + + return tfile; +-out_err: +- vmwgfx_ht_remove(&tfile->ref_hash); +- +- kfree(tfile); +- +- return NULL; + } + + struct ttm_object_device * +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h +index 6870f951b677..67f30d589e27 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.h ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.h +@@ -104,7 +104,7 @@ struct ttm_base_object { + struct ttm_object_file *tfile; + struct kref refcount; + void (*refcount_release) (struct ttm_base_object **base); +- u32 handle; ++ u64 handle; + enum ttm_object_type object_type; + u32 shareable; + }; +@@ -164,7 +164,7 @@ extern int ttm_base_object_init(struct ttm_object_file *tfile, + */ + + extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file +- *tfile, uint32_t key); ++ *tfile, uint64_t key); + + /** + * ttm_base_object_lookup_for_ref +@@ -178,7 +178,7 @@ extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file + */ + + extern struct ttm_base_object * +-ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key); ++ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint64_t key); + + /** + * ttm_base_object_unref +@@ -237,14 +237,12 @@ extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile, + * ttm_object_file_init - initialize a struct ttm_object file + * + * @tdev: A struct ttm_object device this file is initialized on. +- * @hash_order: Order of the hash table used to hold the reference objects. + * + * This is typically called by the file_ops::open function. + */ + + extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device +- *tdev, +- unsigned int hash_order); ++ *tdev); + + /** + * ttm_object_file_release - release data held by a ttm_object_file +@@ -312,7 +310,7 @@ extern int ttm_prime_handle_to_fd(struct ttm_object_file *tfile, + kfree_rcu(__obj, __prime.base.rhead) + + struct ttm_base_object * +-ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key); ++ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key); + + /** + * ttm_base_object_noref_release - release a base object pointer looked up +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 8d77e79bd904..b909a3ce9af3 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -1242,7 +1242,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) + if (unlikely(!vmw_fp)) + return ret; + +- vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); ++ vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev); + if (unlikely(vmw_fp->tfile == NULL)) + goto out_no_tfile; + +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-remove-rcu-locks-from-user-resources.patch b/queue-6.1/drm-vmwgfx-remove-rcu-locks-from-user-resources.patch new file mode 100644 index 00000000000..70632d6b108 --- /dev/null +++ b/queue-6.1/drm-vmwgfx-remove-rcu-locks-from-user-resources.patch @@ -0,0 +1,592 @@ +From aeb4b588ab7935d6cb5910b0577f687b1c64b859 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 12:29:07 -0500 +Subject: drm/vmwgfx: Remove rcu locks from user resources + +From: Zack Rusin + +[ Upstream commit a309c7194e8a2f8bd4539b9449917913f6c2cd50 ] + +User resource lookups used rcu to avoid two extra atomics. Unfortunately +the rcu paths were buggy and it was easy to make the driver crash by +submitting command buffers from two different threads. Because the +lookups never show up in performance profiles replace them with a +regular spin lock which fixes the races in accesses to those shared +resources. + +Fixes kernel oops'es in IGT's vmwgfx execution_buffer stress test and +seen crashes with apps using shared resources. + +Fixes: e14c02e6b699 ("drm/vmwgfx: Look up objects without taking a reference") +Signed-off-by: Zack Rusin +Reviewed-by: Martin Krastev +Reviewed-by: Maaz Mombasawala +Link: https://patchwork.freedesktop.org/patch/msgid/20221207172907.959037-1-zack@kde.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/ttm_object.c | 41 +----- + drivers/gpu/drm/vmwgfx/ttm_object.h | 14 -- + drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 38 ----- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 18 +-- + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 176 +++++++++++------------ + drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 33 ----- + 6 files changed, 87 insertions(+), 233 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c +index 932b125ebf3d..ddf8373c1d77 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.c ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.c +@@ -254,40 +254,6 @@ void ttm_base_object_unref(struct ttm_base_object **p_base) + kref_put(&base->refcount, ttm_release_base); + } + +-/** +- * ttm_base_object_noref_lookup - look up a base object without reference +- * @tfile: The struct ttm_object_file the object is registered with. +- * @key: The object handle. +- * +- * This function looks up a ttm base object and returns a pointer to it +- * without refcounting the pointer. The returned pointer is only valid +- * until ttm_base_object_noref_release() is called, and the object +- * pointed to by the returned pointer may be doomed. Any persistent usage +- * of the object requires a refcount to be taken using kref_get_unless_zero(). +- * Iff this function returns successfully it needs to be paired with +- * ttm_base_object_noref_release() and no sleeping- or scheduling functions +- * may be called inbetween these function callse. +- * +- * Return: A pointer to the object if successful or NULL otherwise. +- */ +-struct ttm_base_object * +-ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key) +-{ +- struct vmwgfx_hash_item *hash; +- int ret; +- +- rcu_read_lock(); +- ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); +- if (ret) { +- rcu_read_unlock(); +- return NULL; +- } +- +- __release(RCU); +- return hlist_entry(hash, struct ttm_ref_object, hash)->obj; +-} +-EXPORT_SYMBOL(ttm_base_object_noref_lookup); +- + struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, + uint64_t key) + { +@@ -295,15 +261,16 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, + struct vmwgfx_hash_item *hash; + int ret; + +- rcu_read_lock(); +- ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); ++ spin_lock(&tfile->lock); ++ ret = ttm_tfile_find_ref(tfile, key, &hash); + + if (likely(ret == 0)) { + base = hlist_entry(hash, struct ttm_ref_object, hash)->obj; + if (!kref_get_unless_zero(&base->refcount)) + base = NULL; + } +- rcu_read_unlock(); ++ spin_unlock(&tfile->lock); ++ + + return base; + } +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h +index f0ebbe340ad6..8098a3846bae 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.h ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.h +@@ -307,18 +307,4 @@ extern int ttm_prime_handle_to_fd(struct ttm_object_file *tfile, + #define ttm_prime_object_kfree(__obj, __prime) \ + kfree_rcu(__obj, __prime.base.rhead) + +-struct ttm_base_object * +-ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key); +- +-/** +- * ttm_base_object_noref_release - release a base object pointer looked up +- * without reference +- * +- * Releases a base object pointer looked up with ttm_base_object_noref_lookup(). +- */ +-static inline void ttm_base_object_noref_release(void) +-{ +- __acquire(RCU); +- rcu_read_unlock(); +-} + #endif +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +index 822251aaab0a..973a0a52462e 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +@@ -715,44 +715,6 @@ int vmw_user_bo_lookup(struct drm_file *filp, + return 0; + } + +-/** +- * vmw_user_bo_noref_lookup - Look up a vmw user buffer object without reference +- * @filp: The TTM object file the handle is registered with. +- * @handle: The user buffer object handle. +- * +- * This function looks up a struct vmw_bo and returns a pointer to the +- * struct vmw_buffer_object it derives from without refcounting the pointer. +- * The returned pointer is only valid until vmw_user_bo_noref_release() is +- * called, and the object pointed to by the returned pointer may be doomed. +- * Any persistent usage of the object requires a refcount to be taken using +- * ttm_bo_reference_unless_doomed(). Iff this function returns successfully it +- * needs to be paired with vmw_user_bo_noref_release() and no sleeping- +- * or scheduling functions may be called in between these function calls. +- * +- * Return: A struct vmw_buffer_object pointer if successful or negative +- * error pointer on failure. +- */ +-struct vmw_buffer_object * +-vmw_user_bo_noref_lookup(struct drm_file *filp, u32 handle) +-{ +- struct vmw_buffer_object *vmw_bo; +- struct ttm_buffer_object *bo; +- struct drm_gem_object *gobj = drm_gem_object_lookup(filp, handle); +- +- if (!gobj) { +- DRM_ERROR("Invalid buffer object handle 0x%08lx.\n", +- (unsigned long)handle); +- return ERR_PTR(-ESRCH); +- } +- vmw_bo = gem_to_vmw_bo(gobj); +- bo = ttm_bo_get_unless_zero(&vmw_bo->base); +- vmw_bo = vmw_buffer_object(bo); +- drm_gem_object_put(gobj); +- +- return vmw_bo; +-} +- +- + /** + * vmw_bo_fence_single - Utility function to fence a single TTM buffer + * object without unreserving it. +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +index 7c45c3de0dcf..0bc1ebc43002 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +@@ -826,12 +826,7 @@ extern int vmw_user_resource_lookup_handle( + uint32_t handle, + const struct vmw_user_resource_conv *converter, + struct vmw_resource **p_res); +-extern struct vmw_resource * +-vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv, +- struct ttm_object_file *tfile, +- uint32_t handle, +- const struct vmw_user_resource_conv * +- converter); ++ + extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, +@@ -870,15 +865,6 @@ static inline bool vmw_resource_mob_attached(const struct vmw_resource *res) + return !RB_EMPTY_NODE(&res->mob_node); + } + +-/** +- * vmw_user_resource_noref_release - release a user resource pointer looked up +- * without reference +- */ +-static inline void vmw_user_resource_noref_release(void) +-{ +- ttm_base_object_noref_release(); +-} +- + /** + * Buffer object helper functions - vmwgfx_bo.c + */ +@@ -930,8 +916,6 @@ extern void vmw_bo_unmap(struct vmw_buffer_object *vbo); + extern void vmw_bo_move_notify(struct ttm_buffer_object *bo, + struct ttm_resource *mem); + extern void vmw_bo_swap_notify(struct ttm_buffer_object *bo); +-extern struct vmw_buffer_object * +-vmw_user_bo_noref_lookup(struct drm_file *filp, u32 handle); + + /** + * vmw_bo_adjust_prio - Adjust the buffer object eviction priority +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index c943ab801ca7..70cfed4fdba0 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -290,20 +290,26 @@ static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, + rcache->valid_handle = 0; + } + ++enum vmw_val_add_flags { ++ vmw_val_add_flag_none = 0, ++ vmw_val_add_flag_noctx = 1 << 0, ++}; ++ + /** +- * vmw_execbuf_res_noref_val_add - Add a resource described by an unreferenced +- * rcu-protected pointer to the validation list. ++ * vmw_execbuf_res_val_add - Add a resource to the validation list. + * + * @sw_context: Pointer to the software context. + * @res: Unreferenced rcu-protected pointer to the resource. + * @dirty: Whether to change dirty status. ++ * @flags: specifies whether to use the context or not + * + * Returns: 0 on success. Negative error code on failure. Typical error codes + * are %-EINVAL on inconsistency and %-ESRCH if the resource was doomed. + */ +-static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, +- struct vmw_resource *res, +- u32 dirty) ++static int vmw_execbuf_res_val_add(struct vmw_sw_context *sw_context, ++ struct vmw_resource *res, ++ u32 dirty, ++ u32 flags) + { + struct vmw_private *dev_priv = res->dev_priv; + int ret; +@@ -318,24 +324,30 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, + if (dirty) + vmw_validation_res_set_dirty(sw_context->ctx, + rcache->private, dirty); +- vmw_user_resource_noref_release(); + return 0; + } + +- priv_size = vmw_execbuf_res_size(dev_priv, res_type); +- ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size, +- dirty, (void **)&ctx_info, +- &first_usage); +- vmw_user_resource_noref_release(); +- if (ret) +- return ret; ++ if ((flags & vmw_val_add_flag_noctx) != 0) { ++ ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty, ++ (void **)&ctx_info, NULL); ++ if (ret) ++ return ret; + +- if (priv_size && first_usage) { +- ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res, +- ctx_info); +- if (ret) { +- VMW_DEBUG_USER("Failed first usage context setup.\n"); ++ } else { ++ priv_size = vmw_execbuf_res_size(dev_priv, res_type); ++ ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size, ++ dirty, (void **)&ctx_info, ++ &first_usage); ++ if (ret) + return ret; ++ ++ if (priv_size && first_usage) { ++ ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res, ++ ctx_info); ++ if (ret) { ++ VMW_DEBUG_USER("Failed first usage context setup.\n"); ++ return ret; ++ } + } + } + +@@ -343,43 +355,6 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, + return 0; + } + +-/** +- * vmw_execbuf_res_noctx_val_add - Add a non-context resource to the resource +- * validation list if it's not already on it +- * +- * @sw_context: Pointer to the software context. +- * @res: Pointer to the resource. +- * @dirty: Whether to change dirty status. +- * +- * Returns: Zero on success. Negative error code on failure. +- */ +-static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context, +- struct vmw_resource *res, +- u32 dirty) +-{ +- struct vmw_res_cache_entry *rcache; +- enum vmw_res_type res_type = vmw_res_type(res); +- void *ptr; +- int ret; +- +- rcache = &sw_context->res_cache[res_type]; +- if (likely(rcache->valid && rcache->res == res)) { +- if (dirty) +- vmw_validation_res_set_dirty(sw_context->ctx, +- rcache->private, dirty); +- return 0; +- } +- +- ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty, +- &ptr, NULL); +- if (ret) +- return ret; +- +- vmw_execbuf_rcache_update(rcache, res, ptr); +- +- return 0; +-} +- + /** + * vmw_view_res_val_add - Add a view and the surface it's pointing to to the + * validation list +@@ -398,13 +373,13 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, + * First add the resource the view is pointing to, otherwise it may be + * swapped out when the view is validated. + */ +- ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view), +- vmw_view_dirtying(view)); ++ ret = vmw_execbuf_res_val_add(sw_context, vmw_view_srf(view), ++ vmw_view_dirtying(view), vmw_val_add_flag_noctx); + if (ret) + return ret; + +- return vmw_execbuf_res_noctx_val_add(sw_context, view, +- VMW_RES_DIRTY_NONE); ++ return vmw_execbuf_res_val_add(sw_context, view, VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + } + + /** +@@ -475,8 +450,9 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, + if (IS_ERR(res)) + continue; + +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_SET); ++ ret = vmw_execbuf_res_val_add(sw_context, res, ++ VMW_RES_DIRTY_SET, ++ vmw_val_add_flag_noctx); + if (unlikely(ret != 0)) + return ret; + } +@@ -490,9 +466,9 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, + if (vmw_res_type(entry->res) == vmw_res_view) + ret = vmw_view_res_val_add(sw_context, entry->res); + else +- ret = vmw_execbuf_res_noctx_val_add +- (sw_context, entry->res, +- vmw_binding_dirtying(entry->bt)); ++ ret = vmw_execbuf_res_val_add(sw_context, entry->res, ++ vmw_binding_dirtying(entry->bt), ++ vmw_val_add_flag_noctx); + if (unlikely(ret != 0)) + break; + } +@@ -658,7 +634,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, + { + struct vmw_res_cache_entry *rcache = &sw_context->res_cache[res_type]; + struct vmw_resource *res; +- int ret; ++ int ret = 0; ++ bool needs_unref = false; + + if (p_res) + *p_res = NULL; +@@ -683,17 +660,18 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, + if (ret) + return ret; + +- res = vmw_user_resource_noref_lookup_handle +- (dev_priv, sw_context->fp->tfile, *id_loc, converter); +- if (IS_ERR(res)) { ++ ret = vmw_user_resource_lookup_handle ++ (dev_priv, sw_context->fp->tfile, *id_loc, converter, &res); ++ if (ret != 0) { + VMW_DEBUG_USER("Could not find/use resource 0x%08x.\n", + (unsigned int) *id_loc); +- return PTR_ERR(res); ++ return ret; + } ++ needs_unref = true; + +- ret = vmw_execbuf_res_noref_val_add(sw_context, res, dirty); ++ ret = vmw_execbuf_res_val_add(sw_context, res, dirty, vmw_val_add_flag_none); + if (unlikely(ret != 0)) +- return ret; ++ goto res_check_done; + + if (rcache->valid && rcache->res == res) { + rcache->valid_handle = true; +@@ -708,7 +686,11 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, + if (p_res) + *p_res = res; + +- return 0; ++res_check_done: ++ if (needs_unref) ++ vmw_resource_unreference(&res); ++ ++ return ret; + } + + /** +@@ -1171,9 +1153,9 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, + int ret; + + vmw_validation_preload_bo(sw_context->ctx); +- vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle); +- if (IS_ERR(vmw_bo)) { +- VMW_DEBUG_USER("Could not find or use MOB buffer.\n"); ++ ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo); ++ if (ret != 0) { ++ drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n"); + return PTR_ERR(vmw_bo); + } + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false); +@@ -1225,9 +1207,9 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, + int ret; + + vmw_validation_preload_bo(sw_context->ctx); +- vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle); +- if (IS_ERR(vmw_bo)) { +- VMW_DEBUG_USER("Could not find or use GMR region.\n"); ++ ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo); ++ if (ret != 0) { ++ drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n"); + return PTR_ERR(vmw_bo); + } + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false); +@@ -2025,8 +2007,9 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, + res = vmw_shader_lookup(vmw_context_res_man(ctx), + cmd->body.shid, cmd->body.type); + if (!IS_ERR(res)) { +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_NONE); ++ ret = vmw_execbuf_res_val_add(sw_context, res, ++ VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + if (unlikely(ret != 0)) + return ret; + +@@ -2273,8 +2256,9 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, + return PTR_ERR(res); + } + +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_NONE); ++ ret = vmw_execbuf_res_val_add(sw_context, res, ++ VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + if (ret) + return ret; + } +@@ -2777,8 +2761,8 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, + return PTR_ERR(res); + } + +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_NONE); ++ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + if (ret) { + VMW_DEBUG_USER("Error creating resource validation node.\n"); + return ret; +@@ -3098,8 +3082,8 @@ static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv, + + vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes); + +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_NONE); ++ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; +@@ -3148,8 +3132,8 @@ static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv, + return 0; + } + +- ret = vmw_execbuf_res_noctx_val_add(sw_context, res, +- VMW_RES_DIRTY_NONE); ++ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE, ++ vmw_val_add_flag_noctx); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; +@@ -4067,22 +4051,26 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, + if (ret) + return ret; + +- res = vmw_user_resource_noref_lookup_handle ++ ret = vmw_user_resource_lookup_handle + (dev_priv, sw_context->fp->tfile, handle, +- user_context_converter); +- if (IS_ERR(res)) { ++ user_context_converter, &res); ++ if (ret != 0) { + VMW_DEBUG_USER("Could not find or user DX context 0x%08x.\n", + (unsigned int) handle); +- return PTR_ERR(res); ++ return ret; + } + +- ret = vmw_execbuf_res_noref_val_add(sw_context, res, VMW_RES_DIRTY_SET); +- if (unlikely(ret != 0)) ++ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_SET, ++ vmw_val_add_flag_none); ++ if (unlikely(ret != 0)) { ++ vmw_resource_unreference(&res); + return ret; ++ } + + sw_context->dx_ctx_node = vmw_execbuf_info_from_res(sw_context, res); + sw_context->man = vmw_context_res_man(res); + ++ vmw_resource_unreference(&res); + return 0; + } + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +index f66caa540e14..c7d645e5ec7b 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -281,39 +281,6 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv, + return ret; + } + +-/** +- * vmw_user_resource_noref_lookup_handle - lookup a struct resource from a +- * TTM user-space handle and perform basic type checks +- * +- * @dev_priv: Pointer to a device private struct +- * @tfile: Pointer to a struct ttm_object_file identifying the caller +- * @handle: The TTM user-space handle +- * @converter: Pointer to an object describing the resource type +- * +- * If the handle can't be found or is associated with an incorrect resource +- * type, -EINVAL will be returned. +- */ +-struct vmw_resource * +-vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv, +- struct ttm_object_file *tfile, +- uint32_t handle, +- const struct vmw_user_resource_conv +- *converter) +-{ +- struct ttm_base_object *base; +- +- base = ttm_base_object_noref_lookup(tfile, handle); +- if (!base) +- return ERR_PTR(-ESRCH); +- +- if (unlikely(ttm_base_object_type(base) != converter->object_type)) { +- ttm_base_object_noref_release(); +- return ERR_PTR(-EINVAL); +- } +- +- return converter->base_obj_to_res(base); +-} +- + /* + * Helper function that looks either a surface or bo. + * +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-remove-ttm-object-hashtable.patch b/queue-6.1/drm-vmwgfx-remove-ttm-object-hashtable.patch new file mode 100644 index 00000000000..ca0c4af75dd --- /dev/null +++ b/queue-6.1/drm-vmwgfx-remove-ttm-object-hashtable.patch @@ -0,0 +1,161 @@ +From eac299d4a11e8351038ab2f59aede53d4c8f52fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:23 -0400 +Subject: drm/vmwgfx: Remove ttm object hashtable + +From: Maaz Mombasawala + +[ Upstream commit 931e09d8d5b4aa19bdae0234f2727049f1cd13d9 ] + +The object_hash hashtable for ttm objects is not being used. +Remove it and perform refactoring in ttm_object init function. + +Signed-off-by: Maaz Mombasawala +Reviewed-by: Zack Rusin +Reviewed-by: Martin Krastev +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-5-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/ttm_object.c | 24 ++++++------------------ + drivers/gpu/drm/vmwgfx/ttm_object.h | 6 ++---- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- + 3 files changed, 9 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c +index 26a55fef1ab5..9546b121bc22 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.c ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.c +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ + /************************************************************************** + * +- * Copyright (c) 2009-2013 VMware, Inc., Palo Alto, CA., USA ++ * Copyright (c) 2009-2022 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a +@@ -44,13 +44,14 @@ + + #define pr_fmt(fmt) "[TTM] " fmt + ++#include "ttm_object.h" ++#include "vmwgfx_drv.h" ++ + #include + #include + #include + #include + #include +-#include "ttm_object.h" +-#include "vmwgfx_drv.h" + + MODULE_IMPORT_NS(DMA_BUF); + +@@ -81,9 +82,7 @@ struct ttm_object_file { + /* + * struct ttm_object_device + * +- * @object_lock: lock that protects the object_hash hash table. +- * +- * @object_hash: hash table for fast lookup of object global names. ++ * @object_lock: lock that protects idr. + * + * @object_count: Per device object count. + * +@@ -92,7 +91,6 @@ struct ttm_object_file { + + struct ttm_object_device { + spinlock_t object_lock; +- struct vmwgfx_open_hash object_hash; + atomic_t object_count; + struct dma_buf_ops ops; + void (*dmabuf_release)(struct dma_buf *dma_buf); +@@ -449,20 +447,15 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev, + } + + struct ttm_object_device * +-ttm_object_device_init(unsigned int hash_order, +- const struct dma_buf_ops *ops) ++ttm_object_device_init(const struct dma_buf_ops *ops) + { + struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL); +- int ret; + + if (unlikely(tdev == NULL)) + return NULL; + + spin_lock_init(&tdev->object_lock); + atomic_set(&tdev->object_count, 0); +- ret = vmwgfx_ht_create(&tdev->object_hash, hash_order); +- if (ret != 0) +- goto out_no_object_hash; + + /* + * Our base is at VMWGFX_NUM_MOB + 1 because we want to create +@@ -477,10 +470,6 @@ ttm_object_device_init(unsigned int hash_order, + tdev->dmabuf_release = tdev->ops.release; + tdev->ops.release = ttm_prime_dmabuf_release; + return tdev; +- +-out_no_object_hash: +- kfree(tdev); +- return NULL; + } + + void ttm_object_device_release(struct ttm_object_device **p_tdev) +@@ -491,7 +480,6 @@ void ttm_object_device_release(struct ttm_object_device **p_tdev) + + WARN_ON_ONCE(!idr_is_empty(&tdev->idr)); + idr_destroy(&tdev->idr); +- vmwgfx_ht_remove(&tdev->object_hash); + + kfree(tdev); + } +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h +index 1a2fa0f83f5f..6870f951b677 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.h ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.h +@@ -1,6 +1,6 @@ + /************************************************************************** + * +- * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA ++ * Copyright (c) 2006-2022 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a +@@ -262,7 +262,6 @@ extern void ttm_object_file_release(struct ttm_object_file **p_tfile); + /** + * ttm_object device init - initialize a struct ttm_object_device + * +- * @hash_order: Order of hash table used to hash the base objects. + * @ops: DMA buf ops for prime objects of this device. + * + * This function is typically called on device initialization to prepare +@@ -270,8 +269,7 @@ extern void ttm_object_file_release(struct ttm_object_file **p_tfile); + */ + + extern struct ttm_object_device * +-ttm_object_device_init(unsigned int hash_order, +- const struct dma_buf_ops *ops); ++ttm_object_device_init(const struct dma_buf_ops *ops); + + /** + * ttm_object_device_release - release data held by a ttm_object_device +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 45028e25d490..13b90273eb77 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -994,7 +994,7 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + goto out_err0; + } + +- dev_priv->tdev = ttm_object_device_init(12, &vmw_prime_dmabuf_ops); ++ dev_priv->tdev = ttm_object_device_init(&vmw_prime_dmabuf_ops); + + if (unlikely(dev_priv->tdev == NULL)) { + drm_err(&dev_priv->drm, +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-remove-vmwgfx_hashtab.patch b/queue-6.1/drm-vmwgfx-remove-vmwgfx_hashtab.patch new file mode 100644 index 00000000000..784edf608f1 --- /dev/null +++ b/queue-6.1/drm-vmwgfx-remove-vmwgfx_hashtab.patch @@ -0,0 +1,462 @@ +From f6bd263170131cfd1f3975110aaef11f994a9e13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:30 -0400 +Subject: drm/vmwgfx: Remove vmwgfx_hashtab + +From: Maaz Mombasawala + +[ Upstream commit 9da30cdd6a318595199319708c143ae318f804ef ] + +The vmwgfx driver has migrated from using the hashtable in vmwgfx_hashtab +to the linux/hashtable implementation. Remove the vmwgfx_hashtab from the +driver. + +Signed-off-by: Maaz Mombasawala +Reviewed-by: Martin Krastev +Reviewed-by: Zack Rusin +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-12-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + Documentation/gpu/todo.rst | 11 -- + drivers/gpu/drm/vmwgfx/Makefile | 2 +- + drivers/gpu/drm/vmwgfx/ttm_object.c | 8 +- + drivers/gpu/drm/vmwgfx/ttm_object.h | 2 - + drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 6 +- + drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c | 199 --------------------- + drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h | 83 --------- + 8 files changed, 12 insertions(+), 303 deletions(-) + delete mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c + delete mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h + +diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst +index 393d218e4a0c..b2c6aaf1edf2 100644 +--- a/Documentation/gpu/todo.rst ++++ b/Documentation/gpu/todo.rst +@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks. + + Contact: Harry Wentland, Alex Deucher + +-vmwgfx: Replace hashtable with Linux' implementation +----------------------------------------------------- +- +-The vmwgfx driver uses its own hashtable implementation. Replace the +-code with Linux' implementation and update the callers. It's mostly a +-refactoring task, but the interfaces are different. +- +-Contact: Zack Rusin, Thomas Zimmermann +- +-Level: Intermediate +- + Bootsplash + ========== + +diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile +index eee73b9aa404..68e350f410ad 100644 +--- a/drivers/gpu/drm/vmwgfx/Makefile ++++ b/drivers/gpu/drm/vmwgfx/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 +-vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_hashtab.o vmwgfx_kms.o vmwgfx_drv.o \ ++vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ + vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_ttm_buffer.o \ + vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ + vmwgfx_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \ +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c +index c07b81fbc495..932b125ebf3d 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.c ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.c +@@ -284,7 +284,7 @@ ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key) + } + + __release(RCU); +- return drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; ++ return hlist_entry(hash, struct ttm_ref_object, hash)->obj; + } + EXPORT_SYMBOL(ttm_base_object_noref_lookup); + +@@ -299,7 +299,7 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, + ret = ttm_tfile_find_ref_rcu(tfile, key, &hash); + + if (likely(ret == 0)) { +- base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; ++ base = hlist_entry(hash, struct ttm_ref_object, hash)->obj; + if (!kref_get_unless_zero(&base->refcount)) + base = NULL; + } +@@ -343,7 +343,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + ret = ttm_tfile_find_ref_rcu(tfile, base->handle, &hash); + + if (ret == 0) { +- ref = drm_hash_entry(hash, struct ttm_ref_object, hash); ++ ref = hlist_entry(hash, struct ttm_ref_object, hash); + if (kref_get_unless_zero(&ref->kref)) { + rcu_read_unlock(); + break; +@@ -407,7 +407,7 @@ int ttm_ref_object_base_unref(struct ttm_object_file *tfile, + spin_unlock(&tfile->lock); + return -EINVAL; + } +- ref = drm_hash_entry(hash, struct ttm_ref_object, hash); ++ ref = hlist_entry(hash, struct ttm_ref_object, hash); + kref_put(&ref->kref, ttm_ref_object_release); + spin_unlock(&tfile->lock); + return 0; +diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h +index 67f30d589e27..f0ebbe340ad6 100644 +--- a/drivers/gpu/drm/vmwgfx/ttm_object.h ++++ b/drivers/gpu/drm/vmwgfx/ttm_object.h +@@ -42,8 +42,6 @@ + #include + #include + +-#include "vmwgfx_hashtab.h" +- + /** + * enum ttm_object_type + * +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +index 142aef686fcd..47bc0b411055 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +@@ -88,7 +88,7 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man, + + hash_for_each_possible_rcu(man->resources, hash, head, key) { + if (hash->key == key) +- return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res; ++ return hlist_entry(hash, struct vmw_cmdbuf_res, hash)->res; + } + return ERR_PTR(-EINVAL); + } +@@ -243,7 +243,7 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, + + hash_for_each_possible_rcu(man->resources, hash, head, key) { + if (hash->key == key) { +- entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash); ++ entry = hlist_entry(hash, struct vmw_cmdbuf_res, hash); + break; + } + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +index d87aeedb78d0..7c45c3de0dcf 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +@@ -43,7 +43,6 @@ + #include "ttm_object.h" + + #include "vmwgfx_fence.h" +-#include "vmwgfx_hashtab.h" + #include "vmwgfx_reg.h" + #include "vmwgfx_validation.h" + +@@ -104,6 +103,11 @@ struct vmw_fpriv { + bool gb_aware; /* user-space is guest-backed aware */ + }; + ++struct vmwgfx_hash_item { ++ struct hlist_node head; ++ unsigned long key; ++}; ++ + /** + * struct vmw_buffer_object - TTM buffer object with vmwgfx additions + * @base: The TTM buffer object +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c b/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c +deleted file mode 100644 +index 06aebc12774e..000000000000 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c ++++ /dev/null +@@ -1,199 +0,0 @@ +-/* +- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. +- * All Rights Reserved. +- * +- * 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, sub license, 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 (including the +- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. +- */ +- +-/* +- * Simple open hash tab implementation. +- * +- * Authors: +- * Thomas Hellström +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include "vmwgfx_hashtab.h" +- +-int vmwgfx_ht_create(struct vmwgfx_open_hash *ht, unsigned int order) +-{ +- unsigned int size = 1 << order; +- +- ht->order = order; +- ht->table = NULL; +- if (size <= PAGE_SIZE / sizeof(*ht->table)) +- ht->table = kcalloc(size, sizeof(*ht->table), GFP_KERNEL); +- else +- ht->table = vzalloc(array_size(size, sizeof(*ht->table))); +- if (!ht->table) { +- DRM_ERROR("Out of memory for hash table\n"); +- return -ENOMEM; +- } +- return 0; +-} +- +-void vmwgfx_ht_verbose_list(struct vmwgfx_open_hash *ht, unsigned long key) +-{ +- struct vmwgfx_hash_item *entry; +- struct hlist_head *h_list; +- unsigned int hashed_key; +- int count = 0; +- +- hashed_key = hash_long(key, ht->order); +- DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); +- h_list = &ht->table[hashed_key]; +- hlist_for_each_entry(entry, h_list, head) +- DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); +-} +- +-static struct hlist_node *vmwgfx_ht_find_key(struct vmwgfx_open_hash *ht, unsigned long key) +-{ +- struct vmwgfx_hash_item *entry; +- struct hlist_head *h_list; +- unsigned int hashed_key; +- +- hashed_key = hash_long(key, ht->order); +- h_list = &ht->table[hashed_key]; +- hlist_for_each_entry(entry, h_list, head) { +- if (entry->key == key) +- return &entry->head; +- if (entry->key > key) +- break; +- } +- return NULL; +-} +- +-static struct hlist_node *vmwgfx_ht_find_key_rcu(struct vmwgfx_open_hash *ht, unsigned long key) +-{ +- struct vmwgfx_hash_item *entry; +- struct hlist_head *h_list; +- unsigned int hashed_key; +- +- hashed_key = hash_long(key, ht->order); +- h_list = &ht->table[hashed_key]; +- hlist_for_each_entry_rcu(entry, h_list, head) { +- if (entry->key == key) +- return &entry->head; +- if (entry->key > key) +- break; +- } +- return NULL; +-} +- +-int vmwgfx_ht_insert_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item) +-{ +- struct vmwgfx_hash_item *entry; +- struct hlist_head *h_list; +- struct hlist_node *parent; +- unsigned int hashed_key; +- unsigned long key = item->key; +- +- hashed_key = hash_long(key, ht->order); +- h_list = &ht->table[hashed_key]; +- parent = NULL; +- hlist_for_each_entry(entry, h_list, head) { +- if (entry->key == key) +- return -EINVAL; +- if (entry->key > key) +- break; +- parent = &entry->head; +- } +- if (parent) +- hlist_add_behind_rcu(&item->head, parent); +- else +- hlist_add_head_rcu(&item->head, h_list); +- return 0; +-} +- +-/* +- * Just insert an item and return any "bits" bit key that hasn't been +- * used before. +- */ +-int vmwgfx_ht_just_insert_please(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item, +- unsigned long seed, int bits, int shift, +- unsigned long add) +-{ +- int ret; +- unsigned long mask = (1UL << bits) - 1; +- unsigned long first, unshifted_key; +- +- unshifted_key = hash_long(seed, bits); +- first = unshifted_key; +- do { +- item->key = (unshifted_key << shift) + add; +- ret = vmwgfx_ht_insert_item(ht, item); +- if (ret) +- unshifted_key = (unshifted_key + 1) & mask; +- } while (ret && (unshifted_key != first)); +- +- if (ret) { +- DRM_ERROR("Available key bit space exhausted\n"); +- return -EINVAL; +- } +- return 0; +-} +- +-int vmwgfx_ht_find_item(struct vmwgfx_open_hash *ht, unsigned long key, +- struct vmwgfx_hash_item **item) +-{ +- struct hlist_node *list; +- +- list = vmwgfx_ht_find_key_rcu(ht, key); +- if (!list) +- return -EINVAL; +- +- *item = hlist_entry(list, struct vmwgfx_hash_item, head); +- return 0; +-} +- +-int vmwgfx_ht_remove_key(struct vmwgfx_open_hash *ht, unsigned long key) +-{ +- struct hlist_node *list; +- +- list = vmwgfx_ht_find_key(ht, key); +- if (list) { +- hlist_del_init_rcu(list); +- return 0; +- } +- return -EINVAL; +-} +- +-int vmwgfx_ht_remove_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item) +-{ +- hlist_del_init_rcu(&item->head); +- return 0; +-} +- +-void vmwgfx_ht_remove(struct vmwgfx_open_hash *ht) +-{ +- if (ht->table) { +- kvfree(ht->table); +- ht->table = NULL; +- } +-} +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h b/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h +deleted file mode 100644 +index a9ce12922e21..000000000000 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h ++++ /dev/null +@@ -1,83 +0,0 @@ +-/* +- * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA. +- * All Rights Reserved. +- * +- * 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, sub license, 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 (including the +- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. +- */ +- +-/* +- * Simple open hash tab implementation. +- * +- * Authors: +- * Thomas Hellström +- */ +- +-/* +- * TODO: Replace this hashtable with Linux' generic implementation +- * from . +- */ +- +-#ifndef VMWGFX_HASHTAB_H +-#define VMWGFX_HASHTAB_H +- +-#include +- +-#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) +- +-struct vmwgfx_hash_item { +- struct hlist_node head; +- unsigned long key; +-}; +- +-struct vmwgfx_open_hash { +- struct hlist_head *table; +- u8 order; +-}; +- +-int vmwgfx_ht_create(struct vmwgfx_open_hash *ht, unsigned int order); +-int vmwgfx_ht_insert_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item); +-int vmwgfx_ht_just_insert_please(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item, +- unsigned long seed, int bits, int shift, +- unsigned long add); +-int vmwgfx_ht_find_item(struct vmwgfx_open_hash *ht, unsigned long key, +- struct vmwgfx_hash_item **item); +- +-void vmwgfx_ht_verbose_list(struct vmwgfx_open_hash *ht, unsigned long key); +-int vmwgfx_ht_remove_key(struct vmwgfx_open_hash *ht, unsigned long key); +-int vmwgfx_ht_remove_item(struct vmwgfx_open_hash *ht, struct vmwgfx_hash_item *item); +-void vmwgfx_ht_remove(struct vmwgfx_open_hash *ht); +- +-/* +- * RCU-safe interface +- * +- * The user of this API needs to make sure that two or more instances of the +- * hash table manipulation functions are never run simultaneously. +- * The lookup function vmwgfx_ht_find_item_rcu may, however, run simultaneously +- * with any of the manipulation functions as long as it's called from within +- * an RCU read-locked section. +- */ +-#define vmwgfx_ht_insert_item_rcu vmwgfx_ht_insert_item +-#define vmwgfx_ht_just_insert_please_rcu vmwgfx_ht_just_insert_please +-#define vmwgfx_ht_remove_key_rcu vmwgfx_ht_remove_key +-#define vmwgfx_ht_remove_item_rcu vmwgfx_ht_remove_item +-#define vmwgfx_ht_find_item_rcu vmwgfx_ht_find_item +- +-#endif +-- +2.35.1 + diff --git a/queue-6.1/drm-vmwgfx-write-the-driver-id-registers.patch b/queue-6.1/drm-vmwgfx-write-the-driver-id-registers.patch new file mode 100644 index 00000000000..a7d488197d9 --- /dev/null +++ b/queue-6.1/drm-vmwgfx-write-the-driver-id-registers.patch @@ -0,0 +1,102 @@ +From 23aba1879cd219c74ce29ae37061f04faeeb71f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 00:02:20 -0400 +Subject: drm/vmwgfx: Write the driver id registers + +From: Zack Rusin + +[ Upstream commit 7f4c33778686cc2d34cb4ef65b4265eea874c159 ] + +Driver id registers are a new mechanism in the svga device to hint to the +device which driver is running. This should not change device behavior +in any way, but might be convenient to work-around specific bugs +in guest drivers. + +Signed-off-by: Zack Rusin +Reviewed-by: Martin Krastev +Reviewed-by: Maaz Mombasawala +Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-2-zack@kde.org +Stable-dep-of: a309c7194e8a ("drm/vmwgfx: Remove rcu locks from user resources") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 43 +++++++++++++++++++++++------ + 1 file changed, 34 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index d7bd5eb1d3ac..45028e25d490 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -25,10 +25,13 @@ + * + **************************************************************************/ + +-#include +-#include +-#include +-#include ++ ++#include "vmwgfx_drv.h" ++ ++#include "vmwgfx_devcaps.h" ++#include "vmwgfx_mksstat.h" ++#include "vmwgfx_binding.h" ++#include "ttm_object.h" + + #include + #include +@@ -41,11 +44,11 @@ + #include + #include + +-#include "ttm_object.h" +-#include "vmwgfx_binding.h" +-#include "vmwgfx_devcaps.h" +-#include "vmwgfx_drv.h" +-#include "vmwgfx_mksstat.h" ++#include ++#include ++#include ++#include ++#include + + #define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" + +@@ -806,6 +809,27 @@ static int vmw_detect_version(struct vmw_private *dev) + return 0; + } + ++static void vmw_write_driver_id(struct vmw_private *dev) ++{ ++ if ((dev->capabilities2 & SVGA_CAP2_DX2) != 0) { ++ vmw_write(dev, SVGA_REG_GUEST_DRIVER_ID, ++ SVGA_REG_GUEST_DRIVER_ID_LINUX); ++ ++ vmw_write(dev, SVGA_REG_GUEST_DRIVER_VERSION1, ++ LINUX_VERSION_MAJOR << 24 | ++ LINUX_VERSION_PATCHLEVEL << 16 | ++ LINUX_VERSION_SUBLEVEL); ++ vmw_write(dev, SVGA_REG_GUEST_DRIVER_VERSION2, ++ VMWGFX_DRIVER_MAJOR << 24 | ++ VMWGFX_DRIVER_MINOR << 16 | ++ VMWGFX_DRIVER_PATCHLEVEL); ++ vmw_write(dev, SVGA_REG_GUEST_DRIVER_VERSION3, 0); ++ ++ vmw_write(dev, SVGA_REG_GUEST_DRIVER_ID, ++ SVGA_REG_GUEST_DRIVER_ID_SUBMIT); ++ } ++} ++ + static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + { + int ret; +@@ -1091,6 +1115,7 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + vmw_host_printf("vmwgfx: Module Version: %d.%d.%d (kernel: %s)", + VMWGFX_DRIVER_MAJOR, VMWGFX_DRIVER_MINOR, + VMWGFX_DRIVER_PATCHLEVEL, UTS_RELEASE); ++ vmw_write_driver_id(dev_priv); + + if (dev_priv->enable_fb) { + vmw_fifo_resource_inc(dev_priv); +-- +2.35.1 + diff --git a/queue-6.1/efi-fix-null-deref-in-init-error-path.patch b/queue-6.1/efi-fix-null-deref-in-init-error-path.patch new file mode 100644 index 00000000000..0dfe0e846e2 --- /dev/null +++ b/queue-6.1/efi-fix-null-deref-in-init-error-path.patch @@ -0,0 +1,56 @@ +From a6e2734462af8ae6eed1702d1482cf017d3d3153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Dec 2022 10:10:04 +0100 +Subject: efi: fix NULL-deref in init error path + +From: Johan Hovold + +[ Upstream commit 703c13fe3c9af557d312f5895ed6a5fda2711104 ] + +In cases where runtime services are not supported or have been disabled, +the runtime services workqueue will never have been allocated. + +Do not try to destroy the workqueue unconditionally in the unlikely +event that EFI initialisation fails to avoid dereferencing a NULL +pointer. + +Fixes: 98086df8b70c ("efi: add missed destroy_workqueue when efisubsys_init fails") +Cc: stable@vger.kernel.org +Cc: Li Heng +Signed-off-by: Johan Hovold +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index f12cc29bd4b8..033aac6be7da 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -374,8 +374,8 @@ static int __init efisubsys_init(void) + efi_kobj = kobject_create_and_add("efi", firmware_kobj); + if (!efi_kobj) { + pr_err("efi: Firmware registration failed.\n"); +- destroy_workqueue(efi_rts_wq); +- return -ENOMEM; ++ error = -ENOMEM; ++ goto err_destroy_wq; + } + + if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE | +@@ -423,7 +423,10 @@ static int __init efisubsys_init(void) + generic_ops_unregister(); + err_put: + kobject_put(efi_kobj); +- destroy_workqueue(efi_rts_wq); ++err_destroy_wq: ++ if (efi_rts_wq) ++ destroy_workqueue(efi_rts_wq); ++ + return error; + } + +-- +2.35.1 + diff --git a/queue-6.1/gro-avoid-checking-for-a-failed-search.patch b/queue-6.1/gro-avoid-checking-for-a-failed-search.patch new file mode 100644 index 00000000000..295ecb3ab5f --- /dev/null +++ b/queue-6.1/gro-avoid-checking-for-a-failed-search.patch @@ -0,0 +1,112 @@ +From b41d00312d790b327a2d71ce796ee84ba56140be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 13:33:28 +0100 +Subject: gro: avoid checking for a failed search + +From: Richard Gobert + +[ Upstream commit e081ecf084d31809242fb0b9f35484d5fb3a161a ] + +After searching for a protocol handler in dev_gro_receive, checking for +failure is redundant. Skip the failure code after finding the +corresponding handler. + +Suggested-by: Eric Dumazet +Signed-off-by: Richard Gobert +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20221108123320.GA59373@debian +Signed-off-by: Paolo Abeni +Stable-dep-of: 7871f54e3dee ("gro: take care of DODGY packets") +Signed-off-by: Sasha Levin +--- + net/core/gro.c | 70 +++++++++++++++++++++++++------------------------- + 1 file changed, 35 insertions(+), 35 deletions(-) + +diff --git a/net/core/gro.c b/net/core/gro.c +index bc9451743307..8e0fe85a647d 100644 +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -489,45 +489,45 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff + + rcu_read_lock(); + list_for_each_entry_rcu(ptype, head, list) { +- if (ptype->type != type || !ptype->callbacks.gro_receive) +- continue; +- +- skb_set_network_header(skb, skb_gro_offset(skb)); +- skb_reset_mac_len(skb); +- BUILD_BUG_ON(sizeof_field(struct napi_gro_cb, zeroed) != sizeof(u32)); +- BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct napi_gro_cb, zeroed), +- sizeof(u32))); /* Avoid slow unaligned acc */ +- *(u32 *)&NAPI_GRO_CB(skb)->zeroed = 0; +- NAPI_GRO_CB(skb)->flush = skb_has_frag_list(skb); +- NAPI_GRO_CB(skb)->is_atomic = 1; +- NAPI_GRO_CB(skb)->count = 1; +- if (unlikely(skb_is_gso(skb))) { +- NAPI_GRO_CB(skb)->count = skb_shinfo(skb)->gso_segs; +- /* Only support TCP at the moment. */ +- if (!skb_is_gso_tcp(skb)) +- NAPI_GRO_CB(skb)->flush = 1; +- } +- +- /* Setup for GRO checksum validation */ +- switch (skb->ip_summed) { +- case CHECKSUM_COMPLETE: +- NAPI_GRO_CB(skb)->csum = skb->csum; +- NAPI_GRO_CB(skb)->csum_valid = 1; +- break; +- case CHECKSUM_UNNECESSARY: +- NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1; +- break; +- } ++ if (ptype->type == type && ptype->callbacks.gro_receive) ++ goto found_ptype; ++ } ++ rcu_read_unlock(); ++ goto normal; ++ ++found_ptype: ++ skb_set_network_header(skb, skb_gro_offset(skb)); ++ skb_reset_mac_len(skb); ++ BUILD_BUG_ON(sizeof_field(struct napi_gro_cb, zeroed) != sizeof(u32)); ++ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct napi_gro_cb, zeroed), ++ sizeof(u32))); /* Avoid slow unaligned acc */ ++ *(u32 *)&NAPI_GRO_CB(skb)->zeroed = 0; ++ NAPI_GRO_CB(skb)->flush = skb_has_frag_list(skb); ++ NAPI_GRO_CB(skb)->is_atomic = 1; ++ NAPI_GRO_CB(skb)->count = 1; ++ if (unlikely(skb_is_gso(skb))) { ++ NAPI_GRO_CB(skb)->count = skb_shinfo(skb)->gso_segs; ++ /* Only support TCP at the moment. */ ++ if (!skb_is_gso_tcp(skb)) ++ NAPI_GRO_CB(skb)->flush = 1; ++ } + +- pp = INDIRECT_CALL_INET(ptype->callbacks.gro_receive, +- ipv6_gro_receive, inet_gro_receive, +- &gro_list->list, skb); ++ /* Setup for GRO checksum validation */ ++ switch (skb->ip_summed) { ++ case CHECKSUM_COMPLETE: ++ NAPI_GRO_CB(skb)->csum = skb->csum; ++ NAPI_GRO_CB(skb)->csum_valid = 1; ++ break; ++ case CHECKSUM_UNNECESSARY: ++ NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1; + break; + } +- rcu_read_unlock(); + +- if (&ptype->list == head) +- goto normal; ++ pp = INDIRECT_CALL_INET(ptype->callbacks.gro_receive, ++ ipv6_gro_receive, inet_gro_receive, ++ &gro_list->list, skb); ++ ++ rcu_read_unlock(); + + if (PTR_ERR(pp) == -EINPROGRESS) { + ret = GRO_CONSUMED; +-- +2.35.1 + diff --git a/queue-6.1/gro-take-care-of-dodgy-packets.patch b/queue-6.1/gro-take-care-of-dodgy-packets.patch new file mode 100644 index 00000000000..671cc474e92 --- /dev/null +++ b/queue-6.1/gro-take-care-of-dodgy-packets.patch @@ -0,0 +1,48 @@ +From 90252422f92611d0d16b429c93ce953d16eb1a14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 14:25:23 +0000 +Subject: gro: take care of DODGY packets + +From: Eric Dumazet + +[ Upstream commit 7871f54e3deed68a27111dda162c4fe9b9c65f8f ] + +Jaroslav reported a recent throughput regression with virtio_net +caused by blamed commit. + +It is unclear if DODGY GSO packets coming from user space +can be accepted by GRO engine in the future with minimal +changes, and if there is any expected gain from it. + +In the meantime, make sure to detect and flush DODGY packets. + +Fixes: 5eddb24901ee ("gro: add support of (hw)gro packets to gro stack") +Signed-off-by: Eric Dumazet +Reported-and-bisected-by: Jaroslav Pulchart +Cc: Coco Li +Cc: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/gro.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/core/gro.c b/net/core/gro.c +index 8e0fe85a647d..1b4abfb9a7a1 100644 +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -507,8 +507,9 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff + NAPI_GRO_CB(skb)->count = 1; + if (unlikely(skb_is_gso(skb))) { + NAPI_GRO_CB(skb)->count = skb_shinfo(skb)->gso_segs; +- /* Only support TCP at the moment. */ +- if (!skb_is_gso_tcp(skb)) ++ /* Only support TCP and non DODGY users. */ ++ if (!skb_is_gso_tcp(skb) || ++ (skb_shinfo(skb)->gso_type & SKB_GSO_DODGY)) + NAPI_GRO_CB(skb)->flush = 1; + } + +-- +2.35.1 + diff --git a/queue-6.1/hvc-xen-lock-console-list-traversal.patch b/queue-6.1/hvc-xen-lock-console-list-traversal.patch new file mode 100644 index 00000000000..d3cf7f2645b --- /dev/null +++ b/queue-6.1/hvc-xen-lock-console-list-traversal.patch @@ -0,0 +1,186 @@ +From 33680937a9219ca16440e284d4c99dcbd1a6f80f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 17:36:02 +0100 +Subject: hvc/xen: lock console list traversal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Roger Pau Monne + +[ Upstream commit c0dccad87cf68fc6012aec7567e354353097ec1a ] + +The currently lockless access to the xen console list in +vtermno_to_xencons() is incorrect, as additions and removals from the +list can happen anytime, and as such the traversal of the list to get +the private console data for a given termno needs to happen with the +lock held. Note users that modify the list already do so with the +lock taken. + +Adjust current lock takers to use the _irq{save,restore} helpers, +since the context in which vtermno_to_xencons() is called can have +interrupts disabled. Use the _irq{save,restore} set of helpers to +switch the current callers to disable interrupts in the locked region. +I haven't checked if existing users could instead use the _irq +variant, as I think it's safer to use _irq{save,restore} upfront. + +While there switch from using list_for_each_entry_safe to +list_for_each_entry: the current entry cursor won't be removed as +part of the code in the loop body, so using the _safe variant is +pointless. + +Fixes: 02e19f9c7cac ('hvc_xen: implement multiconsole support') +Signed-off-by: Roger Pau Monné +Reviewed-by: Stefano Stabellini +Link: https://lore.kernel.org/r/20221130163611.14686-1-roger.pau@citrix.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/tty/hvc/hvc_xen.c | 46 ++++++++++++++++++++++++--------------- + 1 file changed, 29 insertions(+), 17 deletions(-) + +diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c +index 7c23112dc923..37809c6c027f 100644 +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -52,17 +52,22 @@ static DEFINE_SPINLOCK(xencons_lock); + + static struct xencons_info *vtermno_to_xencons(int vtermno) + { +- struct xencons_info *entry, *n, *ret = NULL; ++ struct xencons_info *entry, *ret = NULL; ++ unsigned long flags; + +- if (list_empty(&xenconsoles)) +- return NULL; ++ spin_lock_irqsave(&xencons_lock, flags); ++ if (list_empty(&xenconsoles)) { ++ spin_unlock_irqrestore(&xencons_lock, flags); ++ return NULL; ++ } + +- list_for_each_entry_safe(entry, n, &xenconsoles, list) { ++ list_for_each_entry(entry, &xenconsoles, list) { + if (entry->vtermno == vtermno) { + ret = entry; + break; + } + } ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return ret; + } +@@ -223,7 +228,7 @@ static int xen_hvm_console_init(void) + { + int r; + uint64_t v = 0; +- unsigned long gfn; ++ unsigned long gfn, flags; + struct xencons_info *info; + + if (!xen_hvm_domain()) +@@ -258,9 +263,9 @@ static int xen_hvm_console_init(void) + goto err; + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + err: +@@ -283,6 +288,7 @@ static int xencons_info_pv_init(struct xencons_info *info, int vtermno) + static int xen_pv_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_pv_domain()) + return -ENODEV; +@@ -299,9 +305,9 @@ static int xen_pv_console_init(void) + /* already configured */ + return 0; + } +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + xencons_info_pv_init(info, HVC_COOKIE); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -309,6 +315,7 @@ static int xen_pv_console_init(void) + static int xen_initial_domain_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_initial_domain()) + return -ENODEV; +@@ -323,9 +330,9 @@ static int xen_initial_domain_console_init(void) + info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -380,10 +387,12 @@ static void xencons_free(struct xencons_info *info) + + static int xen_console_remove(struct xencons_info *info) + { ++ unsigned long flags; ++ + xencons_disconnect_backend(info); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->xbdev != NULL) + xencons_free(info); + else { +@@ -464,6 +473,7 @@ static int xencons_probe(struct xenbus_device *dev, + { + int ret, devid; + struct xencons_info *info; ++ unsigned long flags; + + devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; + if (devid == 0) +@@ -482,9 +492,9 @@ static int xencons_probe(struct xenbus_device *dev, + ret = xencons_connect_backend(dev, info); + if (ret < 0) + goto error; +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + +@@ -584,10 +594,12 @@ static int __init xen_hvc_init(void) + + info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); + if (IS_ERR(info->hvc)) { ++ unsigned long flags; ++ + r = PTR_ERR(info->hvc); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->irq) + unbind_from_irqhandler(info->irq, NULL); + kfree(info); +-- +2.35.1 + diff --git a/queue-6.1/ice-add-check-for-kzalloc.patch b/queue-6.1/ice-add-check-for-kzalloc.patch new file mode 100644 index 00000000000..ca2cdaa8d6e --- /dev/null +++ b/queue-6.1/ice-add-check-for-kzalloc.patch @@ -0,0 +1,73 @@ +From 24a5e5dd1d4d6350cf8c1d5d4501eabce0f73607 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Dec 2022 21:35:52 +0800 +Subject: ice: Add check for kzalloc + +From: Jiasheng Jiang + +[ Upstream commit 40543b3d9d2c13227ecd3aa90a713c201d1d7f09 ] + +Add the check for the return value of kzalloc in order to avoid +NULL pointer dereference. +Moreover, use the goto-label to share the clean code. + +Fixes: d6b98c8d242a ("ice: add write functionality for GNSS TTY") +Signed-off-by: Jiasheng Jiang +Reviewed-by: Jiri Pirko +Tested-by: Gurucharan G (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_gnss.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c +index a1915551c69a..43e199b5b513 100644 +--- a/drivers/net/ethernet/intel/ice/ice_gnss.c ++++ b/drivers/net/ethernet/intel/ice/ice_gnss.c +@@ -461,6 +461,9 @@ static struct tty_driver *ice_gnss_create_tty_driver(struct ice_pf *pf) + for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) { + pf->gnss_tty_port[i] = kzalloc(sizeof(*pf->gnss_tty_port[i]), + GFP_KERNEL); ++ if (!pf->gnss_tty_port[i]) ++ goto err_out; ++ + pf->gnss_serial[i] = NULL; + + tty_port_init(pf->gnss_tty_port[i]); +@@ -470,21 +473,23 @@ static struct tty_driver *ice_gnss_create_tty_driver(struct ice_pf *pf) + err = tty_register_driver(tty_driver); + if (err) { + dev_err(dev, "Failed to register TTY driver err=%d\n", err); +- +- for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) { +- tty_port_destroy(pf->gnss_tty_port[i]); +- kfree(pf->gnss_tty_port[i]); +- } +- kfree(ttydrv_name); +- tty_driver_kref_put(pf->ice_gnss_tty_driver); +- +- return NULL; ++ goto err_out; + } + + for (i = 0; i < ICE_GNSS_TTY_MINOR_DEVICES; i++) + dev_info(dev, "%s%d registered\n", ttydrv_name, i); + + return tty_driver; ++ ++err_out: ++ while (i--) { ++ tty_port_destroy(pf->gnss_tty_port[i]); ++ kfree(pf->gnss_tty_port[i]); ++ } ++ kfree(ttydrv_name); ++ tty_driver_kref_put(pf->ice_gnss_tty_driver); ++ ++ return NULL; + } + + /** +-- +2.35.1 + diff --git a/queue-6.1/ice-fix-potential-memory-leak-in-ice_gnss_tty_write.patch b/queue-6.1/ice-fix-potential-memory-leak-in-ice_gnss_tty_write.patch new file mode 100644 index 00000000000..9d312b2929f --- /dev/null +++ b/queue-6.1/ice-fix-potential-memory-leak-in-ice_gnss_tty_write.patch @@ -0,0 +1,39 @@ +From dd52bce5069fb1f62a55aa0d491e163da7fa0b36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 08:55:02 +0000 +Subject: ice: Fix potential memory leak in ice_gnss_tty_write() + +From: Yuan Can + +[ Upstream commit f58985620f55580a07d40062c4115d8c9cf6ae27 ] + +The ice_gnss_tty_write() return directly if the write_buf alloc failed, +leaking the cmd_buf. + +Fix by free cmd_buf if write_buf alloc failed. + +Fixes: d6b98c8d242a ("ice: add write functionality for GNSS TTY") +Signed-off-by: Yuan Can +Reviewed-by: Leon Romanovsky +Tested-by: Gurucharan G (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_gnss.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c +index b5a7f246d230..a1915551c69a 100644 +--- a/drivers/net/ethernet/intel/ice/ice_gnss.c ++++ b/drivers/net/ethernet/intel/ice/ice_gnss.c +@@ -363,6 +363,7 @@ ice_gnss_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) + /* Send the data out to a hardware port */ + write_buf = kzalloc(sizeof(*write_buf), GFP_KERNEL); + if (!write_buf) { ++ kfree(cmd_buf); + err = -ENOMEM; + goto exit; + } +-- +2.35.1 + diff --git a/queue-6.1/igc-fix-pps-delta-between-two-synchronized-end-point.patch b/queue-6.1/igc-fix-pps-delta-between-two-synchronized-end-point.patch new file mode 100644 index 00000000000..1a58526b9aa --- /dev/null +++ b/queue-6.1/igc-fix-pps-delta-between-two-synchronized-end-point.patch @@ -0,0 +1,97 @@ +From e73c9beaf1edc3c92314c2a51b3470607c31f7a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 16:10:38 +0800 +Subject: igc: Fix PPS delta between two synchronized end-points + +From: Christopher S Hall + +[ Upstream commit 5e91c72e560cc85f7163bbe3d14197268de31383 ] + +This patch fix the pulse per second output delta between +two synchronized end-points. + +Based on Intel Discrete I225 Software User Manual Section +4.2.15 TimeSync Auxiliary Control Register, ST0[Bit 4] and +ST1[Bit 7] must be set to ensure that clock output will be +toggles based on frequency value defined. This is to ensure +that output of the PPS is aligned with the clock. + +How to test: + +1) Running time synchronization on both end points. +Ex: ptp4l --step_threshold=1 -m -f gPTP.cfg -i + +2) Configure PPS output using below command for both end-points +Ex: SDP0 on I225 REV4 SKU variant + +./testptp -d /dev/ptp0 -L 0,2 +./testptp -d /dev/ptp0 -p 1000000000 + +3) Measure the output using analyzer for both end-points + +Fixes: 87938851b6ef ("igc: enable auxiliary PHC functions for the i225") +Signed-off-by: Christopher S Hall +Signed-off-by: Muhammad Husaini Zulkifli +Acked-by: Sasha Neftin +Tested-by: Naama Meir +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/igc/igc_defines.h | 2 ++ + drivers/net/ethernet/intel/igc/igc_ptp.c | 10 ++++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h +index 4ad35fbdc02e..dbfa4b9dee06 100644 +--- a/drivers/net/ethernet/intel/igc/igc_defines.h ++++ b/drivers/net/ethernet/intel/igc/igc_defines.h +@@ -466,7 +466,9 @@ + #define IGC_TSAUXC_EN_TT0 BIT(0) /* Enable target time 0. */ + #define IGC_TSAUXC_EN_TT1 BIT(1) /* Enable target time 1. */ + #define IGC_TSAUXC_EN_CLK0 BIT(2) /* Enable Configurable Frequency Clock 0. */ ++#define IGC_TSAUXC_ST0 BIT(4) /* Start Clock 0 Toggle on Target Time 0. */ + #define IGC_TSAUXC_EN_CLK1 BIT(5) /* Enable Configurable Frequency Clock 1. */ ++#define IGC_TSAUXC_ST1 BIT(7) /* Start Clock 1 Toggle on Target Time 1. */ + #define IGC_TSAUXC_EN_TS0 BIT(8) /* Enable hardware timestamp 0. */ + #define IGC_TSAUXC_AUTT0 BIT(9) /* Auxiliary Timestamp Taken. */ + #define IGC_TSAUXC_EN_TS1 BIT(10) /* Enable hardware timestamp 0. */ +diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c +index 8dbb9f903ca7..c34734d432e0 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ptp.c ++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c +@@ -322,7 +322,7 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp, + ts = ns_to_timespec64(ns); + if (rq->perout.index == 1) { + if (use_freq) { +- tsauxc_mask = IGC_TSAUXC_EN_CLK1; ++ tsauxc_mask = IGC_TSAUXC_EN_CLK1 | IGC_TSAUXC_ST1; + tsim_mask = 0; + } else { + tsauxc_mask = IGC_TSAUXC_EN_TT1; +@@ -333,7 +333,7 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp, + freqout = IGC_FREQOUT1; + } else { + if (use_freq) { +- tsauxc_mask = IGC_TSAUXC_EN_CLK0; ++ tsauxc_mask = IGC_TSAUXC_EN_CLK0 | IGC_TSAUXC_ST0; + tsim_mask = 0; + } else { + tsauxc_mask = IGC_TSAUXC_EN_TT0; +@@ -347,10 +347,12 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp, + tsauxc = rd32(IGC_TSAUXC); + tsim = rd32(IGC_TSIM); + if (rq->perout.index == 1) { +- tsauxc &= ~(IGC_TSAUXC_EN_TT1 | IGC_TSAUXC_EN_CLK1); ++ tsauxc &= ~(IGC_TSAUXC_EN_TT1 | IGC_TSAUXC_EN_CLK1 | ++ IGC_TSAUXC_ST1); + tsim &= ~IGC_TSICR_TT1; + } else { +- tsauxc &= ~(IGC_TSAUXC_EN_TT0 | IGC_TSAUXC_EN_CLK0); ++ tsauxc &= ~(IGC_TSAUXC_EN_TT0 | IGC_TSAUXC_EN_CLK0 | ++ IGC_TSAUXC_ST0); + tsim &= ~IGC_TSICR_TT0; + } + if (on) { +-- +2.35.1 + diff --git a/queue-6.1/io_uring-lock-overflowing-for-iopoll.patch b/queue-6.1/io_uring-lock-overflowing-for-iopoll.patch new file mode 100644 index 00000000000..60d3776fd5f --- /dev/null +++ b/queue-6.1/io_uring-lock-overflowing-for-iopoll.patch @@ -0,0 +1,63 @@ +From ee2f4cf9c7408e0ce398eee696ac256a30437f83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Jan 2023 08:41:33 -0700 +Subject: io_uring: lock overflowing for IOPOLL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pavel Begunkov + +commit 544d163d659d45a206d8929370d5a2984e546cb7 upstream. + +syzbot reports an issue with overflow filling for IOPOLL: + +WARNING: CPU: 0 PID: 28 at io_uring/io_uring.c:734 io_cqring_event_overflow+0x1c0/0x230 io_uring/io_uring.c:734 +CPU: 0 PID: 28 Comm: kworker/u4:1 Not tainted 6.2.0-rc3-syzkaller-16369-g358a161a6a9e #0 +Workqueue: events_unbound io_ring_exit_work +Call trace: + io_cqring_event_overflow+0x1c0/0x230 io_uring/io_uring.c:734 + io_req_cqe_overflow+0x5c/0x70 io_uring/io_uring.c:773 + io_fill_cqe_req io_uring/io_uring.h:168 [inline] + io_do_iopoll+0x474/0x62c io_uring/rw.c:1065 + io_iopoll_try_reap_events+0x6c/0x108 io_uring/io_uring.c:1513 + io_uring_try_cancel_requests+0x13c/0x258 io_uring/io_uring.c:3056 + io_ring_exit_work+0xec/0x390 io_uring/io_uring.c:2869 + process_one_work+0x2d8/0x504 kernel/workqueue.c:2289 + worker_thread+0x340/0x610 kernel/workqueue.c:2436 + kthread+0x12c/0x158 kernel/kthread.c:376 + ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:863 + +There is no real problem for normal IOPOLL as flush is also called with +uring_lock taken, but it's getting more complicated for IOPOLL|SQPOLL, +for which __io_cqring_overflow_flush() happens from the CQ waiting path. + +Reported-and-tested-by: syzbot+6805087452d72929404e@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org # 5.10+ +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/rw.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/io_uring/rw.c b/io_uring/rw.c +index bb47cc4da713..6223472095d2 100644 +--- a/io_uring/rw.c ++++ b/io_uring/rw.c +@@ -1055,7 +1055,11 @@ int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin) + continue; + + req->cqe.flags = io_put_kbuf(req, 0); +- __io_fill_cqe_req(req->ctx, req); ++ if (unlikely(!__io_fill_cqe_req(ctx, req))) { ++ spin_lock(&ctx->completion_lock); ++ io_req_cqe_overflow(req); ++ spin_unlock(&ctx->completion_lock); ++ } + } + + if (unlikely(!nr_events)) +-- +2.35.1 + diff --git a/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch b/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch new file mode 100644 index 00000000000..e7356e2354a --- /dev/null +++ b/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch @@ -0,0 +1,119 @@ +From bb806bb3dd58be279a43ca8ac204d653a022067b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Jan 2023 08:46:14 -0700 +Subject: io_uring/poll: attempt request issue after racy poll wakeup + +From: Jens Axboe + +commit 6e5aedb9324aab1c14a23fae3d8eeb64a679c20e upstream. + +If we have multiple requests waiting on the same target poll waitqueue, +then it's quite possible to get a request triggered and get disappointed +in not being able to make any progress with it. If we race in doing so, +we'll potentially leave the poll request on the internal tables, but +removed from the waitqueue. That means that any subsequent trigger of +the poll waitqueue will not kick that request into action, causing an +application to potentially wait for completion of a request that will +never happen. + +Fix this by adding a new poll return state, IOU_POLL_REISSUE. Rather +than have complicated logic for how to re-arm a given type of request, +just punt it for a reissue. + +While in there, move the 'ret' variable to the only section where it +gets used. This avoids confusion the scope of it. + +Cc: stable@vger.kernel.org +Fixes: eb0089d629ba ("io_uring: single shot poll removal optimisation") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/poll.c | 33 ++++++++++++++++++++++----------- + 1 file changed, 22 insertions(+), 11 deletions(-) + +diff --git a/io_uring/poll.c b/io_uring/poll.c +index df42fd8a6ab0..f2f9f174fc62 100644 +--- a/io_uring/poll.c ++++ b/io_uring/poll.c +@@ -223,22 +223,23 @@ enum { + IOU_POLL_DONE = 0, + IOU_POLL_NO_ACTION = 1, + IOU_POLL_REMOVE_POLL_USE_RES = 2, ++ IOU_POLL_REISSUE = 3, + }; + + /* + * All poll tw should go through this. Checks for poll events, manages + * references, does rewait, etc. + * +- * Returns a negative error on failure. IOU_POLL_NO_ACTION when no action require, +- * which is either spurious wakeup or multishot CQE is served. +- * IOU_POLL_DONE when it's done with the request, then the mask is stored in req->cqe.res. +- * IOU_POLL_REMOVE_POLL_USE_RES indicates to remove multishot poll and that the result +- * is stored in req->cqe. ++ * Returns a negative error on failure. IOU_POLL_NO_ACTION when no action ++ * require, which is either spurious wakeup or multishot CQE is served. ++ * IOU_POLL_DONE when it's done with the request, then the mask is stored in ++ * req->cqe.res. IOU_POLL_REMOVE_POLL_USE_RES indicates to remove multishot ++ * poll and that the result is stored in req->cqe. + */ + static int io_poll_check_events(struct io_kiocb *req, bool *locked) + { + struct io_ring_ctx *ctx = req->ctx; +- int v, ret; ++ int v; + + /* req->task == current here, checking PF_EXITING is safe */ + if (unlikely(req->task->flags & PF_EXITING)) +@@ -274,10 +275,15 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) + if (!req->cqe.res) { + struct poll_table_struct pt = { ._key = req->apoll_events }; + req->cqe.res = vfs_poll(req->file, &pt) & req->apoll_events; ++ /* ++ * We got woken with a mask, but someone else got to ++ * it first. The above vfs_poll() doesn't add us back ++ * to the waitqueue, so if we get nothing back, we ++ * should be safe and attempt a reissue. ++ */ ++ if (unlikely(!req->cqe.res)) ++ return IOU_POLL_REISSUE; + } +- +- if ((unlikely(!req->cqe.res))) +- continue; + if (req->apoll_events & EPOLLONESHOT) + return IOU_POLL_DONE; + if (io_is_uring_fops(req->file)) +@@ -294,7 +300,7 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) + return IOU_POLL_REMOVE_POLL_USE_RES; + } + } else { +- ret = io_poll_issue(req, locked); ++ int ret = io_poll_issue(req, locked); + if (ret == IOU_STOP_MULTISHOT) + return IOU_POLL_REMOVE_POLL_USE_RES; + if (ret < 0) +@@ -325,6 +331,11 @@ static void io_poll_task_func(struct io_kiocb *req, bool *locked) + if (ret == IOU_POLL_DONE) { + struct io_poll *poll = io_kiocb_to_cmd(req, struct io_poll); + req->cqe.res = mangle_poll(req->cqe.res & poll->events); ++ } else if (ret == IOU_POLL_REISSUE) { ++ io_poll_remove_entries(req); ++ io_poll_tw_hash_eject(req, locked); ++ io_req_task_submit(req, locked); ++ return; + } else if (ret != IOU_POLL_REMOVE_POLL_USE_RES) { + req->cqe.res = ret; + req_set_fail(req); +@@ -350,7 +361,7 @@ static void io_apoll_task_func(struct io_kiocb *req, bool *locked) + + if (ret == IOU_POLL_REMOVE_POLL_USE_RES) + io_req_complete_post(req); +- else if (ret == IOU_POLL_DONE) ++ else if (ret == IOU_POLL_DONE || ret == IOU_POLL_REISSUE) + io_req_task_submit(req, locked); + else + io_req_complete_failed(req, ret); +-- +2.35.1 + diff --git a/queue-6.1/mtd-cfi-allow-building-spi-intel-standalone.patch b/queue-6.1/mtd-cfi-allow-building-spi-intel-standalone.patch new file mode 100644 index 00000000000..1b55564bb01 --- /dev/null +++ b/queue-6.1/mtd-cfi-allow-building-spi-intel-standalone.patch @@ -0,0 +1,61 @@ +From 81dc790606ab425ed9d6da7a15c9625bd6ce672e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Dec 2022 15:13:34 +0100 +Subject: mtd: cfi: allow building spi-intel standalone + +From: Arnd Bergmann + +[ Upstream commit d19ab1f785d0b6b9f709799f0938658903821ba1 ] + +When MTD or MTD_CFI_GEOMETRY is disabled, the spi-intel driver +fails to build, as it includes the shared CFI header: + +include/linux/mtd/cfi.h:62:2: error: #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. [-Werror=cpp] + 62 | #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. + +linux/mtd/spi-nor.h does not actually need to include cfi.h, so +remove the inclusion here to fix the warning. This uncovers a +missing #include in spi-nor/core.c so add that there to +prevent a different build issue. + +Fixes: e23e5a05d1fd ("mtd: spi-nor: intel-spi: Convert to SPI MEM") +Signed-off-by: Arnd Bergmann +Reviewed-by: Mika Westerberg +Reviewed-by: Tokunori Ikegami +Acked-by: Pratyush Yadav +Reviewed-by: Tudor Ambarus +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20221220141352.1486360-1-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/mtd/spi-nor/core.c | 1 + + include/linux/mtd/spi-nor.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c +index 2e0655c0b606..5dbf52aa0355 100644 +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h +index 42218a1164f6..f92bf7f7a754 100644 +--- a/include/linux/mtd/spi-nor.h ++++ b/include/linux/mtd/spi-nor.h +@@ -7,7 +7,6 @@ + #define __LINUX_MTD_SPI_NOR_H + + #include +-#include + #include + #include + +-- +2.35.1 + diff --git a/queue-6.1/mtd-parsers-scpart-fix-__udivdi3-undefined-on-mips.patch b/queue-6.1/mtd-parsers-scpart-fix-__udivdi3-undefined-on-mips.patch new file mode 100644 index 00000000000..cf242765bfd --- /dev/null +++ b/queue-6.1/mtd-parsers-scpart-fix-__udivdi3-undefined-on-mips.patch @@ -0,0 +1,47 @@ +From f616855d80955160feda5827347906585782f1ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Dec 2022 23:28:29 +0300 +Subject: mtd: parsers: scpart: fix __udivdi3 undefined on mips + +From: Mikhail Zhilkin + +[ Upstream commit 105c14b84d93168431abba5d55e6c26fa4b65abb ] + +This fixes the following compile error on mips architecture with clang +version 16.0.0 reported by the 0-DAY CI Kernel Test Service: + ld.lld: error: undefined symbol: __udivdi3 + referenced by scpart.c + mtd/parsers/scpart.o:(scpart_parse) in archive drivers/built-in.a + +As a workaround this makes 'offs' a 32-bit type. This is enough, because +the mtd containing partition table practically does not exceed 1 MB. We +can revert this when the [Link] has been resolved. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1635 +Fixes: 9b78ef0c7997 ("mtd: parsers: add support for Sercomm partitions") +Reported-by: kernel test robot +Suggested-by: Arnd Bergmann +Signed-off-by: Mikhail Zhilkin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/805fe58e-690f-6a3f-5ebf-2f6f6e6e4599@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/mtd/parsers/scpart.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mtd/parsers/scpart.c b/drivers/mtd/parsers/scpart.c +index 02601bb33de4..6e5e11c37078 100644 +--- a/drivers/mtd/parsers/scpart.c ++++ b/drivers/mtd/parsers/scpart.c +@@ -50,7 +50,7 @@ static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs, + int cnt = 0; + int res = 0; + int res2; +- loff_t offs; ++ uint32_t offs; + size_t retlen; + struct sc_part_desc *pdesc = NULL; + struct sc_part_desc *tmpdesc; +-- +2.35.1 + diff --git a/queue-6.1/net-hns3-fix-wrong-use-of-rss-size-during-vf-rss-con.patch b/queue-6.1/net-hns3-fix-wrong-use-of-rss-size-during-vf-rss-con.patch new file mode 100644 index 00000000000..ccf73b3a83e --- /dev/null +++ b/queue-6.1/net-hns3-fix-wrong-use-of-rss-size-during-vf-rss-con.patch @@ -0,0 +1,42 @@ +From 1c4670326a50afc69e989d8dedfcbf8ae642dad2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jan 2023 19:53:59 +0800 +Subject: net: hns3: fix wrong use of rss size during VF rss config + +From: Jie Wang + +[ Upstream commit ae9f29fdfd827ad06c1ae8155c042245a9d00757 ] + +Currently, it used old rss size to get current tc mode. As a result, the +rss size is updated, but the tc mode is still configured based on the old +rss size. + +So this patch fixes it by using the new rss size in both process. + +Fixes: 93969dc14fcd ("net: hns3: refactor VF rss init APIs with new common rss init APIs") +Signed-off-by: Jie Wang +Signed-off-by: Hao Lan +Reviewed-by: Alexander Duyck +Link: https://lore.kernel.org/r/20230110115359.10163-1-lanhao@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 081bd2c3f289..e84e5be8e59e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3130,7 +3130,7 @@ static int hclgevf_set_channels(struct hnae3_handle *handle, u32 new_tqps_num, + + hclgevf_update_rss_size(handle, new_tqps_num); + +- hclge_comm_get_rss_tc_info(cur_rss_size, hdev->hw_tc_map, ++ hclge_comm_get_rss_tc_info(kinfo->rss_size, hdev->hw_tc_map, + tc_offset, tc_valid, tc_size); + ret = hclge_comm_set_rss_tc_mode(&hdev->hw.hw, tc_offset, + tc_valid, tc_size); +-- +2.35.1 + diff --git a/queue-6.1/net-lan966x-check-for-ptp-to-be-enabled-in-lan966x_p.patch b/queue-6.1/net-lan966x-check-for-ptp-to-be-enabled-in-lan966x_p.patch new file mode 100644 index 00000000000..d7bbf7e611c --- /dev/null +++ b/queue-6.1/net-lan966x-check-for-ptp-to-be-enabled-in-lan966x_p.patch @@ -0,0 +1,42 @@ +From 0df047ca73826a8fb4b6a1130902297779947ea2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 16:32:23 +0100 +Subject: net: lan966x: check for ptp to be enabled in lan966x_ptp_deinit() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Clément Léger + +[ Upstream commit b0e380b5d4275299adf43e249f18309331b6f54f ] + +If ptp was not enabled due to missing IRQ for instance, +lan966x_ptp_deinit() will dereference NULL pointers. + +Fixes: d096459494a8 ("net: lan966x: Add support for ptp clocks") +Signed-off-by: Clément Léger +Reviewed-by: Horatiu Vultur +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +index e5a2bbe064f8..8e368318558a 100644 +--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c ++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +@@ -853,6 +853,9 @@ void lan966x_ptp_deinit(struct lan966x *lan966x) + struct lan966x_port *port; + int i; + ++ if (!lan966x->ptp) ++ return; ++ + for (i = 0; i < lan966x->num_phys_ports; i++) { + port = lan966x->ports[i]; + if (!port) +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5-check-attr-pointer-validity-before-derefere.patch b/queue-6.1/net-mlx5-check-attr-pointer-validity-before-derefere.patch new file mode 100644 index 00000000000..7390393a3b2 --- /dev/null +++ b/queue-6.1/net-mlx5-check-attr-pointer-validity-before-derefere.patch @@ -0,0 +1,38 @@ +From 50d41e137410074b01a8dc5889cd677f14a273d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Aug 2022 23:19:11 +0300 +Subject: net/mlx5: check attr pointer validity before dereferencing it + +From: Ariel Levkovich + +[ Upstream commit e0bf81bf0d3d4747c146e0bf44774d3d881d7137 ] + +Fix attr pointer validity checks after it was already +dereferenced. + +Fixes: cb0d54cbf948 ("net/mlx5e: Fix wrong source vport matching on tunnel rule") +Signed-off-by: Ariel Levkovich +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 8c6c9bcb3dc3..b4e263e8cfb8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -142,7 +142,7 @@ mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw, + if (mlx5_esw_indir_table_decap_vport(attr)) + vport = mlx5_esw_indir_table_decap_vport(attr); + +- if (attr && !attr->chain && esw_attr->int_port) ++ if (!attr->chain && esw_attr && esw_attr->int_port) + metadata = + mlx5e_tc_int_port_get_metadata_for_match(esw_attr->int_port); + else +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5-fix-command-stats-access-after-free.patch b/queue-6.1/net-mlx5-fix-command-stats-access-after-free.patch new file mode 100644 index 00000000000..df3067e9255 --- /dev/null +++ b/queue-6.1/net-mlx5-fix-command-stats-access-after-free.patch @@ -0,0 +1,108 @@ +From 2f23e924c1b50459773895168ead4f44e591597a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 19:05:47 +0200 +Subject: net/mlx5: Fix command stats access after free + +From: Moshe Shemesh + +[ Upstream commit da2e552b469a0cd130ff70a88ccc4139da428a65 ] + +Command may fail while driver is reloading and can't accept FW commands +till command interface is reinitialized. Such command failure is being +logged to command stats. This results in NULL pointer access as command +stats structure is being freed and reallocated during mlx5 devlink +reload (see kernel log below). + +Fix it by making command stats statically allocated on driver probe. + +Kernel log: +[ 2394.808802] BUG: unable to handle kernel paging request at 000000000002a9c0 +[ 2394.810610] PGD 0 P4D 0 +[ 2394.811811] Oops: 0002 [#1] SMP NOPTI +... +[ 2394.815482] RIP: 0010:native_queued_spin_lock_slowpath+0x183/0x1d0 +... +[ 2394.829505] Call Trace: +[ 2394.830667] _raw_spin_lock_irq+0x23/0x26 +[ 2394.831858] cmd_status_err+0x55/0x110 [mlx5_core] +[ 2394.833020] mlx5_access_reg+0xe7/0x150 [mlx5_core] +[ 2394.834175] mlx5_query_port_ptys+0x78/0xa0 [mlx5_core] +[ 2394.835337] mlx5e_ethtool_get_link_ksettings+0x74/0x590 [mlx5_core] +[ 2394.836454] ? kmem_cache_alloc_trace+0x140/0x1c0 +[ 2394.837562] __rh_call_get_link_ksettings+0x33/0x100 +[ 2394.838663] ? __rtnl_unlock+0x25/0x50 +[ 2394.839755] __ethtool_get_link_ksettings+0x72/0x150 +[ 2394.840862] duplex_show+0x6e/0xc0 +[ 2394.841963] dev_attr_show+0x1c/0x40 +[ 2394.843048] sysfs_kf_seq_show+0x9b/0x100 +[ 2394.844123] seq_read+0x153/0x410 +[ 2394.845187] vfs_read+0x91/0x140 +[ 2394.846226] ksys_read+0x4f/0xb0 +[ 2394.847234] do_syscall_64+0x5b/0x1a0 +[ 2394.848228] entry_SYSCALL_64_after_hwframe+0x65/0xca + +Fixes: 34f46ae0d4b3 ("net/mlx5: Add command failures data to debugfs") +Signed-off-by: Moshe Shemesh +Reviewed-by: Shay Drory +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 13 ++----------- + include/linux/mlx5/driver.h | 2 +- + 2 files changed, 3 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +index e7a894ba5c3e..723891eb86ee 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -2177,15 +2177,9 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) + return -EINVAL; + } + +- cmd->stats = kvcalloc(MLX5_CMD_OP_MAX, sizeof(*cmd->stats), GFP_KERNEL); +- if (!cmd->stats) +- return -ENOMEM; +- + cmd->pool = dma_pool_create("mlx5_cmd", mlx5_core_dma_dev(dev), size, align, 0); +- if (!cmd->pool) { +- err = -ENOMEM; +- goto dma_pool_err; +- } ++ if (!cmd->pool) ++ return -ENOMEM; + + err = alloc_cmd_page(dev, cmd); + if (err) +@@ -2269,8 +2263,6 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) + + err_free_pool: + dma_pool_destroy(cmd->pool); +-dma_pool_err: +- kvfree(cmd->stats); + return err; + } + +@@ -2283,7 +2275,6 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev) + destroy_msg_cache(dev); + free_cmd_page(dev, cmd); + dma_pool_destroy(cmd->pool); +- kvfree(cmd->stats); + } + + void mlx5_cmd_set_state(struct mlx5_core_dev *dev, +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 06cbad166225..ad55470a9fb9 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -315,7 +315,7 @@ struct mlx5_cmd { + struct mlx5_cmd_debug dbg; + struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES]; + int checksum_disabled; +- struct mlx5_cmd_stats *stats; ++ struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX]; + }; + + struct mlx5_cmd_mailbox { +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch b/queue-6.1/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch new file mode 100644 index 00000000000..6e44dc09920 --- /dev/null +++ b/queue-6.1/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch @@ -0,0 +1,41 @@ +From d700758da58e3bfec03dccf8896f2cf0f15faa90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 14:26:09 -0800 +Subject: net/mlx5: Fix ptp max frequency adjustment range + +From: Rahul Rameshbabu + +[ Upstream commit fe91d57277eef8bb4aca05acfa337b4a51d0bba4 ] + +.max_adj of ptp_clock_info acts as an absolute value for the amount in ppb +that can be set for a single call of .adjfine. This means that a single +call to .getfine cannot be greater than .max_adj or less than -(.max_adj). +Provides correct value for max frequency adjustment value supported by +devices. + +Fixes: 3d8c38af1493 ("net/mlx5e: Add PTP Hardware Clock (PHC) support") +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Gal Pressman +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index d3a9ae80fd30..d7ddfc489536 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -691,7 +691,7 @@ static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, + static const struct ptp_clock_info mlx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "mlx5_ptp", +- .max_adj = 100000000, ++ .max_adj = 50000000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-don-t-support-encap-rules-with-gbp-option.patch b/queue-6.1/net-mlx5e-don-t-support-encap-rules-with-gbp-option.patch new file mode 100644 index 00000000000..dfed24d1b08 --- /dev/null +++ b/queue-6.1/net-mlx5e-don-t-support-encap-rules-with-gbp-option.patch @@ -0,0 +1,40 @@ +From ffb487e4a5f85eb981b482d7f11660a9b1397a33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Dec 2022 04:54:09 +0200 +Subject: net/mlx5e: Don't support encap rules with gbp option + +From: Gavin Li + +[ Upstream commit d515d63cae2cd186acf40deaa8ef33067bb7f637 ] + +Previously, encap rules with gbp option would be offloaded by mistake but +driver does not support gbp option offload. + +To fix this issue, check if the encap rule has gbp option and don't +offload the rule + +Fixes: d8f9dfae49ce ("net: sched: allow flower to match vxlan options") +Signed-off-by: Gavin Li +Reviewed-by: Maor Dickman +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +index fd07c4cbfd1d..1f62c702b625 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +@@ -88,6 +88,8 @@ static int mlx5e_gen_ip_tunnel_header_vxlan(char buf[], + struct udphdr *udp = (struct udphdr *)(buf); + struct vxlanhdr *vxh; + ++ if (tun_key->tun_flags & TUNNEL_VXLAN_OPT) ++ return -EOPNOTSUPP; + vxh = (struct vxlanhdr *)((char *)udp + sizeof(struct udphdr)); + *ip_proto = IPPROTO_UDP; + +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-fix-macsec-possible-null-dereference-when-.patch b/queue-6.1/net-mlx5e-fix-macsec-possible-null-dereference-when-.patch new file mode 100644 index 00000000000..b059e82c703 --- /dev/null +++ b/queue-6.1/net-mlx5e-fix-macsec-possible-null-dereference-when-.patch @@ -0,0 +1,57 @@ +From c999632c11f42ddd83b6b959a0f13ad6db2e780c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 Dec 2022 13:22:23 +0200 +Subject: net/mlx5e: Fix macsec possible null dereference when updating MAC + security entity (SecY) + +From: Emeel Hakim + +[ Upstream commit 9828994ac492e8e7de47fe66097b7e665328f348 ] + +Upon updating MAC security entity (SecY) in hw offload path, the macsec +security association (SA) initialization routine is called. In case of +extended packet number (epn) is enabled the salt and ssci attributes are +retrieved using the MACsec driver rx_sa context which is unavailable when +updating a SecY property such as encoding-sa hence the null dereference. +Fix by using the provided SA to set those attributes. + +Fixes: 4411a6c0abd3 ("net/mlx5e: Support MACsec offload extended packet number (EPN)") +Signed-off-by: Emeel Hakim +Reviewed-by: Raed Salem +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index 7c0085ba2fc5..b92d541b5286 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -359,7 +359,6 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx, + struct mlx5_core_dev *mdev = priv->mdev; + struct mlx5_macsec_obj_attrs obj_attrs; + union mlx5e_macsec_rule *macsec_rule; +- struct macsec_key *key; + int err; + + obj_attrs.next_pn = sa->next_pn; +@@ -369,13 +368,9 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx, + obj_attrs.aso_pdn = macsec->aso.pdn; + obj_attrs.epn_state = sa->epn_state; + +- key = (is_tx) ? &ctx->sa.tx_sa->key : &ctx->sa.rx_sa->key; +- + if (sa->epn_state.epn_enabled) { +- obj_attrs.ssci = (is_tx) ? cpu_to_be32((__force u32)ctx->sa.tx_sa->ssci) : +- cpu_to_be32((__force u32)ctx->sa.rx_sa->ssci); +- +- memcpy(&obj_attrs.salt, &key->salt, sizeof(key->salt)); ++ obj_attrs.ssci = cpu_to_be32((__force u32)sa->ssci); ++ memcpy(&obj_attrs.salt, &sa->salt, sizeof(sa->salt)); + } + + obj_attrs.replay_window = ctx->secy->replay_window; +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-fix-macsec-ssci-attribute-handling-in-offl.patch b/queue-6.1/net-mlx5e-fix-macsec-ssci-attribute-handling-in-offl.patch new file mode 100644 index 00000000000..5db69406f8b --- /dev/null +++ b/queue-6.1/net-mlx5e-fix-macsec-ssci-attribute-handling-in-offl.patch @@ -0,0 +1,73 @@ +From e9e5408ad28662e95c11afb40269376f3542d623 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 16:34:13 +0200 +Subject: net/mlx5e: Fix macsec ssci attribute handling in offload path + +From: Emeel Hakim + +[ Upstream commit f5e1ed04aa2ea665a796f0109091ca3f2b01024a ] + +Currently when macsec offload is set with extended packet number (epn) +enabled, the driver wrongly deduce the short secure channel identifier +(ssci) from the salt instead of the stand alone ssci attribute as it +should, consequently creating a mismatch between the kernel and driver's +ssci values. +Fix by using the ssci value from the relevant attribute. + +Fixes: 4411a6c0abd3 ("net/mlx5e: Support MACsec offload extended packet number (EPN)") +Signed-off-by: Emeel Hakim +Reviewed-by: Raed Salem +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index f900709639f6..7c0085ba2fc5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -62,6 +62,7 @@ struct mlx5e_macsec_sa { + u32 enc_key_id; + u32 next_pn; + sci_t sci; ++ ssci_t ssci; + salt_t salt; + + struct rhash_head hash; +@@ -499,10 +500,11 @@ mlx5e_macsec_get_macsec_device_context(const struct mlx5e_macsec *macsec, + } + + static void update_macsec_epn(struct mlx5e_macsec_sa *sa, const struct macsec_key *key, +- const pn_t *next_pn_halves) ++ const pn_t *next_pn_halves, ssci_t ssci) + { + struct mlx5e_macsec_epn_state *epn_state = &sa->epn_state; + ++ sa->ssci = ssci; + sa->salt = key->salt; + epn_state->epn_enabled = 1; + epn_state->epn_msb = next_pn_halves->upper; +@@ -550,7 +552,8 @@ static int mlx5e_macsec_add_txsa(struct macsec_context *ctx) + tx_sa->assoc_num = assoc_num; + + if (secy->xpn) +- update_macsec_epn(tx_sa, &ctx_tx_sa->key, &ctx_tx_sa->next_pn_halves); ++ update_macsec_epn(tx_sa, &ctx_tx_sa->key, &ctx_tx_sa->next_pn_halves, ++ ctx_tx_sa->ssci); + + err = mlx5_create_encryption_key(mdev, ctx->sa.key, secy->key_len, + MLX5_ACCEL_OBJ_MACSEC_KEY, +@@ -945,7 +948,8 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx) + rx_sa->fs_id = rx_sc->sc_xarray_element->fs_id; + + if (ctx->secy->xpn) +- update_macsec_epn(rx_sa, &ctx_rx_sa->key, &ctx_rx_sa->next_pn_halves); ++ update_macsec_epn(rx_sa, &ctx_rx_sa->key, &ctx_rx_sa->next_pn_halves, ++ ctx_rx_sa->ssci); + + err = mlx5_create_encryption_key(mdev, ctx->sa.key, ctx->secy->key_len, + MLX5_ACCEL_OBJ_MACSEC_KEY, +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-ipoib-block-pkey-interfaces-with-less-rx-q.patch b/queue-6.1/net-mlx5e-ipoib-block-pkey-interfaces-with-less-rx-q.patch new file mode 100644 index 00000000000..651b23fee62 --- /dev/null +++ b/queue-6.1/net-mlx5e-ipoib-block-pkey-interfaces-with-less-rx-q.patch @@ -0,0 +1,55 @@ +From a757108b4054a61a454edfe05143d23eaccd3fa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Nov 2022 17:51:19 +0200 +Subject: net/mlx5e: IPoIB, Block PKEY interfaces with less rx queues than + parent + +From: Dragos Tatulea + +[ Upstream commit 31c70bfe58ef09fe36327ddcced9143a16e9e83d ] + +A user is able to configure an arbitrary number of rx queues when +creating an interface via netlink. This doesn't work for child PKEY +interfaces because the child interface uses the parent receive channels. + +Although the child shares the parent's receive channels, the number of +rx queues is important for the channel_stats array: the parent's rx +channel index is used to access the child's channel_stats. So the array +has to be at least as large as the parent's rx queue size for the +counting to work correctly and to prevent out of bound accesses. + +This patch checks for the mentioned scenario and returns an error when +trying to create the interface. The error is propagated to the user. + +Fixes: be98737a4faa ("net/mlx5e: Use dynamic per-channel allocations in stats") +Signed-off-by: Dragos Tatulea +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c +index 3d31c59e69d4..0cf4eaf852d2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c +@@ -168,6 +168,15 @@ static int mlx5i_pkey_dev_init(struct net_device *dev) + return -EINVAL; + } + ++ if (dev->num_rx_queues < parent_dev->real_num_rx_queues) { ++ mlx5_core_warn(priv->mdev, ++ "failed to create child device with rx queues [%d] less than parent's [%d]\n", ++ dev->num_rx_queues, ++ parent_dev->real_num_rx_queues); ++ mlx5i_parent_put(dev); ++ return -EINVAL; ++ } ++ + /* Get QPN to netdevice hash table from parent */ + parent_ipriv = netdev_priv(parent_dev); + ipriv->qpn_htbl = parent_ipriv->qpn_htbl; +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-ipoib-block-queue-count-configuration-when.patch b/queue-6.1/net-mlx5e-ipoib-block-queue-count-configuration-when.patch new file mode 100644 index 00000000000..3488437dc9c --- /dev/null +++ b/queue-6.1/net-mlx5e-ipoib-block-queue-count-configuration-when.patch @@ -0,0 +1,184 @@ +From d8cc574f5a33a0981598acd3457d25998fc94ec4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Dec 2022 13:02:38 +0200 +Subject: net/mlx5e: IPoIB, Block queue count configuration when sub interfaces + are present + +From: Dragos Tatulea + +[ Upstream commit 806a8df7126a8c05d60411eeb81057c2a8bbe7a7 ] + +PKEY sub interfaces share the receive queues with the parent interface. +While setting the sub interface queue count is not supported, it is +currently possible to change the number of queues of the parent interface. +Thus we can end up with inconsistent queue sizes between the parent and its +sub interfaces. + +This change disallows setting the queue count on the parent interface when +sub interfaces are present. + +This is achieved by introducing an explicit reference to the parent netdev +in the mlx5i_priv of the child interface. An additional counter is also +required on the parent side to detect when sub interfaces are attached and +for proper cleanup. + +The rtnl lock is taken during the ethtool op and the sub interface +ndo_init/uninit ops. There is no race here around counting the sub +interfaces, reading the sub interfaces and setting the number of +channels. The ASSERT_RTNL was added to document that. + +Fixes: be98737a4faa ("net/mlx5e: Use dynamic per-channel allocations in stats") +Signed-off-by: Dragos Tatulea +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../mellanox/mlx5/core/ipoib/ethtool.c | 16 +++++++- + .../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 38 +++++++++++++++++++ + .../ethernet/mellanox/mlx5/core/ipoib/ipoib.h | 6 +++ + .../mellanox/mlx5/core/ipoib/ipoib_vlan.c | 9 ++--- + 4 files changed, 62 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c +index c247cca154e9..eff92dc0927c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c +@@ -90,9 +90,21 @@ static void mlx5i_get_ringparam(struct net_device *dev, + static int mlx5i_set_channels(struct net_device *dev, + struct ethtool_channels *ch) + { +- struct mlx5e_priv *priv = mlx5i_epriv(dev); ++ struct mlx5i_priv *ipriv = netdev_priv(dev); ++ struct mlx5e_priv *epriv = mlx5i_epriv(dev); ++ ++ /* rtnl lock protects from race between this ethtool op and sub ++ * interface ndo_init/uninit. ++ */ ++ ASSERT_RTNL(); ++ if (ipriv->num_sub_interfaces > 0) { ++ mlx5_core_warn(epriv->mdev, ++ "can't change number of channels for interfaces with sub interfaces (%u)\n", ++ ipriv->num_sub_interfaces); ++ return -EINVAL; ++ } + +- return mlx5e_ethtool_set_channels(priv, ch); ++ return mlx5e_ethtool_set_channels(epriv, ch); + } + + static void mlx5i_get_channels(struct net_device *dev, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +index 84f5352b0ce1..038ae0fcf9d4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +@@ -160,6 +160,44 @@ void mlx5i_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) + stats->tx_dropped = sstats->tx_queue_dropped; + } + ++struct net_device *mlx5i_parent_get(struct net_device *netdev) ++{ ++ struct mlx5e_priv *priv = mlx5i_epriv(netdev); ++ struct mlx5i_priv *ipriv, *parent_ipriv; ++ struct net_device *parent_dev; ++ int parent_ifindex; ++ ++ ipriv = priv->ppriv; ++ ++ parent_ifindex = netdev->netdev_ops->ndo_get_iflink(netdev); ++ parent_dev = dev_get_by_index(dev_net(netdev), parent_ifindex); ++ if (!parent_dev) ++ return NULL; ++ ++ parent_ipriv = netdev_priv(parent_dev); ++ ++ ASSERT_RTNL(); ++ parent_ipriv->num_sub_interfaces++; ++ ++ ipriv->parent_dev = parent_dev; ++ ++ return parent_dev; ++} ++ ++void mlx5i_parent_put(struct net_device *netdev) ++{ ++ struct mlx5e_priv *priv = mlx5i_epriv(netdev); ++ struct mlx5i_priv *ipriv, *parent_ipriv; ++ ++ ipriv = priv->ppriv; ++ parent_ipriv = netdev_priv(ipriv->parent_dev); ++ ++ ASSERT_RTNL(); ++ parent_ipriv->num_sub_interfaces--; ++ ++ dev_put(ipriv->parent_dev); ++} ++ + int mlx5i_init_underlay_qp(struct mlx5e_priv *priv) + { + struct mlx5_core_dev *mdev = priv->mdev; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h +index 99d46fda9f82..f3f2af972020 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h +@@ -54,9 +54,11 @@ struct mlx5i_priv { + struct rdma_netdev rn; /* keep this first */ + u32 qpn; + bool sub_interface; ++ u32 num_sub_interfaces; + u32 qkey; + u16 pkey_index; + struct mlx5i_pkey_qpn_ht *qpn_htbl; ++ struct net_device *parent_dev; + char *mlx5e_priv[]; + }; + +@@ -117,5 +119,9 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, + struct mlx5_av *av, u32 dqpn, u32 dqkey, bool xmit_more); + void mlx5i_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats); + ++/* Reference management for child to parent interfaces. */ ++struct net_device *mlx5i_parent_get(struct net_device *netdev); ++void mlx5i_parent_put(struct net_device *netdev); ++ + #endif /* CONFIG_MLX5_CORE_IPOIB */ + #endif /* __MLX5E_IPOB_H__ */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c +index 0227a521d301..3d31c59e69d4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c +@@ -158,21 +158,19 @@ static int mlx5i_pkey_dev_init(struct net_device *dev) + struct mlx5e_priv *priv = mlx5i_epriv(dev); + struct mlx5i_priv *ipriv, *parent_ipriv; + struct net_device *parent_dev; +- int parent_ifindex; + + ipriv = priv->ppriv; + +- /* Get QPN to netdevice hash table from parent */ +- parent_ifindex = dev->netdev_ops->ndo_get_iflink(dev); +- parent_dev = dev_get_by_index(dev_net(dev), parent_ifindex); ++ /* Link to parent */ ++ parent_dev = mlx5i_parent_get(dev); + if (!parent_dev) { + mlx5_core_warn(priv->mdev, "failed to get parent device\n"); + return -EINVAL; + } + ++ /* Get QPN to netdevice hash table from parent */ + parent_ipriv = netdev_priv(parent_dev); + ipriv->qpn_htbl = parent_ipriv->qpn_htbl; +- dev_put(parent_dev); + + return mlx5i_dev_init(dev); + } +@@ -184,6 +182,7 @@ static int mlx5i_pkey_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + + static void mlx5i_pkey_dev_cleanup(struct net_device *netdev) + { ++ mlx5i_parent_put(netdev); + return mlx5i_dev_cleanup(netdev); + } + +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-ipoib-fix-child-pkey-interface-stats-on-rx.patch b/queue-6.1/net-mlx5e-ipoib-fix-child-pkey-interface-stats-on-rx.patch new file mode 100644 index 00000000000..9977e200194 --- /dev/null +++ b/queue-6.1/net-mlx5e-ipoib-fix-child-pkey-interface-stats-on-rx.patch @@ -0,0 +1,43 @@ +From 0699ee36c1f630d0a65f367338d5f767a7c80d5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 16:59:13 +0200 +Subject: net/mlx5e: IPoIB, Fix child PKEY interface stats on rx path + +From: Dragos Tatulea + +[ Upstream commit b5e23931c45a2f99f60a2f2b98a9e4d5a62a5b13 ] + +The current code always does the accounting using the +stats from the parent interface (linked in the rq). This +doesn't work when there are child interfaces configured. + +Fix this behavior by always using the stats from the child +interface priv. This will also work for parent only +interfaces: the child (netdev) and parent netdev (rq->netdev) +will point to the same thing. + +Fixes: be98737a4faa ("net/mlx5e: Use dynamic per-channel allocations in stats") +Signed-off-by: Dragos Tatulea +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index a61a43fc8d5c..56d1bd22c7c6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -2300,7 +2300,7 @@ static inline void mlx5i_complete_rx_cqe(struct mlx5e_rq *rq, + + priv = mlx5i_epriv(netdev); + tstamp = &priv->tstamp; +- stats = rq->stats; ++ stats = &priv->channel_stats[rq->ix]->rq; + + flags_rqpn = be32_to_cpu(cqe->flags_rqpn); + g = (flags_rqpn >> 28) & 3; +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-tc-keep-mod-hdr-actions-after-mod-hdr-allo.patch b/queue-6.1/net-mlx5e-tc-keep-mod-hdr-actions-after-mod-hdr-allo.patch new file mode 100644 index 00000000000..a03a64a9ca4 --- /dev/null +++ b/queue-6.1/net-mlx5e-tc-keep-mod-hdr-actions-after-mod-hdr-allo.patch @@ -0,0 +1,56 @@ +From e4b6b2764e8ce47f9bd2ca5f93422f583db65cff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Aug 2022 00:32:30 +0300 +Subject: net/mlx5e: TC, Keep mod hdr actions after mod hdr alloc + +From: Ariel Levkovich + +[ Upstream commit 5e72f3f1c558019082cfeedeed73748f35d780c6 ] + +When offloading TC NIC rule which has mod_hdr action, the +mod_hdr actions list is freed upon mod_hdr allocation. + +In the new format of handling multi table actions and CT in +particular, the mod_hdr actions list is still relevant when +setting the pre and post rules and therefore, freeing the list +may cause adding rules which don't set the FTE_ID. + +Therefore, the mod_hdr actions list needs to be kept for the +pre/post flows as well and should be left for these handler to +be freed. + +Fixes: 8300f225268b ("net/mlx5e: Create new flow attr for multi table actions") +Signed-off-by: Ariel Levkovich +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index bd9936af4582..4c313b7424bf 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -1283,7 +1283,6 @@ mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv, + + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { + err = mlx5e_attach_mod_hdr(priv, flow, parse_attr); +- mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); + if (err) + return err; + } +@@ -1341,8 +1340,10 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv, + } + mutex_unlock(&tc->t_lock); + +- if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) ++ if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { ++ mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts); + mlx5e_detach_mod_hdr(priv, flow); ++ } + + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) + mlx5_fc_destroy(priv->mdev, attr->counter); +-- +2.35.1 + diff --git a/queue-6.1/net-mlx5e-verify-dev-is-present-for-fix-features-ndo.patch b/queue-6.1/net-mlx5e-verify-dev-is-present-for-fix-features-ndo.patch new file mode 100644 index 00000000000..b75e4e345d4 --- /dev/null +++ b/queue-6.1/net-mlx5e-verify-dev-is-present-for-fix-features-ndo.patch @@ -0,0 +1,40 @@ +From 34336c2631eae8dd5e5da6c79415a2407be73a3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 11:16:21 +0200 +Subject: net/mlx5e: Verify dev is present for fix features ndo + +From: Roy Novich + +[ Upstream commit ab4b01bfdaa69492fb36484026b0a0f0af02d75a ] + +The native NIC port net device instance is being used as Uplink +representor. While changing profiles private resources are not +available, fix features ndo does not check if the netdev is present. +Add driver protection to verify private resources are ready. + +Fixes: 7a9fb35e8c3a ("net/mlx5e: Do not reload ethernet ports when changing eswitch mode") +Signed-off-by: Roy Novich +Reviewed-by: Roi Dayan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 951ede433813..4dc149ef618c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -4071,6 +4071,9 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev, + struct mlx5e_vlan_table *vlan; + struct mlx5e_params *params; + ++ if (!netif_device_present(netdev)) ++ return features; ++ + vlan = mlx5e_fs_get_vlan(priv->fs); + mutex_lock(&priv->state_lock); + params = &priv->channels.params; +-- +2.35.1 + diff --git a/queue-6.1/net-sched-act_mpls-fix-warning-during-failed-attribu.patch b/queue-6.1/net-sched-act_mpls-fix-warning-during-failed-attribu.patch new file mode 100644 index 00000000000..5aee1941da5 --- /dev/null +++ b/queue-6.1/net-sched-act_mpls-fix-warning-during-failed-attribu.patch @@ -0,0 +1,109 @@ +From 40ac2ed5a74f9c9ca81864219a301e344149acae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Jan 2023 19:10:04 +0200 +Subject: net/sched: act_mpls: Fix warning during failed attribute validation + +From: Ido Schimmel + +[ Upstream commit 9e17f99220d111ea031b44153fdfe364b0024ff2 ] + +The 'TCA_MPLS_LABEL' attribute is of 'NLA_U32' type, but has a +validation type of 'NLA_VALIDATE_FUNCTION'. This is an invalid +combination according to the comment above 'struct nla_policy': + +" +Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN: + NLA_BINARY Validation function called for the attribute. + All other Unused - but note that it's a union +" + +This can trigger the warning [1] in nla_get_range_unsigned() when +validation of the attribute fails. Despite being of 'NLA_U32' type, the +associated 'min'/'max' fields in the policy are negative as they are +aliased by the 'validate' field. + +Fix by changing the attribute type to 'NLA_BINARY' which is consistent +with the above comment and all other users of NLA_POLICY_VALIDATE_FN(). +As a result, move the length validation to the validation function. + +No regressions in MPLS tests: + + # ./tdc.py -f tc-tests/actions/mpls.json + [...] + # echo $? + 0 + +[1] +WARNING: CPU: 0 PID: 17743 at lib/nlattr.c:118 +nla_get_range_unsigned+0x1d8/0x1e0 lib/nlattr.c:117 +Modules linked in: +CPU: 0 PID: 17743 Comm: syz-executor.0 Not tainted 6.1.0-rc8 #3 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +rel-1.13.0-48-gd9c812dda519-prebuilt.qemu.org 04/01/2014 +RIP: 0010:nla_get_range_unsigned+0x1d8/0x1e0 lib/nlattr.c:117 +[...] +Call Trace: + + __netlink_policy_dump_write_attr+0x23d/0x990 net/netlink/policy.c:310 + netlink_policy_dump_write_attr+0x22/0x30 net/netlink/policy.c:411 + netlink_ack_tlv_fill net/netlink/af_netlink.c:2454 [inline] + netlink_ack+0x546/0x760 net/netlink/af_netlink.c:2506 + netlink_rcv_skb+0x1b7/0x240 net/netlink/af_netlink.c:2546 + rtnetlink_rcv+0x18/0x20 net/core/rtnetlink.c:6109 + netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] + netlink_unicast+0x5e9/0x6b0 net/netlink/af_netlink.c:1345 + netlink_sendmsg+0x739/0x860 net/netlink/af_netlink.c:1921 + sock_sendmsg_nosec net/socket.c:714 [inline] + sock_sendmsg net/socket.c:734 [inline] + ____sys_sendmsg+0x38f/0x500 net/socket.c:2482 + ___sys_sendmsg net/socket.c:2536 [inline] + __sys_sendmsg+0x197/0x230 net/socket.c:2565 + __do_sys_sendmsg net/socket.c:2574 [inline] + __se_sys_sendmsg net/socket.c:2572 [inline] + __x64_sys_sendmsg+0x42/0x50 net/socket.c:2572 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Link: https://lore.kernel.org/netdev/CAO4mrfdmjvRUNbDyP0R03_DrD_eFCLCguz6OxZ2TYRSv0K9gxA@mail.gmail.com/ +Fixes: 2a2ea50870ba ("net: sched: add mpls manipulation actions to TC") +Reported-by: Wei Chen +Tested-by: Wei Chen +Signed-off-by: Ido Schimmel +Reviewed-by: Alexander Duyck +Link: https://lore.kernel.org/r/20230107171004.608436-1-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/act_mpls.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c +index 8ad25cc8ccd5..ea5959094adb 100644 +--- a/net/sched/act_mpls.c ++++ b/net/sched/act_mpls.c +@@ -132,6 +132,11 @@ static int valid_label(const struct nlattr *attr, + { + const u32 *label = nla_data(attr); + ++ if (nla_len(attr) != sizeof(*label)) { ++ NL_SET_ERR_MSG_MOD(extack, "Invalid MPLS label length"); ++ return -EINVAL; ++ } ++ + if (*label & ~MPLS_LABEL_MASK || *label == MPLS_LABEL_IMPLNULL) { + NL_SET_ERR_MSG_MOD(extack, "MPLS label out of range"); + return -EINVAL; +@@ -143,7 +148,8 @@ static int valid_label(const struct nlattr *attr, + static const struct nla_policy mpls_policy[TCA_MPLS_MAX + 1] = { + [TCA_MPLS_PARMS] = NLA_POLICY_EXACT_LEN(sizeof(struct tc_mpls)), + [TCA_MPLS_PROTO] = { .type = NLA_U16 }, +- [TCA_MPLS_LABEL] = NLA_POLICY_VALIDATE_FN(NLA_U32, valid_label), ++ [TCA_MPLS_LABEL] = NLA_POLICY_VALIDATE_FN(NLA_BINARY, ++ valid_label), + [TCA_MPLS_TC] = NLA_POLICY_RANGE(NLA_U8, 0, 7), + [TCA_MPLS_TTL] = NLA_POLICY_MIN(NLA_U8, 1), + [TCA_MPLS_BOS] = NLA_POLICY_RANGE(NLA_U8, 0, 1), +-- +2.35.1 + diff --git a/queue-6.1/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch b/queue-6.1/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch new file mode 100644 index 00000000000..c5fc6b3c9eb --- /dev/null +++ b/queue-6.1/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch @@ -0,0 +1,129 @@ +From d7e7d0b2c6d89d76f8fc1e8416e4f811f125108a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 17:23:44 +0900 +Subject: nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() + +From: Minsuk Kang + +[ Upstream commit 9dab880d675b9d0dd56c6428e4e8352a3339371d ] + +Fix a use-after-free that occurs in hcd when in_urb sent from +pn533_usb_send_frame() is completed earlier than out_urb. Its callback +frees the skb data in pn533_send_async_complete() that is used as a +transfer buffer of out_urb. Wait before sending in_urb until the +callback of out_urb is called. To modify the callback of out_urb alone, +separate the complete function of out_urb and ack_urb. + +Found by a modified version of syzkaller. + +BUG: KASAN: use-after-free in dummy_timer +Call Trace: + memcpy (mm/kasan/shadow.c:65) + dummy_perform_transfer (drivers/usb/gadget/udc/dummy_hcd.c:1352) + transfer (drivers/usb/gadget/udc/dummy_hcd.c:1453) + dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:1972) + arch_static_branch (arch/x86/include/asm/jump_label.h:27) + static_key_false (include/linux/jump_label.h:207) + timer_expire_exit (include/trace/events/timer.h:127) + call_timer_fn (kernel/time/timer.c:1475) + expire_timers (kernel/time/timer.c:1519) + __run_timers (kernel/time/timer.c:1790) + run_timer_softirq (kernel/time/timer.c:1803) + +Fixes: c46ee38620a2 ("NFC: pn533: add NXP pn533 nfc device driver") +Signed-off-by: Minsuk Kang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/pn533/usb.c | 44 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c +index 6f71ac72012e..ed9c5e2cf3ad 100644 +--- a/drivers/nfc/pn533/usb.c ++++ b/drivers/nfc/pn533/usb.c +@@ -153,10 +153,17 @@ static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags) + return usb_submit_urb(phy->ack_urb, flags); + } + ++struct pn533_out_arg { ++ struct pn533_usb_phy *phy; ++ struct completion done; ++}; ++ + static int pn533_usb_send_frame(struct pn533 *dev, + struct sk_buff *out) + { + struct pn533_usb_phy *phy = dev->phy; ++ struct pn533_out_arg arg; ++ void *cntx; + int rc; + + if (phy->priv == NULL) +@@ -168,10 +175,17 @@ static int pn533_usb_send_frame(struct pn533 *dev, + print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, + out->data, out->len, false); + ++ init_completion(&arg.done); ++ cntx = phy->out_urb->context; ++ phy->out_urb->context = &arg; ++ + rc = usb_submit_urb(phy->out_urb, GFP_KERNEL); + if (rc) + return rc; + ++ wait_for_completion(&arg.done); ++ phy->out_urb->context = cntx; ++ + if (dev->protocol_type == PN533_PROTO_REQ_RESP) { + /* request for response for sent packet directly */ + rc = pn533_submit_urb_for_response(phy, GFP_KERNEL); +@@ -408,7 +422,31 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy) + return arg.rc; + } + +-static void pn533_send_complete(struct urb *urb) ++static void pn533_out_complete(struct urb *urb) ++{ ++ struct pn533_out_arg *arg = urb->context; ++ struct pn533_usb_phy *phy = arg->phy; ++ ++ switch (urb->status) { ++ case 0: ++ break; /* success */ ++ case -ECONNRESET: ++ case -ENOENT: ++ dev_dbg(&phy->udev->dev, ++ "The urb has been stopped (status %d)\n", ++ urb->status); ++ break; ++ case -ESHUTDOWN: ++ default: ++ nfc_err(&phy->udev->dev, ++ "Urb failure (status %d)\n", ++ urb->status); ++ } ++ ++ complete(&arg->done); ++} ++ ++static void pn533_ack_complete(struct urb *urb) + { + struct pn533_usb_phy *phy = urb->context; + +@@ -496,10 +534,10 @@ static int pn533_usb_probe(struct usb_interface *interface, + + usb_fill_bulk_urb(phy->out_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_out_complete, phy); + usb_fill_bulk_urb(phy->ack_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_ack_complete, phy); + + switch (id->driver_info) { + case PN533_DEVICE_STD: +-- +2.35.1 + diff --git a/queue-6.1/nfsd-add-an-nfsd_file_fsync-tracepoint.patch b/queue-6.1/nfsd-add-an-nfsd_file_fsync-tracepoint.patch new file mode 100644 index 00000000000..b1bf57460a3 --- /dev/null +++ b/queue-6.1/nfsd-add-an-nfsd_file_fsync-tracepoint.patch @@ -0,0 +1,93 @@ +From 057411ae5088b443b23ee7e733e72f442f4ddbc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 16:22:48 -0400 +Subject: NFSD: Add an nfsd_file_fsync tracepoint + +From: Chuck Lever + +[ Upstream commit d7064eaf688cfe454c50db9f59298463d80d403c ] + +Add a tracepoint to capture the number of filecache-triggered fsync +calls and which files needed it. Also, record when an fsync triggers +a write verifier reset. + +Examples: + +<...>-97 [007] 262.505611: nfsd_file_free: inode=0xffff888171e08140 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d2400 +<...>-97 [007] 262.505612: nfsd_file_fsync: inode=0xffff888171e08140 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d2400 ret=0 +<...>-97 [007] 262.505623: nfsd_file_free: inode=0xffff888171e08dc0 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d1e00 +<...>-97 [007] 262.505624: nfsd_file_fsync: inode=0xffff888171e08dc0 ref=0 flags=GC may=WRITE nf_file=0xffff8881373d1e00 ret=0 + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 5 ++++- + fs/nfsd/trace.h | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index f54dd6695741..7c673f98f95c 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -314,10 +314,13 @@ static void + nfsd_file_fsync(struct nfsd_file *nf) + { + struct file *file = nf->nf_file; ++ int ret; + + if (!file || !(file->f_mode & FMODE_WRITE)) + return; +- if (vfs_fsync(file, 1) != 0) ++ ret = vfs_fsync(file, 1); ++ trace_nfsd_file_fsync(nf, ret); ++ if (ret) + nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); + } + +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index 55e9e19cb1ec..08e2738adf8f 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -1182,6 +1182,37 @@ DEFINE_EVENT(nfsd_file_lruwalk_class, name, \ + DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_gc_removed); + DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_shrinker_removed); + ++TRACE_EVENT(nfsd_file_fsync, ++ TP_PROTO( ++ const struct nfsd_file *nf, ++ int ret ++ ), ++ TP_ARGS(nf, ret), ++ TP_STRUCT__entry( ++ __field(void *, nf_inode) ++ __field(int, nf_ref) ++ __field(int, ret) ++ __field(unsigned long, nf_flags) ++ __field(unsigned char, nf_may) ++ __field(struct file *, nf_file) ++ ), ++ TP_fast_assign( ++ __entry->nf_inode = nf->nf_inode; ++ __entry->nf_ref = refcount_read(&nf->nf_ref); ++ __entry->ret = ret; ++ __entry->nf_flags = nf->nf_flags; ++ __entry->nf_may = nf->nf_may; ++ __entry->nf_file = nf->nf_file; ++ ), ++ TP_printk("inode=%p ref=%d flags=%s may=%s nf_file=%p ret=%d", ++ __entry->nf_inode, ++ __entry->nf_ref, ++ show_nf_flags(__entry->nf_flags), ++ show_nfsd_may_flags(__entry->nf_may), ++ __entry->nf_file, __entry->ret ++ ) ++); ++ + #include "cache.h" + + TRACE_DEFINE_ENUM(RC_DROPIT); +-- +2.35.1 + diff --git a/queue-6.1/nfsd-add-an-nfsd_file_gc-flag-to-enable-nfsd_file-ga.patch b/queue-6.1/nfsd-add-an-nfsd_file_gc-flag-to-enable-nfsd_file-ga.patch new file mode 100644 index 00000000000..8630d4b8333 --- /dev/null +++ b/queue-6.1/nfsd-add-an-nfsd_file_gc-flag-to-enable-nfsd_file-ga.patch @@ -0,0 +1,266 @@ +From 20252f33a1fbc03d9d8df264788f541c0246b424 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 10:46:51 -0400 +Subject: NFSD: Add an NFSD_FILE_GC flag to enable nfsd_file garbage collection + +From: Chuck Lever + +[ Upstream commit 4d1ea8455716ca070e3cd85767e6f6a562a58b1b ] + +NFSv4 operations manage the lifetime of nfsd_file items they use by +means of NFSv4 OPEN and CLOSE. Hence there's no need for them to be +garbage collected. + +Introduce a mechanism to enable garbage collection for nfsd_file +items used only by NFSv2/3 callers. + +Note that the change in nfsd_file_put() ensures that both CLOSE and +DELEGRETURN will actually close out and free an nfsd_file on last +reference of a non-garbage-collected file. + +Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=394 +Suggested-by: Trond Myklebust +Signed-off-by: Chuck Lever +Tested-by: Jeff Layton +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 63 +++++++++++++++++++++++++++++++++++++++------ + fs/nfsd/filecache.h | 3 +++ + fs/nfsd/nfs3proc.c | 4 +-- + fs/nfsd/trace.h | 3 ++- + fs/nfsd/vfs.c | 4 +-- + 5 files changed, 64 insertions(+), 13 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index babea79d3f6f..cee44405cf7d 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -63,6 +63,7 @@ struct nfsd_file_lookup_key { + struct net *net; + const struct cred *cred; + unsigned char need; ++ bool gc; + enum nfsd_file_lookup_type type; + }; + +@@ -162,6 +163,8 @@ static int nfsd_file_obj_cmpfn(struct rhashtable_compare_arg *arg, + return 1; + if (!nfsd_match_cred(nf->nf_cred, key->cred)) + return 1; ++ if (!!test_bit(NFSD_FILE_GC, &nf->nf_flags) != key->gc) ++ return 1; + if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) + return 1; + break; +@@ -297,6 +300,8 @@ nfsd_file_alloc(struct nfsd_file_lookup_key *key, unsigned int may) + nf->nf_flags = 0; + __set_bit(NFSD_FILE_HASHED, &nf->nf_flags); + __set_bit(NFSD_FILE_PENDING, &nf->nf_flags); ++ if (key->gc) ++ __set_bit(NFSD_FILE_GC, &nf->nf_flags); + nf->nf_inode = key->inode; + /* nf_ref is pre-incremented for hash table */ + refcount_set(&nf->nf_ref, 2); +@@ -428,16 +433,27 @@ nfsd_file_put_noref(struct nfsd_file *nf) + } + } + ++static void ++nfsd_file_unhash_and_put(struct nfsd_file *nf) ++{ ++ if (nfsd_file_unhash(nf)) ++ nfsd_file_put_noref(nf); ++} ++ + void + nfsd_file_put(struct nfsd_file *nf) + { + might_sleep(); + +- nfsd_file_lru_add(nf); +- if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) { ++ if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) ++ nfsd_file_lru_add(nf); ++ else if (refcount_read(&nf->nf_ref) == 2) ++ nfsd_file_unhash_and_put(nf); ++ ++ if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { + nfsd_file_flush(nf); + nfsd_file_put_noref(nf); +- } else if (nf->nf_file) { ++ } else if (nf->nf_file && test_bit(NFSD_FILE_GC, &nf->nf_flags)) { + nfsd_file_put_noref(nf); + nfsd_file_schedule_laundrette(); + } else +@@ -1016,12 +1032,14 @@ nfsd_file_is_cached(struct inode *inode) + + static __be32 + nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, +- unsigned int may_flags, struct nfsd_file **pnf, bool open) ++ unsigned int may_flags, struct nfsd_file **pnf, ++ bool open, bool want_gc) + { + struct nfsd_file_lookup_key key = { + .type = NFSD_FILE_KEY_FULL, + .need = may_flags & NFSD_FILE_MAY_MASK, + .net = SVC_NET(rqstp), ++ .gc = want_gc, + }; + bool open_retry = true; + struct nfsd_file *nf; +@@ -1117,14 +1135,35 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + * then unhash. + */ + if (status != nfs_ok || key.inode->i_nlink == 0) +- if (nfsd_file_unhash(nf)) +- nfsd_file_put_noref(nf); ++ nfsd_file_unhash_and_put(nf); + clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags); + smp_mb__after_atomic(); + wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); + goto out; + } + ++/** ++ * nfsd_file_acquire_gc - Get a struct nfsd_file with an open file ++ * @rqstp: the RPC transaction being executed ++ * @fhp: the NFS filehandle of the file to be opened ++ * @may_flags: NFSD_MAY_ settings for the file ++ * @pnf: OUT: new or found "struct nfsd_file" object ++ * ++ * The nfsd_file object returned by this API is reference-counted ++ * and garbage-collected. The object is retained for a few ++ * seconds after the final nfsd_file_put() in case the caller ++ * wants to re-use it. ++ * ++ * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in ++ * network byte order is returned. ++ */ ++__be32 ++nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ unsigned int may_flags, struct nfsd_file **pnf) ++{ ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, true); ++} ++ + /** + * nfsd_file_acquire - Get a struct nfsd_file with an open file + * @rqstp: the RPC transaction being executed +@@ -1132,6 +1171,10 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + * @may_flags: NFSD_MAY_ settings for the file + * @pnf: OUT: new or found "struct nfsd_file" object + * ++ * The nfsd_file_object returned by this API is reference-counted ++ * but not garbage-collected. The object is unhashed after the ++ * final nfsd_file_put(). ++ * + * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in + * network byte order is returned. + */ +@@ -1139,7 +1182,7 @@ __be32 + nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf) + { +- return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true); ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, false); + } + + /** +@@ -1149,6 +1192,10 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + * @may_flags: NFSD_MAY_ settings for the file + * @pnf: OUT: new or found "struct nfsd_file" object + * ++ * The nfsd_file_object returned by this API is reference-counted ++ * but not garbage-collected. The object is released immediately ++ * one RCU grace period after the final nfsd_file_put(). ++ * + * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in + * network byte order is returned. + */ +@@ -1156,7 +1203,7 @@ __be32 + nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf) + { +- return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, false); ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, false, false); + } + + /* +diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h +index 6b012ea4bd9d..b7efb2c3ddb1 100644 +--- a/fs/nfsd/filecache.h ++++ b/fs/nfsd/filecache.h +@@ -38,6 +38,7 @@ struct nfsd_file { + #define NFSD_FILE_HASHED (0) + #define NFSD_FILE_PENDING (1) + #define NFSD_FILE_REFERENCED (2) ++#define NFSD_FILE_GC (3) + unsigned long nf_flags; + struct inode *nf_inode; /* don't deref */ + refcount_t nf_ref; +@@ -55,6 +56,8 @@ void nfsd_file_put(struct nfsd_file *nf); + struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); + void nfsd_file_close_inode_sync(struct inode *inode); + bool nfsd_file_is_cached(struct inode *inode); ++__be32 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ unsigned int may_flags, struct nfsd_file **nfp); + __be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **nfp); + __be32 nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, +diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c +index ff2920546333..d01b29aba662 100644 +--- a/fs/nfsd/nfs3proc.c ++++ b/fs/nfsd/nfs3proc.c +@@ -772,8 +772,8 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) + (unsigned long long) argp->offset); + + fh_copy(&resp->fh, &argp->fh); +- resp->status = nfsd_file_acquire(rqstp, &resp->fh, NFSD_MAY_WRITE | +- NFSD_MAY_NOT_BREAK_LEASE, &nf); ++ resp->status = nfsd_file_acquire_gc(rqstp, &resp->fh, NFSD_MAY_WRITE | ++ NFSD_MAY_NOT_BREAK_LEASE, &nf); + if (resp->status) + goto out; + resp->status = nfsd_commit(rqstp, &resp->fh, nf, argp->offset, +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index d4b6839bb459..3fcfeb7b560f 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -817,7 +817,8 @@ DEFINE_CLID_EVENT(confirmed_r); + __print_flags(val, "|", \ + { 1 << NFSD_FILE_HASHED, "HASHED" }, \ + { 1 << NFSD_FILE_PENDING, "PENDING" }, \ +- { 1 << NFSD_FILE_REFERENCED, "REFERENCED"}) ++ { 1 << NFSD_FILE_REFERENCED, "REFERENCED"}, \ ++ { 1 << NFSD_FILE_GC, "GC"}) + + DECLARE_EVENT_CLASS(nfsd_file_class, + TP_PROTO(struct nfsd_file *nf), +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index f1919834a99d..2934ab1d9862 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1085,7 +1085,7 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + __be32 err; + + trace_nfsd_read_start(rqstp, fhp, offset, *count); +- err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_READ, &nf); ++ err = nfsd_file_acquire_gc(rqstp, fhp, NFSD_MAY_READ, &nf); + if (err) + return err; + +@@ -1117,7 +1117,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, + + trace_nfsd_write_start(rqstp, fhp, offset, *cnt); + +- err = nfsd_file_acquire(rqstp, fhp, NFSD_MAY_WRITE, &nf); ++ err = nfsd_file_acquire_gc(rqstp, fhp, NFSD_MAY_WRITE, &nf); + if (err) + goto out; + +-- +2.35.1 + diff --git a/queue-6.1/nfsd-fix-handling-of-cached-open-files-in-nfsd4_open.patch b/queue-6.1/nfsd-fix-handling-of-cached-open-files-in-nfsd4_open.patch new file mode 100644 index 00000000000..eb1334c2e9f --- /dev/null +++ b/queue-6.1/nfsd-fix-handling-of-cached-open-files-in-nfsd4_open.patch @@ -0,0 +1,273 @@ +From 06edd77f710b4e2d4727422d8a698e26d48034fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 14:55:56 -0500 +Subject: nfsd: fix handling of cached open files in nfsd4_open codepath + +From: Jeff Layton + +[ Upstream commit 0b3a551fa58b4da941efeb209b3770868e2eddd7 ] + +Commit fb70bf124b05 ("NFSD: Instantiate a struct file when creating a +regular NFSv4 file") added the ability to cache an open fd over a +compound. There are a couple of problems with the way this currently +works: + +It's racy, as a newly-created nfsd_file can end up with its PENDING bit +cleared while the nf is hashed, and the nf_file pointer is still zeroed +out. Other tasks can find it in this state and they expect to see a +valid nf_file, and can oops if nf_file is NULL. + +Also, there is no guarantee that we'll end up creating a new nfsd_file +if one is already in the hash. If an extant entry is in the hash with a +valid nf_file, nfs4_get_vfs_file will clobber its nf_file pointer with +the value of op_file and the old nf_file will leak. + +Fix both issues by making a new nfsd_file_acquirei_opened variant that +takes an optional file pointer. If one is present when this is called, +we'll take a new reference to it instead of trying to open the file. If +the nfsd_file already has a valid nf_file, we'll just ignore the +optional file and pass the nfsd_file back as-is. + +Also rework the tracepoints a bit to allow for an "opened" variant and +don't try to avoid counting acquisitions in the case where we already +have a cached open file. + +Fixes: fb70bf124b05 ("NFSD: Instantiate a struct file when creating a regular NFSv4 file") +Cc: Trond Myklebust +Reported-by: Stanislav Saner +Reported-and-Tested-by: Ruben Vestergaard +Reported-and-Tested-by: Torkil Svensgaard +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 40 ++++++++++++++++++---------------- + fs/nfsd/filecache.h | 5 +++-- + fs/nfsd/nfs4state.c | 16 ++++---------- + fs/nfsd/trace.h | 52 ++++++++++++--------------------------------- + 4 files changed, 42 insertions(+), 71 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index 9bf78506d071..ea6fb0e6b165 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -1048,8 +1048,8 @@ nfsd_file_is_cached(struct inode *inode) + + static __be32 + nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, +- unsigned int may_flags, struct nfsd_file **pnf, +- bool open, bool want_gc) ++ unsigned int may_flags, struct file *file, ++ struct nfsd_file **pnf, bool want_gc) + { + struct nfsd_file_lookup_key key = { + .type = NFSD_FILE_KEY_FULL, +@@ -1124,8 +1124,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); + out: + if (status == nfs_ok) { +- if (open) +- this_cpu_inc(nfsd_file_acquisitions); ++ this_cpu_inc(nfsd_file_acquisitions); + *pnf = nf; + } else { + if (refcount_dec_and_test(&nf->nf_ref)) +@@ -1135,20 +1134,23 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + + out_status: + put_cred(key.cred); +- if (open) +- trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status); ++ trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status); + return status; + + open_file: + trace_nfsd_file_alloc(nf); + nf->nf_mark = nfsd_file_mark_find_or_create(nf, key.inode); + if (nf->nf_mark) { +- if (open) { ++ if (file) { ++ get_file(file); ++ nf->nf_file = file; ++ status = nfs_ok; ++ trace_nfsd_file_opened(nf, status); ++ } else { + status = nfsd_open_verified(rqstp, fhp, may_flags, + &nf->nf_file); + trace_nfsd_file_open(nf, status); +- } else +- status = nfs_ok; ++ } + } else + status = nfserr_jukebox; + /* +@@ -1184,7 +1186,7 @@ __be32 + nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf) + { +- return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, true); ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, true); + } + + /** +@@ -1205,28 +1207,30 @@ __be32 + nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf) + { +- return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, true, false); ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, false); + } + + /** +- * nfsd_file_create - Get a struct nfsd_file, do not open ++ * nfsd_file_acquire_opened - Get a struct nfsd_file using existing open file + * @rqstp: the RPC transaction being executed + * @fhp: the NFS filehandle of the file just created + * @may_flags: NFSD_MAY_ settings for the file ++ * @file: cached, already-open file (may be NULL) + * @pnf: OUT: new or found "struct nfsd_file" object + * +- * The nfsd_file_object returned by this API is reference-counted +- * but not garbage-collected. The object is released immediately +- * one RCU grace period after the final nfsd_file_put(). ++ * Acquire a nfsd_file object that is not GC'ed. If one doesn't already exist, ++ * and @file is non-NULL, use it to instantiate a new nfsd_file instead of ++ * opening a new one. + * + * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in + * network byte order is returned. + */ + __be32 +-nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, +- unsigned int may_flags, struct nfsd_file **pnf) ++nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ unsigned int may_flags, struct file *file, ++ struct nfsd_file **pnf) + { +- return nfsd_file_do_acquire(rqstp, fhp, may_flags, pnf, false, false); ++ return nfsd_file_do_acquire(rqstp, fhp, may_flags, file, pnf, false); + } + + /* +diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h +index b7efb2c3ddb1..41516a4263ea 100644 +--- a/fs/nfsd/filecache.h ++++ b/fs/nfsd/filecache.h +@@ -60,7 +60,8 @@ __be32 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **nfp); + __be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **nfp); +-__be32 nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, +- unsigned int may_flags, struct nfsd_file **nfp); ++__be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ unsigned int may_flags, struct file *file, ++ struct nfsd_file **nfp); + int nfsd_file_cache_stats_show(struct seq_file *m, void *v); + #endif /* _FS_NFSD_FILECACHE_H */ +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 16c3e991ddcc..2247d107da90 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -5211,18 +5211,10 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, + if (!fp->fi_fds[oflag]) { + spin_unlock(&fp->fi_lock); + +- if (!open->op_filp) { +- status = nfsd_file_acquire(rqstp, cur_fh, access, &nf); +- if (status != nfs_ok) +- goto out_put_access; +- } else { +- status = nfsd_file_create(rqstp, cur_fh, access, &nf); +- if (status != nfs_ok) +- goto out_put_access; +- nf->nf_file = open->op_filp; +- open->op_filp = NULL; +- trace_nfsd_file_create(rqstp, access, nf); +- } ++ status = nfsd_file_acquire_opened(rqstp, cur_fh, access, ++ open->op_filp, &nf); ++ if (status != nfs_ok) ++ goto out_put_access; + + spin_lock(&fp->fi_lock); + if (!fp->fi_fds[oflag]) { +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index 4feeaed32541..4eb4e1039c7f 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -922,43 +922,6 @@ TRACE_EVENT(nfsd_file_acquire, + ) + ); + +-TRACE_EVENT(nfsd_file_create, +- TP_PROTO( +- const struct svc_rqst *rqstp, +- unsigned int may_flags, +- const struct nfsd_file *nf +- ), +- +- TP_ARGS(rqstp, may_flags, nf), +- +- TP_STRUCT__entry( +- __field(const void *, nf_inode) +- __field(const void *, nf_file) +- __field(unsigned long, may_flags) +- __field(unsigned long, nf_flags) +- __field(unsigned long, nf_may) +- __field(unsigned int, nf_ref) +- __field(u32, xid) +- ), +- +- TP_fast_assign( +- __entry->nf_inode = nf->nf_inode; +- __entry->nf_file = nf->nf_file; +- __entry->may_flags = may_flags; +- __entry->nf_flags = nf->nf_flags; +- __entry->nf_may = nf->nf_may; +- __entry->nf_ref = refcount_read(&nf->nf_ref); +- __entry->xid = be32_to_cpu(rqstp->rq_xid); +- ), +- +- TP_printk("xid=0x%x inode=%p may_flags=%s ref=%u nf_flags=%s nf_may=%s nf_file=%p", +- __entry->xid, __entry->nf_inode, +- show_nfsd_may_flags(__entry->may_flags), +- __entry->nf_ref, show_nf_flags(__entry->nf_flags), +- show_nfsd_may_flags(__entry->nf_may), __entry->nf_file +- ) +-); +- + TRACE_EVENT(nfsd_file_insert_err, + TP_PROTO( + const struct svc_rqst *rqstp, +@@ -1020,8 +983,8 @@ TRACE_EVENT(nfsd_file_cons_err, + ) + ); + +-TRACE_EVENT(nfsd_file_open, +- TP_PROTO(struct nfsd_file *nf, __be32 status), ++DECLARE_EVENT_CLASS(nfsd_file_open_class, ++ TP_PROTO(const struct nfsd_file *nf, __be32 status), + TP_ARGS(nf, status), + TP_STRUCT__entry( + __field(void *, nf_inode) /* cannot be dereferenced */ +@@ -1045,6 +1008,17 @@ TRACE_EVENT(nfsd_file_open, + __entry->nf_file) + ) + ++#define DEFINE_NFSD_FILE_OPEN_EVENT(name) \ ++DEFINE_EVENT(nfsd_file_open_class, name, \ ++ TP_PROTO( \ ++ const struct nfsd_file *nf, \ ++ __be32 status \ ++ ), \ ++ TP_ARGS(nf, status)) ++ ++DEFINE_NFSD_FILE_OPEN_EVENT(nfsd_file_open); ++DEFINE_NFSD_FILE_OPEN_EVENT(nfsd_file_opened); ++ + TRACE_EVENT(nfsd_file_is_cached, + TP_PROTO( + const struct inode *inode, +-- +2.35.1 + diff --git a/queue-6.1/nfsd-pass-the-target-nfsd_file-to-nfsd_commit.patch b/queue-6.1/nfsd-pass-the-target-nfsd_file-to-nfsd_commit.patch new file mode 100644 index 00000000000..426611f7620 --- /dev/null +++ b/queue-6.1/nfsd-pass-the-target-nfsd_file-to-nfsd_commit.patch @@ -0,0 +1,153 @@ +From 631c0a99c74f4d87bddfe2f0aa79ce12653e8323 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 10:46:38 -0400 +Subject: NFSD: Pass the target nfsd_file to nfsd_commit() + +From: Chuck Lever + +[ Upstream commit c252849082ff525af18b4f253b3c9ece94e951ed ] + +In a moment I'm going to introduce separate nfsd_file types, one of +which is garbage-collected; the other, not. The garbage-collected +variety is to be used by NFSv2 and v3, and the non-garbage-collected +variety is to be used by NFSv4. + +nfsd_commit() is invoked by both NFSv3 and NFSv4 consumers. We want +nfsd_commit() to find and use the correct variety of cached +nfsd_file object for the NFS version that is in use. + +Signed-off-by: Chuck Lever +Tested-by: Jeff Layton +Reviewed-by: Jeff Layton +Reviewed-by: NeilBrown +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs3proc.c | 10 +++++++++- + fs/nfsd/nfs4proc.c | 11 ++++++++++- + fs/nfsd/vfs.c | 15 ++++----------- + fs/nfsd/vfs.h | 3 ++- + 4 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c +index 923d9a80df92..ff2920546333 100644 +--- a/fs/nfsd/nfs3proc.c ++++ b/fs/nfsd/nfs3proc.c +@@ -13,6 +13,7 @@ + #include "cache.h" + #include "xdr3.h" + #include "vfs.h" ++#include "filecache.h" + + #define NFSDDBG_FACILITY NFSDDBG_PROC + +@@ -763,6 +764,7 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) + { + struct nfsd3_commitargs *argp = rqstp->rq_argp; + struct nfsd3_commitres *resp = rqstp->rq_resp; ++ struct nfsd_file *nf; + + dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", + SVCFH_fmt(&argp->fh), +@@ -770,8 +772,14 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) + (unsigned long long) argp->offset); + + fh_copy(&resp->fh, &argp->fh); +- resp->status = nfsd_commit(rqstp, &resp->fh, argp->offset, ++ resp->status = nfsd_file_acquire(rqstp, &resp->fh, NFSD_MAY_WRITE | ++ NFSD_MAY_NOT_BREAK_LEASE, &nf); ++ if (resp->status) ++ goto out; ++ resp->status = nfsd_commit(rqstp, &resp->fh, nf, argp->offset, + argp->count, resp->verf); ++ nfsd_file_put(nf); ++out: + return rpc_success; + } + +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index c7329523a10f..30a08ec31a70 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -731,10 +731,19 @@ nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) + { + struct nfsd4_commit *commit = &u->commit; ++ struct nfsd_file *nf; ++ __be32 status; + +- return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, ++ status = nfsd_file_acquire(rqstp, &cstate->current_fh, NFSD_MAY_WRITE | ++ NFSD_MAY_NOT_BREAK_LEASE, &nf); ++ if (status != nfs_ok) ++ return status; ++ ++ status = nfsd_commit(rqstp, &cstate->current_fh, nf, commit->co_offset, + commit->co_count, + (__be32 *)commit->co_verf.data); ++ nfsd_file_put(nf); ++ return status; + } + + static __be32 +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 849a720ab43f..f1919834a99d 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1133,6 +1133,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, + * nfsd_commit - Commit pending writes to stable storage + * @rqstp: RPC request being processed + * @fhp: NFS filehandle ++ * @nf: target file + * @offset: raw offset from beginning of file + * @count: raw count of bytes to sync + * @verf: filled in with the server's current write verifier +@@ -1149,19 +1150,13 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, + * An nfsstat value in network byte order. + */ + __be32 +-nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset, +- u32 count, __be32 *verf) ++nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, ++ u64 offset, u32 count, __be32 *verf) + { ++ __be32 err = nfs_ok; + u64 maxbytes; + loff_t start, end; + struct nfsd_net *nn; +- struct nfsd_file *nf; +- __be32 err; +- +- err = nfsd_file_acquire(rqstp, fhp, +- NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &nf); +- if (err) +- goto out; + + /* + * Convert the client-provided (offset, count) range to a +@@ -1202,8 +1197,6 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset, + } else + nfsd_copy_write_verifier(verf, nn); + +- nfsd_file_put(nf); +-out: + return err; + } + +diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h +index 120521bc7b24..9744b041105b 100644 +--- a/fs/nfsd/vfs.h ++++ b/fs/nfsd/vfs.h +@@ -88,7 +88,8 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); + __be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct svc_fh *resfhp, struct nfsd_attrs *iap); + __be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp, +- u64 offset, u32 count, __be32 *verf); ++ struct nfsd_file *nf, u64 offset, u32 count, ++ __be32 *verf); + #ifdef CONFIG_NFSD_V4 + __be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + char *name, void **bufp, int *lenp); +-- +2.35.1 + diff --git a/queue-6.1/nfsd-remove-the-pages_flushed-statistic-from-filecac.patch b/queue-6.1/nfsd-remove-the-pages_flushed-statistic-from-filecac.patch new file mode 100644 index 00000000000..f5b7843edce --- /dev/null +++ b/queue-6.1/nfsd-remove-the-pages_flushed-statistic-from-filecac.patch @@ -0,0 +1,76 @@ +From 959abbdc7fadfe08b0c7c1ce8e2d0344016986f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 14:44:47 -0400 +Subject: nfsd: remove the pages_flushed statistic from filecache + +From: Jeff Layton + +[ Upstream commit 1f696e230ea5198e393368b319eb55651828d687 ] + +We're counting mapping->nrpages, but not all of those are necessarily +dirty. We don't really have a simple way to count just the dirty pages, +so just remove this stat since it's not accurate. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index cee44405cf7d..28fff3672df9 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -33,7 +33,6 @@ static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits); + static DEFINE_PER_CPU(unsigned long, nfsd_file_acquisitions); + static DEFINE_PER_CPU(unsigned long, nfsd_file_releases); + static DEFINE_PER_CPU(unsigned long, nfsd_file_total_age); +-static DEFINE_PER_CPU(unsigned long, nfsd_file_pages_flushed); + static DEFINE_PER_CPU(unsigned long, nfsd_file_evictions); + + struct nfsd_fcache_disposal { +@@ -371,7 +370,6 @@ nfsd_file_flush(struct nfsd_file *nf) + + if (!file || !(file->f_mode & FMODE_WRITE)) + return; +- this_cpu_add(nfsd_file_pages_flushed, file->f_mapping->nrpages); + if (vfs_fsync(file, 1) != 0) + nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); + } +@@ -998,7 +996,6 @@ nfsd_file_cache_shutdown(void) + per_cpu(nfsd_file_acquisitions, i) = 0; + per_cpu(nfsd_file_releases, i) = 0; + per_cpu(nfsd_file_total_age, i) = 0; +- per_cpu(nfsd_file_pages_flushed, i) = 0; + per_cpu(nfsd_file_evictions, i) = 0; + } + } +@@ -1213,7 +1210,7 @@ nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp, + */ + int nfsd_file_cache_stats_show(struct seq_file *m, void *v) + { +- unsigned long releases = 0, pages_flushed = 0, evictions = 0; ++ unsigned long releases = 0, evictions = 0; + unsigned long hits = 0, acquisitions = 0; + unsigned int i, count = 0, buckets = 0; + unsigned long lru = 0, total_age = 0; +@@ -1241,7 +1238,6 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) + releases += per_cpu(nfsd_file_releases, i); + total_age += per_cpu(nfsd_file_total_age, i); + evictions += per_cpu(nfsd_file_evictions, i); +- pages_flushed += per_cpu(nfsd_file_pages_flushed, i); + } + + seq_printf(m, "total entries: %u\n", count); +@@ -1255,6 +1251,5 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) + seq_printf(m, "mean age (ms): %ld\n", total_age / releases); + else + seq_printf(m, "mean age (ms): -\n"); +- seq_printf(m, "pages flushed: %lu\n", pages_flushed); + return 0; + } +-- +2.35.1 + diff --git a/queue-6.1/nfsd-reorganize-filecache.c.patch b/queue-6.1/nfsd-reorganize-filecache.c.patch new file mode 100644 index 00000000000..09ea3ea7490 --- /dev/null +++ b/queue-6.1/nfsd-reorganize-filecache.c.patch @@ -0,0 +1,240 @@ +From de76c3bb47aa0615447be482132f7cf8ede2c34e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 14:44:48 -0400 +Subject: nfsd: reorganize filecache.c + +From: Jeff Layton + +[ Upstream commit 8214118589881b2d390284410c5ff275e7a5e03c ] + +In a coming patch, we're going to rework how the filecache refcounting +works. Move some code around in the function to reduce the churn in the +later patches, and rename some of the functions with (hopefully) clearer +names: nfsd_file_flush becomes nfsd_file_fsync, and +nfsd_file_unhash_and_dispose is renamed to nfsd_file_unhash_and_queue. + +Also, the nfsd_file_put_final tracepoint is renamed to nfsd_file_free, +to better match the name of the function from which it's called. + +Signed-off-by: Jeff Layton +Reviewed-by: NeilBrown +Signed-off-by: Chuck Lever +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 111 ++++++++++++++++++++++---------------------- + fs/nfsd/trace.h | 4 +- + 2 files changed, 58 insertions(+), 57 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index 28fff3672df9..f54dd6695741 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -310,16 +310,59 @@ nfsd_file_alloc(struct nfsd_file_lookup_key *key, unsigned int may) + return nf; + } + ++static void ++nfsd_file_fsync(struct nfsd_file *nf) ++{ ++ struct file *file = nf->nf_file; ++ ++ if (!file || !(file->f_mode & FMODE_WRITE)) ++ return; ++ if (vfs_fsync(file, 1) != 0) ++ nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); ++} ++ ++static int ++nfsd_file_check_write_error(struct nfsd_file *nf) ++{ ++ struct file *file = nf->nf_file; ++ ++ if (!file || !(file->f_mode & FMODE_WRITE)) ++ return 0; ++ return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err)); ++} ++ ++static void ++nfsd_file_hash_remove(struct nfsd_file *nf) ++{ ++ trace_nfsd_file_unhash(nf); ++ ++ if (nfsd_file_check_write_error(nf)) ++ nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); ++ rhashtable_remove_fast(&nfsd_file_rhash_tbl, &nf->nf_rhash, ++ nfsd_file_rhash_params); ++} ++ ++static bool ++nfsd_file_unhash(struct nfsd_file *nf) ++{ ++ if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { ++ nfsd_file_hash_remove(nf); ++ return true; ++ } ++ return false; ++} ++ + static bool + nfsd_file_free(struct nfsd_file *nf) + { + s64 age = ktime_to_ms(ktime_sub(ktime_get(), nf->nf_birthtime)); + bool flush = false; + ++ trace_nfsd_file_free(nf); ++ + this_cpu_inc(nfsd_file_releases); + this_cpu_add(nfsd_file_total_age, age); + +- trace_nfsd_file_put_final(nf); + if (nf->nf_mark) + nfsd_file_mark_put(nf->nf_mark); + if (nf->nf_file) { +@@ -353,27 +396,6 @@ nfsd_file_check_writeback(struct nfsd_file *nf) + mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK); + } + +-static int +-nfsd_file_check_write_error(struct nfsd_file *nf) +-{ +- struct file *file = nf->nf_file; +- +- if (!file || !(file->f_mode & FMODE_WRITE)) +- return 0; +- return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err)); +-} +- +-static void +-nfsd_file_flush(struct nfsd_file *nf) +-{ +- struct file *file = nf->nf_file; +- +- if (!file || !(file->f_mode & FMODE_WRITE)) +- return; +- if (vfs_fsync(file, 1) != 0) +- nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); +-} +- + static void nfsd_file_lru_add(struct nfsd_file *nf) + { + set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); +@@ -387,31 +409,18 @@ static void nfsd_file_lru_remove(struct nfsd_file *nf) + trace_nfsd_file_lru_del(nf); + } + +-static void +-nfsd_file_hash_remove(struct nfsd_file *nf) +-{ +- trace_nfsd_file_unhash(nf); +- +- if (nfsd_file_check_write_error(nf)) +- nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); +- rhashtable_remove_fast(&nfsd_file_rhash_tbl, &nf->nf_rhash, +- nfsd_file_rhash_params); +-} +- +-static bool +-nfsd_file_unhash(struct nfsd_file *nf) ++struct nfsd_file * ++nfsd_file_get(struct nfsd_file *nf) + { +- if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { +- nfsd_file_hash_remove(nf); +- return true; +- } +- return false; ++ if (likely(refcount_inc_not_zero(&nf->nf_ref))) ++ return nf; ++ return NULL; + } + + static void +-nfsd_file_unhash_and_dispose(struct nfsd_file *nf, struct list_head *dispose) ++nfsd_file_unhash_and_queue(struct nfsd_file *nf, struct list_head *dispose) + { +- trace_nfsd_file_unhash_and_dispose(nf); ++ trace_nfsd_file_unhash_and_queue(nf); + if (nfsd_file_unhash(nf)) { + /* caller must call nfsd_file_dispose_list() later */ + nfsd_file_lru_remove(nf); +@@ -449,7 +458,7 @@ nfsd_file_put(struct nfsd_file *nf) + nfsd_file_unhash_and_put(nf); + + if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { +- nfsd_file_flush(nf); ++ nfsd_file_fsync(nf); + nfsd_file_put_noref(nf); + } else if (nf->nf_file && test_bit(NFSD_FILE_GC, &nf->nf_flags)) { + nfsd_file_put_noref(nf); +@@ -458,14 +467,6 @@ nfsd_file_put(struct nfsd_file *nf) + nfsd_file_put_noref(nf); + } + +-struct nfsd_file * +-nfsd_file_get(struct nfsd_file *nf) +-{ +- if (likely(refcount_inc_not_zero(&nf->nf_ref))) +- return nf; +- return NULL; +-} +- + static void + nfsd_file_dispose_list(struct list_head *dispose) + { +@@ -474,7 +475,7 @@ nfsd_file_dispose_list(struct list_head *dispose) + while(!list_empty(dispose)) { + nf = list_first_entry(dispose, struct nfsd_file, nf_lru); + list_del_init(&nf->nf_lru); +- nfsd_file_flush(nf); ++ nfsd_file_fsync(nf); + nfsd_file_put_noref(nf); + } + } +@@ -488,7 +489,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose) + while(!list_empty(dispose)) { + nf = list_first_entry(dispose, struct nfsd_file, nf_lru); + list_del_init(&nf->nf_lru); +- nfsd_file_flush(nf); ++ nfsd_file_fsync(nf); + if (!refcount_dec_and_test(&nf->nf_ref)) + continue; + if (nfsd_file_free(nf)) +@@ -688,7 +689,7 @@ __nfsd_file_close_inode(struct inode *inode, struct list_head *dispose) + nfsd_file_rhash_params); + if (!nf) + break; +- nfsd_file_unhash_and_dispose(nf, dispose); ++ nfsd_file_unhash_and_queue(nf, dispose); + count++; + } while (1); + rcu_read_unlock(); +@@ -890,7 +891,7 @@ __nfsd_file_cache_purge(struct net *net) + nf = rhashtable_walk_next(&iter); + while (!IS_ERR_OR_NULL(nf)) { + if (!net || nf->nf_net == net) +- nfsd_file_unhash_and_dispose(nf, &dispose); ++ nfsd_file_unhash_and_queue(nf, &dispose); + nf = rhashtable_walk_next(&iter); + } + +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index 3fcfeb7b560f..55e9e19cb1ec 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -850,10 +850,10 @@ DEFINE_EVENT(nfsd_file_class, name, \ + TP_PROTO(struct nfsd_file *nf), \ + TP_ARGS(nf)) + +-DEFINE_NFSD_FILE_EVENT(nfsd_file_put_final); ++DEFINE_NFSD_FILE_EVENT(nfsd_file_free); + DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash); + DEFINE_NFSD_FILE_EVENT(nfsd_file_put); +-DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash_and_dispose); ++DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash_and_queue); + + TRACE_EVENT(nfsd_file_alloc, + TP_PROTO( +-- +2.35.1 + diff --git a/queue-6.1/nfsd-revert-nfsd-nfsv4-close-should-release-an-nfsd_.patch b/queue-6.1/nfsd-revert-nfsd-nfsv4-close-should-release-an-nfsd_.patch new file mode 100644 index 00000000000..577852d93af --- /dev/null +++ b/queue-6.1/nfsd-revert-nfsd-nfsv4-close-should-release-an-nfsd_.patch @@ -0,0 +1,96 @@ +From 16d066330e4495eae9987ba3becf18a876f562ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 10:46:44 -0400 +Subject: NFSD: Revert "NFSD: NFSv4 CLOSE should release an nfsd_file + immediately" + +From: Chuck Lever + +[ Upstream commit dcf3f80965ca787c70def402cdf1553c93c75529 ] + +This reverts commit 5e138c4a750dc140d881dab4a8804b094bbc08d2. + +That commit attempted to make files available to other users as soon +as all NFSv4 clients were done with them, rather than waiting until +the filecache LRU had garbage collected them. + +It gets the reference counting wrong, for one thing. + +But it also misses that DELEGRETURN should release a file in the +same fashion. In fact, any nfsd_file_put() on an file held open +by an NFSv4 client needs potentially to release the file +immediately... + +Clear the way for implementing that idea. + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Reviewed-by: NeilBrown +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 18 ------------------ + fs/nfsd/filecache.h | 1 - + fs/nfsd/nfs4state.c | 4 ++-- + 3 files changed, 2 insertions(+), 21 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index ec3fceb92236..babea79d3f6f 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -444,24 +444,6 @@ nfsd_file_put(struct nfsd_file *nf) + nfsd_file_put_noref(nf); + } + +-/** +- * nfsd_file_close - Close an nfsd_file +- * @nf: nfsd_file to close +- * +- * If this is the final reference for @nf, free it immediately. +- * This reflects an on-the-wire CLOSE or DELEGRETURN into the +- * VFS and exported filesystem. +- */ +-void nfsd_file_close(struct nfsd_file *nf) +-{ +- nfsd_file_put(nf); +- if (refcount_dec_if_one(&nf->nf_ref)) { +- nfsd_file_unhash(nf); +- nfsd_file_lru_remove(nf); +- nfsd_file_free(nf); +- } +-} +- + struct nfsd_file * + nfsd_file_get(struct nfsd_file *nf) + { +diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h +index 357832bac736..6b012ea4bd9d 100644 +--- a/fs/nfsd/filecache.h ++++ b/fs/nfsd/filecache.h +@@ -52,7 +52,6 @@ void nfsd_file_cache_shutdown(void); + int nfsd_file_cache_start_net(struct net *net); + void nfsd_file_cache_shutdown_net(struct net *net); + void nfsd_file_put(struct nfsd_file *nf); +-void nfsd_file_close(struct nfsd_file *nf); + struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); + void nfsd_file_close_inode_sync(struct inode *inode); + bool nfsd_file_is_cached(struct inode *inode); +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 52b5552d0d70..16c3e991ddcc 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -842,9 +842,9 @@ static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) + swap(f2, fp->fi_fds[O_RDWR]); + spin_unlock(&fp->fi_lock); + if (f1) +- nfsd_file_close(f1); ++ nfsd_file_put(f1); + if (f2) +- nfsd_file_close(f2); ++ nfsd_file_put(f2); + } + } + +-- +2.35.1 + diff --git a/queue-6.1/nfsd-rework-refcounting-in-filecache.patch b/queue-6.1/nfsd-rework-refcounting-in-filecache.patch new file mode 100644 index 00000000000..d11fcdb07a1 --- /dev/null +++ b/queue-6.1/nfsd-rework-refcounting-in-filecache.patch @@ -0,0 +1,669 @@ +From f46c734da1a479098262420090554e3bdfaa78bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 Dec 2022 06:19:33 -0500 +Subject: nfsd: rework refcounting in filecache + +From: Jeff Layton + +[ Upstream commit ac3a2585f018f10039b4a856dcb122da88c1c1c9 ] + +The filecache refcounting is a bit non-standard for something searchable +by RCU, in that we maintain a sentinel reference while it's hashed. This +in turn requires that we have to do things differently in the "put" +depending on whether its hashed, which we believe to have led to races. + +There are other problems in here too. nfsd_file_close_inode_sync can end +up freeing an nfsd_file while there are still outstanding references to +it, and there are a number of subtle ToC/ToU races. + +Rework the code so that the refcount is what drives the lifecycle. When +the refcount goes to zero, then unhash and rcu free the object. A task +searching for a nfsd_file is allowed to bump its refcount, but only if +it's not already 0. Ensure that we don't make any other changes to it +until a reference is held. + +With this change, the LRU carries a reference. Take special care to deal +with it when removing an entry from the list, and ensure that we only +repurpose the nf_lru list_head when the refcount is 0 to ensure +exclusive access to it. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath") +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 318 +++++++++++++++++++++++--------------------- + fs/nfsd/trace.h | 51 +++---- + 2 files changed, 189 insertions(+), 180 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index 7c673f98f95c..9bf78506d071 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -302,8 +302,7 @@ nfsd_file_alloc(struct nfsd_file_lookup_key *key, unsigned int may) + if (key->gc) + __set_bit(NFSD_FILE_GC, &nf->nf_flags); + nf->nf_inode = key->inode; +- /* nf_ref is pre-incremented for hash table */ +- refcount_set(&nf->nf_ref, 2); ++ refcount_set(&nf->nf_ref, 1); + nf->nf_may = key->need; + nf->nf_mark = NULL; + } +@@ -355,24 +354,35 @@ nfsd_file_unhash(struct nfsd_file *nf) + return false; + } + +-static bool ++static void + nfsd_file_free(struct nfsd_file *nf) + { + s64 age = ktime_to_ms(ktime_sub(ktime_get(), nf->nf_birthtime)); +- bool flush = false; + + trace_nfsd_file_free(nf); + + this_cpu_inc(nfsd_file_releases); + this_cpu_add(nfsd_file_total_age, age); + ++ nfsd_file_unhash(nf); ++ ++ /* ++ * We call fsync here in order to catch writeback errors. It's not ++ * strictly required by the protocol, but an nfsd_file could get ++ * evicted from the cache before a COMMIT comes in. If another ++ * task were to open that file in the interim and scrape the error, ++ * then the client may never see it. By calling fsync here, we ensure ++ * that writeback happens before the entry is freed, and that any ++ * errors reported result in the write verifier changing. ++ */ ++ nfsd_file_fsync(nf); ++ + if (nf->nf_mark) + nfsd_file_mark_put(nf->nf_mark); + if (nf->nf_file) { + get_file(nf->nf_file); + filp_close(nf->nf_file, NULL); + fput(nf->nf_file); +- flush = true; + } + + /* +@@ -380,10 +390,9 @@ nfsd_file_free(struct nfsd_file *nf) + * WARN and leak it to preserve system stability. + */ + if (WARN_ON_ONCE(!list_empty(&nf->nf_lru))) +- return flush; ++ return; + + call_rcu(&nf->nf_rcu, nfsd_file_slab_free); +- return flush; + } + + static bool +@@ -399,17 +408,23 @@ nfsd_file_check_writeback(struct nfsd_file *nf) + mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK); + } + +-static void nfsd_file_lru_add(struct nfsd_file *nf) ++static bool nfsd_file_lru_add(struct nfsd_file *nf) + { + set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); +- if (list_lru_add(&nfsd_file_lru, &nf->nf_lru)) ++ if (list_lru_add(&nfsd_file_lru, &nf->nf_lru)) { + trace_nfsd_file_lru_add(nf); ++ return true; ++ } ++ return false; + } + +-static void nfsd_file_lru_remove(struct nfsd_file *nf) ++static bool nfsd_file_lru_remove(struct nfsd_file *nf) + { +- if (list_lru_del(&nfsd_file_lru, &nf->nf_lru)) ++ if (list_lru_del(&nfsd_file_lru, &nf->nf_lru)) { + trace_nfsd_file_lru_del(nf); ++ return true; ++ } ++ return false; + } + + struct nfsd_file * +@@ -420,86 +435,60 @@ nfsd_file_get(struct nfsd_file *nf) + return NULL; + } + +-static void +-nfsd_file_unhash_and_queue(struct nfsd_file *nf, struct list_head *dispose) +-{ +- trace_nfsd_file_unhash_and_queue(nf); +- if (nfsd_file_unhash(nf)) { +- /* caller must call nfsd_file_dispose_list() later */ +- nfsd_file_lru_remove(nf); +- list_add(&nf->nf_lru, dispose); +- } +-} +- +-static void +-nfsd_file_put_noref(struct nfsd_file *nf) +-{ +- trace_nfsd_file_put(nf); +- +- if (refcount_dec_and_test(&nf->nf_ref)) { +- WARN_ON(test_bit(NFSD_FILE_HASHED, &nf->nf_flags)); +- nfsd_file_lru_remove(nf); +- nfsd_file_free(nf); +- } +-} +- +-static void +-nfsd_file_unhash_and_put(struct nfsd_file *nf) +-{ +- if (nfsd_file_unhash(nf)) +- nfsd_file_put_noref(nf); +-} +- ++/** ++ * nfsd_file_put - put the reference to a nfsd_file ++ * @nf: nfsd_file of which to put the reference ++ * ++ * Put a reference to a nfsd_file. In the non-GC case, we just put the ++ * reference immediately. In the GC case, if the reference would be ++ * the last one, the put it on the LRU instead to be cleaned up later. ++ */ + void + nfsd_file_put(struct nfsd_file *nf) + { + might_sleep(); ++ trace_nfsd_file_put(nf); + +- if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) +- nfsd_file_lru_add(nf); +- else if (refcount_read(&nf->nf_ref) == 2) +- nfsd_file_unhash_and_put(nf); +- +- if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { +- nfsd_file_fsync(nf); +- nfsd_file_put_noref(nf); +- } else if (nf->nf_file && test_bit(NFSD_FILE_GC, &nf->nf_flags)) { +- nfsd_file_put_noref(nf); +- nfsd_file_schedule_laundrette(); +- } else +- nfsd_file_put_noref(nf); +-} +- +-static void +-nfsd_file_dispose_list(struct list_head *dispose) +-{ +- struct nfsd_file *nf; ++ if (test_bit(NFSD_FILE_GC, &nf->nf_flags) && ++ test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { ++ /* ++ * If this is the last reference (nf_ref == 1), then try to ++ * transfer it to the LRU. ++ */ ++ if (refcount_dec_not_one(&nf->nf_ref)) ++ return; ++ ++ /* Try to add it to the LRU. If that fails, decrement. */ ++ if (nfsd_file_lru_add(nf)) { ++ /* If it's still hashed, we're done */ ++ if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { ++ nfsd_file_schedule_laundrette(); ++ return; ++ } + +- while(!list_empty(dispose)) { +- nf = list_first_entry(dispose, struct nfsd_file, nf_lru); +- list_del_init(&nf->nf_lru); +- nfsd_file_fsync(nf); +- nfsd_file_put_noref(nf); ++ /* ++ * We're racing with unhashing, so try to remove it from ++ * the LRU. If removal fails, then someone else already ++ * has our reference. ++ */ ++ if (!nfsd_file_lru_remove(nf)) ++ return; ++ } + } ++ if (refcount_dec_and_test(&nf->nf_ref)) ++ nfsd_file_free(nf); + } + + static void +-nfsd_file_dispose_list_sync(struct list_head *dispose) ++nfsd_file_dispose_list(struct list_head *dispose) + { +- bool flush = false; + struct nfsd_file *nf; + +- while(!list_empty(dispose)) { ++ while (!list_empty(dispose)) { + nf = list_first_entry(dispose, struct nfsd_file, nf_lru); + list_del_init(&nf->nf_lru); +- nfsd_file_fsync(nf); +- if (!refcount_dec_and_test(&nf->nf_ref)) +- continue; +- if (nfsd_file_free(nf)) +- flush = true; ++ nfsd_file_free(nf); + } +- if (flush) +- flush_delayed_fput(); + } + + static void +@@ -569,21 +558,8 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru, + struct list_head *head = arg; + struct nfsd_file *nf = list_entry(item, struct nfsd_file, nf_lru); + +- /* +- * Do a lockless refcount check. The hashtable holds one reference, so +- * we look to see if anything else has a reference, or if any have +- * been put since the shrinker last ran. Those don't get unhashed and +- * released. +- * +- * Note that in the put path, we set the flag and then decrement the +- * counter. Here we check the counter and then test and clear the flag. +- * That order is deliberate to ensure that we can do this locklessly. +- */ +- if (refcount_read(&nf->nf_ref) > 1) { +- list_lru_isolate(lru, &nf->nf_lru); +- trace_nfsd_file_gc_in_use(nf); +- return LRU_REMOVED; +- } ++ /* We should only be dealing with GC entries here */ ++ WARN_ON_ONCE(!test_bit(NFSD_FILE_GC, &nf->nf_flags)); + + /* + * Don't throw out files that are still undergoing I/O or +@@ -594,40 +570,30 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru, + return LRU_SKIP; + } + ++ /* If it was recently added to the list, skip it */ + if (test_and_clear_bit(NFSD_FILE_REFERENCED, &nf->nf_flags)) { + trace_nfsd_file_gc_referenced(nf); + return LRU_ROTATE; + } + +- if (!test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { +- trace_nfsd_file_gc_hashed(nf); +- return LRU_SKIP; ++ /* ++ * Put the reference held on behalf of the LRU. If it wasn't the last ++ * one, then just remove it from the LRU and ignore it. ++ */ ++ if (!refcount_dec_and_test(&nf->nf_ref)) { ++ trace_nfsd_file_gc_in_use(nf); ++ list_lru_isolate(lru, &nf->nf_lru); ++ return LRU_REMOVED; + } + ++ /* Refcount went to zero. Unhash it and queue it to the dispose list */ ++ nfsd_file_unhash(nf); + list_lru_isolate_move(lru, &nf->nf_lru, head); + this_cpu_inc(nfsd_file_evictions); + trace_nfsd_file_gc_disposed(nf); + return LRU_REMOVED; + } + +-/* +- * Unhash items on @dispose immediately, then queue them on the +- * disposal workqueue to finish releasing them in the background. +- * +- * cel: Note that between the time list_lru_shrink_walk runs and +- * now, these items are in the hash table but marked unhashed. +- * Why release these outside of lru_cb ? There's no lock ordering +- * problem since lru_cb currently takes no lock. +- */ +-static void nfsd_file_gc_dispose_list(struct list_head *dispose) +-{ +- struct nfsd_file *nf; +- +- list_for_each_entry(nf, dispose, nf_lru) +- nfsd_file_hash_remove(nf); +- nfsd_file_dispose_list_delayed(dispose); +-} +- + static void + nfsd_file_gc(void) + { +@@ -637,7 +603,7 @@ nfsd_file_gc(void) + ret = list_lru_walk(&nfsd_file_lru, nfsd_file_lru_cb, + &dispose, list_lru_count(&nfsd_file_lru)); + trace_nfsd_file_gc_removed(ret, list_lru_count(&nfsd_file_lru)); +- nfsd_file_gc_dispose_list(&dispose); ++ nfsd_file_dispose_list_delayed(&dispose); + } + + static void +@@ -662,7 +628,7 @@ nfsd_file_lru_scan(struct shrinker *s, struct shrink_control *sc) + ret = list_lru_shrink_walk(&nfsd_file_lru, sc, + nfsd_file_lru_cb, &dispose); + trace_nfsd_file_shrinker_removed(ret, list_lru_count(&nfsd_file_lru)); +- nfsd_file_gc_dispose_list(&dispose); ++ nfsd_file_dispose_list_delayed(&dispose); + return ret; + } + +@@ -672,72 +638,111 @@ static struct shrinker nfsd_file_shrinker = { + .seeks = 1, + }; + +-/* +- * Find all cache items across all net namespaces that match @inode and +- * move them to @dispose. The lookup is atomic wrt nfsd_file_acquire(). ++/** ++ * nfsd_file_queue_for_close: try to close out any open nfsd_files for an inode ++ * @inode: inode on which to close out nfsd_files ++ * @dispose: list on which to gather nfsd_files to close out ++ * ++ * An nfsd_file represents a struct file being held open on behalf of nfsd. An ++ * open file however can block other activity (such as leases), or cause ++ * undesirable behavior (e.g. spurious silly-renames when reexporting NFS). ++ * ++ * This function is intended to find open nfsd_files when this sort of ++ * conflicting access occurs and then attempt to close those files out. ++ * ++ * Populates the dispose list with entries that have already had their ++ * refcounts go to zero. The actual free of an nfsd_file can be expensive, ++ * so we leave it up to the caller whether it wants to wait or not. + */ +-static unsigned int +-__nfsd_file_close_inode(struct inode *inode, struct list_head *dispose) ++static void ++nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose) + { + struct nfsd_file_lookup_key key = { + .type = NFSD_FILE_KEY_INODE, + .inode = inode, + }; +- unsigned int count = 0; + struct nfsd_file *nf; + + rcu_read_lock(); + do { ++ int decrement = 1; ++ + nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, + nfsd_file_rhash_params); + if (!nf) + break; +- nfsd_file_unhash_and_queue(nf, dispose); +- count++; ++ ++ /* If we raced with someone else unhashing, ignore it */ ++ if (!nfsd_file_unhash(nf)) ++ continue; ++ ++ /* If we can't get a reference, ignore it */ ++ if (!nfsd_file_get(nf)) ++ continue; ++ ++ /* Extra decrement if we remove from the LRU */ ++ if (nfsd_file_lru_remove(nf)) ++ ++decrement; ++ ++ /* If refcount goes to 0, then put on the dispose list */ ++ if (refcount_sub_and_test(decrement, &nf->nf_ref)) { ++ list_add(&nf->nf_lru, dispose); ++ trace_nfsd_file_closing(nf); ++ } + } while (1); + rcu_read_unlock(); +- return count; + } + + /** +- * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file ++ * nfsd_file_close_inode - attempt a delayed close of a nfsd_file + * @inode: inode of the file to attempt to remove + * +- * Unhash and put, then flush and fput all cache items associated with @inode. ++ * Close out any open nfsd_files that can be reaped for @inode. The ++ * actual freeing is deferred to the dispose_list_delayed infrastructure. ++ * ++ * This is used by the fsnotify callbacks and setlease notifier. + */ +-void +-nfsd_file_close_inode_sync(struct inode *inode) ++static void ++nfsd_file_close_inode(struct inode *inode) + { + LIST_HEAD(dispose); +- unsigned int count; + +- count = __nfsd_file_close_inode(inode, &dispose); +- trace_nfsd_file_close_inode_sync(inode, count); +- nfsd_file_dispose_list_sync(&dispose); ++ nfsd_file_queue_for_close(inode, &dispose); ++ nfsd_file_dispose_list_delayed(&dispose); + } + + /** +- * nfsd_file_close_inode - attempt a delayed close of a nfsd_file ++ * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file + * @inode: inode of the file to attempt to remove + * +- * Unhash and put all cache item associated with @inode. ++ * Close out any open nfsd_files that can be reaped for @inode. The ++ * nfsd_files are closed out synchronously. ++ * ++ * This is called from nfsd_rename and nfsd_unlink to avoid silly-renames ++ * when reexporting NFS. + */ +-static void +-nfsd_file_close_inode(struct inode *inode) ++void ++nfsd_file_close_inode_sync(struct inode *inode) + { ++ struct nfsd_file *nf; + LIST_HEAD(dispose); +- unsigned int count; + +- count = __nfsd_file_close_inode(inode, &dispose); +- trace_nfsd_file_close_inode(inode, count); +- nfsd_file_dispose_list_delayed(&dispose); ++ trace_nfsd_file_close(inode); ++ ++ nfsd_file_queue_for_close(inode, &dispose); ++ while (!list_empty(&dispose)) { ++ nf = list_first_entry(&dispose, struct nfsd_file, nf_lru); ++ list_del_init(&nf->nf_lru); ++ nfsd_file_free(nf); ++ } ++ flush_delayed_fput(); + } + + /** + * nfsd_file_delayed_close - close unused nfsd_files + * @work: dummy + * +- * Walk the LRU list and close any entries that have not been used since ++ * Walk the LRU list and destroy any entries that have not been used since + * the last scan. + */ + static void +@@ -759,7 +764,7 @@ nfsd_file_lease_notifier_call(struct notifier_block *nb, unsigned long arg, + + /* Only close files for F_SETLEASE leases */ + if (fl->fl_flags & FL_LEASE) +- nfsd_file_close_inode_sync(file_inode(fl->fl_file)); ++ nfsd_file_close_inode(file_inode(fl->fl_file)); + return 0; + } + +@@ -880,6 +885,13 @@ nfsd_file_cache_init(void) + goto out; + } + ++/** ++ * __nfsd_file_cache_purge: clean out the cache for shutdown ++ * @net: net-namespace to shut down the cache (may be NULL) ++ * ++ * Walk the nfsd_file cache and close out any that match @net. If @net is NULL, ++ * then close out everything. Called when an nfsd instance is being shut down. ++ */ + static void + __nfsd_file_cache_purge(struct net *net) + { +@@ -893,8 +905,11 @@ __nfsd_file_cache_purge(struct net *net) + + nf = rhashtable_walk_next(&iter); + while (!IS_ERR_OR_NULL(nf)) { +- if (!net || nf->nf_net == net) +- nfsd_file_unhash_and_queue(nf, &dispose); ++ if (!net || nf->nf_net == net) { ++ nfsd_file_unhash(nf); ++ nfsd_file_lru_remove(nf); ++ list_add(&nf->nf_lru, &dispose); ++ } + nf = rhashtable_walk_next(&iter); + } + +@@ -1061,8 +1076,12 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + if (nf) + nf = nfsd_file_get(nf); + rcu_read_unlock(); +- if (nf) ++ ++ if (nf) { ++ if (nfsd_file_lru_remove(nf)) ++ WARN_ON_ONCE(refcount_dec_and_test(&nf->nf_ref)); + goto wait_for_construction; ++ } + + nf = nfsd_file_alloc(&key, may_flags); + if (!nf) { +@@ -1095,11 +1114,11 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + goto out; + } + open_retry = false; +- nfsd_file_put_noref(nf); ++ if (refcount_dec_and_test(&nf->nf_ref)) ++ nfsd_file_free(nf); + goto retry; + } + +- nfsd_file_lru_remove(nf); + this_cpu_inc(nfsd_file_cache_hits); + + status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); +@@ -1109,7 +1128,8 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + this_cpu_inc(nfsd_file_acquisitions); + *pnf = nf; + } else { +- nfsd_file_put(nf); ++ if (refcount_dec_and_test(&nf->nf_ref)) ++ nfsd_file_free(nf); + nf = NULL; + } + +@@ -1135,8 +1155,10 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + * If construction failed, or we raced with a call to unlink() + * then unhash. + */ +- if (status != nfs_ok || key.inode->i_nlink == 0) +- nfsd_file_unhash_and_put(nf); ++ if (status == nfs_ok && key.inode->i_nlink == 0) ++ status = nfserr_jukebox; ++ if (status != nfs_ok) ++ nfsd_file_unhash(nf); + clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags); + smp_mb__after_atomic(); + wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); +diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h +index 08e2738adf8f..4feeaed32541 100644 +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -817,8 +817,8 @@ DEFINE_CLID_EVENT(confirmed_r); + __print_flags(val, "|", \ + { 1 << NFSD_FILE_HASHED, "HASHED" }, \ + { 1 << NFSD_FILE_PENDING, "PENDING" }, \ +- { 1 << NFSD_FILE_REFERENCED, "REFERENCED"}, \ +- { 1 << NFSD_FILE_GC, "GC"}) ++ { 1 << NFSD_FILE_REFERENCED, "REFERENCED" }, \ ++ { 1 << NFSD_FILE_GC, "GC" }) + + DECLARE_EVENT_CLASS(nfsd_file_class, + TP_PROTO(struct nfsd_file *nf), +@@ -853,6 +853,7 @@ DEFINE_EVENT(nfsd_file_class, name, \ + DEFINE_NFSD_FILE_EVENT(nfsd_file_free); + DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash); + DEFINE_NFSD_FILE_EVENT(nfsd_file_put); ++DEFINE_NFSD_FILE_EVENT(nfsd_file_closing); + DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash_and_queue); + + TRACE_EVENT(nfsd_file_alloc, +@@ -1044,35 +1045,6 @@ TRACE_EVENT(nfsd_file_open, + __entry->nf_file) + ) + +-DECLARE_EVENT_CLASS(nfsd_file_search_class, +- TP_PROTO( +- const struct inode *inode, +- unsigned int count +- ), +- TP_ARGS(inode, count), +- TP_STRUCT__entry( +- __field(const struct inode *, inode) +- __field(unsigned int, count) +- ), +- TP_fast_assign( +- __entry->inode = inode; +- __entry->count = count; +- ), +- TP_printk("inode=%p count=%u", +- __entry->inode, __entry->count) +-); +- +-#define DEFINE_NFSD_FILE_SEARCH_EVENT(name) \ +-DEFINE_EVENT(nfsd_file_search_class, name, \ +- TP_PROTO( \ +- const struct inode *inode, \ +- unsigned int count \ +- ), \ +- TP_ARGS(inode, count)) +- +-DEFINE_NFSD_FILE_SEARCH_EVENT(nfsd_file_close_inode_sync); +-DEFINE_NFSD_FILE_SEARCH_EVENT(nfsd_file_close_inode); +- + TRACE_EVENT(nfsd_file_is_cached, + TP_PROTO( + const struct inode *inode, +@@ -1150,7 +1122,6 @@ DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_lru_del_disposed); + DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_gc_in_use); + DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_gc_writeback); + DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_gc_referenced); +-DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_gc_hashed); + DEFINE_NFSD_FILE_GC_EVENT(nfsd_file_gc_disposed); + + DECLARE_EVENT_CLASS(nfsd_file_lruwalk_class, +@@ -1182,6 +1153,22 @@ DEFINE_EVENT(nfsd_file_lruwalk_class, name, \ + DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_gc_removed); + DEFINE_NFSD_FILE_LRUWALK_EVENT(nfsd_file_shrinker_removed); + ++TRACE_EVENT(nfsd_file_close, ++ TP_PROTO( ++ const struct inode *inode ++ ), ++ TP_ARGS(inode), ++ TP_STRUCT__entry( ++ __field(const void *, inode) ++ ), ++ TP_fast_assign( ++ __entry->inode = inode; ++ ), ++ TP_printk("inode=%p", ++ __entry->inode ++ ) ++); ++ + TRACE_EVENT(nfsd_file_fsync, + TP_PROTO( + const struct nfsd_file *nf, +-- +2.35.1 + diff --git a/queue-6.1/octeontx2-af-fix-lmac-config-in-cgx_lmac_rx_tx_enabl.patch b/queue-6.1/octeontx2-af-fix-lmac-config-in-cgx_lmac_rx_tx_enabl.patch new file mode 100644 index 00000000000..6f28fba7406 --- /dev/null +++ b/queue-6.1/octeontx2-af-fix-lmac-config-in-cgx_lmac_rx_tx_enabl.patch @@ -0,0 +1,57 @@ +From 09b1f72b3a42358b7b4dd63ae385a407e81df45e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 21:31:07 +0530 +Subject: octeontx2-af: Fix LMAC config in cgx_lmac_rx_tx_enable + +From: Angela Czubak + +[ Upstream commit b4e9b8763e417db31c7088103cc557d55cb7a8f5 ] + +PF netdev can request AF to enable or disable reception and transmission +on assigned CGX::LMAC. The current code instead of disabling or enabling +'reception and transmission' also disables/enable the LMAC. This patch +fixes this issue. + +Fixes: 1435f66a28b4 ("octeontx2-af: CGX Rx/Tx enable/disable mbox handlers") +Signed-off-by: Angela Czubak +Signed-off-by: Hariprasad Kelam +Reviewed-by: Leon Romanovsky +Link: https://lore.kernel.org/r/20230105160107.17638-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 4 ++-- + drivers/net/ethernet/marvell/octeontx2/af/cgx.h | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index c8724bfa86b0..8fdd3afe5998 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -768,9 +768,9 @@ int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable) + + cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG); + if (enable) +- cfg |= CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN; ++ cfg |= DATA_PKT_RX_EN | DATA_PKT_TX_EN; + else +- cfg &= ~(CMR_EN | DATA_PKT_RX_EN | DATA_PKT_TX_EN); ++ cfg &= ~(DATA_PKT_RX_EN | DATA_PKT_TX_EN); + cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg); + return 0; + } +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +index 0b06788b8d80..04338db38671 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +@@ -30,7 +30,6 @@ + #define CMR_P2X_SEL_SHIFT 59ULL + #define CMR_P2X_SEL_NIX0 1ULL + #define CMR_P2X_SEL_NIX1 2ULL +-#define CMR_EN BIT_ULL(55) + #define DATA_PKT_TX_EN BIT_ULL(53) + #define DATA_PKT_RX_EN BIT_ULL(54) + #define CGX_LMAC_TYPE_SHIFT 40 +-- +2.35.1 + diff --git a/queue-6.1/octeontx2-pf-fix-resource-leakage-in-vf-driver-unbin.patch b/queue-6.1/octeontx2-pf-fix-resource-leakage-in-vf-driver-unbin.patch new file mode 100644 index 00000000000..99fb8b23ac4 --- /dev/null +++ b/queue-6.1/octeontx2-pf-fix-resource-leakage-in-vf-driver-unbin.patch @@ -0,0 +1,39 @@ +From 27b67d97afcdc7fe75a0d18e9459882a1884427f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 11:43:25 +0530 +Subject: octeontx2-pf: Fix resource leakage in VF driver unbind + +From: Hariprasad Kelam + +[ Upstream commit 53da7aec32982f5ee775b69dce06d63992ce4af3 ] + +resources allocated like mcam entries to support the Ntuple feature +and hash tables for the tc feature are not getting freed in driver +unbind. This patch fixes the issue. + +Fixes: 2da489432747 ("octeontx2-pf: devlink params support to set mcam entry count") +Signed-off-by: Hariprasad Kelam +Signed-off-by: Sunil Kovvuri Goutham +Link: https://lore.kernel.org/r/20230109061325.21395-1-hkelam@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +index 86653bb8e403..7f8ffbf79cf7 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +@@ -758,6 +758,8 @@ static void otx2vf_remove(struct pci_dev *pdev) + if (vf->otx2_wq) + destroy_workqueue(vf->otx2_wq); + otx2_ptp_destroy(vf); ++ otx2_mcam_flow_del(vf); ++ otx2_shutdown_tc(vf); + otx2vf_disable_mbox_intr(vf); + otx2_detach_resources(&vf->mbox); + if (test_bit(CN10K_LMTST, &vf->hw.cap_flag)) +-- +2.35.1 + diff --git a/queue-6.1/perf-build-properly-guard-libbpf-includes.patch b/queue-6.1/perf-build-properly-guard-libbpf-includes.patch new file mode 100644 index 00000000000..9c90a4f61d7 --- /dev/null +++ b/queue-6.1/perf-build-properly-guard-libbpf-includes.patch @@ -0,0 +1,80 @@ +From 24152c02967581cc6178bd920b92684ca3c7139e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 07:13:19 -0800 +Subject: perf build: Properly guard libbpf includes + +From: Ian Rogers + +[ Upstream commit d891f2b724b39a2a41e3ad7b57110193993242ff ] + +Including libbpf header files should be guarded by HAVE_LIBBPF_SUPPORT. +In bpf_counter.h, move the skeleton utilities under HAVE_BPF_SKEL. + +Fixes: d6a735ef3277c45f ("perf bpf_counter: Move common functions to bpf_counter.h") +Reported-by: Mike Leach +Signed-off-by: Ian Rogers +Tested-by: Arnaldo Carvalho de Melo +Tested-by: Jiri Olsa +Tested-by: Mike Leach +Cc: Alexander Shishkin +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: http://lore.kernel.org/lkml/20230105172243.7238-1-mike.leach@linaro.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-trace.c | 2 ++ + tools/perf/util/bpf_counter.h | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 3dcf6aed1ef7..97b17f8941dc 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -17,7 +17,9 @@ + #include "util/record.h" + #include + #include ++#ifdef HAVE_LIBBPF_SUPPORT + #include ++#endif + #include "util/bpf_map.h" + #include "util/rlimit.h" + #include "builtin.h" +diff --git a/tools/perf/util/bpf_counter.h b/tools/perf/util/bpf_counter.h +index 4dbf26408b69..c6d21c07b14c 100644 +--- a/tools/perf/util/bpf_counter.h ++++ b/tools/perf/util/bpf_counter.h +@@ -4,9 +4,12 @@ + + #include + #include ++ ++#ifdef HAVE_LIBBPF_SUPPORT + #include + #include + #include ++#endif + + struct evsel; + struct target; +@@ -87,6 +90,8 @@ static inline void set_max_rlimit(void) + setrlimit(RLIMIT_MEMLOCK, &rinf); + } + ++#ifdef HAVE_BPF_SKEL ++ + static inline __u32 bpf_link_get_id(int fd) + { + struct bpf_link_info link_info = { .id = 0, }; +@@ -127,5 +132,6 @@ static inline int bperf_trigger_reading(int prog_fd, int cpu) + + return bpf_prog_test_run_opts(prog_fd, &opts); + } ++#endif /* HAVE_BPF_SKEL */ + + #endif /* __PERF_BPF_COUNTER_H */ +-- +2.35.1 + diff --git a/queue-6.1/perf-kmem-support-field-node-in-evsel__process_alloc.patch b/queue-6.1/perf-kmem-support-field-node-in-evsel__process_alloc.patch new file mode 100644 index 00000000000..d50e6e3a2d1 --- /dev/null +++ b/queue-6.1/perf-kmem-support-field-node-in-evsel__process_alloc.patch @@ -0,0 +1,111 @@ +From bda77d3c3768476c268d00cb98e6349b5e4e38cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 14:24:00 +0800 +Subject: perf kmem: Support field "node" in evsel__process_alloc_event() + coping with recent tracepoint restructuring + +From: Leo Yan + +[ Upstream commit dce088ab0d51ae3b14fb2bd608e9c649aadfe5dc ] + +Commit 11e9734bcb6a7361 ("mm/slab_common: unify NUMA and UMA version of +tracepoints") adds the field "node" into the tracepoints 'kmalloc' and +'kmem_cache_alloc', so this patch modifies the event process function to +support the field "node". + +If field "node" is detected by checking function evsel__field(), it +stats the cross allocation. + +When the "node" value is NUMA_NO_NODE (-1), it means the memory can be +allocated from any memory node, in this case, we don't account it as a +cross allocation. + +Fixes: 11e9734bcb6a7361 ("mm/slab_common: unify NUMA and UMA version of tracepoints") +Reported-by: Ravi Bangoria +Reviewed-by: James Clark +Signed-off-by: Leo Yan +Cc: Alexander Shishkin +Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Vlastimil Babka +Link: https://lore.kernel.org/r/20230108062400.250690-2-leo.yan@linaro.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-kmem.c | 36 ++++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 12 deletions(-) + +diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c +index 63c759edb8bc..40dd52acc48a 100644 +--- a/tools/perf/builtin-kmem.c ++++ b/tools/perf/builtin-kmem.c +@@ -26,6 +26,7 @@ + #include "util/string2.h" + + #include ++#include + #include + #include + #include +@@ -184,22 +185,33 @@ static int evsel__process_alloc_event(struct evsel *evsel, struct perf_sample *s + total_allocated += bytes_alloc; + + nr_allocs++; +- return 0; +-} + +-static int evsel__process_alloc_node_event(struct evsel *evsel, struct perf_sample *sample) +-{ +- int ret = evsel__process_alloc_event(evsel, sample); ++ /* ++ * Commit 11e9734bcb6a ("mm/slab_common: unify NUMA and UMA ++ * version of tracepoints") adds the field "node" into the ++ * tracepoints 'kmalloc' and 'kmem_cache_alloc'. ++ * ++ * The legacy tracepoints 'kmalloc_node' and 'kmem_cache_alloc_node' ++ * also contain the field "node". ++ * ++ * If the tracepoint contains the field "node" the tool stats the ++ * cross allocation. ++ */ ++ if (evsel__field(evsel, "node")) { ++ int node1, node2; + +- if (!ret) { +- int node1 = cpu__get_node((struct perf_cpu){.cpu = sample->cpu}), +- node2 = evsel__intval(evsel, sample, "node"); ++ node1 = cpu__get_node((struct perf_cpu){.cpu = sample->cpu}); ++ node2 = evsel__intval(evsel, sample, "node"); + +- if (node1 != node2) ++ /* ++ * If the field "node" is NUMA_NO_NODE (-1), we don't take it ++ * as a cross allocation. ++ */ ++ if ((node2 != NUMA_NO_NODE) && (node1 != node2)) + nr_cross_allocs++; + } + +- return ret; ++ return 0; + } + + static int ptr_cmp(void *, void *); +@@ -1368,8 +1380,8 @@ static int __cmd_kmem(struct perf_session *session) + /* slab allocator */ + { "kmem:kmalloc", evsel__process_alloc_event, }, + { "kmem:kmem_cache_alloc", evsel__process_alloc_event, }, +- { "kmem:kmalloc_node", evsel__process_alloc_node_event, }, +- { "kmem:kmem_cache_alloc_node", evsel__process_alloc_node_event, }, ++ { "kmem:kmalloc_node", evsel__process_alloc_event, }, ++ { "kmem:kmem_cache_alloc_node", evsel__process_alloc_event, }, + { "kmem:kfree", evsel__process_free_event, }, + { "kmem:kmem_cache_free", evsel__process_free_event, }, + /* page allocator */ +-- +2.35.1 + diff --git a/queue-6.1/perf-kmem-support-legacy-tracepoints.patch b/queue-6.1/perf-kmem-support-legacy-tracepoints.patch new file mode 100644 index 00000000000..4955b8d836f --- /dev/null +++ b/queue-6.1/perf-kmem-support-legacy-tracepoints.patch @@ -0,0 +1,106 @@ +From 2204e7dd6595ecb466904fd55d84dd54ffa61787 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 14:23:59 +0800 +Subject: perf kmem: Support legacy tracepoints + +From: Leo Yan + +[ Upstream commit b3719108ae60169eda5c941ca5e1be1faa371c57 ] + +Commit 11e9734bcb6a7361 ("mm/slab_common: unify NUMA and UMA version of +tracepoints") removed tracepoints 'kmalloc_node' and +'kmem_cache_alloc_node', we need to consider the tool should be backward +compatible. + +If it detect the tracepoint "kmem:kmalloc_node", this patch enables the +legacy tracepoints, otherwise, it will ignore them. + +Fixes: 11e9734bcb6a7361 ("mm/slab_common: unify NUMA and UMA version of tracepoints") +Reported-by: Ravi Bangoria +Reviewed-by: James Clark +Signed-off-by: Leo Yan +Cc: Alexander Shishkin +Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Vlastimil Babka +Link: https://lore.kernel.org/r/20230108062400.250690-1-leo.yan@linaro.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-kmem.c | 29 ++++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c +index ebfab2ca1702..63c759edb8bc 100644 +--- a/tools/perf/builtin-kmem.c ++++ b/tools/perf/builtin-kmem.c +@@ -1823,6 +1823,19 @@ static int parse_line_opt(const struct option *opt __maybe_unused, + return 0; + } + ++static bool slab_legacy_tp_is_exposed(void) ++{ ++ /* ++ * The tracepoints "kmem:kmalloc_node" and ++ * "kmem:kmem_cache_alloc_node" have been removed on the latest ++ * kernel, if the tracepoint "kmem:kmalloc_node" is existed it ++ * means the tool is running on an old kernel, we need to ++ * rollback to support these legacy tracepoints. ++ */ ++ return IS_ERR(trace_event__tp_format("kmem", "kmalloc_node")) ? ++ false : true; ++} ++ + static int __cmd_record(int argc, const char **argv) + { + const char * const record_args[] = { +@@ -1830,22 +1843,28 @@ static int __cmd_record(int argc, const char **argv) + }; + const char * const slab_events[] = { + "-e", "kmem:kmalloc", +- "-e", "kmem:kmalloc_node", + "-e", "kmem:kfree", + "-e", "kmem:kmem_cache_alloc", +- "-e", "kmem:kmem_cache_alloc_node", + "-e", "kmem:kmem_cache_free", + }; ++ const char * const slab_legacy_events[] = { ++ "-e", "kmem:kmalloc_node", ++ "-e", "kmem:kmem_cache_alloc_node", ++ }; + const char * const page_events[] = { + "-e", "kmem:mm_page_alloc", + "-e", "kmem:mm_page_free", + }; + unsigned int rec_argc, i, j; + const char **rec_argv; ++ unsigned int slab_legacy_tp_exposed = slab_legacy_tp_is_exposed(); + + rec_argc = ARRAY_SIZE(record_args) + argc - 1; +- if (kmem_slab) ++ if (kmem_slab) { + rec_argc += ARRAY_SIZE(slab_events); ++ if (slab_legacy_tp_exposed) ++ rec_argc += ARRAY_SIZE(slab_legacy_events); ++ } + if (kmem_page) + rec_argc += ARRAY_SIZE(page_events) + 1; /* for -g */ + +@@ -1860,6 +1879,10 @@ static int __cmd_record(int argc, const char **argv) + if (kmem_slab) { + for (j = 0; j < ARRAY_SIZE(slab_events); j++, i++) + rec_argv[i] = strdup(slab_events[j]); ++ if (slab_legacy_tp_exposed) { ++ for (j = 0; j < ARRAY_SIZE(slab_legacy_events); j++, i++) ++ rec_argv[i] = strdup(slab_legacy_events[j]); ++ } + } + if (kmem_page) { + rec_argv[i++] = strdup("-g"); +-- +2.35.1 + diff --git a/queue-6.1/platform-surface-aggregator-add-missing-call-to-ssam.patch b/queue-6.1/platform-surface-aggregator-add-missing-call-to-ssam.patch new file mode 100644 index 00000000000..9d27593abc8 --- /dev/null +++ b/queue-6.1/platform-surface-aggregator-add-missing-call-to-ssam.patch @@ -0,0 +1,43 @@ +From d5eb3d2b510ca09d450bfa8310a08f782c2cd0ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Dec 2022 18:56:07 +0100 +Subject: platform/surface: aggregator: Add missing call to + ssam_request_sync_free() + +From: Maximilian Luz + +[ Upstream commit c965daac370f08a9b71d573a71d13cda76f2a884 ] + +Although rare, ssam_request_sync_init() can fail. In that case, the +request should be freed via ssam_request_sync_free(). Currently it is +leaked instead. Fix this. + +Fixes: c167b9c7e3d6 ("platform/surface: Add Surface Aggregator subsystem") +Signed-off-by: Maximilian Luz +Link: https://lore.kernel.org/r/20221220175608.1436273-1-luzmaximilian@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/surface/aggregator/controller.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c +index 43e765199137..c6537a1b3a2e 100644 +--- a/drivers/platform/surface/aggregator/controller.c ++++ b/drivers/platform/surface/aggregator/controller.c +@@ -1700,8 +1700,10 @@ int ssam_request_sync(struct ssam_controller *ctrl, + return status; + + status = ssam_request_sync_init(rqst, spec->flags); +- if (status) ++ if (status) { ++ ssam_request_sync_free(rqst); + return status; ++ } + + ssam_request_sync_set_resp(rqst, rsp); + +-- +2.35.1 + diff --git a/queue-6.1/platform-x86-amd-fix-refcount-leak-in-amd_pmc_probe.patch b/queue-6.1/platform-x86-amd-fix-refcount-leak-in-amd_pmc_probe.patch new file mode 100644 index 00000000000..3c089039a4e --- /dev/null +++ b/queue-6.1/platform-x86-amd-fix-refcount-leak-in-amd_pmc_probe.patch @@ -0,0 +1,40 @@ +From a2c8df242de4bc49b27ab6650daa5bc6f9013c3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Dec 2022 11:25:33 +0400 +Subject: platform/x86/amd: Fix refcount leak in amd_pmc_probe + +From: Miaoqian Lin + +[ Upstream commit ccb32e2be14271a60e9ba89c6d5660cc9998773c ] + +pci_get_domain_bus_and_slot() takes reference, the caller should release +the reference by calling pci_dev_put() after use. Call pci_dev_put() in +the error path to fix this. + +Fixes: 3d7d407dfb05 ("platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature") +Signed-off-by: Miaoqian Lin +Reviewed-by: Mario Limonciello +Link: https://lore.kernel.org/r/20221229072534.1381432-1-linmq006@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/amd/pmc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c +index 439d282aafd1..8d924986381b 100644 +--- a/drivers/platform/x86/amd/pmc.c ++++ b/drivers/platform/x86/amd/pmc.c +@@ -932,7 +932,7 @@ static int amd_pmc_probe(struct platform_device *pdev) + if (enable_stb && (dev->cpu_id == AMD_CPU_ID_YC || dev->cpu_id == AMD_CPU_ID_CB)) { + err = amd_pmc_s2d_init(dev); + if (err) +- return err; ++ goto err_pci_dev_put; + } + + platform_set_drvdata(pdev, dev); +-- +2.35.1 + diff --git a/queue-6.1/regulator-da9211-use-irq-handler-when-ready.patch b/queue-6.1/regulator-da9211-use-irq-handler-when-ready.patch new file mode 100644 index 00000000000..26174a8a040 --- /dev/null +++ b/queue-6.1/regulator-da9211-use-irq-handler-when-ready.patch @@ -0,0 +1,66 @@ +From c9e45fbf36a9ab6af1a28ec6699638c51f64d104 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Nov 2022 22:06:02 +0100 +Subject: regulator: da9211: Use irq handler when ready + +From: Ricardo Ribalda + +[ Upstream commit 02228f6aa6a64d588bc31e3267d05ff184d772eb ] + +If the system does not come from reset (like when it is kexec()), the +regulator might have an IRQ waiting for us. + +If we enable the IRQ handler before its structures are ready, we crash. + +This patch fixes: + +[ 1.141839] Unable to handle kernel read from unreadable memory at virtual address 0000000000000078 +[ 1.316096] Call trace: +[ 1.316101] blocking_notifier_call_chain+0x20/0xa8 +[ 1.322757] cpu cpu0: dummy supplies not allowed for exclusive requests +[ 1.327823] regulator_notifier_call_chain+0x1c/0x2c +[ 1.327825] da9211_irq_handler+0x68/0xf8 +[ 1.327829] irq_thread+0x11c/0x234 +[ 1.327833] kthread+0x13c/0x154 + +Signed-off-by: Ricardo Ribalda +Reviewed-by: Adam Ward +Link: https://lore.kernel.org/r/20221124-da9211-v2-0-1779e3c5d491@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/da9211-regulator.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c +index e01b32d1fa17..00828f5baa97 100644 +--- a/drivers/regulator/da9211-regulator.c ++++ b/drivers/regulator/da9211-regulator.c +@@ -498,6 +498,12 @@ static int da9211_i2c_probe(struct i2c_client *i2c) + + chip->chip_irq = i2c->irq; + ++ ret = da9211_regulator_init(chip); ++ if (ret < 0) { ++ dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); ++ return ret; ++ } ++ + if (chip->chip_irq != 0) { + ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL, + da9211_irq_handler, +@@ -512,11 +518,6 @@ static int da9211_i2c_probe(struct i2c_client *i2c) + dev_warn(chip->dev, "No IRQ configured\n"); + } + +- ret = da9211_regulator_init(chip); +- +- if (ret < 0) +- dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); +- + return ret; + } + +-- +2.35.1 + diff --git a/queue-6.1/revert-r8169-disable-detection-of-chip-version-36.patch b/queue-6.1/revert-r8169-disable-detection-of-chip-version-36.patch new file mode 100644 index 00000000000..f2d41fd19e2 --- /dev/null +++ b/queue-6.1/revert-r8169-disable-detection-of-chip-version-36.patch @@ -0,0 +1,43 @@ +From 21155065d6a30fab6afe3dad66dc920880d8bb66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 20:37:53 +0100 +Subject: Revert "r8169: disable detection of chip version 36" + +From: Heiner Kallweit + +[ Upstream commit 2ea26b4de6f42b74a5f1701de41efa6bc9f12666 ] + +This reverts commit 42666b2c452ce87894786aae05e3fad3cfc6cb59. + +This chip version seems to be very rare, but it exits in consumer +devices, see linked report. + +Link: https://stackoverflow.com/questions/75049473/cant-setup-a-wired-network-in-archlinux-fresh-install +Fixes: 42666b2c452c ("r8169: disable detection of chip version 36") +Signed-off-by: Heiner Kallweit +Link: https://lore.kernel.org/r/42e9674c-d5d0-a65a-f578-e5c74f244739@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index a73d061d9fcb..fe8dc8e0522b 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -1996,10 +1996,7 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) + + /* 8168F family. */ + { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 }, +- /* It seems this chip version never made it to +- * the wild. Let's disable detection. +- * { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, +- */ ++ { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, + { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 }, + + /* 8168E family. */ +-- +2.35.1 + diff --git a/queue-6.1/sched-core-fix-arch_scale_freq_tick-on-tickless-syst.patch b/queue-6.1/sched-core-fix-arch_scale_freq_tick-on-tickless-syst.patch new file mode 100644 index 00000000000..95ecdb9dcf4 --- /dev/null +++ b/queue-6.1/sched-core-fix-arch_scale_freq_tick-on-tickless-syst.patch @@ -0,0 +1,56 @@ +From 6abbcb374d5cc479423241ca6f867fe11d806c41 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 14:51:21 +0200 +Subject: sched/core: Fix arch_scale_freq_tick() on tickless systems + +From: Yair Podemsky + +[ Upstream commit 7fb3ff22ad8772bbf0e3ce1ef3eb7b09f431807f ] + +In order for the scheduler to be frequency invariant we measure the +ratio between the maximum CPU frequency and the actual CPU frequency. + +During long tickless periods of time the calculations that keep track +of that might overflow, in the function scale_freq_tick(): + + if (check_shl_overflow(acnt, 2*SCHED_CAPACITY_SHIFT, &acnt)) + goto error; + +eventually forcing the kernel to disable the feature for all CPUs, +and show the warning message: + + "Scheduler frequency invariance went wobbly, disabling!". + +Let's avoid that by limiting the frequency invariant calculations +to CPUs with regular tick. + +Fixes: e2b0d619b400 ("x86, sched: check for counters overflow in frequency invariant accounting") +Suggested-by: "Peter Zijlstra (Intel)" +Signed-off-by: Yair Podemsky +Signed-off-by: Ingo Molnar +Reviewed-by: Valentin Schneider +Acked-by: Giovanni Gherdovich +Link: https://lore.kernel.org/r/20221130125121.34407-1-ypodemsk@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/sched/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 981e41cc4121..172ec79b66f6 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -5498,7 +5498,9 @@ void scheduler_tick(void) + unsigned long thermal_pressure; + u64 resched_latency; + +- arch_scale_freq_tick(); ++ if (housekeeping_cpu(cpu, HK_TYPE_TICK)) ++ arch_scale_freq_tick(); ++ + sched_clock_tick(); + + rq_lock(rq, &rf); +-- +2.35.1 + diff --git a/queue-6.1/scsi-mpi3mr-refer-config_scsi_mpi3mr-in-makefile.patch b/queue-6.1/scsi-mpi3mr-refer-config_scsi_mpi3mr-in-makefile.patch new file mode 100644 index 00000000000..94e711f6713 --- /dev/null +++ b/queue-6.1/scsi-mpi3mr-refer-config_scsi_mpi3mr-in-makefile.patch @@ -0,0 +1,44 @@ +From 3153380ff980cb26ef68601ae93d1a9e069dd30c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 11:36:59 +0900 +Subject: scsi: mpi3mr: Refer CONFIG_SCSI_MPI3MR in Makefile + +From: Shin'ichiro Kawasaki + +[ Upstream commit f0a43ba6c66cc0688e2748d986a1459fdd3442ef ] + +When Kconfig item CONFIG_SCSI_MPI3MR was introduced for mpi3mr driver, the +Makefile of the driver was not modified to refer the Kconfig item. + +As a result, mpi3mr.ko is built regardless of the Kconfig item value y or +m. Also, if 'make localmodconfig' can not find the Kconfig item in the +Makefile, then it does not generate CONFIG_SCSI_MPI3MR=m even when +mpi3mr.ko is loaded on the system. + +Refer to the Kconfig item to avoid the issues. + +Fixes: c4f7ac64616e ("scsi: mpi3mr: Add mpi30 Rev-R headers and Kconfig") +Signed-off-by: Shin'ichiro Kawasaki +Link: https://lore.kernel.org/r/20221207023659.2411785-1-shinichiro.kawasaki@wdc.com +Reviewed-by: Damien Le Moal +Acked-by: Sathya Prakash Veerichetty +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpi3mr/Makefile b/drivers/scsi/mpi3mr/Makefile +index ef86ca46646b..3bf8cf34e1c3 100644 +--- a/drivers/scsi/mpi3mr/Makefile ++++ b/drivers/scsi/mpi3mr/Makefile +@@ -1,5 +1,5 @@ + # mpi3mr makefile +-obj-m += mpi3mr.o ++obj-$(CONFIG_SCSI_MPI3MR) += mpi3mr.o + mpi3mr-y += mpi3mr_os.o \ + mpi3mr_fw.o \ + mpi3mr_app.o \ +-- +2.35.1 + diff --git a/queue-6.1/scsi-storvsc-fix-swiotlb-bounce-buffer-leak-in-confi.patch b/queue-6.1/scsi-storvsc-fix-swiotlb-bounce-buffer-leak-in-confi.patch new file mode 100644 index 00000000000..42547b4e11e --- /dev/null +++ b/queue-6.1/scsi-storvsc-fix-swiotlb-bounce-buffer-leak-in-confi.patch @@ -0,0 +1,51 @@ +From 4332ec1394ed16170d756433aa7867f97709eb08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 4 Dec 2022 11:52:44 -0800 +Subject: scsi: storvsc: Fix swiotlb bounce buffer leak in confidential VM + +From: Michael Kelley + +[ Upstream commit 67ff3d0a49f3d445c3922e30a54e03c161da561e ] + +storvsc_queuecommand() maps the scatter/gather list using scsi_dma_map(), +which in a confidential VM allocates swiotlb bounce buffers. If the I/O +submission fails in storvsc_do_io(), the I/O is typically retried by higher +level code, but the bounce buffer memory is never freed. The mostly like +cause of I/O submission failure is a full VMBus channel ring buffer, which +is not uncommon under high I/O loads. Eventually enough bounce buffer +memory leaks that the confidential VM can't do any I/O. The same problem +can arise in a non-confidential VM with kernel boot parameter +swiotlb=force. + +Fix this by doing scsi_dma_unmap() in the case of an I/O submission +error, which frees the bounce buffer memory. + +Fixes: 743b237c3a7b ("scsi: storvsc: Add Isolation VM support for storvsc driver") +Signed-off-by: Michael Kelley +Link: https://lore.kernel.org/r/1670183564-76254-1-git-send-email-mikelley@microsoft.com +Tested-by: Dexuan Cui +Reviewed-by: Dexuan Cui +Reviewed-by: Tianyu Lan +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/storvsc_drv.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 3c5b7e4227b2..55d6fb452680 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1823,6 +1823,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + ret = storvsc_do_io(dev, cmd_request, get_cpu()); + put_cpu(); + ++ if (ret) ++ scsi_dma_unmap(scmnd); ++ + if (ret == -EAGAIN) { + /* no more space */ + ret = SCSI_MLQUEUE_DEVICE_BUSY; +-- +2.35.1 + diff --git a/queue-6.1/scsi-ufs-core-wlun-suspend-ssu-enter-hibern8-fail-re.patch b/queue-6.1/scsi-ufs-core-wlun-suspend-ssu-enter-hibern8-fail-re.patch new file mode 100644 index 00000000000..adeb805f2f4 --- /dev/null +++ b/queue-6.1/scsi-ufs-core-wlun-suspend-ssu-enter-hibern8-fail-re.patch @@ -0,0 +1,79 @@ +From 0cceeb7e85a809b6d3410ce006510967ea81f084 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Dec 2022 15:25:20 +0800 +Subject: scsi: ufs: core: WLUN suspend SSU/enter hibern8 fail recovery + +From: Peter Wang + +[ Upstream commit 1a5665fc8d7a000671ebd3fe69c6f9acf1e0dcd9 ] + +When SSU/enter hibern8 fail in WLUN suspend flow, trigger the error handler +and return busy to break the suspend. Otherwise the consumer will get +stuck in runtime suspend status. + +Fixes: b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun") +Signed-off-by: Peter Wang +Link: https://lore.kernel.org/r/20221208072520.26210-1-peter.wang@mediatek.com +Reviewed-by: Stanley Chu +Reviewed-by: Bart Van Assche +Reviewed-by: Adrian Hunter +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index d1db6be80156..b048357d21e3 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -6094,6 +6094,14 @@ void ufshcd_schedule_eh_work(struct ufs_hba *hba) + } + } + ++static void ufshcd_force_error_recovery(struct ufs_hba *hba) ++{ ++ spin_lock_irq(hba->host->host_lock); ++ hba->force_reset = true; ++ ufshcd_schedule_eh_work(hba); ++ spin_unlock_irq(hba->host->host_lock); ++} ++ + static void ufshcd_clk_scaling_allow(struct ufs_hba *hba, bool allow) + { + down_write(&hba->clk_scaling_lock); +@@ -9066,6 +9074,15 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + + if (!hba->dev_info.b_rpm_dev_flush_capable) { + ret = ufshcd_set_dev_pwr_mode(hba, req_dev_pwr_mode); ++ if (ret && pm_op != UFS_SHUTDOWN_PM) { ++ /* ++ * If return err in suspend flow, IO will hang. ++ * Trigger error handler and break suspend for ++ * error recovery. ++ */ ++ ufshcd_force_error_recovery(hba); ++ ret = -EBUSY; ++ } + if (ret) + goto enable_scaling; + } +@@ -9077,6 +9094,15 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) + */ + check_for_bkops = !ufshcd_is_ufs_dev_deepsleep(hba); + ret = ufshcd_link_state_transition(hba, req_link_state, check_for_bkops); ++ if (ret && pm_op != UFS_SHUTDOWN_PM) { ++ /* ++ * If return err in suspend flow, IO will hang. ++ * Trigger error handler and break suspend for ++ * error recovery. ++ */ ++ ufshcd_force_error_recovery(hba); ++ ret = -EBUSY; ++ } + if (ret) + goto set_dev_active; + +-- +2.35.1 + diff --git a/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-ensure-environme.patch b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-ensure-environme.patch new file mode 100644 index 00000000000..c55f33dffd0 --- /dev/null +++ b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-ensure-environme.patch @@ -0,0 +1,113 @@ +From 7e16342d79be2cf3c16266bc8ca1670575626cd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 16:45:50 +0100 +Subject: selftests/net: l2_tos_ttl_inherit.sh: Ensure environment cleanup on + failure. + +From: Guillaume Nault + +[ Upstream commit d68ff8ad3351b8fc8d6f14b9a4f5cc8ba3e8bd13 ] + +Use 'set -e' and an exit handler to stop the script if a command fails +and ensure the test environment is cleaned up in any case. Also, handle +the case where the script is interrupted by SIGINT. + +The only command that's expected to fail is 'wait $ping_pid', since +it's killed by the script. Handle this case with '|| true' to make it +play well with 'set -e'. + +Finally, return the Kselftest SKIP code (4) when the script breaks +because of an environment problem or a command line failure. The 0 and +1 return codes should now reliably indicate that all tests have been +run (0: all tests run and passed, 1: all tests run but at least one +failed, 4: test script didn't run completely). + +Fixes: b690842d12fd ("selftests/net: test l2 tunnel TOS/TTL inheriting") +Reported-by: Mirsad Goran Todorovac +Tested-by: Mirsad Goran Todorovac +Signed-off-by: Guillaume Nault +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../selftests/net/l2_tos_ttl_inherit.sh | 40 +++++++++++++++++-- + 1 file changed, 36 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +index cf56680d598f..f11756e7df2f 100755 +--- a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh ++++ b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +@@ -12,13 +12,16 @@ + # In addition this script also checks if forcing a specific field in the + # outer header is working. + ++# Return 4 by default (Kselftest SKIP code) ++ERR=4 ++ + if [ "$(id -u)" != "0" ]; then + echo "Please run as root." +- exit 0 ++ exit $ERR + fi + if ! which tcpdump > /dev/null 2>&1; then + echo "No tcpdump found. Required for this test." +- exit 0 ++ exit $ERR + fi + + expected_tos="0x00" +@@ -340,7 +343,7 @@ verify() { + fi + fi + kill -9 $ping_pid +- wait $ping_pid 2>/dev/null ++ wait $ping_pid 2>/dev/null || true + result="FAIL" + if [ "$outer" = "4" ]; then + captured_ttl="$(get_field "ttl" "$out")" +@@ -380,6 +383,31 @@ cleanup() { + ip netns del "${NS1}" 2>/dev/null + } + ++exit_handler() { ++ # Don't exit immediately if one of the intermediate commands fails. ++ # We might be called at the end of the script, when the network ++ # namespaces have already been deleted. So cleanup() may fail, but we ++ # still need to run until 'exit $ERR' or the script won't return the ++ # correct error code. ++ set +e ++ ++ cleanup ++ ++ exit $ERR ++} ++ ++# Restore the default SIGINT handler (just in case) and exit. ++# The exit handler will take care of cleaning everything up. ++interrupted() { ++ trap - INT ++ ++ exit $ERR ++} ++ ++set -e ++trap exit_handler EXIT ++trap interrupted INT ++ + printf "┌────────┬───────┬───────┬──────────────┬" + printf "──────────────┬───────┬────────┐\n" + for type in gre vxlan geneve; do +@@ -409,6 +437,10 @@ done + printf "└────────┴───────┴───────┴──────────────┴" + printf "──────────────┴───────┴────────┘\n" + ++# All tests done. ++# Set ERR appropriately: it will be returned by the exit handler. + if $failed; then +- exit 1 ++ ERR=1 ++else ++ ERR=0 + fi +-- +2.35.1 + diff --git a/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-run-tests-in-the.patch b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-run-tests-in-the.patch new file mode 100644 index 00000000000..07d21d2bf41 --- /dev/null +++ b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-run-tests-in-the.patch @@ -0,0 +1,309 @@ +From 89dc77464444ff55b9bf378460a272ade4285b0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 16:45:46 +0100 +Subject: selftests/net: l2_tos_ttl_inherit.sh: Run tests in their own netns. + +From: Guillaume Nault + +[ Upstream commit c53cb00f7983a5474f2d36967f84908b85af9159 ] + +This selftest currently runs half in the current namespace and half in +a netns of its own. Therefore, the test can fail if the current +namespace is already configured with incompatible parameters (for +example if it already has a veth0 interface). + +Adapt the script to put both ends of the veth pair in their own netns. +Now veth0 is created in NS0 instead of the current namespace, while +veth1 is set up in NS1 (instead of the 'testing' netns). + +The user visible netns names are randomised to minimise the risk of +conflicts with already existing namespaces. The cleanup() function +doesn't need to remove the virtual interface anymore: deleting NS0 and +NS1 automatically removes the virtual interfaces they contained. + +We can remove $ns, which was only used to run ip commands in the +'testing' netns (let's use the builtin "-netns" option instead). +However, we still need a similar functionality as ping and tcpdump +now need to run in NS0. So we now have $RUN_NS0 for that. + +Fixes: b690842d12fd ("selftests/net: test l2 tunnel TOS/TTL inheriting") +Reported-by: Mirsad Goran Todorovac +Tested-by: Mirsad Goran Todorovac +Signed-off-by: Guillaume Nault +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../selftests/net/l2_tos_ttl_inherit.sh | 162 ++++++++++-------- + 1 file changed, 93 insertions(+), 69 deletions(-) + +diff --git a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +index e2574b08eabc..cf56680d598f 100755 +--- a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh ++++ b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +@@ -25,6 +25,11 @@ expected_tos="0x00" + expected_ttl="0" + failed=false + ++readonly NS0=$(mktemp -u ns0-XXXXXXXX) ++readonly NS1=$(mktemp -u ns1-XXXXXXXX) ++ ++RUN_NS0="ip netns exec ${NS0}" ++ + get_random_tos() { + # Get a random hex tos value between 0x00 and 0xfc, a multiple of 4 + echo "0x$(tr -dc '0-9a-f' < /dev/urandom | head -c 1)\ +@@ -61,7 +66,6 @@ setup() { + local vlan="$5" + local test_tos="0x00" + local test_ttl="0" +- local ns="ip netns exec testing" + + # We don't want a test-tos of 0x00, + # because this is the value that we get when no tos is set. +@@ -94,14 +98,15 @@ setup() { + printf "│%7s │%6s │%6s │%13s │%13s │%6s │" \ + "$type" "$outer" "$inner" "$tos" "$ttl" "$vlan" + +- # Create 'testing' netns, veth pair and connect main ns with testing ns +- ip netns add testing +- ip link add type veth +- ip link set veth1 netns testing +- ip link set veth0 up +- $ns ip link set veth1 up +- ip addr flush dev veth0 +- $ns ip addr flush dev veth1 ++ # Create netns NS0 and NS1 and connect them with a veth pair ++ ip netns add "${NS0}" ++ ip netns add "${NS1}" ++ ip link add name veth0 netns "${NS0}" type veth \ ++ peer name veth1 netns "${NS1}" ++ ip -netns "${NS0}" link set dev veth0 up ++ ip -netns "${NS1}" link set dev veth1 up ++ ip -netns "${NS0}" address flush dev veth0 ++ ip -netns "${NS1}" address flush dev veth1 + + local local_addr1="" + local local_addr2="" +@@ -127,51 +132,59 @@ setup() { + if [ "$type" = "gre" ]; then + type="gretap" + fi +- ip addr add 198.18.0.1/24 dev veth0 +- $ns ip addr add 198.18.0.2/24 dev veth1 +- ip link add name tep0 type $type $local_addr1 remote \ +- 198.18.0.2 tos $test_tos ttl $test_ttl $vxlan $geneve +- $ns ip link add name tep1 type $type $local_addr2 remote \ +- 198.18.0.1 tos $test_tos ttl $test_ttl $vxlan $geneve ++ ip -netns "${NS0}" address add 198.18.0.1/24 dev veth0 ++ ip -netns "${NS1}" address add 198.18.0.2/24 dev veth1 ++ ip -netns "${NS0}" link add name tep0 type $type $local_addr1 \ ++ remote 198.18.0.2 tos $test_tos ttl $test_ttl \ ++ $vxlan $geneve ++ ip -netns "${NS1}" link add name tep1 type $type $local_addr2 \ ++ remote 198.18.0.1 tos $test_tos ttl $test_ttl \ ++ $vxlan $geneve + elif [ "$outer" = "6" ]; then + if [ "$type" = "gre" ]; then + type="ip6gretap" + fi +- ip addr add fdd1:ced0:5d88:3fce::1/64 dev veth0 nodad +- $ns ip addr add fdd1:ced0:5d88:3fce::2/64 dev veth1 nodad +- ip link add name tep0 type $type $local_addr1 \ +- remote fdd1:ced0:5d88:3fce::2 tos $test_tos ttl $test_ttl \ +- $vxlan $geneve +- $ns ip link add name tep1 type $type $local_addr2 \ +- remote fdd1:ced0:5d88:3fce::1 tos $test_tos ttl $test_ttl \ +- $vxlan $geneve ++ ip -netns "${NS0}" address add fdd1:ced0:5d88:3fce::1/64 \ ++ dev veth0 nodad ++ ip -netns "${NS1}" address add fdd1:ced0:5d88:3fce::2/64 \ ++ dev veth1 nodad ++ ip -netns "${NS0}" link add name tep0 type $type $local_addr1 \ ++ remote fdd1:ced0:5d88:3fce::2 tos $test_tos \ ++ ttl $test_ttl $vxlan $geneve ++ ip -netns "${NS1}" link add name tep1 type $type $local_addr2 \ ++ remote fdd1:ced0:5d88:3fce::1 tos $test_tos \ ++ ttl $test_ttl $vxlan $geneve + fi + + # Bring L2-tunnel link up and create VLAN on top +- ip link set tep0 up +- $ns ip link set tep1 up +- ip addr flush dev tep0 +- $ns ip addr flush dev tep1 ++ ip -netns "${NS0}" link set tep0 up ++ ip -netns "${NS1}" link set tep1 up ++ ip -netns "${NS0}" address flush dev tep0 ++ ip -netns "${NS1}" address flush dev tep1 + local parent + if $vlan; then + parent="vlan99-" +- ip link add link tep0 name ${parent}0 type vlan id 99 +- $ns ip link add link tep1 name ${parent}1 type vlan id 99 +- ip link set ${parent}0 up +- $ns ip link set ${parent}1 up +- ip addr flush dev ${parent}0 +- $ns ip addr flush dev ${parent}1 ++ ip -netns "${NS0}" link add link tep0 name ${parent}0 \ ++ type vlan id 99 ++ ip -netns "${NS1}" link add link tep1 name ${parent}1 \ ++ type vlan id 99 ++ ip -netns "${NS0}" link set dev ${parent}0 up ++ ip -netns "${NS1}" link set dev ${parent}1 up ++ ip -netns "${NS0}" address flush dev ${parent}0 ++ ip -netns "${NS1}" address flush dev ${parent}1 + else + parent="tep" + fi + + # Assign inner IPv4/IPv6 addresses + if [ "$inner" = "4" ] || [ "$inner" = "other" ]; then +- ip addr add 198.19.0.1/24 brd + dev ${parent}0 +- $ns ip addr add 198.19.0.2/24 brd + dev ${parent}1 ++ ip -netns "${NS0}" address add 198.19.0.1/24 brd + dev ${parent}0 ++ ip -netns "${NS1}" address add 198.19.0.2/24 brd + dev ${parent}1 + elif [ "$inner" = "6" ]; then +- ip addr add fdd4:96cf:4eae:443b::1/64 dev ${parent}0 nodad +- $ns ip addr add fdd4:96cf:4eae:443b::2/64 dev ${parent}1 nodad ++ ip -netns "${NS0}" address add fdd4:96cf:4eae:443b::1/64 \ ++ dev ${parent}0 nodad ++ ip -netns "${NS1}" address add fdd4:96cf:4eae:443b::2/64 \ ++ dev ${parent}1 nodad + fi + } + +@@ -192,10 +205,10 @@ verify() { + ping_dst="198.19.0.3" # Generates ARPs which are not IPv4/IPv6 + fi + if [ "$tos_ttl" = "inherit" ]; then +- ping -i 0.1 $ping_dst -Q "$expected_tos" -t "$expected_ttl" \ +- 2>/dev/null 1>&2 & ping_pid="$!" ++ ${RUN_NS0} ping -i 0.1 $ping_dst -Q "$expected_tos" \ ++ -t "$expected_ttl" 2>/dev/null 1>&2 & ping_pid="$!" + else +- ping -i 0.1 $ping_dst 2>/dev/null 1>&2 & ping_pid="$!" ++ ${RUN_NS0} ping -i 0.1 $ping_dst 2>/dev/null 1>&2 & ping_pid="$!" + fi + local tunnel_type_offset tunnel_type_proto req_proto_offset req_offset + if [ "$type" = "gre" ]; then +@@ -216,10 +229,12 @@ verify() { + req_proto_offset="$((req_proto_offset + 4))" + req_offset="$((req_offset + 4))" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip[$req_proto_offset] = 0x01 and \ +- ip[$req_offset] = 0x08 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip[$req_proto_offset] = 0x01 and \ ++ ip[$req_offset] = 0x08 2>/dev/null \ ++ | head -n 1)" + elif [ "$inner" = "6" ]; then + req_proto_offset="44" + req_offset="78" +@@ -231,10 +246,12 @@ verify() { + req_proto_offset="$((req_proto_offset + 4))" + req_offset="$((req_offset + 4))" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip[$req_proto_offset] = 0x3a and \ +- ip[$req_offset] = 0x80 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip[$req_proto_offset] = 0x3a and \ ++ ip[$req_offset] = 0x80 2>/dev/null \ ++ | head -n 1)" + elif [ "$inner" = "other" ]; then + req_proto_offset="36" + req_offset="45" +@@ -250,11 +267,13 @@ verify() { + expected_tos="0x00" + expected_ttl="64" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip[$req_proto_offset] = 0x08 and \ +- ip[$((req_proto_offset + 1))] = 0x06 and \ +- ip[$req_offset] = 0x01 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip[$req_proto_offset] = 0x08 and \ ++ ip[$((req_proto_offset + 1))] = 0x06 and \ ++ ip[$req_offset] = 0x01 2>/dev/null \ ++ | head -n 1)" + fi + elif [ "$outer" = "6" ]; then + if [ "$type" = "gre" ]; then +@@ -273,10 +292,12 @@ verify() { + req_proto_offset="$((req_proto_offset + 4))" + req_offset="$((req_offset + 4))" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip6[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip6[$req_proto_offset] = 0x01 and \ +- ip6[$req_offset] = 0x08 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip6[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip6[$req_proto_offset] = 0x01 and \ ++ ip6[$req_offset] = 0x08 2>/dev/null \ ++ | head -n 1)" + elif [ "$inner" = "6" ]; then + local req_proto_offset="72" + local req_offset="106" +@@ -288,10 +309,12 @@ verify() { + req_proto_offset="$((req_proto_offset + 4))" + req_offset="$((req_offset + 4))" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip6[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip6[$req_proto_offset] = 0x3a and \ +- ip6[$req_offset] = 0x80 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip6[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip6[$req_proto_offset] = 0x3a and \ ++ ip6[$req_offset] = 0x80 2>/dev/null \ ++ | head -n 1)" + elif [ "$inner" = "other" ]; then + local req_proto_offset="64" + local req_offset="73" +@@ -307,11 +330,13 @@ verify() { + expected_tos="0x00" + expected_ttl="64" + fi +- out="$(tcpdump --immediate-mode -p -c 1 -v -i veth0 -n \ +- ip6[$tunnel_type_offset] = $tunnel_type_proto and \ +- ip6[$req_proto_offset] = 0x08 and \ +- ip6[$((req_proto_offset + 1))] = 0x06 and \ +- ip6[$req_offset] = 0x01 2>/dev/null | head -n 1)" ++ out="$(${RUN_NS0} tcpdump --immediate-mode -p -c 1 -v \ ++ -i veth0 -n \ ++ ip6[$tunnel_type_offset] = $tunnel_type_proto and \ ++ ip6[$req_proto_offset] = 0x08 and \ ++ ip6[$((req_proto_offset + 1))] = 0x06 and \ ++ ip6[$req_offset] = 0x01 2>/dev/null \ ++ | head -n 1)" + fi + fi + kill -9 $ping_pid +@@ -351,9 +376,8 @@ verify() { + } + + cleanup() { +- ip link del veth0 2>/dev/null +- ip netns del testing 2>/dev/null +- ip link del tep0 2>/dev/null ++ ip netns del "${NS0}" 2>/dev/null ++ ip netns del "${NS1}" 2>/dev/null + } + + printf "┌────────┬───────┬───────┬──────────────┬" +-- +2.35.1 + diff --git a/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-set-ipv6-address.patch b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-set-ipv6-address.patch new file mode 100644 index 00000000000..7303f9465ac --- /dev/null +++ b/queue-6.1/selftests-net-l2_tos_ttl_inherit.sh-set-ipv6-address.patch @@ -0,0 +1,52 @@ +From 7ab6b7c24ac07a7eb678ee0571c84a73c46f9b27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Jan 2023 16:45:41 +0100 +Subject: selftests/net: l2_tos_ttl_inherit.sh: Set IPv6 addresses with + "nodad". + +From: Guillaume Nault + +[ Upstream commit e59370b2e96eb8e7e057a2a16e999ff385a3f2fb ] + +The ping command can run before DAD completes. In that case, ping may +fail and break the selftest. + +We don't need DAD here since we're working on isolated device pairs. + +Fixes: b690842d12fd ("selftests/net: test l2 tunnel TOS/TTL inheriting") +Signed-off-by: Guillaume Nault +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/l2_tos_ttl_inherit.sh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +index dca1e6f777a8..e2574b08eabc 100755 +--- a/tools/testing/selftests/net/l2_tos_ttl_inherit.sh ++++ b/tools/testing/selftests/net/l2_tos_ttl_inherit.sh +@@ -137,8 +137,8 @@ setup() { + if [ "$type" = "gre" ]; then + type="ip6gretap" + fi +- ip addr add fdd1:ced0:5d88:3fce::1/64 dev veth0 +- $ns ip addr add fdd1:ced0:5d88:3fce::2/64 dev veth1 ++ ip addr add fdd1:ced0:5d88:3fce::1/64 dev veth0 nodad ++ $ns ip addr add fdd1:ced0:5d88:3fce::2/64 dev veth1 nodad + ip link add name tep0 type $type $local_addr1 \ + remote fdd1:ced0:5d88:3fce::2 tos $test_tos ttl $test_ttl \ + $vxlan $geneve +@@ -170,8 +170,8 @@ setup() { + ip addr add 198.19.0.1/24 brd + dev ${parent}0 + $ns ip addr add 198.19.0.2/24 brd + dev ${parent}1 + elif [ "$inner" = "6" ]; then +- ip addr add fdd4:96cf:4eae:443b::1/64 dev ${parent}0 +- $ns ip addr add fdd4:96cf:4eae:443b::2/64 dev ${parent}1 ++ ip addr add fdd4:96cf:4eae:443b::1/64 dev ${parent}0 nodad ++ $ns ip addr add fdd4:96cf:4eae:443b::2/64 dev ${parent}1 nodad + fi + } + +-- +2.35.1 + diff --git a/queue-6.1/series b/queue-6.1/series index bdd578303bf..25f18e5969f 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -94,3 +94,84 @@ edac-device-fix-period-calculation-in-edac_device_reset_delay_period.patch x86-pat-fix-pat_x_mtrr_type-for-mtrr-disabled-case.patch x86-resctrl-fix-task-closid-rmid-update-race.patch x86-resctrl-fix-event-counts-regression-in-reused-rmids.patch +regulator-da9211-use-irq-handler-when-ready.patch +scsi-storvsc-fix-swiotlb-bounce-buffer-leak-in-confi.patch +scsi-mpi3mr-refer-config_scsi_mpi3mr-in-makefile.patch +scsi-ufs-core-wlun-suspend-ssu-enter-hibern8-fail-re.patch +asoc-intel-fix-sof-nau8825-link-failure.patch +asoc-intel-sof_nau8825-support-rt1015p-speaker-ampli.patch +asoc-intel-sof-nau8825-fix-module-alias-overflow.patch +drm-msm-dpu-fix-some-kernel-doc-comments.patch +drm-msm-dpu-fix-memory-leak-in-msm_mdss_parse_data_b.patch +asoc-wm8904-fix-wrong-outputs-volume-after-power-rea.patch +mtd-parsers-scpart-fix-__udivdi3-undefined-on-mips.patch +mtd-cfi-allow-building-spi-intel-standalone.patch +alsa-usb-audio-make-sure-to-stop-endpoints-before-cl.patch +alsa-usb-audio-relax-hw-constraints-for-implicit-fb-.patch +stmmac-dwmac-mediatek-remove-the-dwmac_fix_mac_speed.patch +tipc-fix-unexpected-link-reset-due-to-discovery-mess.patch +nfsd-pass-the-target-nfsd_file-to-nfsd_commit.patch +nfsd-revert-nfsd-nfsv4-close-should-release-an-nfsd_.patch +nfsd-add-an-nfsd_file_gc-flag-to-enable-nfsd_file-ga.patch +nfsd-remove-the-pages_flushed-statistic-from-filecac.patch +nfsd-reorganize-filecache.c.patch +nfsd-add-an-nfsd_file_fsync-tracepoint.patch +nfsd-rework-refcounting-in-filecache.patch +nfsd-fix-handling-of-cached-open-files-in-nfsd4_open.patch +octeontx2-af-fix-lmac-config-in-cgx_lmac_rx_tx_enabl.patch +sched-core-fix-arch_scale_freq_tick-on-tickless-syst.patch +blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch +blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch +block-factor-out-a-blk_debugfs_remove-helper.patch +block-fix-error-unwinding-in-blk_register_queue.patch +block-untangle-request_queue-refcounting-from-sysfs.patch +block-mark-blk_put_queue-as-potentially-blocking.patch +block-drop-spurious-might_sleep-from-blk_put_queue.patch +hvc-xen-lock-console-list-traversal.patch +nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch +gro-avoid-checking-for-a-failed-search.patch +gro-take-care-of-dodgy-packets.patch +af_unix-selftest-fix-the-size-of-the-parameter-to-co.patch +asoc-qcom-fix-building-apq8016-machine-driver-withou.patch +tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch +tools-nolibc-fix-the-o_-fcntl-open-macro-definitions.patch +drm-amdgpu-fix-potential-null-dereference.patch +ice-fix-potential-memory-leak-in-ice_gnss_tty_write.patch +ice-add-check-for-kzalloc.patch +drm-vmwgfx-write-the-driver-id-registers.patch +drm-vmwgfx-refactor-resource-manager-s-hashtable-to-.patch +drm-vmwgfx-remove-ttm-object-hashtable.patch +drm-vmwgfx-refactor-resource-validation-hashtable-to.patch +drm-vmwgfx-refactor-ttm-reference-object-hashtable-t.patch +drm-vmwgfx-remove-vmwgfx_hashtab.patch +drm-vmwgfx-remove-rcu-locks-from-user-resources.patch +net-sched-act_mpls-fix-warning-during-failed-attribu.patch +revert-r8169-disable-detection-of-chip-version-36.patch +net-mlx5-check-attr-pointer-validity-before-derefere.patch +net-mlx5e-tc-keep-mod-hdr-actions-after-mod-hdr-allo.patch +net-mlx5-fix-command-stats-access-after-free.patch +net-mlx5e-verify-dev-is-present-for-fix-features-ndo.patch +net-mlx5e-ipoib-block-queue-count-configuration-when.patch +net-mlx5e-ipoib-block-pkey-interfaces-with-less-rx-q.patch +net-mlx5e-ipoib-fix-child-pkey-interface-stats-on-rx.patch +net-mlx5-fix-ptp-max-frequency-adjustment-range.patch +net-mlx5e-don-t-support-encap-rules-with-gbp-option.patch +net-mlx5e-fix-macsec-ssci-attribute-handling-in-offl.patch +net-mlx5e-fix-macsec-possible-null-dereference-when-.patch +selftests-net-l2_tos_ttl_inherit.sh-set-ipv6-address.patch +selftests-net-l2_tos_ttl_inherit.sh-run-tests-in-the.patch +selftests-net-l2_tos_ttl_inherit.sh-ensure-environme.patch +octeontx2-pf-fix-resource-leakage-in-vf-driver-unbin.patch +perf-build-properly-guard-libbpf-includes.patch +perf-kmem-support-legacy-tracepoints.patch +perf-kmem-support-field-node-in-evsel__process_alloc.patch +igc-fix-pps-delta-between-two-synchronized-end-point.patch +net-lan966x-check-for-ptp-to-be-enabled-in-lan966x_p.patch +net-hns3-fix-wrong-use-of-rss-size-during-vf-rss-con.patch +bnxt-make-sure-we-return-pages-to-the-pool.patch +platform-surface-aggregator-add-missing-call-to-ssam.patch +platform-x86-amd-fix-refcount-leak-in-amd_pmc_probe.patch +alsa-usb-audio-fix-possible-null-pointer-dereference.patch +efi-fix-null-deref-in-init-error-path.patch +io_uring-lock-overflowing-for-iopoll.patch +io_uring-poll-attempt-request-issue-after-racy-poll-.patch diff --git a/queue-6.1/stmmac-dwmac-mediatek-remove-the-dwmac_fix_mac_speed.patch b/queue-6.1/stmmac-dwmac-mediatek-remove-the-dwmac_fix_mac_speed.patch new file mode 100644 index 00000000000..17f8d8bf0d9 --- /dev/null +++ b/queue-6.1/stmmac-dwmac-mediatek-remove-the-dwmac_fix_mac_speed.patch @@ -0,0 +1,81 @@ +From 80b2eb9b85e87fb17187dbef32e5f4c9144cce97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 09:07:11 +0800 +Subject: stmmac: dwmac-mediatek: remove the dwmac_fix_mac_speed + +From: Biao Huang + +[ Upstream commit c26de7507d1f5ffa5daf6a4980ef7896889691a9 ] + +In current driver, MAC will always enable 2ns delay in RGMII mode, +but that's not the correct usage. + +Remove the dwmac_fix_mac_speed() in driver, and recommend "rgmii-id" +for phy-mode in device tree. + +Fixes: f2d356a6ab71 ("stmmac: dwmac-mediatek: add support for mt8195") +Reviewed-by: Andrew Lunn +Signed-off-by: Biao Huang +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/stmicro/stmmac/dwmac-mediatek.c | 26 ------------------- + 1 file changed, 26 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c +index d42e1afb6521..2f7d8e4561d9 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c +@@ -90,7 +90,6 @@ struct mediatek_dwmac_plat_data { + struct mediatek_dwmac_variant { + int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat); + int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat); +- void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed); + + /* clock ids to be requested */ + const char * const *clk_list; +@@ -443,32 +442,9 @@ static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat) + return 0; + } + +-static void mt8195_fix_mac_speed(void *priv, unsigned int speed) +-{ +- struct mediatek_dwmac_plat_data *priv_plat = priv; +- +- if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) { +- /* prefer 2ns fixed delay which is controlled by TXC_PHASE_CTRL, +- * when link speed is 1Gbps with RGMII interface, +- * Fall back to delay macro circuit for 10/100Mbps link speed. +- */ +- if (speed == SPEED_1000) +- regmap_update_bits(priv_plat->peri_regmap, +- MT8195_PERI_ETH_CTRL0, +- MT8195_RGMII_TXC_PHASE_CTRL | +- MT8195_DLY_GTXC_ENABLE | +- MT8195_DLY_GTXC_INV | +- MT8195_DLY_GTXC_STAGES, +- MT8195_RGMII_TXC_PHASE_CTRL); +- else +- mt8195_set_delay(priv_plat); +- } +-} +- + static const struct mediatek_dwmac_variant mt8195_gmac_variant = { + .dwmac_set_phy_interface = mt8195_set_interface, + .dwmac_set_delay = mt8195_set_delay, +- .dwmac_fix_mac_speed = mt8195_fix_mac_speed, + .clk_list = mt8195_dwmac_clk_l, + .num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l), + .dma_bit_mask = 35, +@@ -619,8 +595,6 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev, + plat->bsp_priv = priv_plat; + plat->init = mediatek_dwmac_init; + plat->clks_config = mediatek_dwmac_clks_config; +- if (priv_plat->variant->dwmac_fix_mac_speed) +- plat->fix_mac_speed = priv_plat->variant->dwmac_fix_mac_speed; + + plat->safety_feat_cfg = devm_kzalloc(&pdev->dev, + sizeof(*plat->safety_feat_cfg), +-- +2.35.1 + diff --git a/queue-6.1/tipc-fix-unexpected-link-reset-due-to-discovery-mess.patch b/queue-6.1/tipc-fix-unexpected-link-reset-due-to-discovery-mess.patch new file mode 100644 index 00000000000..4c9f5777168 --- /dev/null +++ b/queue-6.1/tipc-fix-unexpected-link-reset-due-to-discovery-mess.patch @@ -0,0 +1,111 @@ +From 1b2f3c186114c3012e40a60fe45d11eec9d19ddf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 06:02:51 +0000 +Subject: tipc: fix unexpected link reset due to discovery messages + +From: Tung Nguyen + +[ Upstream commit c244c092f1ed2acfb5af3d3da81e22367d3dd733 ] + +This unexpected behavior is observed: + +node 1 | node 2 +------ | ------ +link is established | link is established +reboot | link is reset +up | send discovery message +receive discovery message | +link is established | link is established +send discovery message | + | receive discovery message + | link is reset (unexpected) + | send reset message +link is reset | + +It is due to delayed re-discovery as described in function +tipc_node_check_dest(): "this link endpoint has already reset +and re-established contact with the peer, before receiving a +discovery message from that node." + +However, commit 598411d70f85 has changed the condition for calling +tipc_node_link_down() which was the acceptance of new media address. + +This commit fixes this by restoring the old and correct behavior. + +Fixes: 598411d70f85 ("tipc: make resetting of links non-atomic") +Acked-by: Jon Maloy +Signed-off-by: Tung Nguyen +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tipc/node.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/net/tipc/node.c b/net/tipc/node.c +index 49ddc484c4fe..5e000fde8067 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -1179,8 +1179,9 @@ void tipc_node_check_dest(struct net *net, u32 addr, + bool addr_match = false; + bool sign_match = false; + bool link_up = false; ++ bool link_is_reset = false; + bool accept_addr = false; +- bool reset = true; ++ bool reset = false; + char *if_name; + unsigned long intv; + u16 session; +@@ -1200,14 +1201,14 @@ void tipc_node_check_dest(struct net *net, u32 addr, + /* Prepare to validate requesting node's signature and media address */ + l = le->link; + link_up = l && tipc_link_is_up(l); ++ link_is_reset = l && tipc_link_is_reset(l); + addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr)); + sign_match = (signature == n->signature); + + /* These three flags give us eight permutations: */ + + if (sign_match && addr_match && link_up) { +- /* All is fine. Do nothing. */ +- reset = false; ++ /* All is fine. Ignore requests. */ + /* Peer node is not a container/local namespace */ + if (!n->peer_hash_mix) + n->peer_hash_mix = hash_mixes; +@@ -1232,6 +1233,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, + */ + accept_addr = true; + *respond = true; ++ reset = true; + } else if (!sign_match && addr_match && link_up) { + /* Peer node rebooted. Two possibilities: + * - Delayed re-discovery; this link endpoint has already +@@ -1263,6 +1265,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, + n->signature = signature; + accept_addr = true; + *respond = true; ++ reset = true; + } + + if (!accept_addr) +@@ -1291,6 +1294,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, + tipc_link_fsm_evt(l, LINK_RESET_EVT); + if (n->state == NODE_FAILINGOVER) + tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); ++ link_is_reset = tipc_link_is_reset(l); + le->link = l; + n->link_cnt++; + tipc_node_calculate_timer(n, l); +@@ -1303,7 +1307,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, + memcpy(&le->maddr, maddr, sizeof(*maddr)); + exit: + tipc_node_write_unlock(n); +- if (reset && l && !tipc_link_is_reset(l)) ++ if (reset && !link_is_reset) + tipc_node_link_down(n, b->identity, false); + tipc_node_put(n); + } +-- +2.35.1 + diff --git a/queue-6.1/tools-nolibc-fix-the-o_-fcntl-open-macro-definitions.patch b/queue-6.1/tools-nolibc-fix-the-o_-fcntl-open-macro-definitions.patch new file mode 100644 index 00000000000..ae07360ae51 --- /dev/null +++ b/queue-6.1/tools-nolibc-fix-the-o_-fcntl-open-macro-definitions.patch @@ -0,0 +1,49 @@ +From cba524cff2d1415bdaa95a9a066b456c33304375 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 08:54:42 +0100 +Subject: tools/nolibc: fix the O_* fcntl/open macro definitions for riscv + +From: Willy Tarreau + +[ Upstream commit 00b18da4089330196906b9fe075c581c17eb726c ] + +When RISCV port was imported in 5.2, the O_* macros were taken with +their octal value and written as-is in hex, resulting in the getdents64() +to fail in nolibc-test. + +Fixes: 582e84f7b779 ("tool headers nolibc: add RISCV support") #5.2 +Signed-off-by: Willy Tarreau +Signed-off-by: Paul E. McKenney +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/arch-riscv.h | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h +index ba04771cb3a3..a3bdd9803f8c 100644 +--- a/tools/include/nolibc/arch-riscv.h ++++ b/tools/include/nolibc/arch-riscv.h +@@ -11,13 +11,13 @@ + #define O_RDONLY 0 + #define O_WRONLY 1 + #define O_RDWR 2 +-#define O_CREAT 0x100 +-#define O_EXCL 0x200 +-#define O_NOCTTY 0x400 +-#define O_TRUNC 0x1000 +-#define O_APPEND 0x2000 +-#define O_NONBLOCK 0x4000 +-#define O_DIRECTORY 0x200000 ++#define O_CREAT 0x40 ++#define O_EXCL 0x80 ++#define O_NOCTTY 0x100 ++#define O_TRUNC 0x200 ++#define O_APPEND 0x400 ++#define O_NONBLOCK 0x800 ++#define O_DIRECTORY 0x10000 + + struct sys_stat_struct { + unsigned long st_dev; /* Device. */ +-- +2.35.1 + diff --git a/queue-6.1/tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch b/queue-6.1/tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch new file mode 100644 index 00000000000..582ae00b3a7 --- /dev/null +++ b/queue-6.1/tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch @@ -0,0 +1,80 @@ +From 74c6ada39b016d83095dea69585ec5455f9e9fff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 08:54:39 +0100 +Subject: tools/nolibc: restore mips branch ordering in the _start block + +From: Willy Tarreau + +[ Upstream commit 184177c3d6e023da934761e198c281344d7dd65b ] + +Depending on the compiler used and the optimization options, the sbrk() +test was crashing, both on real hardware (mips-24kc) and in qemu. One +such example is kernel.org toolchain in version 11.3 optimizing at -Os. + +Inspecting the sys_brk() call shows the following code: + + 0040047c : + 40047c: 24020fcd li v0,4045 + 400480: 27bdffe0 addiu sp,sp,-32 + 400484: 0000000c syscall + 400488: 27bd0020 addiu sp,sp,32 + 40048c: 10e00001 beqz a3,400494 + 400490: 00021023 negu v0,v0 + 400494: 03e00008 jr ra + +It is obviously wrong, the "negu" instruction is placed in beqz's +delayed slot, and worse, there's no nop nor instruction after the +return, so the next function's first instruction (addiu sip,sip,-32) +will also be executed as part of the delayed slot that follows the +return. + +This is caused by the ".set noreorder" directive in the _start block, +that applies to the whole program. The compiler emits code without the +delayed slots and relies on the compiler to swap instructions when this +option is not set. Removing the option would require to change the +startup code in a way that wouldn't make it look like the resulting +code, which would not be easy to debug. Instead let's just save the +default ordering before changing it, and restore it at the end of the +_start block. Now the code is correct: + + 0040047c : + 40047c: 24020fcd li v0,4045 + 400480: 27bdffe0 addiu sp,sp,-32 + 400484: 0000000c syscall + 400488: 10e00002 beqz a3,400494 + 40048c: 27bd0020 addiu sp,sp,32 + 400490: 00021023 negu v0,v0 + 400494: 03e00008 jr ra + 400498: 00000000 nop + +Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") #5.0 +Signed-off-by: Willy Tarreau +Signed-off-by: Paul E. McKenney +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/arch-mips.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h +index 5fc5b8029bff..7380093ba9e7 100644 +--- a/tools/include/nolibc/arch-mips.h ++++ b/tools/include/nolibc/arch-mips.h +@@ -192,6 +192,7 @@ struct sys_stat_struct { + __asm__ (".section .text\n" + ".weak __start\n" + ".set nomips16\n" ++ ".set push\n" + ".set noreorder\n" + ".option pic0\n" + ".ent __start\n" +@@ -210,6 +211,7 @@ __asm__ (".section .text\n" + "li $v0, 4001\n" // NR_exit == 4001 + "syscall\n" + ".end __start\n" ++ ".set pop\n" + ""); + + #endif // _NOLIBC_ARCH_MIPS_H +-- +2.35.1 + -- 2.47.3