regmap: Allocate buffers with GFP_ATOMIC when fast_io == true

If a regmap is using fast_io, allocate the scratch buffer in
regmap_bulk_write() with GFP_ATOMIC instead of GFP_KERNEL.
Otherwise we may schedule while atomic.

Reported-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Stephen Boyd 2015-09-11 16:37:05 -07:00 committed by Mark Brown
parent 6ff33f3902
commit b4a21fc275
2 changed files with 12 additions and 1 deletions

View file

@ -59,6 +59,7 @@ struct regmap {
regmap_lock lock;
regmap_unlock unlock;
void *lock_arg; /* This is passed to lock/unlock functions */
gfp_t alloc_flags;
struct device *dev; /* Device we do I/O on */
void *work_buf; /* Scratch buffer used to format I/O */

View file

@ -561,6 +561,16 @@ struct regmap *__regmap_init(struct device *dev,
}
map->lock_arg = map;
}
/*
* When we write in fast-paths with regmap_bulk_write() don't allocate
* scratch buffers with sleeping allocations.
*/
if ((bus && bus->fast_io) || config->fast_io)
map->alloc_flags = GFP_ATOMIC;
else
map->alloc_flags = GFP_KERNEL;
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
map->format.pad_bytes = config->pad_bits / 8;
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
@ -1786,7 +1796,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
if (!val_count)
return -EINVAL;
wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
if (!wval) {
dev_err(map->dev, "Error in memory allocation\n");
return -ENOMEM;