Commit 08b005f1 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: remove kmem_zalloc_greedy

The sole remaining caller of kmem_zalloc_greedy is bulkstat, which uses
it to grab 1-4 pages for staging of inobt records.  The infinite loop in
the greedy allocation function is causing hangs[1] in generic/269, so
just get rid of the greedy allocator in favor of kmem_zalloc_large.
This makes bulkstat somewhat more likely to ENOMEM if there's really no
pages to spare, but eliminates a source of hangs.

[1] http://lkml.kernel.org/r/20170301044634.rgidgdqqiiwsmfpj%40XZHOUW.usersys.redhat.comSigned-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
---
v2: remove single-page fallback
parent d5825712
...@@ -25,24 +25,6 @@ ...@@ -25,24 +25,6 @@
#include "kmem.h" #include "kmem.h"
#include "xfs_message.h" #include "xfs_message.h"
/*
* Greedy allocation. May fail and may return vmalloced memory.
*/
void *
kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize)
{
void *ptr;
size_t kmsize = maxsize;
while (!(ptr = vzalloc(kmsize))) {
if ((kmsize >>= 1) <= minsize)
kmsize = minsize;
}
if (ptr)
*size = kmsize;
return ptr;
}
void * void *
kmem_alloc(size_t size, xfs_km_flags_t flags) kmem_alloc(size_t size, xfs_km_flags_t flags)
{ {
......
...@@ -69,8 +69,6 @@ static inline void kmem_free(const void *ptr) ...@@ -69,8 +69,6 @@ static inline void kmem_free(const void *ptr)
} }
extern void *kmem_zalloc_greedy(size_t *, size_t, size_t);
static inline void * static inline void *
kmem_zalloc(size_t size, xfs_km_flags_t flags) kmem_zalloc(size_t size, xfs_km_flags_t flags)
{ {
......
...@@ -361,7 +361,6 @@ xfs_bulkstat( ...@@ -361,7 +361,6 @@ xfs_bulkstat(
xfs_agino_t agino; /* inode # in allocation group */ xfs_agino_t agino; /* inode # in allocation group */
xfs_agnumber_t agno; /* allocation group number */ xfs_agnumber_t agno; /* allocation group number */
xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
size_t irbsize; /* size of irec buffer in bytes */
xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */
int nirbuf; /* size of irbuf */ int nirbuf; /* size of irbuf */
int ubcount; /* size of user's buffer */ int ubcount; /* size of user's buffer */
...@@ -388,11 +387,10 @@ xfs_bulkstat( ...@@ -388,11 +387,10 @@ xfs_bulkstat(
*ubcountp = 0; *ubcountp = 0;
*done = 0; *done = 0;
irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4); irbuf = kmem_zalloc_large(PAGE_SIZE * 4, KM_SLEEP);
if (!irbuf) if (!irbuf)
return -ENOMEM; return -ENOMEM;
nirbuf = (PAGE_SIZE * 4) / sizeof(*irbuf);
nirbuf = irbsize / sizeof(*irbuf);
/* /*
* Loop over the allocation groups, starting from the last * Loop over the allocation groups, starting from the last
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment