Skip to content

Commit

Permalink
fs/9p: use kvzalloc/kvfree to allocate struct p9_rdir and its buffer
Browse files Browse the repository at this point in the history
The buffers can easily get large and fail allocations. One of the
networking tests running in a VM tries to run perf which occasionally
ends with:

  perf: page allocation failure: order:6, mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0

Even tho free memory is available:

  free:97464 free_pcp:321 free_cma:0

Switch to kvzalloc() to make large allocations less likely to fail.

Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: NipaLocal <nipa@local>
  • Loading branch information
kuba-moo authored and NipaLocal committed Dec 3, 2024
1 parent 389b971 commit b4a23e4
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions fs/9p/vfs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
return fid->rdir;
}

static void v9fs_free_rdir_buf(struct file *filp)
{
struct p9_fid *fid = filp->private_data;

kfree(fid->rdir);
fid->rdir = NULL;
}

/**
* v9fs_dir_readdir - iterate through a directory
* @file: opened file structure
Expand Down Expand Up @@ -129,8 +137,10 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
over = !dir_emit(ctx, st.name, strlen(st.name),
QID2INO(&st.qid), dt_type(&st));
p9stat_free(&st);
if (over)
if (over) {
v9fs_free_rdir_buf(file);
return 0;
}

rdir->head += err;
ctx->pos += err;
Expand Down Expand Up @@ -185,8 +195,10 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
if (!dir_emit(ctx, curdirent.d_name,
strlen(curdirent.d_name),
QID2INO(&curdirent.qid),
curdirent.d_type))
curdirent.d_type)) {
v9fs_free_rdir_buf(file);
return 0;
}

ctx->pos = curdirent.d_off;
rdir->head += err;
Expand Down

0 comments on commit b4a23e4

Please sign in to comment.