Skip to content

Commit c99dac5

Browse files
Sebastian Andrzej SiewiorPaolo Abeni
authored andcommitted
net: dst_cache: Use nested-BH locking for dst_cache::cache
dst_cache::cache is a per-CPU variable and relies on disabled BH for its locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT this data structure requires explicit locking. Add a local_lock_t to the data structure and use local_lock_nested_bh() for locking. This change adds only lockdep coverage and does not alter the functional behaviour for !PREEMPT_RT. Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 32471b2 commit c99dac5

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

net/core/dst_cache.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
struct dst_cache_pcpu {
1818
unsigned long refresh_ts;
1919
struct dst_entry *dst;
20+
local_lock_t bh_lock;
2021
u32 cookie;
2122
union {
2223
struct in_addr in_saddr;
@@ -65,10 +66,15 @@ static struct dst_entry *dst_cache_per_cpu_get(struct dst_cache *dst_cache,
6566

6667
struct dst_entry *dst_cache_get(struct dst_cache *dst_cache)
6768
{
69+
struct dst_entry *dst;
70+
6871
if (!dst_cache->cache)
6972
return NULL;
7073

71-
return dst_cache_per_cpu_get(dst_cache, this_cpu_ptr(dst_cache->cache));
74+
local_lock_nested_bh(&dst_cache->cache->bh_lock);
75+
dst = dst_cache_per_cpu_get(dst_cache, this_cpu_ptr(dst_cache->cache));
76+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
77+
return dst;
7278
}
7379
EXPORT_SYMBOL_GPL(dst_cache_get);
7480

@@ -80,12 +86,16 @@ struct rtable *dst_cache_get_ip4(struct dst_cache *dst_cache, __be32 *saddr)
8086
if (!dst_cache->cache)
8187
return NULL;
8288

89+
local_lock_nested_bh(&dst_cache->cache->bh_lock);
8390
idst = this_cpu_ptr(dst_cache->cache);
8491
dst = dst_cache_per_cpu_get(dst_cache, idst);
85-
if (!dst)
92+
if (!dst) {
93+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
8694
return NULL;
95+
}
8796

8897
*saddr = idst->in_saddr.s_addr;
98+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
8999
return dst_rtable(dst);
90100
}
91101
EXPORT_SYMBOL_GPL(dst_cache_get_ip4);
@@ -98,9 +108,11 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst,
98108
if (!dst_cache->cache)
99109
return;
100110

111+
local_lock_nested_bh(&dst_cache->cache->bh_lock);
101112
idst = this_cpu_ptr(dst_cache->cache);
102113
dst_cache_per_cpu_dst_set(idst, dst, 0);
103114
idst->in_saddr.s_addr = saddr;
115+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
104116
}
105117
EXPORT_SYMBOL_GPL(dst_cache_set_ip4);
106118

@@ -113,10 +125,13 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
113125
if (!dst_cache->cache)
114126
return;
115127

128+
local_lock_nested_bh(&dst_cache->cache->bh_lock);
129+
116130
idst = this_cpu_ptr(dst_cache->cache);
117131
dst_cache_per_cpu_dst_set(idst, dst,
118132
rt6_get_cookie(dst_rt6_info(dst)));
119133
idst->in6_saddr = *saddr;
134+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
120135
}
121136
EXPORT_SYMBOL_GPL(dst_cache_set_ip6);
122137

@@ -129,23 +144,32 @@ struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache,
129144
if (!dst_cache->cache)
130145
return NULL;
131146

147+
local_lock_nested_bh(&dst_cache->cache->bh_lock);
148+
132149
idst = this_cpu_ptr(dst_cache->cache);
133150
dst = dst_cache_per_cpu_get(dst_cache, idst);
134-
if (!dst)
151+
if (!dst) {
152+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
135153
return NULL;
154+
}
136155

137156
*saddr = idst->in6_saddr;
157+
local_unlock_nested_bh(&dst_cache->cache->bh_lock);
138158
return dst;
139159
}
140160
EXPORT_SYMBOL_GPL(dst_cache_get_ip6);
141161
#endif
142162

143163
int dst_cache_init(struct dst_cache *dst_cache, gfp_t gfp)
144164
{
165+
unsigned int i;
166+
145167
dst_cache->cache = alloc_percpu_gfp(struct dst_cache_pcpu,
146168
gfp | __GFP_ZERO);
147169
if (!dst_cache->cache)
148170
return -ENOMEM;
171+
for_each_possible_cpu(i)
172+
local_lock_init(&per_cpu_ptr(dst_cache->cache, i)->bh_lock);
149173

150174
dst_cache_reset(dst_cache);
151175
return 0;

0 commit comments

Comments
 (0)