]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Retry memory allocation failures
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 31 Dec 2021 01:26:09 +0000 (20:26 -0500)
committerKent Overstreet <kent.overstreet@gmail.com>
Sun, 2 Jan 2022 02:14:28 +0000 (21:14 -0500)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
include/linux/slab.h
include/linux/vmalloc.h

index ef86153898130432d8119f9373546f7cb13124ec..67633c982e844c15fdf246502f807df1e5bd2ee3 100644 (file)
 
 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;
 }
index c674d9a2c05737da3e94d21234dd366f59ecbab9..ccb319eb52a4a444db0f5981f23a7acfa92bc2f7 100644 (file)
 
 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;
 }