From c557557e4a7fba0c580afd66b3f31f8d4186c7a5 Mon Sep 17 00:00:00 2001 From: "Ricardo M. Correia" Date: Wed, 10 Mar 2010 11:51:43 -0800 Subject: [PATCH] Add umem_alloc_aligned() and honor cache_align field for umem caches Under linux we open block devices with O_DIRECT which means we must provide aligned memory buffers. This patch adds the needed umem interfaces or in the case of caches simply honors alignment provided at cache creation time. --- lib/libspl/include/umem.h | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/libspl/include/umem.h b/lib/libspl/include/umem.h index 0ed55ae5af..87db1f451e 100644 --- a/lib/libspl/include/umem.h +++ b/lib/libspl/include/umem.h @@ -37,6 +37,7 @@ */ #include +#include #ifdef __cplusplus extern "C" { @@ -82,9 +83,30 @@ umem_alloc(size_t size, int flags) { void *ptr; - ptr = malloc(size); - while (ptr == NULL && (flags & UMEM_NOFAIL)) + do { ptr = malloc(size); + } while (ptr == NULL && (flags & UMEM_NOFAIL)); + + return ptr; +} + +static inline void * +umem_alloc_aligned(size_t size, size_t align, int flags) +{ + void *ptr; + int rc; + + do { + rc = posix_memalign(&ptr, align, size); + } while (rc == ENOMEM && (flags & UMEM_NOFAIL)); + + if (rc == EINVAL) { + fprintf(stderr, "%s: invalid memory alignment (%zd)\n", + __func__, align); + if (flags & UMEM_NOFAIL) + abort(); + return NULL; + } return ptr; } @@ -146,7 +168,11 @@ umem_cache_alloc(umem_cache_t *cp, int flags) { void *ptr; - ptr = umem_alloc(cp->cache_bufsize, flags); + if (cp->cache_align != 0) + ptr = umem_alloc_aligned(cp->cache_bufsize, cp->cache_align, flags); + else + ptr = umem_alloc(cp->cache_bufsize, flags); + if (ptr && cp->cache_constructor) cp->cache_constructor(ptr, cp->cache_private, UMEM_DEFAULT);