aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed S. Darwish <a.darwish@linutronix.de>2021-03-16 11:56:30 +0100
committerSteffen Klassert <steffen.klassert@secunet.com>2021-03-22 07:38:08 +0100
commitbc8e0adff343d992ca76d871e8b5e6cb86e1fad9 (patch)
tree4845b0b91b017a9a7533312696baad9393699b54
parentnet: xfrm: Localize sequence counter per network namespace (diff)
downloadlinux-dev-bc8e0adff343d992ca76d871e8b5e6cb86e1fad9.tar.xz
linux-dev-bc8e0adff343d992ca76d871e8b5e6cb86e1fad9.zip
net: xfrm: Use sequence counter with associated spinlock
A sequence counter write section must be serialized or its internal state can get corrupted. A plain seqcount_t does not contain the information of which lock must be held to guaranteee write side serialization. For xfrm_state_hash_generation, use seqcount_spinlock_t instead of plain seqcount_t. This allows to associate the spinlock used for write serialization with the sequence counter. It thus enables lockdep to verify that the write serialization lock is indeed held before entering the sequence counter write section. If lockdep is disabled, this lock association is compiled out and has neither storage size nor runtime overhead. Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--include/net/netns/xfrm.h2
-rw-r--r--net/xfrm/xfrm_state.c3
2 files changed, 3 insertions, 2 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index b59d73d529ba..e816b6a3ef2b 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -73,7 +73,7 @@ struct netns_xfrm {
struct dst_ops xfrm6_dst_ops;
#endif
spinlock_t xfrm_state_lock;
- seqcount_t xfrm_state_hash_generation;
+ seqcount_spinlock_t xfrm_state_hash_generation;
spinlock_t xfrm_policy_lock;
struct mutex xfrm_cfg_mutex;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ffd315cff984..4496f7efa220 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2665,7 +2665,8 @@ int __net_init xfrm_state_init(struct net *net)
net->xfrm.state_num = 0;
INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
spin_lock_init(&net->xfrm.xfrm_state_lock);
- seqcount_init(&net->xfrm.xfrm_state_hash_generation);
+ seqcount_spinlock_init(&net->xfrm.xfrm_state_hash_generation,
+ &net->xfrm.xfrm_state_lock);
return 0;
out_byspi: