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>
This commit is contained in:
parent
9f27889f3a
commit
664b60f6ba
|
@ -93,19 +93,23 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
kmem_realloc(const void *ptr, size_t newsize, size_t oldsize,
|
kmem_realloc(const void *old, size_t newsize, xfs_km_flags_t flags)
|
||||||
xfs_km_flags_t flags)
|
|
||||||
{
|
{
|
||||||
void *new;
|
int retries = 0;
|
||||||
|
gfp_t lflags = kmem_flags_convert(flags);
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
new = kmem_alloc(newsize, flags);
|
do {
|
||||||
if (ptr) {
|
ptr = krealloc(old, newsize, lflags);
|
||||||
if (new)
|
if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
|
||||||
memcpy(new, ptr,
|
return ptr;
|
||||||
((oldsize < newsize) ? oldsize : newsize));
|
if (!(++retries % 100))
|
||||||
kmem_free(ptr);
|
xfs_err(NULL,
|
||||||
}
|
"%s(%u) possible memory allocation deadlock size %zu in %s (mode:0x%x)",
|
||||||
return new;
|
current->comm, current->pid,
|
||||||
|
newsize, __func__, lflags);
|
||||||
|
congestion_wait(BLK_RW_ASYNC, HZ/50);
|
||||||
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -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_alloc(size_t, xfs_km_flags_t);
|
||||||
extern void *kmem_zalloc_large(size_t size, 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)
|
static inline void kmem_free(const void *ptr)
|
||||||
{
|
{
|
||||||
kvfree(ptr);
|
kvfree(ptr);
|
||||||
|
|
|
@ -516,7 +516,6 @@ xfs_iroot_realloc(
|
||||||
new_max = cur_max + rec_diff;
|
new_max = cur_max + rec_diff;
|
||||||
new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
|
new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
|
||||||
ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
|
ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
|
||||||
XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
|
|
||||||
KM_SLEEP | KM_NOFS);
|
KM_SLEEP | KM_NOFS);
|
||||||
op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
|
op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
|
||||||
ifp->if_broot_bytes);
|
ifp->if_broot_bytes);
|
||||||
|
@ -660,7 +659,6 @@ xfs_idata_realloc(
|
||||||
ifp->if_u1.if_data =
|
ifp->if_u1.if_data =
|
||||||
kmem_realloc(ifp->if_u1.if_data,
|
kmem_realloc(ifp->if_u1.if_data,
|
||||||
real_size,
|
real_size,
|
||||||
ifp->if_real_bytes,
|
|
||||||
KM_SLEEP | KM_NOFS);
|
KM_SLEEP | KM_NOFS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1376,8 +1374,7 @@ xfs_iext_realloc_direct(
|
||||||
if (rnew_size != ifp->if_real_bytes) {
|
if (rnew_size != ifp->if_real_bytes) {
|
||||||
ifp->if_u1.if_extents =
|
ifp->if_u1.if_extents =
|
||||||
kmem_realloc(ifp->if_u1.if_extents,
|
kmem_realloc(ifp->if_u1.if_extents,
|
||||||
rnew_size,
|
rnew_size, KM_NOFS);
|
||||||
ifp->if_real_bytes, KM_NOFS);
|
|
||||||
}
|
}
|
||||||
if (rnew_size > ifp->if_real_bytes) {
|
if (rnew_size > ifp->if_real_bytes) {
|
||||||
memset(&ifp->if_u1.if_extents[ifp->if_bytes /
|
memset(&ifp->if_u1.if_extents[ifp->if_bytes /
|
||||||
|
@ -1461,9 +1458,8 @@ xfs_iext_realloc_indirect(
|
||||||
if (new_size == 0) {
|
if (new_size == 0) {
|
||||||
xfs_iext_destroy(ifp);
|
xfs_iext_destroy(ifp);
|
||||||
} else {
|
} else {
|
||||||
ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
|
ifp->if_u1.if_ext_irec =
|
||||||
kmem_realloc(ifp->if_u1.if_ext_irec,
|
kmem_realloc(ifp->if_u1.if_ext_irec, new_size, KM_NOFS);
|
||||||
new_size, size, KM_NOFS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3843,7 +3843,7 @@ xlog_recover_add_to_cont_trans(
|
||||||
old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
|
old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
|
||||||
old_len = item->ri_buf[item->ri_cnt-1].i_len;
|
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);
|
memcpy(&ptr[old_len], dp, len);
|
||||||
item->ri_buf[item->ri_cnt-1].i_len += len;
|
item->ri_buf[item->ri_cnt-1].i_len += len;
|
||||||
item->ri_buf[item->ri_cnt-1].i_addr = ptr;
|
item->ri_buf[item->ri_cnt-1].i_addr = ptr;
|
||||||
|
|
|
@ -89,7 +89,6 @@ xfs_uuid_mount(
|
||||||
if (hole < 0) {
|
if (hole < 0) {
|
||||||
xfs_uuid_table = kmem_realloc(xfs_uuid_table,
|
xfs_uuid_table = kmem_realloc(xfs_uuid_table,
|
||||||
(xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
|
(xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
|
||||||
xfs_uuid_table_size * sizeof(*xfs_uuid_table),
|
|
||||||
KM_SLEEP);
|
KM_SLEEP);
|
||||||
hole = xfs_uuid_table_size++;
|
hole = xfs_uuid_table_size++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue