summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolmes Chou <holmeschou@google.com>2023-04-27 04:07:47 +0000
committerHolmes Chou <holmeschou@google.com>2023-04-27 04:13:59 +0000
commitaa841a07067a4d06073e016d065ea4c4e139cdf4 (patch)
tree9f9291fbdbe6ddbd5970942469fee4dd5d8ededa
parentd4c5dd6632128acbf16e8e121a7c96084fcfee42 (diff)
downloadlwis-aa841a07067a4d06073e016d065ea4c4e139cdf4.tar.gz
LWIS: Allow user input GFP flags for different use cases
Extend LWIS recycling allocator to let users input GFP flags to make it suited for different use cases. Bug: 279671358 Test: GCA, CTS Change-Id: If0a96ce5a8889f2f77faa2e6ddd014c854a7782e Signed-off-by: Holmes Chou <holmeschou@google.com>
-rw-r--r--lwis_allocator.c10
-rw-r--r--lwis_allocator.h2
-rw-r--r--lwis_ioctl.c16
-rw-r--r--lwis_periodic_io.c2
4 files changed, 15 insertions, 15 deletions
diff --git a/lwis_allocator.c b/lwis_allocator.c
index 3b64fbd..0e4d55d 100644
--- a/lwis_allocator.c
+++ b/lwis_allocator.c
@@ -237,7 +237,7 @@ void lwis_allocator_release(struct lwis_device *lwis_dev)
mutex_unlock(&lwis_dev->client_lock);
}
-void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size)
+void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size, gfp_t gfp_flags)
{
struct lwis_allocator_block_mgr *block_mgr;
struct lwis_allocator_block_pool *block_pool;
@@ -301,7 +301,7 @@ void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size)
* memory on hand.
*/
if (idx > 19) {
- block = kmalloc(sizeof(struct lwis_allocator_block), GFP_KERNEL);
+ block = kmalloc(sizeof(struct lwis_allocator_block), gfp_flags);
if (block == NULL) {
dev_err(lwis_dev->dev, "Allocate failed\n");
return NULL;
@@ -309,7 +309,7 @@ void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size)
block->type = idx;
block->next = NULL;
block->prev = NULL;
- block->ptr = kvmalloc(size, GFP_KERNEL);
+ block->ptr = kvmalloc(size, gfp_flags);
if (block->ptr == NULL) {
dev_err(lwis_dev->dev, "Allocate failed\n");
kfree(block);
@@ -336,7 +336,7 @@ void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size)
}
/* Allocate new block */
- block = kmalloc(sizeof(struct lwis_allocator_block), GFP_KERNEL);
+ block = kmalloc(sizeof(struct lwis_allocator_block), gfp_flags);
if (block == NULL) {
dev_err(lwis_dev->dev, "Allocate failed\n");
return NULL;
@@ -345,7 +345,7 @@ void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size)
block->next = NULL;
block->prev = NULL;
block_size = 1 << idx;
- block->ptr = kvmalloc(block_size, GFP_KERNEL);
+ block->ptr = kvmalloc(block_size, gfp_flags);
if (block->ptr == NULL) {
dev_err(lwis_dev->dev, "Allocate failed\n");
kfree(block);
diff --git a/lwis_allocator.h b/lwis_allocator.h
index 3809b60..b72f0ba 100644
--- a/lwis_allocator.h
+++ b/lwis_allocator.h
@@ -62,7 +62,7 @@ void lwis_allocator_release(struct lwis_device *lwis_dev);
/*
* lwis_allocator_allocate: Allocate a block from the recycling memory allocator
*/
-void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size);
+void *lwis_allocator_allocate(struct lwis_device *lwis_dev, size_t size, gfp_t gfp_flags);
/*
* lwis_allocator_free: Free a block to the recycling memory allocator
diff --git a/lwis_ioctl.c b/lwis_ioctl.c
index ba53fed..c2ff8b9 100644
--- a/lwis_ioctl.c
+++ b/lwis_ioctl.c
@@ -80,8 +80,8 @@ static int register_read(struct lwis_device *lwis_dev, struct lwis_io_entry *rea
/* Save the userspace buffer address */
user_buf = read_entry->rw_batch.buf;
/* Allocate read buffer */
- read_entry->rw_batch.buf =
- lwis_allocator_allocate(lwis_dev, read_entry->rw_batch.size_in_bytes);
+ read_entry->rw_batch.buf = lwis_allocator_allocate(
+ lwis_dev, read_entry->rw_batch.size_in_bytes, GFP_KERNEL);
if (!read_entry->rw_batch.buf) {
dev_err_ratelimited(lwis_dev->dev,
"Failed to allocate register read buffer\n");
@@ -136,8 +136,8 @@ static int register_write(struct lwis_device *lwis_dev, struct lwis_io_entry *wr
/* Save the userspace buffer address */
user_buf = write_entry->rw_batch.buf;
/* Allocate write buffer and copy contents from userspace */
- write_entry->rw_batch.buf =
- lwis_allocator_allocate(lwis_dev, write_entry->rw_batch.size_in_bytes);
+ write_entry->rw_batch.buf = lwis_allocator_allocate(
+ lwis_dev, write_entry->rw_batch.size_in_bytes, GFP_KERNEL);
if (!write_entry->rw_batch.buf) {
dev_err_ratelimited(lwis_dev->dev,
"Failed to allocate register write buffer\n");
@@ -251,7 +251,7 @@ static int construct_io_entry(struct lwis_client *client, struct lwis_io_entry *
dev_err(lwis_dev->dev, "Failed to prepare io entries due to integer overflow\n");
return -EOVERFLOW;
}
- k_entries = lwis_allocator_allocate(lwis_dev, entry_size);
+ k_entries = lwis_allocator_allocate(lwis_dev, entry_size, GFP_KERNEL);
if (!k_entries) {
dev_err(lwis_dev->dev, "Failed to allocate io entries\n");
return -ENOMEM;
@@ -271,8 +271,8 @@ static int construct_io_entry(struct lwis_client *client, struct lwis_io_entry *
for (i = 0; i < num_io_entries; ++i) {
if (k_entries[i].type == LWIS_IO_ENTRY_WRITE_BATCH) {
user_buf = k_entries[i].rw_batch.buf;
- k_buf = lwis_allocator_allocate(lwis_dev,
- k_entries[i].rw_batch.size_in_bytes);
+ k_buf = lwis_allocator_allocate(
+ lwis_dev, k_entries[i].rw_batch.size_in_bytes, GFP_KERNEL);
if (!k_buf) {
dev_err_ratelimited(lwis_dev->dev,
"Failed to allocate io write buffer\n");
@@ -557,7 +557,7 @@ static int copy_io_entries_from_cmd(struct lwis_device *lwis_dev,
dev_err(lwis_dev->dev, "Failed to copy io_entries due to integer overflow.\n");
return -EOVERFLOW;
}
- io_entries = lwis_allocator_allocate(lwis_dev, buf_size);
+ io_entries = lwis_allocator_allocate(lwis_dev, buf_size, GFP_KERNEL);
if (!io_entries) {
dev_err(lwis_dev->dev, "Failed to allocate io_entries buffer\n");
return -ENOMEM;
diff --git a/lwis_periodic_io.c b/lwis_periodic_io.c
index 06f855b..442153e 100644
--- a/lwis_periodic_io.c
+++ b/lwis_periodic_io.c
@@ -44,7 +44,7 @@ static enum hrtimer_restart periodic_io_timer_func(struct hrtimer *timer)
periodic_io = list_entry(it_period, struct lwis_periodic_io, timer_list_node);
if (periodic_io->active) {
periodic_io_proxy = lwis_allocator_allocate(
- client->lwis_dev, sizeof(struct lwis_periodic_io_proxy));
+ client->lwis_dev, sizeof(*periodic_io_proxy), GFP_ATOMIC);
if (!periodic_io_proxy) {
/* Non-fatal, skip this period */
pr_warn("Cannot allocate new periodic io proxy.\n");