Messages in this thread Patch in this message | | | Date | Thu, 19 Oct 2023 12:50:48 +0200 | From | Michal Kubecek <> | Subject | Re: [PATCH net v1 1/1] ethtool: fix clearing of WoL flags |
| |
On Thu, Oct 19, 2023 at 12:21:14PM +0200, Köry Maincent wrote: > On Thu, 19 Oct 2023 11:51:40 +0200 > Michal Kubecek <mkubecek@suse.cz> wrote: > > > > The issue was indeed introduced by commit 108a36d07c01 ("ethtool: Fix > > mod state of verbose no_mask bitset"). The problem is that a "no mask" > > verbose bitset only contains bit attributes for bits to be set. This > > worked correctly before this commit because we were always updating > > a zero bitmap (since commit 6699170376ab ("ethtool: fix application of > > verbose no_mask bitset"), that is) so that the rest was left zero > > naturally. But now the 1->0 change (old_val is true, bit not present in > > netlink nest) no longer works. > > Doh I had not seen this issue! Thanks you for reporting it. > I will send the revert then and will update the fix for next merge-window.
Something like the diff below (against current mainline) might do the trick but it's just an idea, not even build tested.
Michal
diff --git a/net/ethtool/bitset.c b/net/ethtool/bitset.c index 883ed9be81f9..4d4398879c95 100644 --- a/net/ethtool/bitset.c +++ b/net/ethtool/bitset.c @@ -74,6 +74,28 @@ static void ethnl_bitmap32_clear(u32 *dst, unsigned int start, unsigned int end, } } +/** + * ethnl_bitmap32_equal() - Compare two bitmaps + * @map1: first bitmap + * @map2: second bitmap + * @nbits: bit size to compare + * + * Return: true if first @nbits are equal, false if not + */ + +static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2, + unsigned int nbits) +{ + bool ret; + + if (memcmp(map1, map2, nbits / 32 * sizeof(u32))) + return false; + if (nbits % 32 == 0) + return true; + return !((map1[nbits / 32] ^ map2[nbits / 32]) & + ethnl_lower_bits(nbits % 32)); +} + /** * ethnl_bitmap32_not_zero() - Check if any bit is set in an interval * @map: bitmap to test @@ -431,7 +453,7 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, ethnl_string_array_t names, struct netlink_ext_ack *extack, bool *mod) { - u32 *orig_bitmap, *saved_bitmap = NULL; + u32 *saved_bitmap = NULL; struct nlattr *bit_attr; bool no_mask; bool dummy; @@ -462,9 +484,6 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, return -ENOMEM; memcpy(saved_bitmap, bitmap, nbytes); ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy); - orig_bitmap = saved_bitmap; - } else { - orig_bitmap = bitmap; } nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) { @@ -481,7 +500,7 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, names, extack); if (ret < 0) goto out; - old_val = orig_bitmap[idx / 32] & ((u32)1 << (idx % 32)); + old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32)); if (new_val != old_val) { if (new_val) bitmap[idx / 32] |= ((u32)1 << (idx % 32)); @@ -490,6 +509,8 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, *mod = true; } } + if (saved_bitmap) + *mod = ethnl_bitmap32_cmp(saved_bitmap, bitmap, nbits); ret = 0; out:[unhandled content-type:application/pgp-signature] | |