Commit 5c36968343fcd013a3f7ae93f246c2e75596780b

Authored by Trond Myklebust
1 parent 9fd367f0f3

NFS cleanup: speed up nfs_scan_commit using radix tree tags

Add a tag for requests that are waiting for a COMMIT

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 3 changed files with 15 additions and 10 deletions Side-by-side Diff

... ... @@ -381,10 +381,10 @@
381 381 /**
382 382 * nfs_scan_list - Scan a list for matching requests
383 383 * @nfsi: NFS inode
384   - * @head: One of the NFS inode request lists
385 384 * @dst: Destination list
386 385 * @idx_start: lower bound of page->index to scan
387 386 * @npages: idx_start + npages sets the upper bound to scan.
  387 + * @tag: tag to scan for
388 388 *
389 389 * Moves elements from one of the inode request lists.
390 390 * If the number of requests is set to 0, the entire address_space
391 391  
... ... @@ -392,9 +392,9 @@
392 392 * The requests are *not* checked to ensure that they form a contiguous set.
393 393 * You must be holding the inode's req_lock when calling this function
394 394 */
395   -int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head,
  395 +int nfs_scan_list(struct nfs_inode *nfsi,
396 396 struct list_head *dst, pgoff_t idx_start,
397   - unsigned int npages)
  397 + unsigned int npages, int tag)
398 398 {
399 399 struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
400 400 struct nfs_page *req;
401 401  
... ... @@ -409,9 +409,9 @@
409 409 idx_end = idx_start + npages - 1;
410 410  
411 411 for (;;) {
412   - found = radix_tree_gang_lookup(&nfsi->nfs_page_tree,
  412 + found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree,
413 413 (void **)&pgvec[0], idx_start,
414   - NFS_SCAN_MAXENTRIES);
  414 + NFS_SCAN_MAXENTRIES, tag);
415 415 if (found <= 0)
416 416 break;
417 417 for (i = 0; i < found; i++) {
418 418  
... ... @@ -419,10 +419,10 @@
419 419 if (req->wb_index > idx_end)
420 420 goto out;
421 421 idx_start = req->wb_index + 1;
422   - if (req->wb_list_head != head)
423   - continue;
424 422 if (nfs_set_page_tag_locked(req)) {
425 423 nfs_list_remove_request(req);
  424 + radix_tree_tag_clear(&nfsi->nfs_page_tree,
  425 + req->wb_index, tag);
426 426 nfs_list_add_request(req, dst);
427 427 res++;
428 428 }
... ... @@ -462,6 +462,9 @@
462 462 nfs_list_add_request(req, &nfsi->commit);
463 463 nfsi->ncommit++;
464 464 set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
  465 + radix_tree_tag_set(&nfsi->nfs_page_tree,
  466 + req->wb_index,
  467 + NFS_PAGE_TAG_COMMIT);
465 468 spin_unlock(&nfsi->req_lock);
466 469 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
467 470 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
... ... @@ -575,7 +578,8 @@
575 578 int res = 0;
576 579  
577 580 if (nfsi->ncommit != 0) {
578   - res = nfs_scan_list(nfsi, &nfsi->commit, dst, idx_start, npages);
  581 + res = nfs_scan_list(nfsi, dst, idx_start, npages,
  582 + NFS_PAGE_TAG_COMMIT);
579 583 nfsi->ncommit -= res;
580 584 if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
581 585 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
include/linux/nfs_page.h
... ... @@ -22,6 +22,7 @@
22 22 * Valid flags for the radix tree
23 23 */
24 24 #define NFS_PAGE_TAG_LOCKED 0
  25 +#define NFS_PAGE_TAG_COMMIT 1
25 26  
26 27 /*
27 28 * Valid flags for a dirty buffer
... ... @@ -71,8 +72,8 @@
71 72 extern void nfs_release_request(struct nfs_page *req);
72 73  
73 74  
74   -extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, struct list_head *dst,
75   - pgoff_t idx_start, unsigned int npages);
  75 +extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst,
  76 + pgoff_t idx_start, unsigned int npages, int tag);
76 77 extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
77 78 struct inode *inode,
78 79 int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int),