mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
net: shaper: annotate the data races
As previously discussed we don't care about making the shaper state fully RCU-compliant because the hierarchy itself can't be dumped in one go over Netlink. Let's annotate the reads and writes to make that clear. The field-by-field assignments will also be useful for the next commit which adds explicit "valid" field (which we don't want to override with the current full struct assignment). Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260515221325.1685455-2-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
abe003b332
commit
a3442936dd
|
|
@ -138,35 +138,58 @@ static int net_shaper_fill_handle(struct sk_buff *msg,
|
|||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void net_shaper_copy(struct net_shaper *dst,
|
||||
const struct net_shaper *src)
|
||||
{
|
||||
WRITE_ONCE(dst->parent.scope, READ_ONCE(src->parent.scope));
|
||||
WRITE_ONCE(dst->parent.id, READ_ONCE(src->parent.id));
|
||||
WRITE_ONCE(dst->handle.scope, READ_ONCE(src->handle.scope));
|
||||
WRITE_ONCE(dst->handle.id, READ_ONCE(src->handle.id));
|
||||
|
||||
WRITE_ONCE(dst->metric, READ_ONCE(src->metric));
|
||||
WRITE_ONCE(dst->bw_min, READ_ONCE(src->bw_min));
|
||||
WRITE_ONCE(dst->bw_max, READ_ONCE(src->bw_max));
|
||||
WRITE_ONCE(dst->burst, READ_ONCE(src->burst));
|
||||
WRITE_ONCE(dst->priority, READ_ONCE(src->priority));
|
||||
WRITE_ONCE(dst->weight, READ_ONCE(src->weight));
|
||||
|
||||
/* private fields are only used on the write path under the lock */
|
||||
data_race(dst->leaves = src->leaves);
|
||||
}
|
||||
|
||||
static int
|
||||
net_shaper_fill_one(struct sk_buff *msg,
|
||||
const struct net_shaper_binding *binding,
|
||||
const struct net_shaper *shaper,
|
||||
const struct genl_info *info)
|
||||
{
|
||||
struct net_shaper cur;
|
||||
void *hdr;
|
||||
|
||||
hdr = genlmsg_iput(msg, info);
|
||||
if (!hdr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
/* Make a copy to avoid data races */
|
||||
net_shaper_copy(&cur, shaper);
|
||||
|
||||
if (net_shaper_fill_binding(msg, binding, NET_SHAPER_A_IFINDEX) ||
|
||||
net_shaper_fill_handle(msg, &shaper->parent,
|
||||
net_shaper_fill_handle(msg, &cur.parent,
|
||||
NET_SHAPER_A_PARENT) ||
|
||||
net_shaper_fill_handle(msg, &shaper->handle,
|
||||
net_shaper_fill_handle(msg, &cur.handle,
|
||||
NET_SHAPER_A_HANDLE) ||
|
||||
((shaper->bw_min || shaper->bw_max || shaper->burst) &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_METRIC, shaper->metric)) ||
|
||||
(shaper->bw_min &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BW_MIN, shaper->bw_min)) ||
|
||||
(shaper->bw_max &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BW_MAX, shaper->bw_max)) ||
|
||||
(shaper->burst &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BURST, shaper->burst)) ||
|
||||
(shaper->priority &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_PRIORITY, shaper->priority)) ||
|
||||
(shaper->weight &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_WEIGHT, shaper->weight)))
|
||||
((cur.bw_min || cur.bw_max || cur.burst) &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_METRIC, cur.metric)) ||
|
||||
(cur.bw_min &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BW_MIN, cur.bw_min)) ||
|
||||
(cur.bw_max &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BW_MAX, cur.bw_max)) ||
|
||||
(cur.burst &&
|
||||
nla_put_uint(msg, NET_SHAPER_A_BURST, cur.burst)) ||
|
||||
(cur.priority &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_PRIORITY, cur.priority)) ||
|
||||
(cur.weight &&
|
||||
nla_put_u32(msg, NET_SHAPER_A_WEIGHT, cur.weight)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
|
@ -424,7 +447,7 @@ static void net_shaper_commit(struct net_shaper_binding *binding,
|
|||
/* Successful update: drop the tentative mark
|
||||
* and update the hierarchy container.
|
||||
*/
|
||||
*cur = shapers[i];
|
||||
net_shaper_copy(cur, &shapers[i]);
|
||||
smp_wmb();
|
||||
__xa_set_mark(&hierarchy->shapers, index, NET_SHAPER_VALID);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user