Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fc5d959 authored by David Chinner's avatar David Chinner Committed by Nathan Scott
Browse files

[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: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 8272145c
Loading
Loading
Loading
Loading
+12 −17
Original line number Diff line number Diff line
@@ -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,22 +726,14 @@ 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 */
		chl = ip->i_chash;
		if (chl->chl_prev)
			chl->chl_prev->chl_next = chl->chl_next;
		else
			ch->ch_list = chl->chl_next;
				} else {
					chm->chl_next = chl->chl_next;
				}
		if (chl->chl_next)
			chl->chl_next->chl_prev = chl->chl_prev;
		kmem_zone_free(xfs_chashlist_zone, chl);
				break;
			} else {
				ASSERT(chl->chl_ip != ip);
				chm = chl;
			}
		}
		ASSERT_ALWAYS(chl != NULL);
	} else {
		/* delete one inode from a non-empty list */
		iq = ip->i_cnext;
+1 −0
Original line number Diff line number Diff line
@@ -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 */