summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-12-30 20:26:09 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2022-01-01 21:14:28 -0500
commit617dc6dd68f9fc4a65334de6ad499be29fcdaba4 (patch)
treecb877fb1d68d21dc8f9ce25b79ef55b0d4d895a7
parenta6390a80126b9a16406d2a6de31778abd652844d (diff)
Retry memory allocation failures
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--include/linux/slab.h40
-rw-r--r--include/linux/vmalloc.h14
2 files changed, 29 insertions, 25 deletions
diff --git a/include/linux/slab.h b/include/linux/slab.h
index ef861538..67633c98 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -16,20 +16,23 @@
static inline void *kmalloc(size_t size, gfp_t flags)
{
+ unsigned i = 0;
void *p;
- run_shrinkers();
-
- if (size) {
- size_t alignment = min(rounddown_pow_of_two(size), (size_t)PAGE_SIZE);
- alignment = max(sizeof(void *), alignment);
- if (posix_memalign(&p, alignment, size))
- p = NULL;
- } else {
- p = malloc(0);
- }
- if (p && (flags & __GFP_ZERO))
- memset(p, 0, size);
+ do {
+ run_shrinkers();
+
+ if (size) {
+ size_t alignment = min(rounddown_pow_of_two(size), (size_t)PAGE_SIZE);
+ alignment = max(sizeof(void *), alignment);
+ if (posix_memalign(&p, alignment, size))
+ p = NULL;
+ } else {
+ p = malloc(0);
+ }
+ if (p && (flags & __GFP_ZERO))
+ memset(p, 0, size);
+ } while (!p && i++ < 10);
return p;
}
@@ -38,8 +41,6 @@ static inline void *krealloc(void *old, size_t size, gfp_t flags)
{
void *new;
- run_shrinkers();
-
new = kmalloc(size, flags);
if (!new)
return NULL;
@@ -74,13 +75,16 @@ static inline void *krealloc(void *old, size_t size, gfp_t flags)
static inline struct page *alloc_pages(gfp_t flags, unsigned int order)
{
size_t size = PAGE_SIZE << order;
+ unsigned i = 0;
void *p;
- run_shrinkers();
+ do {
+ run_shrinkers();
- p = aligned_alloc(PAGE_SIZE, size);
- if (p && (flags & __GFP_ZERO))
- memset(p, 0, size);
+ p = aligned_alloc(PAGE_SIZE, size);
+ if (p && (flags & __GFP_ZERO))
+ memset(p, 0, size);
+ } while (!p && i++ < 10);
return p;
}
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index c674d9a2..ccb319eb 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -14,18 +14,18 @@
static inline void *__vmalloc(unsigned long size, gfp_t gfp_mask)
{
+ unsigned i = 0;
void *p;
size = round_up(size, PAGE_SIZE);
- run_shrinkers();
+ do {
+ run_shrinkers();
- p = aligned_alloc(PAGE_SIZE, size);
- if (!p)
- return NULL;
-
- if (gfp_mask & __GFP_ZERO)
- memset(p, 0, size);
+ p = aligned_alloc(PAGE_SIZE, size);
+ if (p && gfp_mask & __GFP_ZERO)
+ memset(p, 0, size);
+ } while (!p && i++ < 10);
return p;
}