aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-04-05 19:47:01 -0400
committerDave Chinner <david@fromorbit.com>2016-04-05 19:47:01 -0400
commit664b60f6babc98ee03c2ff15b9482cc8c5e15a83 (patch)
tree195d42b776a4e311a912147722aa516e9e6d9048 /fs/xfs
parent9f27889f3a96ff356ac92688cc0c4be3935ae3af (diff)
xfs: improve kmem_realloc
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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/kmem.c26
-rw-r--r--fs/xfs/kmem.h2
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c10
-rw-r--r--fs/xfs/xfs_log_recover.c2
-rw-r--r--fs/xfs/xfs_mount.c1
5 files changed, 20 insertions, 21 deletions
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index 686ba6fb20dd..339c696bbc01 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -93,19 +93,23 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
93} 93}
94 94
95void * 95void *
96kmem_realloc(const void *ptr, size_t newsize, size_t oldsize, 96kmem_realloc(const void *old, size_t newsize, xfs_km_flags_t flags)
97 xfs_km_flags_t flags)
98{ 97{
99 void *new; 98 int retries = 0;
99 gfp_t lflags = kmem_flags_convert(flags);
100 void *ptr;
100 101
101 new = kmem_alloc(newsize, flags); 102 do {
102 if (ptr) { 103 ptr = krealloc(old, newsize, lflags);
103 if (new) 104 if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
104 memcpy(new, ptr, 105 return ptr;
105 ((oldsize < newsize) ? oldsize : newsize)); 106 if (!(++retries % 100))
106 kmem_free(ptr); 107 xfs_err(NULL,
107 } 108 "%s(%u) possible memory allocation deadlock size %zu in %s (mode:0x%x)",
108 return new; 109 current->comm, current->pid,
110 newsize, __func__, lflags);
111 congestion_wait(BLK_RW_ASYNC, HZ/50);
112 } while (1);
109} 113}
110 114
111void * 115void *
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index d1c66e465ca5..689f746224e7 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -62,7 +62,7 @@ kmem_flags_convert(xfs_km_flags_t flags)
62 62
63extern void *kmem_alloc(size_t, xfs_km_flags_t); 63extern void *kmem_alloc(size_t, xfs_km_flags_t);
64extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t); 64extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
65extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); 65extern void *kmem_realloc(const void *, size_t, xfs_km_flags_t);
66static inline void kmem_free(const void *ptr) 66static inline void kmem_free(const void *ptr)
67{ 67{
68 kvfree(ptr); 68 kvfree(ptr);
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 11faf7df14c8..1c842dce44b6 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -516,7 +516,6 @@ xfs_iroot_realloc(
516 new_max = cur_max + rec_diff; 516 new_max = cur_max + rec_diff;
517 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); 517 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
518 ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, 518 ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
519 XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
520 KM_SLEEP | KM_NOFS); 519 KM_SLEEP | KM_NOFS);
521 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 520 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
522 ifp->if_broot_bytes); 521 ifp->if_broot_bytes);
@@ -660,7 +659,6 @@ xfs_idata_realloc(
660 ifp->if_u1.if_data = 659 ifp->if_u1.if_data =
661 kmem_realloc(ifp->if_u1.if_data, 660 kmem_realloc(ifp->if_u1.if_data,
662 real_size, 661 real_size,
663 ifp->if_real_bytes,
664 KM_SLEEP | KM_NOFS); 662 KM_SLEEP | KM_NOFS);
665 } 663 }
666 } else { 664 } else {
@@ -1376,8 +1374,7 @@ xfs_iext_realloc_direct(
1376 if (rnew_size != ifp->if_real_bytes) { 1374 if (rnew_size != ifp->if_real_bytes) {
1377 ifp->if_u1.if_extents = 1375 ifp->if_u1.if_extents =
1378 kmem_realloc(ifp->if_u1.if_extents, 1376 kmem_realloc(ifp->if_u1.if_extents,
1379 rnew_size, 1377 rnew_size, KM_NOFS);
1380 ifp->if_real_bytes, KM_NOFS);
1381 } 1378 }
1382 if (rnew_size > ifp->if_real_bytes) { 1379 if (rnew_size > ifp->if_real_bytes) {
1383 memset(&ifp->if_u1.if_extents[ifp->if_bytes / 1380 memset(&ifp->if_u1.if_extents[ifp->if_bytes /
@@ -1461,9 +1458,8 @@ xfs_iext_realloc_indirect(
1461 if (new_size == 0) { 1458 if (new_size == 0) {
1462 xfs_iext_destroy(ifp); 1459 xfs_iext_destroy(ifp);
1463 } else { 1460 } else {
1464 ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) 1461 ifp->if_u1.if_ext_irec =
1465 kmem_realloc(ifp->if_u1.if_ext_irec, 1462 kmem_realloc(ifp->if_u1.if_ext_irec, new_size, KM_NOFS);
1466 new_size, size, KM_NOFS);
1467 } 1463 }
1468} 1464}
1469 1465
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 396565f43247..bf6e80703613 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3843,7 +3843,7 @@ xlog_recover_add_to_cont_trans(
3843 old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; 3843 old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
3844 old_len = item->ri_buf[item->ri_cnt-1].i_len; 3844 old_len = item->ri_buf[item->ri_cnt-1].i_len;
3845 3845
3846 ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP); 3846 ptr = kmem_realloc(old_ptr, len + old_len, KM_SLEEP);
3847 memcpy(&ptr[old_len], dp, len); 3847 memcpy(&ptr[old_len], dp, len);
3848 item->ri_buf[item->ri_cnt-1].i_len += len; 3848 item->ri_buf[item->ri_cnt-1].i_len += len;
3849 item->ri_buf[item->ri_cnt-1].i_addr = ptr; 3849 item->ri_buf[item->ri_cnt-1].i_addr = ptr;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 536a0ee9cd5a..654799f716fc 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -89,7 +89,6 @@ xfs_uuid_mount(
89 if (hole < 0) { 89 if (hole < 0) {
90 xfs_uuid_table = kmem_realloc(xfs_uuid_table, 90 xfs_uuid_table = kmem_realloc(xfs_uuid_table,
91 (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table), 91 (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
92 xfs_uuid_table_size * sizeof(*xfs_uuid_table),
93 KM_SLEEP); 92 KM_SLEEP);
94 hole = xfs_uuid_table_size++; 93 hole = xfs_uuid_table_size++;
95 } 94 }