+++ /dev/null
-From 824dc7ddba91e1469044597d361d97df752b4043 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 12 Oct 2021 11:21:36 +0300
-Subject: btrfs: pull up qgroup checks from delayed-ref core to init time
-
-From: Nikolay Borisov <nborisov@suse.com>
-
-[ Upstream commit 681145d4acf4ecba052432f2e466b120c3739d01 ]
-
-Instead of checking whether qgroup processing for a dealyed ref has to
-happen in the core of delayed ref, simply pull the check at init time of
-respective delayed ref structures. This eliminates the final use of
-real_root in delayed-ref core paving the way to making this member
-optional.
-
-Signed-off-by: Nikolay Borisov <nborisov@suse.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Stable-dep-of: cef7820d6abf ("btrfs: fix missed extent on fsync after dropping extent maps")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/delayed-ref.c | 4 ----
- fs/btrfs/delayed-ref.h | 11 +++++++++++
- fs/btrfs/extent-tree.c | 5 -----
- fs/btrfs/inode.c | 1 -
- fs/btrfs/relocation.c | 7 -------
- 5 files changed, 11 insertions(+), 17 deletions(-)
-
-diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
-index 53a80163c1d7..5f4b58d8d101 100644
---- a/fs/btrfs/delayed-ref.c
-+++ b/fs/btrfs/delayed-ref.c
-@@ -921,8 +921,6 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
- }
-
- if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
-- is_fstree(generic_ref->real_root) &&
-- is_fstree(generic_ref->tree_ref.owning_root) &&
- !generic_ref->skip_qgroup) {
- record = kzalloc(sizeof(*record), GFP_NOFS);
- if (!record) {
-@@ -1027,8 +1025,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
- }
-
- if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
-- is_fstree(ref_root) &&
-- is_fstree(generic_ref->real_root) &&
- !generic_ref->skip_qgroup) {
- record = kzalloc(sizeof(*record), GFP_NOFS);
- if (!record) {
-diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
-index 8ab79def8e98..7a0a2b21975d 100644
---- a/fs/btrfs/delayed-ref.h
-+++ b/fs/btrfs/delayed-ref.h
-@@ -279,6 +279,12 @@ static inline void btrfs_init_tree_ref(struct btrfs_ref *generic_ref,
- generic_ref->tree_ref.level = level;
- generic_ref->tree_ref.owning_root = root;
- generic_ref->type = BTRFS_REF_METADATA;
-+ if (skip_qgroup || !(is_fstree(root) &&
-+ (!mod_root || is_fstree(mod_root))))
-+ generic_ref->skip_qgroup = true;
-+ else
-+ generic_ref->skip_qgroup = false;
-+
- }
-
- static inline void btrfs_init_data_ref(struct btrfs_ref *generic_ref,
-@@ -292,6 +298,11 @@ static inline void btrfs_init_data_ref(struct btrfs_ref *generic_ref,
- generic_ref->data_ref.ino = ino;
- generic_ref->data_ref.offset = offset;
- generic_ref->type = BTRFS_REF_DATA;
-+ if (skip_qgroup || !(is_fstree(ref_root) &&
-+ (!mod_root || is_fstree(mod_root))))
-+ generic_ref->skip_qgroup = true;
-+ else
-+ generic_ref->skip_qgroup = false;
- }
-
- static inline struct btrfs_delayed_extent_op *
-diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
-index 8419315a59ff..9fdb880f900e 100644
---- a/fs/btrfs/extent-tree.c
-+++ b/fs/btrfs/extent-tree.c
-@@ -2437,11 +2437,9 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
- key.offset -= btrfs_file_extent_offset(buf, fi);
- btrfs_init_generic_ref(&generic_ref, action, bytenr,
- num_bytes, parent);
-- generic_ref.real_root = root->root_key.objectid;
- btrfs_init_data_ref(&generic_ref, ref_root, key.objectid,
- key.offset, root->root_key.objectid,
- for_reloc);
-- generic_ref.skip_qgroup = for_reloc;
- if (inc)
- ret = btrfs_inc_extent_ref(trans, &generic_ref);
- else
-@@ -2453,10 +2451,8 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
- num_bytes = fs_info->nodesize;
- btrfs_init_generic_ref(&generic_ref, action, bytenr,
- num_bytes, parent);
-- generic_ref.real_root = root->root_key.objectid;
- btrfs_init_tree_ref(&generic_ref, level - 1, ref_root,
- root->root_key.objectid, for_reloc);
-- generic_ref.skip_qgroup = for_reloc;
- if (inc)
- ret = btrfs_inc_extent_ref(trans, &generic_ref);
- else
-@@ -4922,7 +4918,6 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
-
- btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_EXTENT,
- ins.objectid, ins.offset, parent);
-- generic_ref.real_root = root->root_key.objectid;
- btrfs_init_tree_ref(&generic_ref, level, root_objectid,
- root->root_key.objectid, false);
- btrfs_ref_tree_mod(fs_info, &generic_ref);
-diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
-index f8a01964a216..f9df0000cd88 100644
---- a/fs/btrfs/inode.c
-+++ b/fs/btrfs/inode.c
-@@ -4974,7 +4974,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
-
- btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
- extent_start, extent_num_bytes, 0);
-- ref.real_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- ino, extent_offset,
- root->root_key.objectid, false);
-diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
-index becf3396d533..374c5353fe65 100644
---- a/fs/btrfs/relocation.c
-+++ b/fs/btrfs/relocation.c
-@@ -1145,7 +1145,6 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
- key.offset -= btrfs_file_extent_offset(leaf, fi);
- btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
- num_bytes, parent);
-- ref.real_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- key.objectid, key.offset,
- root->root_key.objectid, false);
-@@ -1157,7 +1156,6 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
-
- btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
- num_bytes, parent);
-- ref.real_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- key.objectid, key.offset,
- root->root_key.objectid, false);
-@@ -1371,7 +1369,6 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
-
- btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr,
- blocksize, path->nodes[level]->start);
-- ref.skip_qgroup = true;
- btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid,
- 0, true);
- ret = btrfs_inc_extent_ref(trans, &ref);
-@@ -1381,7 +1378,6 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
- }
- btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
- blocksize, 0);
-- ref.skip_qgroup = true;
- btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid, 0,
- true);
- ret = btrfs_inc_extent_ref(trans, &ref);
-@@ -1394,7 +1390,6 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
- blocksize, path->nodes[level]->start);
- btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid,
- 0, true);
-- ref.skip_qgroup = true;
- ret = btrfs_free_extent(trans, &ref);
- if (ret) {
- btrfs_abort_transaction(trans, ret);
-@@ -1405,7 +1400,6 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
- blocksize, 0);
- btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid,
- 0, true);
-- ref.skip_qgroup = true;
- ret = btrfs_free_extent(trans, &ref);
- if (ret) {
- btrfs_abort_transaction(trans, ret);
-@@ -2481,7 +2475,6 @@ static int do_relocation(struct btrfs_trans_handle *trans,
- btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF,
- node->eb->start, blocksize,
- upper->eb->start);
-- ref.real_root = root->root_key.objectid;
- btrfs_init_tree_ref(&ref, node->level,
- btrfs_header_owner(upper->eb),
- root->root_key.objectid, false);
---
-2.35.1
-
+++ /dev/null
-From e17ece4ef86c5ef5191c06eaa8bba72235325f44 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 12 Oct 2021 11:21:33 +0300
-Subject: btrfs: rename root fields in delayed refs structs
-
-From: Nikolay Borisov <nborisov@suse.com>
-
-[ Upstream commit 113479d5b8eb20d685da63b89e97b6ebb4206f15 ]
-
-Both data and metadata delayed ref structures have fields named
-root/ref_root respectively. Those are somewhat cryptic and don't really
-convey the real meaning. In fact those roots are really the original
-owners of the respective block (i.e in case of a snapshot a data delayed
-ref will contain the original root that owns the given block). Rename
-those fields accordingly and adjust comments.
-
-Signed-off-by: Nikolay Borisov <nborisov@suse.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Stable-dep-of: cef7820d6abf ("btrfs: fix missed extent on fsync after dropping extent maps")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/delayed-ref.c | 13 +++++++------
- fs/btrfs/delayed-ref.h | 12 ++++++------
- fs/btrfs/extent-tree.c | 10 +++++-----
- fs/btrfs/ref-verify.c | 4 ++--
- 4 files changed, 20 insertions(+), 19 deletions(-)
-
-diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
-index ca848b183474..53a80163c1d7 100644
---- a/fs/btrfs/delayed-ref.c
-+++ b/fs/btrfs/delayed-ref.c
-@@ -922,7 +922,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
-
- if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
- is_fstree(generic_ref->real_root) &&
-- is_fstree(generic_ref->tree_ref.root) &&
-+ is_fstree(generic_ref->tree_ref.owning_root) &&
- !generic_ref->skip_qgroup) {
- record = kzalloc(sizeof(*record), GFP_NOFS);
- if (!record) {
-@@ -938,14 +938,15 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
- ref_type = BTRFS_TREE_BLOCK_REF_KEY;
-
- init_delayed_ref_common(fs_info, &ref->node, bytenr, num_bytes,
-- generic_ref->tree_ref.root, action, ref_type);
-- ref->root = generic_ref->tree_ref.root;
-+ generic_ref->tree_ref.owning_root, action,
-+ ref_type);
-+ ref->root = generic_ref->tree_ref.owning_root;
- ref->parent = parent;
- ref->level = level;
-
- init_delayed_ref_head(head_ref, record, bytenr, num_bytes,
-- generic_ref->tree_ref.root, 0, action, false,
-- is_system);
-+ generic_ref->tree_ref.owning_root, 0, action,
-+ false, is_system);
- head_ref->extent_op = extent_op;
-
- delayed_refs = &trans->transaction->delayed_refs;
-@@ -997,7 +998,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
- u64 bytenr = generic_ref->bytenr;
- u64 num_bytes = generic_ref->len;
- u64 parent = generic_ref->parent;
-- u64 ref_root = generic_ref->data_ref.ref_root;
-+ u64 ref_root = generic_ref->data_ref.owning_root;
- u64 owner = generic_ref->data_ref.ino;
- u64 offset = generic_ref->data_ref.offset;
- u8 ref_type;
-diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
-index 31266ba1d430..8ab79def8e98 100644
---- a/fs/btrfs/delayed-ref.h
-+++ b/fs/btrfs/delayed-ref.h
-@@ -186,8 +186,8 @@ enum btrfs_ref_type {
- struct btrfs_data_ref {
- /* For EXTENT_DATA_REF */
-
-- /* Root which refers to this data extent */
-- u64 ref_root;
-+ /* Original root this data extent belongs to */
-+ u64 owning_root;
-
- /* Inode which refers to this data extent */
- u64 ino;
-@@ -210,11 +210,11 @@ struct btrfs_tree_ref {
- int level;
-
- /*
-- * Root which refers to this tree block.
-+ * Root which owns this tree block.
- *
- * For TREE_BLOCK_REF (skinny metadata, either inline or keyed)
- */
-- u64 root;
-+ u64 owning_root;
-
- /* For non-skinny metadata, no special member needed */
- };
-@@ -277,7 +277,7 @@ static inline void btrfs_init_tree_ref(struct btrfs_ref *generic_ref,
- if (!generic_ref->real_root)
- generic_ref->real_root = root;
- generic_ref->tree_ref.level = level;
-- generic_ref->tree_ref.root = root;
-+ generic_ref->tree_ref.owning_root = root;
- generic_ref->type = BTRFS_REF_METADATA;
- }
-
-@@ -288,7 +288,7 @@ static inline void btrfs_init_data_ref(struct btrfs_ref *generic_ref,
- /* If @real_root not set, use @root as fallback */
- if (!generic_ref->real_root)
- generic_ref->real_root = ref_root;
-- generic_ref->data_ref.ref_root = ref_root;
-+ generic_ref->data_ref.owning_root = ref_root;
- generic_ref->data_ref.ino = ino;
- generic_ref->data_ref.offset = offset;
- generic_ref->type = BTRFS_REF_DATA;
-diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
-index b90e9aa24005..8419315a59ff 100644
---- a/fs/btrfs/extent-tree.c
-+++ b/fs/btrfs/extent-tree.c
-@@ -1396,7 +1396,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
- ASSERT(generic_ref->type != BTRFS_REF_NOT_SET &&
- generic_ref->action);
- BUG_ON(generic_ref->type == BTRFS_REF_METADATA &&
-- generic_ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID);
-+ generic_ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID);
-
- if (generic_ref->type == BTRFS_REF_METADATA)
- ret = btrfs_add_delayed_tree_ref(trans, generic_ref, NULL);
-@@ -3362,9 +3362,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
- * tree, just update pinning info and exit early.
- */
- if ((ref->type == BTRFS_REF_METADATA &&
-- ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID) ||
-+ ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID) ||
- (ref->type == BTRFS_REF_DATA &&
-- ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)) {
-+ ref->data_ref.owning_root == BTRFS_TREE_LOG_OBJECTID)) {
- /* unlocks the pinned mutex */
- btrfs_pin_extent(trans, ref->bytenr, ref->len, 1);
- ret = 0;
-@@ -3375,9 +3375,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
- }
-
- if (!((ref->type == BTRFS_REF_METADATA &&
-- ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID) ||
-+ ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID) ||
- (ref->type == BTRFS_REF_DATA &&
-- ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)))
-+ ref->data_ref.owning_root == BTRFS_TREE_LOG_OBJECTID)))
- btrfs_ref_tree_mod(fs_info, ref);
-
- return ret;
-diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c
-index d2062d5f71dd..e2b9f8616501 100644
---- a/fs/btrfs/ref-verify.c
-+++ b/fs/btrfs/ref-verify.c
-@@ -678,10 +678,10 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
-
- if (generic_ref->type == BTRFS_REF_METADATA) {
- if (!parent)
-- ref_root = generic_ref->tree_ref.root;
-+ ref_root = generic_ref->tree_ref.owning_root;
- owner = generic_ref->tree_ref.level;
- } else if (!parent) {
-- ref_root = generic_ref->data_ref.ref_root;
-+ ref_root = generic_ref->data_ref.owning_root;
- owner = generic_ref->data_ref.ino;
- offset = generic_ref->data_ref.offset;
- }
---
-2.35.1
-
+++ /dev/null
-From c05a282e8fd0cf9ee7f350e8f6c6debb1ee45160 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 7 Oct 2022 20:31:49 +0530
-Subject: drm/amd/display: explicitly disable psr_feature_enable appropriately
-
-From: Shirish S <shirish.s@amd.com>
-
-[ Upstream commit 6094b9136ca9038b61e9c4b5d25cd5512ce50b34 ]
-
-[Why]
-If psr_feature_enable is set to true by default, it continues to be enabled
-for non capable links.
-
-[How]
-explicitly disable the feature on links that are not capable of the same.
-
-Fixes: 8c322309e48e9 ("drm/amd/display: Enable PSR")
-Signed-off-by: Shirish S <shirish.s@amd.com>
-Reviewed-by: Leo Li <sunpeng.li@amd.com>
-Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
-Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-Cc: stable@vger.kernel.org # 5.15+
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-index 39eb6452b986..393369aa3d03 100644
---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-@@ -101,11 +101,15 @@ static bool link_supports_psrsu(struct dc_link *link)
- */
- void amdgpu_dm_set_psr_caps(struct dc_link *link)
- {
-- if (!(link->connector_signal & SIGNAL_TYPE_EDP))
-+ if (!(link->connector_signal & SIGNAL_TYPE_EDP)) {
-+ link->psr_settings.psr_feature_enabled = false;
- return;
-+ }
-
-- if (link->type == dc_connection_none)
-+ if (link->type == dc_connection_none) {
-+ link->psr_settings.psr_feature_enabled = false;
- return;
-+ }
-
- if (!link_get_psr_caps(link)) {
- DRM_ERROR("amdgpu: Failed to read PSR Caps!\n");
---
-2.35.1
-
+++ /dev/null
-From 5e41019c79e6b8d506c859ca4c15c3fba06d5a29 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 10 Dec 2021 15:04:02 -0800
-Subject: drm/amd/display: parse and check PSR SU caps
-
-From: Mikita Lipski <mikita.lipski@amd.com>
-
-[ Upstream commit cd9a0d026baa10c75688908556b3af218bc4ddad ]
-
-[why]
-Adding a function to read PSR capabilities
-and ALPM capabilities.
-Also adding a helper function to validate if
-the sink and the driver support PSR SU.
-[how]
-- isolated all PSR and ALPM reading calls to a separate funciton
-- set all required PSR caps
-- added a helper function to check if PSR SU is supported by sink
-and the driver
-
-Reviewed-by: Roman Li <Roman.Li@amd.com>
-Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
-Acked-by: Pavle Kotarac <Pavle.Kotarac@amd.com>
-Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
-Signed-off-by: Mikita Lipski <mikita.lipski@amd.com>
-Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-Stable-dep-of: 6094b9136ca9 ("drm/amd/display: explicitly disable psr_feature_enable appropriately")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 101 +++++++++++++++---
- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 9 ++
- drivers/gpu/drm/amd/display/dc/dc_types.h | 1 +
- 3 files changed, 98 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-index 7072fb2ec07f..39eb6452b986 100644
---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
-@@ -26,6 +26,73 @@
- #include "amdgpu_dm_psr.h"
- #include "dc.h"
- #include "dm_helpers.h"
-+#include "amdgpu_dm.h"
-+
-+static bool link_get_psr_caps(struct dc_link *link)
-+{
-+ uint8_t psr_dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
-+ uint8_t edp_rev_dpcd_data;
-+
-+
-+
-+ if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
-+ psr_dpcd_data, sizeof(psr_dpcd_data)))
-+ return false;
-+
-+ if (!dm_helpers_dp_read_dpcd(NULL, link, DP_EDP_DPCD_REV,
-+ &edp_rev_dpcd_data, sizeof(edp_rev_dpcd_data)))
-+ return false;
-+
-+ link->dpcd_caps.psr_caps.psr_version = psr_dpcd_data[0];
-+ link->dpcd_caps.psr_caps.edp_revision = edp_rev_dpcd_data;
-+
-+#ifdef CONFIG_DRM_AMD_DC_DCN
-+ if (link->dpcd_caps.psr_caps.psr_version > 0x1) {
-+ uint8_t alpm_dpcd_data;
-+ uint8_t su_granularity_dpcd_data;
-+
-+ if (!dm_helpers_dp_read_dpcd(NULL, link, DP_RECEIVER_ALPM_CAP,
-+ &alpm_dpcd_data, sizeof(alpm_dpcd_data)))
-+ return false;
-+
-+ if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR2_SU_Y_GRANULARITY,
-+ &su_granularity_dpcd_data, sizeof(su_granularity_dpcd_data)))
-+ return false;
-+
-+ link->dpcd_caps.psr_caps.y_coordinate_required = psr_dpcd_data[1] & DP_PSR2_SU_Y_COORDINATE_REQUIRED;
-+ link->dpcd_caps.psr_caps.su_granularity_required = psr_dpcd_data[1] & DP_PSR2_SU_GRANULARITY_REQUIRED;
-+
-+ link->dpcd_caps.psr_caps.alpm_cap = alpm_dpcd_data & DP_ALPM_CAP;
-+ link->dpcd_caps.psr_caps.standby_support = alpm_dpcd_data & (1 << 1);
-+
-+ link->dpcd_caps.psr_caps.su_y_granularity = su_granularity_dpcd_data;
-+ }
-+#endif
-+ return true;
-+}
-+
-+#ifdef CONFIG_DRM_AMD_DC_DCN
-+static bool link_supports_psrsu(struct dc_link *link)
-+{
-+ struct dc *dc = link->ctx->dc;
-+
-+ if (!dc->caps.dmcub_support)
-+ return false;
-+
-+ if (dc->ctx->dce_version < DCN_VERSION_3_1)
-+ return false;
-+
-+ if (!link->dpcd_caps.psr_caps.alpm_cap ||
-+ !link->dpcd_caps.psr_caps.y_coordinate_required)
-+ return false;
-+
-+ if (link->dpcd_caps.psr_caps.su_granularity_required &&
-+ !link->dpcd_caps.psr_caps.su_y_granularity)
-+ return false;
-+
-+ return true;
-+}
-+#endif
-
- /*
- * amdgpu_dm_set_psr_caps() - set link psr capabilities
-@@ -34,26 +101,34 @@
- */
- void amdgpu_dm_set_psr_caps(struct dc_link *link)
- {
-- uint8_t dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
--
- if (!(link->connector_signal & SIGNAL_TYPE_EDP))
- return;
-+
- if (link->type == dc_connection_none)
- return;
-- if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
-- dpcd_data, sizeof(dpcd_data))) {
-- link->dpcd_caps.psr_caps.psr_version = dpcd_data[0];
--
-- if (dpcd_data[0] == 0) {
-- link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
-- link->psr_settings.psr_feature_enabled = false;
-- } else {
-+
-+ if (!link_get_psr_caps(link)) {
-+ DRM_ERROR("amdgpu: Failed to read PSR Caps!\n");
-+ return;
-+ }
-+
-+ if (link->dpcd_caps.psr_caps.psr_version == 0) {
-+ link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
-+ link->psr_settings.psr_feature_enabled = false;
-+
-+ } else {
-+#ifdef CONFIG_DRM_AMD_DC_DCN
-+ if (link_supports_psrsu(link))
-+ link->psr_settings.psr_version = DC_PSR_VERSION_SU_1;
-+ else
-+#endif
- link->psr_settings.psr_version = DC_PSR_VERSION_1;
-- link->psr_settings.psr_feature_enabled = true;
-- }
-
-- DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled);
-+ link->psr_settings.psr_feature_enabled = true;
- }
-+
-+ DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled);
-+
- }
-
- /*
-diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
-index 4f54bde1bb1c..6d0dc178fe53 100644
---- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
-+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
-@@ -756,6 +756,15 @@ struct psr_caps {
- unsigned char psr_version;
- unsigned int psr_rfb_setup_time;
- bool psr_exit_link_training_required;
-+ unsigned char edp_revision;
-+ unsigned char support_ver;
-+ bool su_granularity_required;
-+ bool y_coordinate_required;
-+ uint8_t su_y_granularity;
-+ bool alpm_cap;
-+ bool standby_support;
-+ uint8_t rate_control_caps;
-+ unsigned int psr_power_opt_flag;
- };
-
- #endif /* DC_DP_TYPES_H */
-diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
-index c1532930169b..018e132dbedf 100644
---- a/drivers/gpu/drm/amd/display/dc/dc_types.h
-+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
-@@ -928,6 +928,7 @@ enum dc_gpu_mem_alloc_type {
-
- enum dc_psr_version {
- DC_PSR_VERSION_1 = 0,
-+ DC_PSR_VERSION_SU_1 = 1,
- DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF,
- };
-
---
-2.35.1
-
+++ /dev/null
-From 023f0bf44580af3a3a4133f865e30cf139951ba7 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 15 Oct 2021 10:21:24 -0700
-Subject: perf parse-events: Add const to evsel name
-
-From: Ian Rogers <irogers@google.com>
-
-[ Upstream commit 8e8bbfb311a26a17834f1839e15e2c29ea5e58c6 ]
-
-The evsel name is strdup-ed before assignment and so can be const.
-
-A later change will add another similar string.
-
-Using const makes it clearer that these are not out arguments.
-
-Signed-off-by: Ian Rogers <irogers@google.com>
-Acked-by: Andi Kleen <ak@linux.intel.com>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
-Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-Cc: Andrew Kilroy <andrew.kilroy@arm.com>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Cc: Changbin Du <changbin.du@intel.com>
-Cc: Denys Zagorui <dzagorui@cisco.com>
-Cc: Fabian Hemmer <copy@copy.sh>
-Cc: Felix Fietkau <nbd@nbd.name>
-Cc: Heiko Carstens <hca@linux.ibm.com>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Jacob Keller <jacob.e.keller@intel.com>
-Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
-Cc: Jin Yao <yao.jin@linux.intel.com>
-Cc: Jiri Olsa <jolsa@redhat.com>
-Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
-Cc: John Garry <john.garry@huawei.com>
-Cc: Kajol Jain <kjain@linux.ibm.com>
-Cc: Kan Liang <kan.liang@linux.intel.com>
-Cc: Kees Kook <keescook@chromium.org>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Namhyung Kim <namhyung@kernel.org>
-Cc: Nicholas Fraser <nfraser@codeweavers.com>
-Cc: Nick Desaulniers <ndesaulniers@google.com>
-Cc: Paul Clarke <pc@us.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Riccardo Mancini <rickyman7@gmail.com>
-Cc: Sami Tolvanen <samitolvanen@google.com>
-Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
-Cc: Song Liu <songliubraving@fb.com>
-Cc: Stephane Eranian <eranian@google.com>
-Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
-Cc: Thomas Richter <tmricht@linux.ibm.com>
-Cc: Wan Jiabing <wanjiabing@vivo.com>
-Cc: Zhen Lei <thunder.leizhen@huawei.com>
-Link: https://lore.kernel.org/r/20211015172132.1162559-14-irogers@google.com
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Stable-dep-of: e552b7be12ed ("perf: Skip and warn on unknown format 'configN' attrs")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- tools/perf/util/parse-events-hybrid.c | 15 +++++++++------
- tools/perf/util/parse-events-hybrid.h | 6 ++++--
- tools/perf/util/parse-events.c | 15 ++++++++-------
- tools/perf/util/parse-events.h | 7 ++++---
- tools/perf/util/pmu.c | 2 +-
- tools/perf/util/pmu.h | 2 +-
- 6 files changed, 27 insertions(+), 20 deletions(-)
-
-diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
-index b234d95fb10a..7e44deee1343 100644
---- a/tools/perf/util/parse-events-hybrid.c
-+++ b/tools/perf/util/parse-events-hybrid.c
-@@ -38,7 +38,7 @@ static void config_hybrid_attr(struct perf_event_attr *attr,
-
- static int create_event_hybrid(__u32 config_type, int *idx,
- struct list_head *list,
-- struct perf_event_attr *attr, char *name,
-+ struct perf_event_attr *attr, const char *name,
- struct list_head *config_terms,
- struct perf_pmu *pmu)
- {
-@@ -70,7 +70,7 @@ static int pmu_cmp(struct parse_events_state *parse_state,
-
- static int add_hw_hybrid(struct parse_events_state *parse_state,
- struct list_head *list, struct perf_event_attr *attr,
-- char *name, struct list_head *config_terms)
-+ const char *name, struct list_head *config_terms)
- {
- struct perf_pmu *pmu;
- int ret;
-@@ -94,7 +94,8 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
- }
-
- static int create_raw_event_hybrid(int *idx, struct list_head *list,
-- struct perf_event_attr *attr, char *name,
-+ struct perf_event_attr *attr,
-+ const char *name,
- struct list_head *config_terms,
- struct perf_pmu *pmu)
- {
-@@ -113,7 +114,7 @@ static int create_raw_event_hybrid(int *idx, struct list_head *list,
-
- static int add_raw_hybrid(struct parse_events_state *parse_state,
- struct list_head *list, struct perf_event_attr *attr,
-- char *name, struct list_head *config_terms)
-+ const char *name, struct list_head *config_terms)
- {
- struct perf_pmu *pmu;
- int ret;
-@@ -138,7 +139,8 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
- int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
- struct list_head *list,
- struct perf_event_attr *attr,
-- char *name, struct list_head *config_terms,
-+ const char *name,
-+ struct list_head *config_terms,
- bool *hybrid)
- {
- *hybrid = false;
-@@ -159,7 +161,8 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
- }
-
- int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
-- struct perf_event_attr *attr, char *name,
-+ struct perf_event_attr *attr,
-+ const char *name,
- struct list_head *config_terms,
- bool *hybrid,
- struct parse_events_state *parse_state)
-diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
-index f33bd67aa851..25a4a4f73f3a 100644
---- a/tools/perf/util/parse-events-hybrid.h
-+++ b/tools/perf/util/parse-events-hybrid.h
-@@ -11,11 +11,13 @@
- int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
- struct list_head *list,
- struct perf_event_attr *attr,
-- char *name, struct list_head *config_terms,
-+ const char *name,
-+ struct list_head *config_terms,
- bool *hybrid);
-
- int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
-- struct perf_event_attr *attr, char *name,
-+ struct perf_event_attr *attr,
-+ const char *name,
- struct list_head *config_terms,
- bool *hybrid,
- struct parse_events_state *parse_state);
-diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
-index b93a36ffeb9e..aaeebf0752b7 100644
---- a/tools/perf/util/parse-events.c
-+++ b/tools/perf/util/parse-events.c
-@@ -347,7 +347,7 @@ static int parse_events__is_name_term(struct parse_events_term *term)
- return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
- }
-
--static char *get_config_name(struct list_head *head_terms)
-+static const char *get_config_name(struct list_head *head_terms)
- {
- struct parse_events_term *term;
-
-@@ -365,7 +365,7 @@ static struct evsel *
- __add_event(struct list_head *list, int *idx,
- struct perf_event_attr *attr,
- bool init_attr,
-- char *name, struct perf_pmu *pmu,
-+ const char *name, struct perf_pmu *pmu,
- struct list_head *config_terms, bool auto_merge_stats,
- const char *cpu_list)
- {
-@@ -404,14 +404,14 @@ __add_event(struct list_head *list, int *idx,
- }
-
- struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
-- char *name, struct perf_pmu *pmu)
-+ const char *name, struct perf_pmu *pmu)
- {
- return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
- NULL);
- }
-
- static int add_event(struct list_head *list, int *idx,
-- struct perf_event_attr *attr, char *name,
-+ struct perf_event_attr *attr, const char *name,
- struct list_head *config_terms)
- {
- return __add_event(list, idx, attr, true, name, NULL, config_terms,
-@@ -474,7 +474,8 @@ int parse_events_add_cache(struct list_head *list, int *idx,
- {
- struct perf_event_attr attr;
- LIST_HEAD(config_terms);
-- char name[MAX_NAME_LEN], *config_name;
-+ char name[MAX_NAME_LEN];
-+ const char *config_name;
- int cache_type = -1, cache_op = -1, cache_result = -1;
- char *op_result[2] = { op_result1, op_result2 };
- int i, n, ret;
-@@ -2038,7 +2039,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
- return 0;
- }
-
--int parse_events_name(struct list_head *list, char *name)
-+int parse_events_name(struct list_head *list, const char *name)
- {
- struct evsel *evsel;
-
-@@ -3295,7 +3296,7 @@ char *parse_events_formats_error_string(char *additional_terms)
-
- struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
- struct perf_event_attr *attr,
-- char *name, struct perf_pmu *pmu,
-+ const char *name, struct perf_pmu *pmu,
- struct list_head *config_terms)
- {
- return __add_event(list, idx, attr, true, name, pmu,
-diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
-index bf6e41aa9b6a..6ef506c1b29e 100644
---- a/tools/perf/util/parse-events.h
-+++ b/tools/perf/util/parse-events.h
-@@ -162,7 +162,7 @@ void parse_events_terms__purge(struct list_head *terms);
- void parse_events__clear_array(struct parse_events_array *a);
- int parse_events__modifier_event(struct list_head *list, char *str, bool add);
- int parse_events__modifier_group(struct list_head *list, char *event_mod);
--int parse_events_name(struct list_head *list, char *name);
-+int parse_events_name(struct list_head *list, const char *name);
- int parse_events_add_tracepoint(struct list_head *list, int *idx,
- const char *sys, const char *event,
- struct parse_events_error *error,
-@@ -200,7 +200,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
- bool use_alias);
-
- struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
-- char *name, struct perf_pmu *pmu);
-+ const char *name, struct perf_pmu *pmu);
-
- int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
- char *str,
-@@ -267,7 +267,8 @@ int perf_pmu__test_parse_init(void);
-
- struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
- struct perf_event_attr *attr,
-- char *name, struct perf_pmu *pmu,
-+ const char *name,
-+ struct perf_pmu *pmu,
- struct list_head *config_terms);
-
- #endif /* __PERF_PARSE_EVENTS_H */
-diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
-index bdabd62170d2..c647b3633d1d 100644
---- a/tools/perf/util/pmu.c
-+++ b/tools/perf/util/pmu.c
-@@ -1906,7 +1906,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu)
- }
-
- void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
-- char *name)
-+ const char *name)
- {
- struct perf_pmu_format *format;
- __u64 masks = 0, bits;
-diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
-index 394898b07fd9..dd0736de32c8 100644
---- a/tools/perf/util/pmu.h
-+++ b/tools/perf/util/pmu.h
-@@ -134,7 +134,7 @@ int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
- int perf_pmu__caps_parse(struct perf_pmu *pmu);
-
- void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
-- char *name);
-+ const char *name);
-
- bool perf_pmu__has_hybrid(void);
- int perf_pmu__match(char *pattern, char *name, char *tok);
---
-2.35.1
-
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- tools/perf/util/parse-events.c | 3 +++
- tools/perf/util/pmu.c | 17 +++++++++++++++++
- tools/perf/util/pmu.h | 2 ++
- tools/perf/util/pmu.l | 2 --
- tools/perf/util/pmu.y | 15 ++++-----------
+ tools/perf/util/parse-events.c | 3 +++
+ tools/perf/util/pmu.c | 17 +++++++++++++++++
+ tools/perf/util/pmu.h | 2 ++
+ tools/perf/util/pmu.l | 2 --
+ tools/perf/util/pmu.y | 15 ++++-----------
5 files changed, 26 insertions(+), 13 deletions(-)
-diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
-index aaeebf0752b7..b2804e65f93a 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
-@@ -373,6 +373,9 @@ __add_event(struct list_head *list, int *idx,
+@@ -373,6 +373,9 @@ __add_event(struct list_head *list, int
struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
if (pmu && attr->type == PERF_TYPE_RAW)
perf_pmu__warn_invalid_config(pmu, attr->config, name);
-diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
-index c647b3633d1d..988aae2cbdc3 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
-@@ -1048,6 +1048,23 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name)
+@@ -1048,6 +1048,23 @@ err:
return NULL;
}
static struct perf_pmu *pmu_find(const char *name)
{
struct perf_pmu *pmu;
-diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
-index dd0736de32c8..b621c9f9e104 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -17,6 +17,7 @@ enum {
};
#define PERF_PMU_FORMAT_BITS 64
-@@ -135,6 +136,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
+@@ -135,6 +136,7 @@ int perf_pmu__caps_parse(struct perf_pmu
void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
- const char *name);
+ char *name);
+void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
bool perf_pmu__has_hybrid(void);
int perf_pmu__match(char *pattern, char *name, char *tok);
-diff --git a/tools/perf/util/pmu.l b/tools/perf/util/pmu.l
-index a15d9fbd7c0e..58b4926cfaca 100644
--- a/tools/perf/util/pmu.l
+++ b/tools/perf/util/pmu.l
@@ -27,8 +27,6 @@ num_dec [0-9]+
- { return '-'; }
: { return ':'; }
, { return ','; }
-diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y
-index bfd7e8509869..283efe059819 100644
--- a/tools/perf/util/pmu.y
+++ b/tools/perf/util/pmu.y
@@ -20,7 +20,7 @@ do { \
}
bits:
---
-2.35.1
-
+++ /dev/null
-From dd42026a63215bac5e387a95be0e85d70dac30ad Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 10 Sep 2021 16:31:55 -0700
-Subject: scsi: lpfc: Adjust bytes received vales during cmf timer interval
-
-From: James Smart <jsmart2021@gmail.com>
-
-[ Upstream commit d5ac69b332d8859d1f8bd5d4dee31f3267f6b0d2 ]
-
-The newly added congestion mgmt framework is seeing unexpected congestion
-FPINs and signals. In analysis, time values given to the adapter are not
-at hard time intervals. Thus the drift vs the transfer count seen is
-affecting how the framework manages things.
-
-Adjust counters to cover the drift.
-
-Link: https://lore.kernel.org/r/20210910233159.115896-11-jsmart2021@gmail.com
-Co-developed-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: James Smart <jsmart2021@gmail.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Stable-dep-of: bd269188ea94 ("scsi: lpfc: Rework MIB Rx Monitor debug info logic")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/scsi/lpfc/lpfc_init.c | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index 48043e1ba485..730a6de4b8a6 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -5869,7 +5869,7 @@ lpfc_cmf_timer(struct hrtimer *timer)
- uint32_t io_cnt;
- uint32_t head, tail;
- uint32_t busy, max_read;
-- uint64_t total, rcv, lat, mbpi;
-+ uint64_t total, rcv, lat, mbpi, extra;
- int timer_interval = LPFC_CMF_INTERVAL;
- uint32_t ms;
- struct lpfc_cgn_stat *cgs;
-@@ -5936,7 +5936,19 @@ lpfc_cmf_timer(struct hrtimer *timer)
- phba->hba_flag & HBA_SETUP) {
- mbpi = phba->cmf_last_sync_bw;
- phba->cmf_last_sync_bw = 0;
-- lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total);
-+ extra = 0;
-+
-+ /* Calculate any extra bytes needed to account for the
-+ * timer accuracy. If we are less than LPFC_CMF_INTERVAL
-+ * add an extra 3% slop factor, equal to LPFC_CMF_INTERVAL
-+ * add an extra 2%. The goal is to equalize total with a
-+ * time > LPFC_CMF_INTERVAL or <= LPFC_CMF_INTERVAL + 1
-+ */
-+ if (ms == LPFC_CMF_INTERVAL)
-+ extra = div_u64(total, 50);
-+ else if (ms < LPFC_CMF_INTERVAL)
-+ extra = div_u64(total, 33);
-+ lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra);
- } else {
- /* For Monitor mode or link down we want mbpi
- * to be the full link speed
---
-2.35.1
-
+++ /dev/null
-From 4b18481655a14a5f5eaa9ab2a4ce82e75e35b873 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 3 Dec 2021 16:26:41 -0800
-Subject: scsi: lpfc: Adjust CMF total bytes and rxmonitor
-
-From: James Smart <jsmart2021@gmail.com>
-
-[ Upstream commit a6269f837045acb02904f31f05acde847ec8f8a7 ]
-
-Calculate any extra bytes needed to account for timer accuracy. If we are
-less than LPFC_CMF_INTERVAL, then calculate the adjustment needed for total
-to reflect a full LPFC_CMF_INTERVAL.
-
-Add additional info to rxmonitor, and adjust some log formatting.
-
-Link: https://lore.kernel.org/r/20211204002644.116455-7-jsmart2021@gmail.com
-Co-developed-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: James Smart <jsmart2021@gmail.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Stable-dep-of: bd269188ea94 ("scsi: lpfc: Rework MIB Rx Monitor debug info logic")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/scsi/lpfc/lpfc.h | 1 +
- drivers/scsi/lpfc/lpfc_debugfs.c | 14 ++++++++------
- drivers/scsi/lpfc/lpfc_debugfs.h | 2 +-
- drivers/scsi/lpfc/lpfc_init.c | 20 ++++++++++++--------
- 4 files changed, 22 insertions(+), 15 deletions(-)
-
-diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
-index f3bcb56e9ef2..fb5092ca9397 100644
---- a/drivers/scsi/lpfc/lpfc.h
-+++ b/drivers/scsi/lpfc/lpfc.h
-@@ -1615,6 +1615,7 @@ struct lpfc_hba {
- #define LPFC_MAX_RXMONITOR_ENTRY 800
- #define LPFC_MAX_RXMONITOR_DUMP 32
- struct rxtable_entry {
-+ uint64_t cmf_bytes; /* Total no of read bytes for CMF_SYNC_WQE */
- uint64_t total_bytes; /* Total no of read bytes requested */
- uint64_t rcv_bytes; /* Total no of read bytes completed */
- uint64_t avg_io_size;
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
-index 79bc86ba59b3..61f8dcd072ac 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.c
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
-@@ -5561,22 +5561,24 @@ lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes,
- start = tail;
-
- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
-- " MaxBPI\t Total Data Cmd Total Data Cmpl "
-- " Latency(us) Avg IO Size\tMax IO Size IO cnt "
-- "Info BWutil(ms)\n");
-+ " MaxBPI Tot_Data_CMF Tot_Data_Cmd "
-+ "Tot_Data_Cmpl Lat(us) Avg_IO Max_IO "
-+ "Bsy IO_cnt Info BWutil(ms)\n");
- get_table:
- for (i = start; i < last; i++) {
- entry = &phba->rxtable[i];
- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
-- "%3d:%12lld %12lld\t%12lld\t"
-- "%8lldus\t%8lld\t%10lld "
-- "%8d %2d %2d(%2d)\n",
-+ "%3d:%12lld %12lld %12lld %12lld "
-+ "%7lldus %8lld %7lld "
-+ "%2d %4d %2d %2d(%2d)\n",
- i, entry->max_bytes_per_interval,
-+ entry->cmf_bytes,
- entry->total_bytes,
- entry->rcv_bytes,
- entry->avg_io_latency,
- entry->avg_io_size,
- entry->max_read_cnt,
-+ entry->cmf_busy,
- entry->io_cnt,
- entry->cmf_info,
- entry->timer_utilization,
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
-index a5bf71b34972..6dd361c1fd31 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.h
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
-@@ -282,7 +282,7 @@ struct lpfc_idiag {
- void *ptr_private;
- };
-
--#define MAX_DEBUGFS_RX_TABLE_SIZE (100 * LPFC_MAX_RXMONITOR_ENTRY)
-+#define MAX_DEBUGFS_RX_TABLE_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY)
- struct lpfc_rx_monitor_debug {
- char *i_private;
- char *buffer;
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index 730a6de4b8a6..7545ff55ff50 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -5869,7 +5869,7 @@ lpfc_cmf_timer(struct hrtimer *timer)
- uint32_t io_cnt;
- uint32_t head, tail;
- uint32_t busy, max_read;
-- uint64_t total, rcv, lat, mbpi, extra;
-+ uint64_t total, rcv, lat, mbpi, extra, cnt;
- int timer_interval = LPFC_CMF_INTERVAL;
- uint32_t ms;
- struct lpfc_cgn_stat *cgs;
-@@ -5940,20 +5940,23 @@ lpfc_cmf_timer(struct hrtimer *timer)
-
- /* Calculate any extra bytes needed to account for the
- * timer accuracy. If we are less than LPFC_CMF_INTERVAL
-- * add an extra 3% slop factor, equal to LPFC_CMF_INTERVAL
-- * add an extra 2%. The goal is to equalize total with a
-- * time > LPFC_CMF_INTERVAL or <= LPFC_CMF_INTERVAL + 1
-+ * calculate the adjustment needed for total to reflect
-+ * a full LPFC_CMF_INTERVAL.
- */
-- if (ms == LPFC_CMF_INTERVAL)
-- extra = div_u64(total, 50);
-- else if (ms < LPFC_CMF_INTERVAL)
-- extra = div_u64(total, 33);
-+ if (ms && ms < LPFC_CMF_INTERVAL) {
-+ cnt = div_u64(total, ms); /* bytes per ms */
-+ cnt *= LPFC_CMF_INTERVAL; /* what total should be */
-+ if (cnt > mbpi)
-+ cnt = mbpi;
-+ extra = cnt - total;
-+ }
- lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra);
- } else {
- /* For Monitor mode or link down we want mbpi
- * to be the full link speed
- */
- mbpi = phba->cmf_link_byte_count;
-+ extra = 0;
- }
- phba->cmf_timer_cnt++;
-
-@@ -5984,6 +5987,7 @@ lpfc_cmf_timer(struct hrtimer *timer)
- LPFC_RXMONITOR_TABLE_IN_USE);
- entry = &phba->rxtable[head];
- entry->total_bytes = total;
-+ entry->cmf_bytes = total + extra;
- entry->rcv_bytes = rcv;
- entry->cmf_busy = busy;
- entry->cmf_info = phba->cmf_active_info;
---
-2.35.1
-
+++ /dev/null
-From b70fb09cf0a3f6e10d5973c29f4020a49bfc7e5f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 18 Aug 2022 18:17:32 -0700
-Subject: scsi: lpfc: Rework MIB Rx Monitor debug info logic
-
-From: James Smart <jsmart2021@gmail.com>
-
-[ Upstream commit bd269188ea94e40ab002cad7b0df8f12b8f0de54 ]
-
-The kernel test robot reported the following sparse warning:
-
-arch/arm64/include/asm/cmpxchg.h:88:1: sparse: sparse: cast truncates
- bits from constant value (369 becomes 69)
-
-On arm64, atomic_xchg only works on 8-bit byte fields. Thus, the macro
-usage of LPFC_RXMONITOR_TABLE_IN_USE can be unintentionally truncated
-leading to all logic involving the LPFC_RXMONITOR_TABLE_IN_USE macro to not
-work properly.
-
-Replace the Rx Table atomic_t indexing logic with a new
-lpfc_rx_info_monitor structure that holds a circular ring buffer. For
-locking semantics, a spinlock_t is used.
-
-Link: https://lore.kernel.org/r/20220819011736.14141-4-jsmart2021@gmail.com
-Fixes: 17b27ac59224 ("scsi: lpfc: Add rx monitoring statistics")
-Cc: <stable@vger.kernel.org> # v5.15+
-Co-developed-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: James Smart <jsmart2021@gmail.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/scsi/lpfc/lpfc.h | 14 ++-
- drivers/scsi/lpfc/lpfc_crtn.h | 8 ++
- drivers/scsi/lpfc/lpfc_debugfs.c | 59 ++--------
- drivers/scsi/lpfc/lpfc_debugfs.h | 2 +-
- drivers/scsi/lpfc/lpfc_init.c | 83 ++++----------
- drivers/scsi/lpfc/lpfc_mem.c | 9 +-
- drivers/scsi/lpfc/lpfc_sli.c | 190 +++++++++++++++++++++++++++++--
- 7 files changed, 240 insertions(+), 125 deletions(-)
-
-diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
-index fb5092ca9397..7eaaa421848d 100644
---- a/drivers/scsi/lpfc/lpfc.h
-+++ b/drivers/scsi/lpfc/lpfc.h
-@@ -1562,10 +1562,7 @@ struct lpfc_hba {
- u32 cgn_acqe_cnt;
-
- /* RX monitor handling for CMF */
-- struct rxtable_entry *rxtable; /* RX_monitor information */
-- atomic_t rxtable_idx_head;
--#define LPFC_RXMONITOR_TABLE_IN_USE (LPFC_MAX_RXMONITOR_ENTRY + 73)
-- atomic_t rxtable_idx_tail;
-+ struct lpfc_rx_info_monitor *rx_monitor;
- atomic_t rx_max_read_cnt; /* Maximum read bytes */
- uint64_t rx_block_cnt;
-
-@@ -1614,7 +1611,7 @@ struct lpfc_hba {
-
- #define LPFC_MAX_RXMONITOR_ENTRY 800
- #define LPFC_MAX_RXMONITOR_DUMP 32
--struct rxtable_entry {
-+struct rx_info_entry {
- uint64_t cmf_bytes; /* Total no of read bytes for CMF_SYNC_WQE */
- uint64_t total_bytes; /* Total no of read bytes requested */
- uint64_t rcv_bytes; /* Total no of read bytes completed */
-@@ -1629,6 +1626,13 @@ struct rxtable_entry {
- uint32_t timer_interval;
- };
-
-+struct lpfc_rx_info_monitor {
-+ struct rx_info_entry *ring; /* info organized in a circular buffer */
-+ u32 head_idx, tail_idx; /* index to head/tail of ring */
-+ spinlock_t lock; /* spinlock for ring */
-+ u32 entries; /* storing number entries/size of ring */
-+};
-+
- static inline struct Scsi_Host *
- lpfc_shost_from_vport(struct lpfc_vport *vport)
- {
-diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
-index f7bf589b63fb..a485b8905a23 100644
---- a/drivers/scsi/lpfc/lpfc_crtn.h
-+++ b/drivers/scsi/lpfc/lpfc_crtn.h
-@@ -90,6 +90,14 @@ void lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba);
- void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag);
- void lpfc_unblock_requests(struct lpfc_hba *phba);
- void lpfc_block_requests(struct lpfc_hba *phba);
-+int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
-+ u32 entries);
-+void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor);
-+void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
-+ struct rx_info_entry *entry);
-+u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
-+ struct lpfc_rx_info_monitor *rx_monitor, char *buf,
-+ u32 buf_len, u32 max_read_entries);
-
- void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
- void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
-index 61f8dcd072ac..8e8bbe734e87 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.c
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
-@@ -5520,7 +5520,7 @@ lpfc_rx_monitor_open(struct inode *inode, struct file *file)
- if (!debug)
- goto out;
-
-- debug->buffer = vmalloc(MAX_DEBUGFS_RX_TABLE_SIZE);
-+ debug->buffer = vmalloc(MAX_DEBUGFS_RX_INFO_SIZE);
- if (!debug->buffer) {
- kfree(debug);
- goto out;
-@@ -5541,57 +5541,18 @@ lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes,
- struct lpfc_rx_monitor_debug *debug = file->private_data;
- struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
- char *buffer = debug->buffer;
-- struct rxtable_entry *entry;
-- int i, len = 0, head, tail, last, start;
--
-- head = atomic_read(&phba->rxtable_idx_head);
-- while (head == LPFC_RXMONITOR_TABLE_IN_USE) {
-- /* Table is getting updated */
-- msleep(20);
-- head = atomic_read(&phba->rxtable_idx_head);
-- }
-
-- tail = atomic_xchg(&phba->rxtable_idx_tail, head);
-- if (!phba->rxtable || head == tail) {
-- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
-- "Rxtable is empty\n");
-- goto out;
-- }
-- last = (head > tail) ? head : LPFC_MAX_RXMONITOR_ENTRY;
-- start = tail;
--
-- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
-- " MaxBPI Tot_Data_CMF Tot_Data_Cmd "
-- "Tot_Data_Cmpl Lat(us) Avg_IO Max_IO "
-- "Bsy IO_cnt Info BWutil(ms)\n");
--get_table:
-- for (i = start; i < last; i++) {
-- entry = &phba->rxtable[i];
-- len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
-- "%3d:%12lld %12lld %12lld %12lld "
-- "%7lldus %8lld %7lld "
-- "%2d %4d %2d %2d(%2d)\n",
-- i, entry->max_bytes_per_interval,
-- entry->cmf_bytes,
-- entry->total_bytes,
-- entry->rcv_bytes,
-- entry->avg_io_latency,
-- entry->avg_io_size,
-- entry->max_read_cnt,
-- entry->cmf_busy,
-- entry->io_cnt,
-- entry->cmf_info,
-- entry->timer_utilization,
-- entry->timer_interval);
-+ if (!phba->rx_monitor) {
-+ scnprintf(buffer, MAX_DEBUGFS_RX_INFO_SIZE,
-+ "Rx Monitor Info is empty.\n");
-+ } else {
-+ lpfc_rx_monitor_report(phba, phba->rx_monitor, buffer,
-+ MAX_DEBUGFS_RX_INFO_SIZE,
-+ LPFC_MAX_RXMONITOR_ENTRY);
- }
-
-- if (head != last) {
-- start = 0;
-- last = head;
-- goto get_table;
-- }
--out:
-- return simple_read_from_buffer(buf, nbytes, ppos, buffer, len);
-+ return simple_read_from_buffer(buf, nbytes, ppos, buffer,
-+ strlen(buffer));
- }
-
- static int
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
-index 6dd361c1fd31..f71e5b6311ac 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.h
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
-@@ -282,7 +282,7 @@ struct lpfc_idiag {
- void *ptr_private;
- };
-
--#define MAX_DEBUGFS_RX_TABLE_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY)
-+#define MAX_DEBUGFS_RX_INFO_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY)
- struct lpfc_rx_monitor_debug {
- char *i_private;
- char *buffer;
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index 7545ff55ff50..f69a797a58f2 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -5427,38 +5427,12 @@ lpfc_async_link_speed_to_read_top(struct lpfc_hba *phba, uint8_t speed_code)
- void
- lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba)
- {
-- struct rxtable_entry *entry;
-- int cnt = 0, head, tail, last, start;
--
-- head = atomic_read(&phba->rxtable_idx_head);
-- tail = atomic_read(&phba->rxtable_idx_tail);
-- if (!phba->rxtable || head == tail) {
-- lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
-- "4411 Rxtable is empty\n");
-- return;
-- }
-- last = tail;
-- start = head;
--
-- /* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */
-- while (start != last) {
-- if (start)
-- start--;
-- else
-- start = LPFC_MAX_RXMONITOR_ENTRY - 1;
-- entry = &phba->rxtable[start];
-+ if (!phba->rx_monitor) {
- lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
-- "4410 %02d: MBPI %lld Xmit %lld Cmpl %lld "
-- "Lat %lld ASz %lld Info %02d BWUtil %d "
-- "Int %d slot %d\n",
-- cnt, entry->max_bytes_per_interval,
-- entry->total_bytes, entry->rcv_bytes,
-- entry->avg_io_latency, entry->avg_io_size,
-- entry->cmf_info, entry->timer_utilization,
-- entry->timer_interval, start);
-- cnt++;
-- if (cnt >= LPFC_MAX_RXMONITOR_DUMP)
-- return;
-+ "4411 Rx Monitor Info is empty.\n");
-+ } else {
-+ lpfc_rx_monitor_report(phba, phba->rx_monitor, NULL, 0,
-+ LPFC_MAX_RXMONITOR_DUMP);
- }
- }
-
-@@ -5865,9 +5839,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
- {
- struct lpfc_hba *phba = container_of(timer, struct lpfc_hba,
- cmf_timer);
-- struct rxtable_entry *entry;
-+ struct rx_info_entry entry;
- uint32_t io_cnt;
-- uint32_t head, tail;
- uint32_t busy, max_read;
- uint64_t total, rcv, lat, mbpi, extra, cnt;
- int timer_interval = LPFC_CMF_INTERVAL;
-@@ -5982,40 +5955,30 @@ lpfc_cmf_timer(struct hrtimer *timer)
- }
-
- /* Save rxmonitor information for debug */
-- if (phba->rxtable) {
-- head = atomic_xchg(&phba->rxtable_idx_head,
-- LPFC_RXMONITOR_TABLE_IN_USE);
-- entry = &phba->rxtable[head];
-- entry->total_bytes = total;
-- entry->cmf_bytes = total + extra;
-- entry->rcv_bytes = rcv;
-- entry->cmf_busy = busy;
-- entry->cmf_info = phba->cmf_active_info;
-+ if (phba->rx_monitor) {
-+ entry.total_bytes = total;
-+ entry.cmf_bytes = total + extra;
-+ entry.rcv_bytes = rcv;
-+ entry.cmf_busy = busy;
-+ entry.cmf_info = phba->cmf_active_info;
- if (io_cnt) {
-- entry->avg_io_latency = div_u64(lat, io_cnt);
-- entry->avg_io_size = div_u64(rcv, io_cnt);
-+ entry.avg_io_latency = div_u64(lat, io_cnt);
-+ entry.avg_io_size = div_u64(rcv, io_cnt);
- } else {
-- entry->avg_io_latency = 0;
-- entry->avg_io_size = 0;
-+ entry.avg_io_latency = 0;
-+ entry.avg_io_size = 0;
- }
-- entry->max_read_cnt = max_read;
-- entry->io_cnt = io_cnt;
-- entry->max_bytes_per_interval = mbpi;
-+ entry.max_read_cnt = max_read;
-+ entry.io_cnt = io_cnt;
-+ entry.max_bytes_per_interval = mbpi;
- if (phba->cmf_active_mode == LPFC_CFG_MANAGED)
-- entry->timer_utilization = phba->cmf_last_ts;
-+ entry.timer_utilization = phba->cmf_last_ts;
- else
-- entry->timer_utilization = ms;
-- entry->timer_interval = ms;
-+ entry.timer_utilization = ms;
-+ entry.timer_interval = ms;
- phba->cmf_last_ts = 0;
-
-- /* Increment rxtable index */
-- head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY;
-- tail = atomic_read(&phba->rxtable_idx_tail);
-- if (head == tail) {
-- tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY;
-- atomic_set(&phba->rxtable_idx_tail, tail);
-- }
-- atomic_set(&phba->rxtable_idx_head, head);
-+ lpfc_rx_monitor_record(phba->rx_monitor, &entry);
- }
-
- if (phba->cmf_active_mode == LPFC_CFG_MONITOR) {
-diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
-index 870e53b8f81d..5d36b3514864 100644
---- a/drivers/scsi/lpfc/lpfc_mem.c
-+++ b/drivers/scsi/lpfc/lpfc_mem.c
-@@ -344,9 +344,12 @@ lpfc_mem_free_all(struct lpfc_hba *phba)
- phba->cgn_i = NULL;
- }
-
-- /* Free RX table */
-- kfree(phba->rxtable);
-- phba->rxtable = NULL;
-+ /* Free RX Monitor */
-+ if (phba->rx_monitor) {
-+ lpfc_rx_monitor_destroy_ring(phba->rx_monitor);
-+ kfree(phba->rx_monitor);
-+ phba->rx_monitor = NULL;
-+ }
-
- /* Free the iocb lookup array */
- kfree(psli->iocbq_lookup);
-diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
-index f594a006d04c..21779ec043e3 100644
---- a/drivers/scsi/lpfc/lpfc_sli.c
-+++ b/drivers/scsi/lpfc/lpfc_sli.c
-@@ -7880,6 +7880,172 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
- }
- }
-
-+/**
-+ * lpfc_rx_monitor_create_ring - Initialize ring buffer for rx_monitor
-+ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
-+ * @entries: Number of rx_info_entry objects to allocate in ring
-+ *
-+ * Return:
-+ * 0 - Success
-+ * ENOMEM - Failure to kmalloc
-+ **/
-+int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
-+ u32 entries)
-+{
-+ rx_monitor->ring = kmalloc_array(entries, sizeof(struct rx_info_entry),
-+ GFP_KERNEL);
-+ if (!rx_monitor->ring)
-+ return -ENOMEM;
-+
-+ rx_monitor->head_idx = 0;
-+ rx_monitor->tail_idx = 0;
-+ spin_lock_init(&rx_monitor->lock);
-+ rx_monitor->entries = entries;
-+
-+ return 0;
-+}
-+
-+/**
-+ * lpfc_rx_monitor_destroy_ring - Free ring buffer for rx_monitor
-+ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
-+ **/
-+void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor)
-+{
-+ spin_lock(&rx_monitor->lock);
-+ kfree(rx_monitor->ring);
-+ rx_monitor->ring = NULL;
-+ rx_monitor->entries = 0;
-+ rx_monitor->head_idx = 0;
-+ rx_monitor->tail_idx = 0;
-+ spin_unlock(&rx_monitor->lock);
-+}
-+
-+/**
-+ * lpfc_rx_monitor_record - Insert an entry into rx_monitor's ring
-+ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
-+ * @entry: Pointer to rx_info_entry
-+ *
-+ * Used to insert an rx_info_entry into rx_monitor's ring. Note that this is a
-+ * deep copy of rx_info_entry not a shallow copy of the rx_info_entry ptr.
-+ *
-+ * This is called from lpfc_cmf_timer, which is in timer/softirq context.
-+ *
-+ * In cases of old data overflow, we do a best effort of FIFO order.
-+ **/
-+void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
-+ struct rx_info_entry *entry)
-+{
-+ struct rx_info_entry *ring = rx_monitor->ring;
-+ u32 *head_idx = &rx_monitor->head_idx;
-+ u32 *tail_idx = &rx_monitor->tail_idx;
-+ spinlock_t *ring_lock = &rx_monitor->lock;
-+ u32 ring_size = rx_monitor->entries;
-+
-+ spin_lock(ring_lock);
-+ memcpy(&ring[*tail_idx], entry, sizeof(*entry));
-+ *tail_idx = (*tail_idx + 1) % ring_size;
-+
-+ /* Best effort of FIFO saved data */
-+ if (*tail_idx == *head_idx)
-+ *head_idx = (*head_idx + 1) % ring_size;
-+
-+ spin_unlock(ring_lock);
-+}
-+
-+/**
-+ * lpfc_rx_monitor_report - Read out rx_monitor's ring
-+ * @phba: Pointer to lpfc_hba object
-+ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
-+ * @buf: Pointer to char buffer that will contain rx monitor info data
-+ * @buf_len: Length buf including null char
-+ * @max_read_entries: Maximum number of entries to read out of ring
-+ *
-+ * Used to dump/read what's in rx_monitor's ring buffer.
-+ *
-+ * If buf is NULL || buf_len == 0, then it is implied that we want to log the
-+ * information to kmsg instead of filling out buf.
-+ *
-+ * Return:
-+ * Number of entries read out of the ring
-+ **/
-+u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
-+ struct lpfc_rx_info_monitor *rx_monitor, char *buf,
-+ u32 buf_len, u32 max_read_entries)
-+{
-+ struct rx_info_entry *ring = rx_monitor->ring;
-+ struct rx_info_entry *entry;
-+ u32 *head_idx = &rx_monitor->head_idx;
-+ u32 *tail_idx = &rx_monitor->tail_idx;
-+ spinlock_t *ring_lock = &rx_monitor->lock;
-+ u32 ring_size = rx_monitor->entries;
-+ u32 cnt = 0;
-+ char tmp[DBG_LOG_STR_SZ] = {0};
-+ bool log_to_kmsg = (!buf || !buf_len) ? true : false;
-+
-+ if (!log_to_kmsg) {
-+ /* clear the buffer to be sure */
-+ memset(buf, 0, buf_len);
-+
-+ scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s"
-+ "%-8s%-8s%-8s%-16s\n",
-+ "MaxBPI", "Tot_Data_CMF",
-+ "Tot_Data_Cmd", "Tot_Data_Cmpl",
-+ "Lat(us)", "Avg_IO", "Max_IO", "Bsy",
-+ "IO_cnt", "Info", "BWutil(ms)");
-+ }
-+
-+ /* Needs to be _bh because record is called from timer interrupt
-+ * context
-+ */
-+ spin_lock_bh(ring_lock);
-+ while (*head_idx != *tail_idx) {
-+ entry = &ring[*head_idx];
-+
-+ /* Read out this entry's data. */
-+ if (!log_to_kmsg) {
-+ /* If !log_to_kmsg, then store to buf. */
-+ scnprintf(tmp, sizeof(tmp),
-+ "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu"
-+ "%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
-+ *head_idx, entry->max_bytes_per_interval,
-+ entry->cmf_bytes, entry->total_bytes,
-+ entry->rcv_bytes, entry->avg_io_latency,
-+ entry->avg_io_size, entry->max_read_cnt,
-+ entry->cmf_busy, entry->io_cnt,
-+ entry->cmf_info, entry->timer_utilization,
-+ entry->timer_interval);
-+
-+ /* Check for buffer overflow */
-+ if ((strlen(buf) + strlen(tmp)) >= buf_len)
-+ break;
-+
-+ /* Append entry's data to buffer */
-+ strlcat(buf, tmp, buf_len);
-+ } else {
-+ lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
-+ "4410 %02u: MBPI %llu Xmit %llu "
-+ "Cmpl %llu Lat %llu ASz %llu Info %02u "
-+ "BWUtil %u Int %u slot %u\n",
-+ cnt, entry->max_bytes_per_interval,
-+ entry->total_bytes, entry->rcv_bytes,
-+ entry->avg_io_latency,
-+ entry->avg_io_size, entry->cmf_info,
-+ entry->timer_utilization,
-+ entry->timer_interval, *head_idx);
-+ }
-+
-+ *head_idx = (*head_idx + 1) % ring_size;
-+
-+ /* Don't feed more than max_read_entries */
-+ cnt++;
-+ if (cnt >= max_read_entries)
-+ break;
-+ }
-+ spin_unlock_bh(ring_lock);
-+
-+ return cnt;
-+}
-+
- /**
- * lpfc_cmf_setup - Initialize idle_stat tracking
- * @phba: Pointer to HBA context object.
-@@ -8071,19 +8237,29 @@ lpfc_cmf_setup(struct lpfc_hba *phba)
- phba->cmf_interval_rate = LPFC_CMF_INTERVAL;
-
- /* Allocate RX Monitor Buffer */
-- if (!phba->rxtable) {
-- phba->rxtable = kmalloc_array(LPFC_MAX_RXMONITOR_ENTRY,
-- sizeof(struct rxtable_entry),
-- GFP_KERNEL);
-- if (!phba->rxtable) {
-+ if (!phba->rx_monitor) {
-+ phba->rx_monitor = kzalloc(sizeof(*phba->rx_monitor),
-+ GFP_KERNEL);
-+
-+ if (!phba->rx_monitor) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2644 Failed to alloc memory "
- "for RX Monitor Buffer\n");
- return -ENOMEM;
- }
-+
-+ /* Instruct the rx_monitor object to instantiate its ring */
-+ if (lpfc_rx_monitor_create_ring(phba->rx_monitor,
-+ LPFC_MAX_RXMONITOR_ENTRY)) {
-+ kfree(phba->rx_monitor);
-+ phba->rx_monitor = NULL;
-+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+ "2645 Failed to alloc memory "
-+ "for RX Monitor's Ring\n");
-+ return -ENOMEM;
-+ }
- }
-- atomic_set(&phba->rxtable_idx_head, 0);
-- atomic_set(&phba->rxtable_idx_tail, 0);
-+
- return 0;
- }
-
---
-2.35.1
-
iommu-vt-d-allow-nvs-regions-in-arch_rmrr_sanity_che.patch
iommu-vt-d-clean-up-si_domain-in-the-init_dmars-erro.patch
fs-dlm-fix-invalid-derefence-of-sb_lvbptr.patch
-scsi-lpfc-adjust-bytes-received-vales-during-cmf-tim.patch
-scsi-lpfc-adjust-cmf-total-bytes-and-rxmonitor.patch
-scsi-lpfc-rework-mib-rx-monitor-debug-info-logic.patch
arm64-mte-move-register-initialization-to-c.patch
-btrfs-rename-root-fields-in-delayed-refs-structs.patch
-btrfs-pull-up-qgroup-checks-from-delayed-ref-core-to.patch
ksmbd-handle-smb2-query-dir-request-for-outputbuffer.patch
ksmbd-fix-incorrect-handling-of-iterate_dir.patch
tracing-simplify-conditional-compilation-code-in-tra.patch
tracing-do-not-free-snapshot-if-tracer-is-on-cmdline.patch
mmc-sdhci-tegra-use-actual-clock-rate-for-sw-tuning-.patch
-drm-amd-display-parse-and-check-psr-su-caps.patch
-drm-amd-display-explicitly-disable-psr_feature_enabl.patch
-perf-parse-events-add-const-to-evsel-name.patch
perf-skip-and-warn-on-unknown-format-confign-attrs.patch