ANDROID: fuse-bpf: Use cache and refcount

Allocates the iocb we create for asynchronous IO from a cache instead of
a regular kzalloc

Test: generic/467 and fuse_test
Bug: 217570523
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I27dcec89cd585835f6a8e80e1ae30c503f4038c8
This commit is contained in:
Daniel Rosenberg
2022-04-08 19:08:53 -07:00
parent 8e24eb9a2d
commit 128ed57bca
4 changed files with 45 additions and 7 deletions

View File

@@ -17,9 +17,12 @@
struct fuse_bpf_aio_req {
struct kiocb iocb;
refcount_t ref;
struct kiocb *iocb_orig;
};
static struct kmem_cache *fuse_bpf_aio_request_cachep;
static void fuse_file_accessed(struct file *dst_file, struct file *src_file)
{
struct inode *dst_inode;
@@ -810,6 +813,12 @@ void *fuse_removexattr_finalize(struct fuse_args *fa,
return NULL;
}
static inline void fuse_bpf_aio_put(struct fuse_bpf_aio_req *aio_req)
{
if (refcount_dec_and_test(&aio_req->ref))
kmem_cache_free(fuse_bpf_aio_request_cachep, aio_req);
}
static void fuse_bpf_aio_cleanup_handler(struct fuse_bpf_aio_req *aio_req)
{
struct kiocb *iocb = &aio_req->iocb;
@@ -821,9 +830,8 @@ static void fuse_bpf_aio_cleanup_handler(struct fuse_bpf_aio_req *aio_req)
file_end_write(iocb->ki_filp);
fuse_copyattr(iocb_orig->ki_filp, iocb->ki_filp);
}
iocb_orig->ki_pos = iocb->ki_pos;
kfree(aio_req);
fuse_bpf_aio_put(aio_req);
}
static void fuse_bpf_aio_rw_complete(struct kiocb *iocb, long res, long res2)
@@ -896,13 +904,16 @@ int fuse_file_read_iter_backing(struct fuse_args *fa,
struct fuse_bpf_aio_req *aio_req;
ret = -ENOMEM;
aio_req = kzalloc(sizeof(struct fuse_bpf_aio_req), GFP_KERNEL);
aio_req = kmem_cache_zalloc(fuse_bpf_aio_request_cachep, GFP_KERNEL);
if (!aio_req)
goto out;
aio_req->iocb_orig = iocb;
kiocb_clone(&aio_req->iocb, iocb, ff->backing_file);
aio_req->iocb.ki_complete = fuse_bpf_aio_rw_complete;
refcount_set(&aio_req->ref, 2);
ret = vfs_iocb_iter_read(ff->backing_file, &aio_req->iocb, to);
fuse_bpf_aio_put(aio_req);
if (ret != -EIOCBQUEUED)
fuse_bpf_aio_cleanup_handler(aio_req);
}
@@ -984,8 +995,7 @@ int fuse_file_write_iter_backing(struct fuse_args *fa,
struct fuse_bpf_aio_req *aio_req;
ret = -ENOMEM;
/* TODO get this from a cache? */
aio_req = kzalloc(sizeof(struct fuse_bpf_aio_req), GFP_KERNEL);
aio_req = kmem_cache_zalloc(fuse_bpf_aio_request_cachep, GFP_KERNEL);
if (!aio_req)
goto out;
@@ -994,7 +1004,9 @@ int fuse_file_write_iter_backing(struct fuse_args *fa,
aio_req->iocb_orig = iocb;
kiocb_clone(&aio_req->iocb, iocb, ff->backing_file);
aio_req->iocb.ki_complete = fuse_bpf_aio_rw_complete;
refcount_set(&aio_req->ref, 2);
ret = vfs_iocb_iter_write(ff->backing_file, &aio_req->iocb, from);
fuse_bpf_aio_put(aio_req);
if (ret != -EIOCBQUEUED)
fuse_bpf_aio_cleanup_handler(aio_req);
}
@@ -2369,3 +2381,19 @@ void *fuse_access_finalize(struct fuse_args *fa, struct inode *inode, int mask)
{
return NULL;
}
int __init fuse_bpf_init(void)
{
fuse_bpf_aio_request_cachep = kmem_cache_create("fuse_bpf_aio_req",
sizeof(struct fuse_bpf_aio_req),
0, SLAB_HWCACHE_ALIGN, NULL);
if (!fuse_bpf_aio_request_cachep)
return -ENOMEM;
return 0;
}
void __exit fuse_bpf_cleanup(void)
{
kmem_cache_destroy(fuse_bpf_aio_request_cachep);
}

View File

@@ -395,7 +395,7 @@ int __init fuse_ctl_init(void)
return register_filesystem(&fuse_ctl_fs_type);
}
void __exit fuse_ctl_cleanup(void)
void fuse_ctl_cleanup(void)
{
unregister_filesystem(&fuse_ctl_fs_type);
}

View File

@@ -1055,7 +1055,7 @@ int fuse_dev_init(void);
void fuse_dev_cleanup(void);
int fuse_ctl_init(void);
void __exit fuse_ctl_cleanup(void);
void fuse_ctl_cleanup(void);
/**
* Simple request sending that does request allocation and freeing
@@ -1780,6 +1780,9 @@ struct fuse_err_ret {
bool ret;
};
int __init fuse_bpf_init(void);
void __exit fuse_bpf_cleanup(void);
/*
* expression statement to wrap the backing filter logic
* struct inode *inode: inode with bpf and backing inode

View File

@@ -1903,11 +1903,17 @@ static int __init fuse_init(void)
if (res)
goto err_sysfs_cleanup;
res = fuse_bpf_init();
if (res)
goto err_ctl_cleanup;
sanitize_global_limit(&max_user_bgreq);
sanitize_global_limit(&max_user_congthresh);
return 0;
err_ctl_cleanup:
fuse_ctl_cleanup();
err_sysfs_cleanup:
fuse_sysfs_cleanup();
err_dev_cleanup:
@@ -1925,6 +1931,7 @@ static void __exit fuse_exit(void)
fuse_ctl_cleanup();
fuse_sysfs_cleanup();
fuse_fs_cleanup();
fuse_bpf_cleanup();
fuse_dev_cleanup();
}