919b6b44da059b40c72bf48bcafbc4f2510085df
[openwrt/staging/stintel.git] /
1 From 38358fa3cc8e16c6862a3e5c5c233f9f652e3a6d Mon Sep 17 00:00:00 2001
2 From: Lorenzo Bianconi <lorenzo@kernel.org>
3 Date: Thu, 31 Jul 2025 12:29:08 +0200
4 Subject: [PATCH] net: airoha: Fix PPE table access in
5 airoha_ppe_debugfs_foe_show()
6
7 In order to avoid any possible race we need to hold the ppe_lock
8 spinlock accessing the hw PPE table. airoha_ppe_foe_get_entry routine is
9 always executed holding ppe_lock except in airoha_ppe_debugfs_foe_show
10 routine. Fix the problem introducing airoha_ppe_foe_get_entry_locked
11 routine.
12
13 Fixes: 3fe15c640f380 ("net: airoha: Introduce PPE debugfs support")
14 Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
15 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
16 Link: https://patch.msgid.link/20250731-airoha_ppe_foe_get_entry_locked-v2-1-50efbd8c0fd6@kernel.org
17 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
18 ---
19 drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++++++++++++++++++------
20 1 file changed, 20 insertions(+), 6 deletions(-)
21
22 --- a/drivers/net/ethernet/airoha/airoha_ppe.c
23 +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
24 @@ -508,9 +508,11 @@ static void airoha_ppe_foe_flow_stats_up
25 FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq);
26 }
27
28 -struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
29 - u32 hash)
30 +static struct airoha_foe_entry *
31 +airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)
32 {
33 + lockdep_assert_held(&ppe_lock);
34 +
35 if (hash < PPE_SRAM_NUM_ENTRIES) {
36 u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry);
37 struct airoha_eth *eth = ppe->eth;
38 @@ -537,6 +539,18 @@ struct airoha_foe_entry *airoha_ppe_foe_
39 return ppe->foe + hash * sizeof(struct airoha_foe_entry);
40 }
41
42 +struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
43 + u32 hash)
44 +{
45 + struct airoha_foe_entry *hwe;
46 +
47 + spin_lock_bh(&ppe_lock);
48 + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash);
49 + spin_unlock_bh(&ppe_lock);
50 +
51 + return hwe;
52 +}
53 +
54 static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e,
55 struct airoha_foe_entry *hwe)
56 {
57 @@ -651,7 +665,7 @@ airoha_ppe_foe_commit_subflow_entry(stru
58 struct airoha_flow_table_entry *f;
59 int type;
60
61 - hwe_p = airoha_ppe_foe_get_entry(ppe, hash);
62 + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, hash);
63 if (!hwe_p)
64 return -EINVAL;
65
66 @@ -703,7 +717,7 @@ static void airoha_ppe_foe_insert_entry(
67
68 spin_lock_bh(&ppe_lock);
69
70 - hwe = airoha_ppe_foe_get_entry(ppe, hash);
71 + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash);
72 if (!hwe)
73 goto unlock;
74
75 @@ -818,7 +832,7 @@ airoha_ppe_foe_flow_l2_entry_update(stru
76 u32 ib1, state;
77 int idle;
78
79 - hwe = airoha_ppe_foe_get_entry(ppe, iter->hash);
80 + hwe = airoha_ppe_foe_get_entry_locked(ppe, iter->hash);
81 if (!hwe)
82 continue;
83
84 @@ -855,7 +869,7 @@ static void airoha_ppe_foe_flow_entry_up
85 if (e->hash == 0xffff)
86 goto unlock;
87
88 - hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash);
89 + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, e->hash);
90 if (!hwe_p)
91 goto unlock;
92