btrfs: add memalloc_nofs protections around alloc_workspace callback
The workspaces are preallocated at the beginning where we can safely use GFP_KERNEL, but in some cases the find_workspace might reach the allocation again, now in a more restricted context when the bios or pages are being compressed. To avoid potential lockup when alloc_workspace -> vmalloc would silently use the GFP_KERNEL, add the memalloc_nofs helpers around the critical call site. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
adf0212396
commit
fe30853307
|
@ -32,6 +32,7 @@
|
|||
#include <linux/writeback.h>
|
||||
#include <linux/bit_spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include "ctree.h"
|
||||
#include "disk-io.h"
|
||||
#include "transaction.h"
|
||||
|
@ -757,6 +758,7 @@ static struct list_head *find_workspace(int type)
|
|||
struct list_head *workspace;
|
||||
int cpus = num_online_cpus();
|
||||
int idx = type - 1;
|
||||
unsigned nofs_flag;
|
||||
|
||||
struct list_head *idle_ws = &btrfs_comp_ws[idx].idle_ws;
|
||||
spinlock_t *ws_lock = &btrfs_comp_ws[idx].ws_lock;
|
||||
|
@ -786,7 +788,15 @@ again:
|
|||
atomic_inc(total_ws);
|
||||
spin_unlock(ws_lock);
|
||||
|
||||
/*
|
||||
* Allocation helpers call vmalloc that can't use GFP_NOFS, so we have
|
||||
* to turn it off here because we might get called from the restricted
|
||||
* context of btrfs_compress_bio/btrfs_compress_pages
|
||||
*/
|
||||
nofs_flag = memalloc_nofs_save();
|
||||
workspace = btrfs_compress_op[idx]->alloc_workspace();
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
|
||||
if (IS_ERR(workspace)) {
|
||||
atomic_dec(total_ws);
|
||||
wake_up(ws_wait);
|
||||
|
|
Loading…
Reference in New Issue