提交 1fc5d959 编写于 作者: D David Chinner 提交者: Nathan Scott

[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: NDavid Chinner <dgc@sgi.com>
Signed-off-by: NNathan Scott <nathans@sgi.com>
上级 8272145c
......@@ -421,7 +421,10 @@ xfs_iget_core(
ip->i_chash = chlnew;
chlnew->chl_ip = ip;
chlnew->chl_blkno = ip->i_blkno;
if (ch->ch_list)
ch->ch_list->chl_prev = chlnew;
chlnew->chl_next = ch->ch_list;
chlnew->chl_prev = NULL;
ch->ch_list = chlnew;
chlnew = NULL;
}
......@@ -723,23 +726,15 @@ xfs_iextract(
ASSERT(ip->i_cnext == ip && ip->i_cprev == ip);
ASSERT(ip->i_chash != NULL);
chm=NULL;
for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
if (chl->chl_blkno == ip->i_blkno) {
if (chm == NULL) {
/* first item on the list */
ch->ch_list = chl->chl_next;
} else {
chm->chl_next = chl->chl_next;
}
kmem_zone_free(xfs_chashlist_zone, chl);
break;
} else {
ASSERT(chl->chl_ip != ip);
chm = chl;
}
}
ASSERT_ALWAYS(chl != NULL);
} else {
chl = ip->i_chash;
if (chl->chl_prev)
chl->chl_prev->chl_next = chl->chl_next;
else
ch->ch_list = chl->chl_next;
if (chl->chl_next)
chl->chl_next->chl_prev = chl->chl_prev;
kmem_zone_free(xfs_chashlist_zone, chl);
} else {
/* delete one inode from a non-empty list */
iq = ip->i_cnext;
iq->i_cprev = ip->i_cprev;
......
......@@ -189,6 +189,7 @@ typedef struct xfs_ihash {
*/
typedef struct xfs_chashlist {
struct xfs_chashlist *chl_next;
struct xfs_chashlist *chl_prev;
struct xfs_inode *chl_ip;
xfs_daddr_t chl_blkno; /* starting block number of
* the cluster */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册