Message ID | 20210126132311.3061388-2-idosch@idosch.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Add notifications when route hardware flags change | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | success | CCed 3 of 3 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | warning | WARNING: line length of 100 exceeds 80 columns |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On 1/26/21 6:23 AM, Ido Schimmel wrote: > @@ -889,22 +882,29 @@ static void nsim_nexthop_destroy(struct nsim_nexthop *nexthop) > static int nsim_nexthop_account(struct nsim_fib_data *data, u64 occ, > bool add, struct netlink_ext_ack *extack) > { > - int err = 0; > + int i, err = 0; > > if (add) { > - if (data->nexthops.num + occ <= data->nexthops.max) { > - data->nexthops.num += occ; > - } else { > - err = -ENOSPC; > - NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); > - } > + for (i = 0; i < occ; i++) > + if (!atomic64_add_unless(&data->nexthops.num, 1, > + data->nexthops.max)) { seems like this can be if (!atomic64_add_unless(&data->nexthops.num, occ, data->nexthops.max)) { and then the err_num_decrease is not needed > + err = -ENOSPC; > + NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); > + goto err_num_decrease; > + } > } else { > - if (WARN_ON(occ > data->nexthops.num)) > + if (WARN_ON(occ > atomic64_read(&data->nexthops.num))) > return -EINVAL; > - data->nexthops.num -= occ; > + atomic64_sub(occ, &data->nexthops.num); > } > > return err; > + > +err_num_decrease: > + for (i--; i >= 0; i--) > + atomic64_dec(&data->nexthops.num); and if this path is really needed, why not atomic64_sub here? > + return err; > + > } > > static int nsim_nexthop_add(struct nsim_fib_data *data, >
>-----Original Message----- >From: David Ahern <dsahern@gmail.com> >Sent: Wednesday, January 27, 2021 6:33 >To: Ido Schimmel <idosch@idosch.org>; netdev@vger.kernel.org >Cc: davem@davemloft.net; kuba@kernel.org; Amit Cohen <amcohen@nvidia.com>; Roopa Prabhu <roopa@nvidia.com>; Donald >Sharp <sharpd@nvidia.com>; Benjamin Poirier <bpoirier@nvidia.com>; mlxsw <mlxsw@nvidia.com>; Ido Schimmel ><idosch@nvidia.com> >Subject: Re: [PATCH net-next 01/10] netdevsim: fib: Convert the current occupancy to an atomic variable > >On 1/26/21 6:23 AM, Ido Schimmel wrote: >> @@ -889,22 +882,29 @@ static void nsim_nexthop_destroy(struct >> nsim_nexthop *nexthop) static int nsim_nexthop_account(struct nsim_fib_data *data, u64 occ, >> bool add, struct netlink_ext_ack *extack) { >> - int err = 0; >> + int i, err = 0; >> >> if (add) { >> - if (data->nexthops.num + occ <= data->nexthops.max) { >> - data->nexthops.num += occ; >> - } else { >> - err = -ENOSPC; >> - NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); >> - } >> + for (i = 0; i < occ; i++) >> + if (!atomic64_add_unless(&data->nexthops.num, 1, >> + data->nexthops.max)) { > >seems like this can be > if (!atomic64_add_unless(&data->nexthops.num, occ, > data->nexthops.max)) { atomic64_add_unless(x, y, z) adds y to x if x was not already z. Which means that when for example num=2, occ=2, max=3: atomic64_add_unless(&data->nexthops.num, occ, data->nexthops.max) won't fail when it should. This situation is realistic and actually with atomic64_add_unless() selftests/drivers/net/netdevsim/nexthop.sh fails. > >and then the err_num_decrease is not needed > >> + err = -ENOSPC; >> + NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); >> + goto err_num_decrease; >> + } >> } else { >> - if (WARN_ON(occ > data->nexthops.num)) >> + if (WARN_ON(occ > atomic64_read(&data->nexthops.num))) >> return -EINVAL; >> - data->nexthops.num -= occ; >> + atomic64_sub(occ, &data->nexthops.num); >> } >> >> return err; >> + >> +err_num_decrease: >> + for (i--; i >= 0; i--) >> + atomic64_dec(&data->nexthops.num); > >and if this path is really needed, why not atomic64_sub here? > >> + return err; >> + >> } >> >> static int nsim_nexthop_add(struct nsim_fib_data *data, >>
On 1/27/21 3:51 AM, Amit Cohen wrote: > > >> -----Original Message----- >> From: David Ahern <dsahern@gmail.com> >> Sent: Wednesday, January 27, 2021 6:33 >> To: Ido Schimmel <idosch@idosch.org>; netdev@vger.kernel.org >> Cc: davem@davemloft.net; kuba@kernel.org; Amit Cohen <amcohen@nvidia.com>; Roopa Prabhu <roopa@nvidia.com>; Donald >> Sharp <sharpd@nvidia.com>; Benjamin Poirier <bpoirier@nvidia.com>; mlxsw <mlxsw@nvidia.com>; Ido Schimmel >> <idosch@nvidia.com> >> Subject: Re: [PATCH net-next 01/10] netdevsim: fib: Convert the current occupancy to an atomic variable >> >> On 1/26/21 6:23 AM, Ido Schimmel wrote: >>> @@ -889,22 +882,29 @@ static void nsim_nexthop_destroy(struct >>> nsim_nexthop *nexthop) static int nsim_nexthop_account(struct nsim_fib_data *data, u64 occ, >>> bool add, struct netlink_ext_ack *extack) { >>> - int err = 0; >>> + int i, err = 0; >>> >>> if (add) { >>> - if (data->nexthops.num + occ <= data->nexthops.max) { >>> - data->nexthops.num += occ; >>> - } else { >>> - err = -ENOSPC; >>> - NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); >>> - } >>> + for (i = 0; i < occ; i++) >>> + if (!atomic64_add_unless(&data->nexthops.num, 1, >>> + data->nexthops.max)) { >> >> seems like this can be >> if (!atomic64_add_unless(&data->nexthops.num, occ, >> data->nexthops.max)) { > > atomic64_add_unless(x, y, z) adds y to x if x was not already z. > Which means that when for example num=2, occ=2, max=3: > atomic64_add_unless(&data->nexthops.num, occ, data->nexthops.max) won't fail when it should. > ok, missed that in the description. I thought it was if the total would equal or be greater than z.
diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c index 45d8a7790bd5..3f48c0883225 100644 --- a/drivers/net/netdevsim/fib.c +++ b/drivers/net/netdevsim/fib.c @@ -31,7 +31,7 @@ struct nsim_fib_entry { u64 max; - u64 num; + atomic64_t num; }; struct nsim_per_fib_data { @@ -46,7 +46,7 @@ struct nsim_fib_data { struct nsim_fib_entry nexthops; struct rhashtable fib_rt_ht; struct list_head fib_rt_list; - spinlock_t fib_lock; /* Protects hashtable, list and accounting */ + spinlock_t fib_lock; /* Protects hashtable and list */ struct notifier_block nexthop_nb; struct rhashtable nexthop_ht; struct devlink *devlink; @@ -128,7 +128,7 @@ u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, return 0; } - return max ? entry->max : entry->num; + return max ? entry->max : atomic64_read(&entry->num); } static void nsim_fib_set_max(struct nsim_fib_data *fib_data, @@ -165,14 +165,12 @@ static int nsim_fib_rule_account(struct nsim_fib_entry *entry, bool add, int err = 0; if (add) { - if (entry->num < entry->max) { - entry->num++; - } else { + if (!atomic64_add_unless(&entry->num, 1, entry->max)) { err = -ENOSPC; NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported fib rule entries"); } } else { - entry->num--; + atomic64_dec_if_positive(&entry->num); } return err; @@ -202,14 +200,12 @@ static int nsim_fib_account(struct nsim_fib_entry *entry, bool add, int err = 0; if (add) { - if (entry->num < entry->max) { - entry->num++; - } else { + if (!atomic64_add_unless(&entry->num, 1, entry->max)) { err = -ENOSPC; NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported fib entries"); } } else { - entry->num--; + atomic64_dec_if_positive(&entry->num); } return err; @@ -769,25 +765,22 @@ static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, struct fib_notifier_info *info = ptr; int err = 0; - /* IPv6 routes can be added via RAs from softIRQ. */ - spin_lock_bh(&data->fib_lock); - switch (event) { case FIB_EVENT_RULE_ADD: case FIB_EVENT_RULE_DEL: err = nsim_fib_rule_event(data, info, event == FIB_EVENT_RULE_ADD); break; - case FIB_EVENT_ENTRY_REPLACE: case FIB_EVENT_ENTRY_APPEND: case FIB_EVENT_ENTRY_DEL: + /* IPv6 routes can be added via RAs from softIRQ. */ + spin_lock_bh(&data->fib_lock); err = nsim_fib_event(data, info, event); + spin_unlock_bh(&data->fib_lock); break; } - spin_unlock_bh(&data->fib_lock); - return notifier_from_errno(err); } @@ -847,8 +840,8 @@ static void nsim_fib_dump_inconsistent(struct notifier_block *nb) nsim_fib_rt_free(fib_rt, data); } - data->ipv4.rules.num = 0ULL; - data->ipv6.rules.num = 0ULL; + atomic64_set(&data->ipv4.rules.num, 0ULL); + atomic64_set(&data->ipv6.rules.num, 0ULL); } static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data, @@ -889,22 +882,29 @@ static void nsim_nexthop_destroy(struct nsim_nexthop *nexthop) static int nsim_nexthop_account(struct nsim_fib_data *data, u64 occ, bool add, struct netlink_ext_ack *extack) { - int err = 0; + int i, err = 0; if (add) { - if (data->nexthops.num + occ <= data->nexthops.max) { - data->nexthops.num += occ; - } else { - err = -ENOSPC; - NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); - } + for (i = 0; i < occ; i++) + if (!atomic64_add_unless(&data->nexthops.num, 1, + data->nexthops.max)) { + err = -ENOSPC; + NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported nexthops"); + goto err_num_decrease; + } } else { - if (WARN_ON(occ > data->nexthops.num)) + if (WARN_ON(occ > atomic64_read(&data->nexthops.num))) return -EINVAL; - data->nexthops.num -= occ; + atomic64_sub(occ, &data->nexthops.num); } return err; + +err_num_decrease: + for (i--; i >= 0; i--) + atomic64_dec(&data->nexthops.num); + return err; + } static int nsim_nexthop_add(struct nsim_fib_data *data,