History

fuse: allocate page array more efficiently

When allocating page array for a request the array for the page pointers and the array for page descriptors are allocated by two separate kmalloc() calls. Merge these into one allocation. Also instead of initializing the request and the page arrays with memset(), use the zeroing allocation variants. Reserved requests never carry pages (page array size is zero). Make that explicit by initializing the page array pointers to NULL and make sure the assumption remains true by adding a WARN_ON().

Miklos Szeredi committed 8 years ago

Commit 8a7aa281 parent ab2257e1 file · +18 −26Browse files

Unified · Split

fs/fuse/dev.c+18−26
@@ -44,9 +44,6 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, · 43 unmodified lines
4444 struct fuse_page_desc *page_descs,
4545 unsigned npages)
4646 {
47− memset(req, 0, sizeof(*req));
48− memset(pages, 0, sizeof(*pages) * npages);
49− memset(page_descs, 0, sizeof(*page_descs) * npages);
5047 INIT_LIST_HEAD(&req->list);
5148 INIT_LIST_HEAD(&req->intr_entry);
5249 init_waitqueue_head(&req->waitq);
@@ -59,28 +56,22 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, · 6 unmodified lines
5956
6057 static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
6158 {
62− struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags);
59+ struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
6360 if (req) {
64− struct page **pages;
65− struct fuse_page_desc *page_descs;
66−
67− if (npages <= FUSE_REQ_INLINE_PAGES) {
61+ struct page **pages = NULL;
62+ struct fuse_page_desc *page_descs = NULL;
63+
64+ if (npages > FUSE_REQ_INLINE_PAGES) {
65+ pages = kzalloc(npages * (sizeof(*pages) +
66+ sizeof(*page_descs)), flags);
67+ if (!pages) {
68+ kmem_cache_free(fuse_req_cachep, req);
69+ return NULL;
70+ }
71+ page_descs = (void *) pages + npages * sizeof(*pages);
72+ } else if (npages) {
6873 pages = req->inline_pages;
6974 page_descs = req->inline_page_descs;
70− } else {
71− pages = kmalloc_array(npages, sizeof(struct page *),
72− flags);
73− page_descs =
74− kmalloc_array(npages,
75− sizeof(struct fuse_page_desc),
76− flags);
77− }
78−
79− if (!pages || !page_descs) {
80− kfree(pages);
81− kfree(page_descs);
82− kmem_cache_free(fuse_req_cachep, req);
83− return NULL;
8475 }
8576
8677 fuse_request_init(req, pages, page_descs, npages);
@@ -101,10 +92,9 @@ struct fuse_req *fuse_request_alloc_nofs(unsigned npages) · 14 unmodified lines
10192
10293 void fuse_request_free(struct fuse_req *req)
10394 {
104− if (req->pages != req->inline_pages) {
95+ if (req->pages != req->inline_pages)
10596 kfree(req->pages);
106− kfree(req->page_descs);
107− }
97+
10898 kmem_cache_free(fuse_req_cachep, req);
10999 }
110100
@@ -239,8 +229,10 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) · 128 unmodified lines
239229 struct file *file = req->stolen_file;
240230 struct fuse_file *ff = file->private_data;
241231
232+ WARN_ON(req->max_pages);
242233 spin_lock(&fc->lock);
243− fuse_request_init(req, req->pages, req->page_descs, req->max_pages);
234+ memset(req, 0, sizeof(*req));
235+ fuse_request_init(req, NULL, NULL, 0);
244236 BUG_ON(ff->reserved_req);
245237 ff->reserved_req = req;
246238 wake_up_all(&fc->reserved_req_waitq);