xfs: improve kmem_realloc
authorChristoph Hellwig <hch@lst.de>
Tue, 5 Apr 2016 23:47:01 +0000 (09:47 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 5 Apr 2016 23:47:01 +0000 (09:47 +1000)
Use krealloc to implement our realloc function.  This helps to avoid
new allocations if we are still in the slab bucket.  At least for the
bmap btree root that's actually the common case.

This also allows removing the now unused oldsize argument.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/kmem.c
fs/xfs/kmem.h
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c

index 686ba6fb20ddc942638f6e698b98bf4c1bb8785f..339c696bbc0186b9a0064ec0146d5e143bbe2569 100644 (file)
@@ -93,19 +93,23 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
 }
 
 void *
-kmem_realloc(const void *ptr, size_t newsize, size_t oldsize,
-            xfs_km_flags_t flags)
+kmem_realloc(const void *old, size_t newsize, xfs_km_flags_t flags)
 {
-       void    *new;
+       int     retries = 0;
+       gfp_t   lflags = kmem_flags_convert(flags);
+       void    *ptr;
 
-       new = kmem_alloc(newsize, flags);
-       if (ptr) {
-               if (new)
-                       memcpy(new, ptr,
-                               ((oldsize < newsize) ? oldsize : newsize));
-               kmem_free(ptr);
-       }
-       return new;
+       do {
+               ptr = krealloc(old, newsize, lflags);
+               if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
+                       return ptr;
+               if (!(++retries % 100))
+                       xfs_err(NULL,
+       "%s(%u) possible memory allocation deadlock size %zu in %s (mode:0x%x)",
+                               current->comm, current->pid,
+                               newsize, __func__, lflags);
+               congestion_wait(BLK_RW_ASYNC, HZ/50);
+       } while (1);
 }
 
 void *
index d1c66e465ca5629fe3e330b9f6b87b07a5f9a1fa..689f746224e7ab8a0fbf3d2f9acb4f1dd68a9a16 100644 (file)
@@ -62,7 +62,7 @@ kmem_flags_convert(xfs_km_flags_t flags)
 
 extern void *kmem_alloc(size_t, xfs_km_flags_t);
 extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
-extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t);
+extern void *kmem_realloc(const void *, size_t, xfs_km_flags_t);
 static inline void  kmem_free(const void *ptr)
 {
        kvfree(ptr);
index 11faf7df14c8099e49759f51f0315dd5caec6632..1c842dce44b637a75402c95ed01c847b27a9cfa0 100644 (file)
@@ -516,7 +516,6 @@ xfs_iroot_realloc(
                new_max = cur_max + rec_diff;
                new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
                ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
-                               XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
                                KM_SLEEP | KM_NOFS);
                op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
                                                     ifp->if_broot_bytes);
@@ -660,7 +659,6 @@ xfs_idata_realloc(
                                ifp->if_u1.if_data =
                                        kmem_realloc(ifp->if_u1.if_data,
                                                        real_size,
-                                                       ifp->if_real_bytes,
                                                        KM_SLEEP | KM_NOFS);
                        }
                } else {
@@ -1376,8 +1374,7 @@ xfs_iext_realloc_direct(
                if (rnew_size != ifp->if_real_bytes) {
                        ifp->if_u1.if_extents =
                                kmem_realloc(ifp->if_u1.if_extents,
-                                               rnew_size,
-                                               ifp->if_real_bytes, KM_NOFS);
+                                               rnew_size, KM_NOFS);
                }
                if (rnew_size > ifp->if_real_bytes) {
                        memset(&ifp->if_u1.if_extents[ifp->if_bytes /
@@ -1461,9 +1458,8 @@ xfs_iext_realloc_indirect(
        if (new_size == 0) {
                xfs_iext_destroy(ifp);
        } else {
-               ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
-                       kmem_realloc(ifp->if_u1.if_ext_irec,
-                               new_size, size, KM_NOFS);
+               ifp->if_u1.if_ext_irec =
+                       kmem_realloc(ifp->if_u1.if_ext_irec, new_size, KM_NOFS);
        }
 }
 
index 396565f4324764058b979cf5e4c5bd96744f8ef8..bf6e807036136b458ed84251264e0c6021cefe1d 100644 (file)
@@ -3843,7 +3843,7 @@ xlog_recover_add_to_cont_trans(
        old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
        old_len = item->ri_buf[item->ri_cnt-1].i_len;
 
-       ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP);
+       ptr = kmem_realloc(old_ptr, len + old_len, KM_SLEEP);
        memcpy(&ptr[old_len], dp, len);
        item->ri_buf[item->ri_cnt-1].i_len += len;
        item->ri_buf[item->ri_cnt-1].i_addr = ptr;
index 536a0ee9cd5af1fbbc89960a597eb7158b676771..654799f716fc3918802c06914751bee4f4beaf50 100644 (file)
@@ -89,7 +89,6 @@ xfs_uuid_mount(
        if (hole < 0) {
                xfs_uuid_table = kmem_realloc(xfs_uuid_table,
                        (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
-                       xfs_uuid_table_size  * sizeof(*xfs_uuid_table),
                        KM_SLEEP);
                hole = xfs_uuid_table_size++;
        }
This page took 0.029064 seconds and 5 git commands to generate.