[PATCH review for 4.4 46/47] xfs: remove kmem_zalloc_greedy

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: "Darrick J. Wong" 

[ Upstream commit 08b005f1333154ae5b404ca28766e0ffb9f1c150 ]

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.com

Signed-off-by: Darrick J. Wong 
Reviewed-by: Christoph Hellwig 
---
v2: remove single-page fallback

Signed-off-by: Sasha Levin 
---
 fs/xfs/kmem.c   | 18 --
 fs/xfs/kmem.h   |  2 --
 fs/xfs/xfs_itable.c |  6 ++
 3 files changed, 2 insertions(+), 24 deletions(-)

diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index 686ba6fb20dd..8067364c602f 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -24,24 +24,6 @@
 #include "kmem.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 *
 kmem_alloc(size_t size, xfs_km_flags_t flags)
 {
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index cc6b768fc068..ae45f77ce33b 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -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 *
 kmem_zalloc(size_t size, xfs_km_flags_t flags)
 {
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 930ebd86beba..99a4891c00ab 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -351,7 +351,6 @@ xfs_bulkstat(
xfs_agino_t agino;  /* inode # in allocation group */
xfs_agnumber_t  agno;   /* allocation group number */
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 */
int nirbuf; /* size of irbuf */
int ubcount; /* size of user's buffer */
@@ -378,11 +377,10 @@ xfs_bulkstat(
*ubcountp = 0;
*done = 0;
 
-   irbuf = kmem_zalloc_greedy(, PAGE_SIZE, PAGE_SIZE * 4);
+   irbuf = kmem_zalloc_large(PAGE_SIZE * 4, KM_SLEEP);
if (!irbuf)
return -ENOMEM;
-
-   nirbuf = irbsize / sizeof(*irbuf);
+   nirbuf = (PAGE_SIZE * 4) / sizeof(*irbuf);
 
/*
 * Loop over the allocation groups, starting from the last
-- 
2.11.0


[PATCH review for 4.4 46/47] xfs: remove kmem_zalloc_greedy

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: "Darrick J. Wong" 

[ Upstream commit 08b005f1333154ae5b404ca28766e0ffb9f1c150 ]

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.com

Signed-off-by: Darrick J. Wong 
Reviewed-by: Christoph Hellwig 
---
v2: remove single-page fallback

Signed-off-by: Sasha Levin 
---
 fs/xfs/kmem.c   | 18 --
 fs/xfs/kmem.h   |  2 --
 fs/xfs/xfs_itable.c |  6 ++
 3 files changed, 2 insertions(+), 24 deletions(-)

diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index 686ba6fb20dd..8067364c602f 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -24,24 +24,6 @@
 #include "kmem.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 *
 kmem_alloc(size_t size, xfs_km_flags_t flags)
 {
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index cc6b768fc068..ae45f77ce33b 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -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 *
 kmem_zalloc(size_t size, xfs_km_flags_t flags)
 {
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 930ebd86beba..99a4891c00ab 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -351,7 +351,6 @@ xfs_bulkstat(
xfs_agino_t agino;  /* inode # in allocation group */
xfs_agnumber_t  agno;   /* allocation group number */
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 */
int nirbuf; /* size of irbuf */
int ubcount; /* size of user's buffer */
@@ -378,11 +377,10 @@ xfs_bulkstat(
*ubcountp = 0;
*done = 0;
 
-   irbuf = kmem_zalloc_greedy(, PAGE_SIZE, PAGE_SIZE * 4);
+   irbuf = kmem_zalloc_large(PAGE_SIZE * 4, KM_SLEEP);
if (!irbuf)
return -ENOMEM;
-
-   nirbuf = irbsize / sizeof(*irbuf);
+   nirbuf = (PAGE_SIZE * 4) / sizeof(*irbuf);
 
/*
 * Loop over the allocation groups, starting from the last
-- 
2.11.0