diff mbox series

regmap: maple: Drop the RCU read lock while syncing registers

Message ID 20230523-regcache-maple-sync-lock-v1-1-530e4d68dfab@kernel.org (mailing list archive)
State New, archived
Headers show
Series regmap: maple: Drop the RCU read lock while syncing registers | expand

Commit Message

Mark Brown May 23, 2023, 10:18 p.m. UTC
Unfortunately the maple tree requires us to explicitly lock it so we need
to take the RCU read lock while iterating. When syncing this means that we
end up trying to write out register values while holding the RCU read lock
which triggers lockdep issues since that is an atomic context but most
buses can't be used in atomic context. Pause the iteration and drop the
lock for each register we check to avoid this.

Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/base/regmap/regcache-maple.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)


---
base-commit: 44c026a73be8038f03dbdeef028b642880cf1511
change-id: 20230523-regcache-maple-sync-lock-57ea356dc60b

Best regards,

Comments

Pierre-Louis Bossart May 23, 2023, 10:24 p.m. UTC | #1
On 5/23/23 17:18, Mark Brown wrote:
> Unfortunately the maple tree requires us to explicitly lock it so we need
> to take the RCU read lock while iterating. When syncing this means that we
> end up trying to write out register values while holding the RCU read lock
> which triggers lockdep issues since that is an atomic context but most
> buses can't be used in atomic context. Pause the iteration and drop the
> lock for each register we check to avoid this.
> 
> Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Closes: https://github.com/thesofproject/linux/issues/4371
Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  drivers/base/regmap/regcache-maple.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
> index 9b1b559107ef..c2e3a0f6c218 100644
> --- a/drivers/base/regmap/regcache-maple.c
> +++ b/drivers/base/regmap/regcache-maple.c
> @@ -203,15 +203,18 @@ static int regcache_maple_sync(struct regmap *map, unsigned int min,
>  
>  	mas_for_each(&mas, entry, max) {
>  		for (r = max(mas.index, lmin); r <= min(mas.last, lmax); r++) {
> +			mas_pause(&mas);
> +			rcu_read_unlock();
>  			ret = regcache_sync_val(map, r, entry[r - mas.index]);
>  			if (ret != 0)
>  				goto out;
> +			rcu_read_lock();
>  		}
>  	}
>  
> -out:
>  	rcu_read_unlock();
>  
> +out:
>  	map->cache_bypass = false;
>  
>  	return ret;
> 
> ---
> base-commit: 44c026a73be8038f03dbdeef028b642880cf1511
> change-id: 20230523-regcache-maple-sync-lock-57ea356dc60b
> 
> Best regards,
Mark Brown May 24, 2023, 11:58 a.m. UTC | #2
On Tue, 23 May 2023 23:18:19 +0100, Mark Brown wrote:
> Unfortunately the maple tree requires us to explicitly lock it so we need
> to take the RCU read lock while iterating. When syncing this means that we
> end up trying to write out register values while holding the RCU read lock
> which triggers lockdep issues since that is an atomic context but most
> buses can't be used in atomic context. Pause the iteration and drop the
> lock for each register we check to avoid this.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next

Thanks!

[1/1] regmap: maple: Drop the RCU read lock while syncing registers
      commit: 0cc6578048e0980d254aee345130cced4912f723

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark
diff mbox series

Patch

diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
index 9b1b559107ef..c2e3a0f6c218 100644
--- a/drivers/base/regmap/regcache-maple.c
+++ b/drivers/base/regmap/regcache-maple.c
@@ -203,15 +203,18 @@  static int regcache_maple_sync(struct regmap *map, unsigned int min,
 
 	mas_for_each(&mas, entry, max) {
 		for (r = max(mas.index, lmin); r <= min(mas.last, lmax); r++) {
+			mas_pause(&mas);
+			rcu_read_unlock();
 			ret = regcache_sync_val(map, r, entry[r - mas.index]);
 			if (ret != 0)
 				goto out;
+			rcu_read_lock();
 		}
 	}
 
-out:
 	rcu_read_unlock();
 
+out:
 	map->cache_bypass = false;
 
 	return ret;