* [PATCH 0/2] iio: adc: ad*: Fix comparisons using memcmp @ 2025-01-30 17:45 Uwe Kleine-König 2025-01-30 17:45 ` [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König 2025-01-30 17:45 ` [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs Uwe Kleine-König 0 siblings, 2 replies; 8+ messages in thread From: Uwe Kleine-König @ 2025-01-30 17:45 UTC (permalink / raw) To: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Andy Shevchenko, Dumitru Ceclan Cc: linux-iio Hello, I recently sent a patch fixing a bad coding pattern in the ad7124 driver; see https://lore.kernel.org/linux-iio/20250124160124.435520-2-u.kleine-koenig@baylibre.com/. The same pattern is used for ad4130 and ad7173. This series fixes these two drivers in the same way. As for the ad7124 driver this didn't break in production and if the memcmp comparison wrongly returns false, nothing bad happens. Only usage of the resources isn't optimal then but that is probably nothing a user would notice. So there is no urge here. Still it's the correct thing to do to drop the comparison using memcmp and compare member-by-member instead. Best regards Uwe Uwe Kleine-König (2): iio: adc: ad4130: Fix comparison of channel setups iio: adc: ad7173: Fix comparison of channel configs drivers/iio/adc/ad4130.c | 33 +++++++++++++++++++++++++++++++-- drivers/iio/adc/ad7173.c | 15 ++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) base-commit: a13f6e0f405ed0d3bcfd37c692c7d7fa3c052154 -- 2.47.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups 2025-01-30 17:45 [PATCH 0/2] iio: adc: ad*: Fix comparisons using memcmp Uwe Kleine-König @ 2025-01-30 17:45 ` Uwe Kleine-König 2025-01-30 18:08 ` Andy Shevchenko 2025-01-30 18:14 ` Andy Shevchenko 2025-01-30 17:45 ` [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs Uwe Kleine-König 1 sibling, 2 replies; 8+ messages in thread From: Uwe Kleine-König @ 2025-01-30 17:45 UTC (permalink / raw) To: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Andy Shevchenko, Dumitru Ceclan Cc: linux-iio Checking the binary representation of two structs (of the same type) for equality doesn't have the same semantic as comparing all members for equality. The former might find a difference where the latter doesn't in the presence of padding or when ambiguous types like float or bool are involved. (Floats typically have different representations for single values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has at least 8 bits and the raw values 1 and 2 (probably) both evaluate to true, but memcmp finds a difference.) When searching for a channel that already has the configuration we need, the comparison by member is the one that is needed. Convert the comparison accordingly to compare the members one after another. Also add a BUILD_BUG guard to (somewhat) ensure that when struct ad4130_setup_info is expanded, the comparison is adapted, too. Fixes: 62094060cf3a ("iio: adc: ad4130: add AD4130 driver") Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> --- drivers/iio/adc/ad4130.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index de32cc9d18c5..ae321df426b5 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -591,6 +591,36 @@ static irqreturn_t ad4130_irq_handler(int irq, void *private) return IRQ_HANDLED; } +static bool ad4130_setup_info_eq(struct ad4130_setup_info *a, + struct ad4130_setup_info *b) +{ + BUILD_BUG_ON(sizeof(*a) != + sizeof(struct { + unsigned int iout0_val; + unsigned int iout1_val; + unsigned int burnout; + unsigned int pga; + unsigned int fs; + u32 ref_sel; + enum ad4130_filter_mode filter_mode; + bool ref_bufp; + bool ref_bufm; + })); + + if (a->iout0_val != b->iout0_val || + a->iout1_val != b->iout1_val || + a->burnout != b->burnout || + a->pga != b->pga || + a->fs != b->fs || + a->ref_sel != b->ref_sel || + a->filter_mode != b->filter_mode || + a->ref_bufp != b->ref_bufp || + a->ref_bufm != b->ref_bufm) + return false; + + return true; +} + static int ad4130_find_slot(struct ad4130_state *st, struct ad4130_setup_info *target_setup_info, unsigned int *slot, bool *overwrite) @@ -604,8 +634,7 @@ static int ad4130_find_slot(struct ad4130_state *st, struct ad4130_slot_info *slot_info = &st->slots_info[i]; /* Immediately accept a matching setup info. */ - if (!memcmp(target_setup_info, &slot_info->setup, - sizeof(*target_setup_info))) { + if (ad4130_setup_info_eq(target_setup_info, &slot_info->setup)) { *slot = i; return 0; } -- 2.47.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups 2025-01-30 17:45 ` [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König @ 2025-01-30 18:08 ` Andy Shevchenko 2025-01-30 18:14 ` Andy Shevchenko 1 sibling, 0 replies; 8+ messages in thread From: Andy Shevchenko @ 2025-01-30 18:08 UTC (permalink / raw) To: Uwe Kleine-König Cc: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Dumitru Ceclan, linux-iio On Thu, Jan 30, 2025 at 06:45:01PM +0100, Uwe Kleine-König wrote: > Checking the binary representation of two structs (of the same type) > for equality doesn't have the same semantic as comparing all members for > equality. The former might find a difference where the latter doesn't in > the presence of padding or when ambiguous types like float or bool are > involved. (Floats typically have different representations for single > values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has > at least 8 bits and the raw values 1 and 2 (probably) both evaluate to > true, but memcmp finds a difference.) > > When searching for a channel that already has the configuration we need, > the comparison by member is the one that is needed. > > Convert the comparison accordingly to compare the members one after > another. Also add a BUILD_BUG guard to (somewhat) ensure that when Why do you use BUILD_BUG_ON() instead of static_assert()? > struct ad4130_setup_info is expanded, the comparison is adapted, too. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups 2025-01-30 17:45 ` [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König 2025-01-30 18:08 ` Andy Shevchenko @ 2025-01-30 18:14 ` Andy Shevchenko 2025-02-12 9:01 ` Uwe Kleine-König 1 sibling, 1 reply; 8+ messages in thread From: Andy Shevchenko @ 2025-01-30 18:14 UTC (permalink / raw) To: Uwe Kleine-König Cc: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Dumitru Ceclan, linux-iio On Thu, Jan 30, 2025 at 06:45:01PM +0100, Uwe Kleine-König wrote: ... > + BUILD_BUG_ON(sizeof(*a) != > + sizeof(struct { > + unsigned int iout0_val; > + unsigned int iout1_val; > + unsigned int burnout; > + unsigned int pga; > + unsigned int fs; > + u32 ref_sel; > + enum ad4130_filter_mode filter_mode; > + bool ref_bufp; > + bool ref_bufm; > + })); Is I shuffle the fields (for whatever reason) this may give false positive warnings. I think this BUILD_BUG_ON() is unreliable and ugly looking (static_assert() won't help much here either), so on the second though I think it's better to simply add a comments in both places (here and near to the structure definition) to explain that these needs to be in sync. > + if (a->iout0_val != b->iout0_val || > + a->iout1_val != b->iout1_val || > + a->burnout != b->burnout || > + a->pga != b->pga || > + a->fs != b->fs || > + a->ref_sel != b->ref_sel || > + a->filter_mode != b->filter_mode || > + a->ref_bufp != b->ref_bufp || > + a->ref_bufm != b->ref_bufm) > + return false; > + > + return true; -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups 2025-01-30 18:14 ` Andy Shevchenko @ 2025-02-12 9:01 ` Uwe Kleine-König 2025-02-13 14:14 ` Nuno Sá 0 siblings, 1 reply; 8+ messages in thread From: Uwe Kleine-König @ 2025-02-12 9:01 UTC (permalink / raw) To: Andy Shevchenko Cc: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Dumitru Ceclan, linux-iio [-- Attachment #1: Type: text/plain, Size: 1314 bytes --] On Thu, Jan 30, 2025 at 08:14:39PM +0200, Andy Shevchenko wrote: > On Thu, Jan 30, 2025 at 06:45:01PM +0100, Uwe Kleine-König wrote: > > ... > > > + BUILD_BUG_ON(sizeof(*a) != > > + sizeof(struct { > > + unsigned int iout0_val; > > + unsigned int iout1_val; > > + unsigned int burnout; > > + unsigned int pga; > > + unsigned int fs; > > + u32 ref_sel; > > + enum ad4130_filter_mode filter_mode; > > + bool ref_bufp; > > + bool ref_bufm; > > + })); > > Is I shuffle the fields (for whatever reason) this may give false positive > warnings. That's fine in by book. Whenever the struct is changed it's a good opportunity to check if the cmp function needs adaption, too. > I think this BUILD_BUG_ON() is unreliable and ugly looking > (static_assert() won't help much here either), so on the second though I think > it's better to simply add a comments in both places (here and near to the > structure definition) to explain that these needs to be in sync. The nice thing about BUILD_BUG_ON (or static assert) is that the compiler quite reliably enforces the two being in sync. A comment doesn't. But I don't care much and can rework to use whatever pleases the responsible guys. Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups 2025-02-12 9:01 ` Uwe Kleine-König @ 2025-02-13 14:14 ` Nuno Sá 0 siblings, 0 replies; 8+ messages in thread From: Nuno Sá @ 2025-02-13 14:14 UTC (permalink / raw) To: Uwe Kleine-König, Andy Shevchenko Cc: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Dumitru Ceclan, linux-iio On Wed, 2025-02-12 at 10:01 +0100, Uwe Kleine-König wrote: > On Thu, Jan 30, 2025 at 08:14:39PM +0200, Andy Shevchenko wrote: > > On Thu, Jan 30, 2025 at 06:45:01PM +0100, Uwe Kleine-König wrote: > > > > ... > > > > > + BUILD_BUG_ON(sizeof(*a) != > > > + sizeof(struct { > > > + unsigned int iout0_val; > > > + unsigned int iout1_val; > > > + unsigned int burnout; > > > + unsigned int pga; > > > + unsigned int fs; > > > + u32 ref_sel; > > > + enum ad4130_filter_mode filter_mode; > > > + bool ref_bufp; > > > + bool ref_bufm; > > > + })); > > > > Is I shuffle the fields (for whatever reason) this may give false positive > > warnings. > > That's fine in by book. Whenever the struct is changed it's a good > opportunity to check if the cmp function needs adaption, too. > In practise I think shuffling the fields is unlikely... > > I think this BUILD_BUG_ON() is unreliable and ugly looking > > (static_assert() won't help much here either), so on the second though I > > think > > it's better to simply add a comments in both places (here and near to the > > structure definition) to explain that these needs to be in sync. > > The nice thing about BUILD_BUG_ON (or static assert) is that the > compiler quite reliably enforces the two being in sync. A comment > doesn't. > Agreed... I guess we could also add a comment on top of the affected struct so that if someone messes with it, is also aware of this comparison. - Nuno Sá ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs 2025-01-30 17:45 [PATCH 0/2] iio: adc: ad*: Fix comparisons using memcmp Uwe Kleine-König 2025-01-30 17:45 ` [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König @ 2025-01-30 17:45 ` Uwe Kleine-König 2025-01-30 18:11 ` Andy Shevchenko 1 sibling, 1 reply; 8+ messages in thread From: Uwe Kleine-König @ 2025-01-30 17:45 UTC (permalink / raw) To: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Andy Shevchenko, Dumitru Ceclan Cc: linux-iio Checking the binary representation of two structs (of the same type) for equality doesn't have the same semantic as comparing all members for equality. The former might find a difference where the latter doesn't in the presence of padding or when ambiguous types like float or bool are involved. (Floats typically have different representations for single values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has at least 8 bits and the raw values 1 and 2 (probably) both evaluate to true, but memcmp finds a difference.) When searching for a channel that already has the configuration we need, the comparison by member is the one that is needed. Convert the comparison accordingly to compare the members one after another. Also add a BUILD_BUG guard to (somewhat) ensure that when struct ad7173_channel_config::config_props is expanded, the comparison is adapted, too. Fixes: 76a1e6a42802 ("iio: adc: ad7173: add AD7173 driver") Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> --- drivers/iio/adc/ad7173.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 6c4ed10ae580..67821c889010 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -712,15 +712,24 @@ static struct ad7173_channel_config * ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg) { struct ad7173_channel_config *cfg_aux; - ptrdiff_t cmp_size; int i; - cmp_size = sizeof_field(struct ad7173_channel_config, config_props); + BUILD_BUG_ON(sizeof_field(struct ad7173_channel_config, config_props) != + sizeof(struct { + bool bipolar; + bool input_buf; + u8 odr; + u8 ref_sel; + })); + for (i = 0; i < st->num_channels; i++) { cfg_aux = &st->channels[i].cfg; if (cfg_aux->live && - !memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size)) + cfg->bipolar == cfg_aux->bipolar && + cfg->input_buf == cfg_aux->input_buf && + cfg->odr == cfg_aux->odr && + cfg->ref_sel == cfg_aux->ref_sel) return cfg_aux; } return NULL; -- 2.47.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs 2025-01-30 17:45 ` [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs Uwe Kleine-König @ 2025-01-30 18:11 ` Andy Shevchenko 0 siblings, 0 replies; 8+ messages in thread From: Andy Shevchenko @ 2025-01-30 18:11 UTC (permalink / raw) To: Uwe Kleine-König Cc: Cosmin Tanislav, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron, Michael Walle, Nuno Sa, Dumitru Ceclan, linux-iio On Thu, Jan 30, 2025 at 06:45:02PM +0100, Uwe Kleine-König wrote: > Checking the binary representation of two structs (of the same type) > for equality doesn't have the same semantic as comparing all members for > equality. The former might find a difference where the latter doesn't in > the presence of padding or when ambiguous types like float or bool are > involved. (Floats typically have different representations for single > values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has > at least 8 bits and the raw values 1 and 2 (probably) both evaluate to > true, but memcmp finds a difference.) memcmp() > When searching for a channel that already has the configuration we need, > the comparison by member is the one that is needed. > > Convert the comparison accordingly to compare the members one after > another. Also add a BUILD_BUG guard to (somewhat) ensure that when static_assert() will give a better messaging. > struct ad7173_channel_config::config_props is expanded, the comparison > is adapted, too. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-02-13 14:14 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-01-30 17:45 [PATCH 0/2] iio: adc: ad*: Fix comparisons using memcmp Uwe Kleine-König 2025-01-30 17:45 ` [PATCH 1/2] iio: adc: ad4130: Fix comparison of channel setups Uwe Kleine-König 2025-01-30 18:08 ` Andy Shevchenko 2025-01-30 18:14 ` Andy Shevchenko 2025-02-12 9:01 ` Uwe Kleine-König 2025-02-13 14:14 ` Nuno Sá 2025-01-30 17:45 ` [PATCH 2/2] iio: adc: ad7173: Fix comparison of channel configs Uwe Kleine-König 2025-01-30 18:11 ` Andy Shevchenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).