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:
@ -59,6 +59,7 @@ struct regmap {
|
|||||||
regmap_lock lock;
|
regmap_lock lock;
|
||||||
regmap_unlock unlock;
|
regmap_unlock unlock;
|
||||||
void *lock_arg; /* This is passed to lock/unlock functions */
|
void *lock_arg; /* This is passed to lock/unlock functions */
|
||||||
|
gfp_t alloc_flags;
|
||||||
|
|
||||||
struct device *dev; /* Device we do I/O on */
|
struct device *dev; /* Device we do I/O on */
|
||||||
void *work_buf; /* Scratch buffer used to format I/O */
|
void *work_buf; /* Scratch buffer used to format I/O */
|
||||||
|
@ -561,6 +561,16 @@ struct regmap *__regmap_init(struct device *dev,
|
|||||||
}
|
}
|
||||||
map->lock_arg = map;
|
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.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
|
||||||
map->format.pad_bytes = config->pad_bits / 8;
|
map->format.pad_bytes = config->pad_bits / 8;
|
||||||
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
|
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
|
||||||
@ -1786,7 +1796,7 @@ out:
|
|||||||
if (!val_count)
|
if (!val_count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
|
wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
|
||||||
if (!wval) {
|
if (!wval) {
|
||||||
dev_err(map->dev, "Error in memory allocation\n");
|
dev_err(map->dev, "Error in memory allocation\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
Reference in New Issue
Block a user