Skip to content

Commit 1fc5d95

Browse files
David Chinnernatoscott
authored andcommitted
[XFS] Fix inode reclaim scalability regression. When a filesystem has
millions of inodes cached and has sparse cluster population, removing inodes from the cluster hash consumes excessive amounts of CPU time. Reduce the CPU cost by making removal O(1) via use of a double linked list for the hash chains. SGI-PV: 951551 SGI-Modid: xfs-linux-melb:xfs-kern:25683a Signed-off-by: David Chinner <[email protected]> Signed-off-by: Nathan Scott <[email protected]>
1 parent 8272145 commit 1fc5d95

File tree

2 files changed

+13
-17
lines changed

2 files changed

+13
-17
lines changed

fs/xfs/xfs_iget.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,10 @@ xfs_iget_core(
421421
ip->i_chash = chlnew;
422422
chlnew->chl_ip = ip;
423423
chlnew->chl_blkno = ip->i_blkno;
424+
if (ch->ch_list)
425+
ch->ch_list->chl_prev = chlnew;
424426
chlnew->chl_next = ch->ch_list;
427+
chlnew->chl_prev = NULL;
425428
ch->ch_list = chlnew;
426429
chlnew = NULL;
427430
}
@@ -723,23 +726,15 @@ xfs_iextract(
723726
ASSERT(ip->i_cnext == ip && ip->i_cprev == ip);
724727
ASSERT(ip->i_chash != NULL);
725728
chm=NULL;
726-
for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
727-
if (chl->chl_blkno == ip->i_blkno) {
728-
if (chm == NULL) {
729-
/* first item on the list */
730-
ch->ch_list = chl->chl_next;
731-
} else {
732-
chm->chl_next = chl->chl_next;
733-
}
734-
kmem_zone_free(xfs_chashlist_zone, chl);
735-
break;
736-
} else {
737-
ASSERT(chl->chl_ip != ip);
738-
chm = chl;
739-
}
740-
}
741-
ASSERT_ALWAYS(chl != NULL);
742-
} else {
729+
chl = ip->i_chash;
730+
if (chl->chl_prev)
731+
chl->chl_prev->chl_next = chl->chl_next;
732+
else
733+
ch->ch_list = chl->chl_next;
734+
if (chl->chl_next)
735+
chl->chl_next->chl_prev = chl->chl_prev;
736+
kmem_zone_free(xfs_chashlist_zone, chl);
737+
} else {
743738
/* delete one inode from a non-empty list */
744739
iq = ip->i_cnext;
745740
iq->i_cprev = ip->i_cprev;

fs/xfs/xfs_inode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ typedef struct xfs_ihash {
189189
*/
190190
typedef struct xfs_chashlist {
191191
struct xfs_chashlist *chl_next;
192+
struct xfs_chashlist *chl_prev;
192193
struct xfs_inode *chl_ip;
193194
xfs_daddr_t chl_blkno; /* starting block number of
194195
* the cluster */

0 commit comments

Comments
 (0)