linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization
@ 2020-01-29 15:44 Konstantin Khlebnikov
  2020-01-29 19:53 ` Andreas Dilger
  2020-01-29 22:15 ` Theodore Y. Ts'o
  0 siblings, 2 replies; 3+ messages in thread
From: Konstantin Khlebnikov @ 2020-01-29 15:44 UTC (permalink / raw)
  To: Theodore Ts'o, linux-kernel, David Howells, Alexander Viro,
	linux-fsdevel, linux-ext4, Dmitry Monakhov

Function ext4_update_other_inodes_time() implements optimization which
opportunistically updates times for inodes within same inode table block.

For now	concurrent inode lookup by number does not scale well because
inode hash table is protected with single spinlock. It could become very
hot at concurrent writes to fast nvme when inode cache has enough inodes.

Probably someday inode hash will become searchable under RCU.
(see linked patchset by David Howells)

Let's skip concurrent updates instead of wasting cpu time at spinlock.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Link: https://lore.kernel.org/lkml/155620449631.4720.8762546550728087460.stgit@warthog.procyon.org.uk/
---
 fs/ext4/inode.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 629a25d999f0..dc3e1b38e3ed 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4849,11 +4849,16 @@ static int other_inode_match(struct inode * inode, unsigned long ino,
 static void ext4_update_other_inodes_time(struct super_block *sb,
 					  unsigned long orig_ino, char *buf)
 {
+	static DEFINE_SPINLOCK(lock);
 	struct other_inode oi;
 	unsigned long ino;
 	int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
 	int inode_size = EXT4_INODE_SIZE(sb);
 
+	/* Don't bother inode_hash_lock with concurrent updates. */
+	if (!spin_trylock(&lock))
+		return;
+
 	oi.orig_ino = orig_ino;
 	/*
 	 * Calculate the first inode in the inode table block.  Inode
@@ -4867,6 +4872,8 @@ static void ext4_update_other_inodes_time(struct super_block *sb,
 		oi.raw_inode = (struct ext4_inode *) buf;
 		(void) find_inode_nowait(sb, ino, other_inode_match, &oi);
 	}
+
+	spin_unlock(&lock);
 }
 
 /*


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization
  2020-01-29 15:44 [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization Konstantin Khlebnikov
@ 2020-01-29 19:53 ` Andreas Dilger
  2020-01-29 22:15 ` Theodore Y. Ts'o
  1 sibling, 0 replies; 3+ messages in thread
From: Andreas Dilger @ 2020-01-29 19:53 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: Theodore Ts'o, Linux Kernel Mailing List, David Howells,
	Alexander Viro, linux-fsdevel, linux-ext4, Dmitry Monakhov

[-- Attachment #1: Type: text/plain, Size: 2372 bytes --]

On Jan 29, 2020, at 8:44 AM, Konstantin Khlebnikov <khlebnikov@yandex-team.ru> wrote:
> 
> Function ext4_update_other_inodes_time() implements optimization which
> opportunistically updates times for inodes within same inode table block.
> 
> For now	concurrent inode lookup by number does not scale well because
> inode hash table is protected with single spinlock. It could become very
> hot at concurrent writes to fast nvme when inode cache has enough inodes.
> 
> Probably someday inode hash will become searchable under RCU.
> (see linked patchset by David Howells)
> 
> Let's skip concurrent updates instead of wasting cpu time at spinlock.

Do you have any benchmark numbers to confirm that this is an improvement?
The performance results should be included here in the commit message, so
that the patch reviewers can make a useful decision about the patch, and
in the future if this patch is shown to be a regression for some other
workload we can see what workload(s) it originally improved performance on.

Cheers, Andreas

> 
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Link: https://lore.kernel.org/lkml/155620449631.4720.8762546550728087460.stgit@warthog.procyon.org.uk/
> ---
> fs/ext4/inode.c |    7 +++++++
> 1 file changed, 7 insertions(+)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 629a25d999f0..dc3e1b38e3ed 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -4849,11 +4849,16 @@ static int other_inode_match(struct inode * inode, unsigned long ino,
> static void ext4_update_other_inodes_time(struct super_block *sb,
> 					  unsigned long orig_ino, char *buf)
> {
> +	static DEFINE_SPINLOCK(lock);
> 	struct other_inode oi;
> 	unsigned long ino;
> 	int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
> 	int inode_size = EXT4_INODE_SIZE(sb);
> 
> +	/* Don't bother inode_hash_lock with concurrent updates. */
> +	if (!spin_trylock(&lock))
> +		return;
> +
> 	oi.orig_ino = orig_ino;
> 	/*
> 	 * Calculate the first inode in the inode table block.  Inode
> @@ -4867,6 +4872,8 @@ static void ext4_update_other_inodes_time(struct super_block *sb,
> 		oi.raw_inode = (struct ext4_inode *) buf;
> 		(void) find_inode_nowait(sb, ino, other_inode_match, &oi);
> 	}
> +
> +	spin_unlock(&lock);
> }
> 
> /*
> 


Cheers, Andreas






[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 873 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization
  2020-01-29 15:44 [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization Konstantin Khlebnikov
  2020-01-29 19:53 ` Andreas Dilger
@ 2020-01-29 22:15 ` Theodore Y. Ts'o
  1 sibling, 0 replies; 3+ messages in thread
From: Theodore Y. Ts'o @ 2020-01-29 22:15 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: linux-kernel, David Howells, Alexander Viro, linux-fsdevel,
	linux-ext4, Dmitry Monakhov

On Wed, Jan 29, 2020 at 06:44:05PM +0300, Konstantin Khlebnikov wrote:
> Function ext4_update_other_inodes_time() implements optimization which
> opportunistically updates times for inodes within same inode table block.
> 
> For now	concurrent inode lookup by number does not scale well because
> inode hash table is protected with single spinlock. It could become very
> hot at concurrent writes to fast nvme when inode cache has enough inodes.
> 
> Probably someday inode hash will become searchable under RCU.
> (see linked patchset by David Howells)
> 
> Let's skip concurrent updates instead of wasting cpu time at spinlock.
> 
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Link: https://lore.kernel.org/lkml/155620449631.4720.8762546550728087460.stgit@warthog.procyon.org.uk/

Hmm.... I wonder what Al thinks of adding a varaint of
find_inode_nowait() which uses tries to grab the inode_hash_lock()
using a trylock, and returns ERR_PTR(-EAGAIN) if the attempt to grab
the lock fails.

This might be better since it will prevent other conflicts between
ext4_update_other_inodes_time() and other attempts to lookup inodes
which can't be skipped if things are busy.

      	       	       	  	     - Ted

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-29 22:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-29 15:44 [PATCH RFC] ext4: skip concurrent inode updates in lazytime optimization Konstantin Khlebnikov
2020-01-29 19:53 ` Andreas Dilger
2020-01-29 22:15 ` Theodore Y. Ts'o

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).