Skip to content

Commit b460a52

Browse files
committed
regcache: Push async I/O request down into the rbtree cache
Currently the regcache core unconditionally enables async I/O for all cache types, causing problems for the maple tree cache which dynamically allocates the buffers used to write registers to the device since async requires the buffers to be kept around until the I/O has been completed. This use of async I/O is mainly for the rbtree cache which stores data in a format directly usable for regmap_raw_write(), though there is a special case for single register writes which would also have allowed it to be used with the flat cache. It is a bit of a landmine for other caches since it implicitly converts sync operations to async, and with modern hardware it is not clear that async I/O is actually a performance win as shown by the performance work David Jander did with SPI. In multi core systems the cost of managing concurrency ends up swamping the performance benefit and almost all modern systems are multi core. Address this by pushing the enablement of async I/O down into the rbtree cache where it is actively used, avoiding surprises for other cache implementations. Reported-by: Charles Keepax <ckeepax@opensource.cirrus.com> Fixes: bfa0b38 ("regmap: maple: Implement block sync for the maple tree cache") Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com> Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20230719-regcache-async-rbtree-v1-1-b03d30cf1daf@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 0c9d2eb commit b460a52

File tree

2 files changed

+4
-3
lines changed

2 files changed

+4
-3
lines changed

drivers/base/regmap/regcache-rbtree.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
471471
unsigned int start, end;
472472
int ret;
473473

474+
map->async = true;
475+
474476
rbtree_ctx = map->cache;
475477
for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
476478
rbnode = rb_entry(node, struct regcache_rbtree_node, node);
@@ -499,6 +501,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
499501
return ret;
500502
}
501503

504+
map->async = false;
505+
502506
return regmap_async_complete(map);
503507
}
504508

drivers/base/regmap/regcache.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,6 @@ int regcache_sync(struct regmap *map)
368368
if (!map->cache_dirty)
369369
goto out;
370370

371-
map->async = true;
372-
373371
/* Apply any patch first */
374372
map->cache_bypass = true;
375373
for (i = 0; i < map->patch_regs; i++) {
@@ -392,7 +390,6 @@ int regcache_sync(struct regmap *map)
392390

393391
out:
394392
/* Restore the bypass state */
395-
map->async = false;
396393
map->cache_bypass = bypass;
397394
map->no_sync_defaults = false;
398395
map->unlock(map->lock_arg);

0 commit comments

Comments
 (0)