Skip to content

Commit 9574b21

Browse files
Ming Leiaxboe
authored andcommitted
kfifo: add kfifo_alloc_node() helper for NUMA awareness
Add __kfifo_alloc_node() by refactoring and reusing __kfifo_alloc(), and define kfifo_alloc_node() macro to support NUMA-aware memory allocation. The new __kfifo_alloc_node() function accepts a NUMA node parameter and uses kmalloc_array_node() instead of kmalloc_array() for node-specific allocation. The existing __kfifo_alloc() now calls __kfifo_alloc_node() with NUMA_NO_NODE to maintain backward compatibility. This enables users to allocate kfifo buffers on specific NUMA nodes, which is important for performance in NUMA systems where the kfifo will be primarily accessed by threads running on specific nodes. Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 89e1fb7 commit 9574b21

2 files changed

Lines changed: 36 additions & 6 deletions

File tree

include/linux/kfifo.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,30 @@ __kfifo_int_must_check_helper( \
369369
}) \
370370
)
371371

372+
/**
373+
* kfifo_alloc_node - dynamically allocates a new fifo buffer on a NUMA node
374+
* @fifo: pointer to the fifo
375+
* @size: the number of elements in the fifo, this must be a power of 2
376+
* @gfp_mask: get_free_pages mask, passed to kmalloc()
377+
* @node: NUMA node to allocate memory on
378+
*
379+
* This macro dynamically allocates a new fifo buffer with NUMA node awareness.
380+
*
381+
* The number of elements will be rounded-up to a power of 2.
382+
* The fifo will be release with kfifo_free().
383+
* Return 0 if no error, otherwise an error code.
384+
*/
385+
#define kfifo_alloc_node(fifo, size, gfp_mask, node) \
386+
__kfifo_int_must_check_helper( \
387+
({ \
388+
typeof((fifo) + 1) __tmp = (fifo); \
389+
struct __kfifo *__kfifo = &__tmp->kfifo; \
390+
__is_kfifo_ptr(__tmp) ? \
391+
__kfifo_alloc_node(__kfifo, size, sizeof(*__tmp->type), gfp_mask, node) : \
392+
-EINVAL; \
393+
}) \
394+
)
395+
372396
/**
373397
* kfifo_free - frees the fifo
374398
* @fifo: the fifo to be freed
@@ -899,8 +923,14 @@ __kfifo_uint_must_check_helper( \
899923
)
900924

901925

902-
extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
903-
size_t esize, gfp_t gfp_mask);
926+
extern int __kfifo_alloc_node(struct __kfifo *fifo, unsigned int size,
927+
size_t esize, gfp_t gfp_mask, int node);
928+
929+
static inline int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
930+
size_t esize, gfp_t gfp_mask)
931+
{
932+
return __kfifo_alloc_node(fifo, size, esize, gfp_mask, NUMA_NO_NODE);
933+
}
904934

905935
extern void __kfifo_free(struct __kfifo *fifo);
906936

lib/kfifo.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ static inline unsigned int kfifo_unused(struct __kfifo *fifo)
2222
return (fifo->mask + 1) - (fifo->in - fifo->out);
2323
}
2424

25-
int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
26-
size_t esize, gfp_t gfp_mask)
25+
int __kfifo_alloc_node(struct __kfifo *fifo, unsigned int size,
26+
size_t esize, gfp_t gfp_mask, int node)
2727
{
2828
/*
2929
* round up to the next power of 2, since our 'let the indices
@@ -41,7 +41,7 @@ int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
4141
return -EINVAL;
4242
}
4343

44-
fifo->data = kmalloc_array(esize, size, gfp_mask);
44+
fifo->data = kmalloc_array_node(esize, size, gfp_mask, node);
4545

4646
if (!fifo->data) {
4747
fifo->mask = 0;
@@ -51,7 +51,7 @@ int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
5151

5252
return 0;
5353
}
54-
EXPORT_SYMBOL(__kfifo_alloc);
54+
EXPORT_SYMBOL(__kfifo_alloc_node);
5555

5656
void __kfifo_free(struct __kfifo *fifo)
5757
{

0 commit comments

Comments
 (0)