* [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true
@ 2015-09-10 19:27 Stephen Boyd
2015-09-11 10:28 ` Mark Brown
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Boyd @ 2015-09-10 19:27 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-kernel
If a regmap is using fast_io, allocate buffers in the write APIs
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>
---
drivers/base/regmap/internal.h | 1 +
drivers/base/regmap/regmap.c | 16 +++++++++++-----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 873ddf91c9d3..3470ec146f12 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -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 */
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 29128c6af445..0ad22f4d40b1 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -563,6 +563,12 @@ struct regmap *regmap_init(struct device *dev,
}
map->lock_arg = map;
}
+
+ 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);
@@ -1296,7 +1302,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
return -ENOMEM;
async->work_buf = kzalloc(map->format.buf_size,
- GFP_KERNEL | GFP_DMA);
+ map->alloc_flags | GFP_DMA);
if (!async->work_buf) {
kfree(async);
return -ENOMEM;
@@ -1358,7 +1364,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
/* If that didn't work fall back on linearising by hand. */
if (ret == -ENOTSUPP) {
len = map->format.reg_bytes + map->format.pad_bytes + val_len;
- buf = kzalloc(len, GFP_KERNEL);
+ buf = kzalloc(len, map->alloc_flags);
if (!buf)
return -ENOMEM;
@@ -1729,7 +1735,7 @@ out:
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;
@@ -1771,7 +1777,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
if (!len)
return -EINVAL;
- buf = kzalloc(len, GFP_KERNEL);
+ buf = kzalloc(len, map->alloc_flags);
if (!buf)
return -ENOMEM;
@@ -1909,7 +1915,7 @@ static int _regmap_multi_reg_write(struct regmap *map,
if (range) {
size_t len = sizeof(struct reg_sequence)*num_regs;
struct reg_sequence *base = kmemdup(regs, len,
- GFP_KERNEL);
+ map->alloc_flags);
if (!base)
return -ENOMEM;
ret = _regmap_range_multi_paged_reg_write(map, base,
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true
2015-09-10 19:27 [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true Stephen Boyd
@ 2015-09-11 10:28 ` Mark Brown
2015-09-11 16:16 ` Stephen Boyd
0 siblings, 1 reply; 4+ messages in thread
From: Mark Brown @ 2015-09-11 10:28 UTC (permalink / raw)
To: Stephen Boyd; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 452 bytes --]
On Thu, Sep 10, 2015 at 12:27:01PM -0700, Stephen Boyd wrote:
> If a regmap is using fast_io, allocate buffers in the write APIs
> with GFP_ATOMIC instead of GFP_KERNEL. Otherwise we may schedule
> while atomic.
Why is this needed? If something needs fast I/O it probably doesn't
want to be going down any of the code paths that result in us doing
allocations. I'd expect either no cache, a flat cache or setting up
defaults at initialisation time.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true
2015-09-11 10:28 ` Mark Brown
@ 2015-09-11 16:16 ` Stephen Boyd
2015-09-11 17:24 ` Mark Brown
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Boyd @ 2015-09-11 16:16 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-kernel, Abhijeet Dharmapurikar
On 09/11, Mark Brown wrote:
> On Thu, Sep 10, 2015 at 12:27:01PM -0700, Stephen Boyd wrote:
> > If a regmap is using fast_io, allocate buffers in the write APIs
> > with GFP_ATOMIC instead of GFP_KERNEL. Otherwise we may schedule
> > while atomic.
>
> Why is this needed? If something needs fast I/O it probably doesn't
> want to be going down any of the code paths that result in us doing
> allocations. I'd expect either no cache, a flat cache or setting up
> defaults at initialisation time.
We tripped over this with regmap_bulk_write() users on the SPMI
bus. How about going down the same paths as !map->can_multi_write
and map->use_single_rw if fast_io == true? Something like this
untested patch.
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 29128c6af445..4f2d75527c7f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,8 +573,8 @@ struct regmap *regmap_init(struct device *dev,
map->reg_stride = config->reg_stride;
else
map->reg_stride = 1;
- map->use_single_rw = config->use_single_rw;
- map->can_multi_write = config->can_multi_write;
+ map->use_single_rw = config->use_single_rw || config->fast_io;
+ map->can_multi_write = config->can_multi_write && !config->fast_io;
map->dev = dev;
map->bus = bus;
map->bus_context = bus_context;
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true
2015-09-11 16:16 ` Stephen Boyd
@ 2015-09-11 17:24 ` Mark Brown
0 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2015-09-11 17:24 UTC (permalink / raw)
To: Stephen Boyd; +Cc: linux-kernel, Abhijeet Dharmapurikar
[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]
On Fri, Sep 11, 2015 at 09:16:47AM -0700, Stephen Boyd wrote:
> On 09/11, Mark Brown wrote:
> > Why is this needed? If something needs fast I/O it probably doesn't
> > want to be going down any of the code paths that result in us doing
> > allocations. I'd expect either no cache, a flat cache or setting up
> > defaults at initialisation time.
> We tripped over this with regmap_bulk_write() users on the SPMI
> bus. How about going down the same paths as !map->can_multi_write
> and map->use_single_rw if fast_io == true? Something like this
> untested patch.
Hrm, OK. Bulk writes are a reasonable use case here but we should be
able to do better... if we had a cache we could bulk write directly
from the cache but I don't think the SPMI devices tend to have caches so
that won't help.
> - map->use_single_rw = config->use_single_rw;
> - map->can_multi_write = config->can_multi_write;
> + map->use_single_rw = config->use_single_rw || config->fast_io;
> + map->can_multi_write = config->can_multi_write && !config->fast_io;
The trouble with this is that you end up doing register at a time writes
which isn't ideal for performance. Unless we can figure out a way to
reliably allocate a bigger buffer ahead of time which I can't think of a
way to do reliably without just putting a random number in the config
(that we then end up either hitting or making too big) I think this is
actually a reasonable use case.
Can you redo your patch to touch only the allocations in your data paths
(I'm thinking particularly of the async changes as being unneeded, now I
look again you didn't touch the cache code anyway) and put a comment in
there about the alloc flags being used in fast path cases please?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-09-11 17:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-10 19:27 [PATCH] regmap: Allocate buffers with GFP_ATOMIC when fast_io == true Stephen Boyd
2015-09-11 10:28 ` Mark Brown
2015-09-11 16:16 ` Stephen Boyd
2015-09-11 17:24 ` Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.