public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Daniel McNeil <daniel@osdl.org>
To: Andrea Arcangeli <andrea@suse.de>
Cc: linux-kernel@vger.kernel.org
Subject: Re: 2.4.19rc2aa1 i_size atomic access
Date: 19 Jul 2002 15:56:36 -0700	[thread overview]
Message-ID: <1027119396.2629.16.camel@IBM-C> (raw)
In-Reply-To: <20020719112305.A15517@oldwotan.suse.de>

On Fri, 2002-07-19 at 02:23, Andrea Arcangeli wrote:
> On Thu, Jul 18, 2002 at 05:09:21PM -0700, Daniel McNeil wrote:
> > fstat() was an easy way to test for incorrect reading of i_size,
> > so I could test the cmpxchg8 code to read a 64-bit value.
> 
> yes that's probably the simpler way to reproduce it.
> 
> > This cacheline bouncing is the thing I don't like.  It was not clear
> 
> I don't like it either of course, but I couldn't figure out a way to read 64bit
> atomically without generating it.
> 
> > > 
> > > If you have suggestions that's welcome, thanks.
> > 
> > I'll let you know if I think of any.
> 
> I guess cmpxchg8b is the best way at least for 2.4.
> 
> Andrea

Andrea,

Here is another approach. I added two version fields to the inode
structure. The first one is updated before i_size and the 2nd is
updated after with memory barriers in between.  The i_size_read()
samples the version fields and i_size and loops until it can read
i_size without an i_size update happening at the same time.  It is
not pretty but it does fix the problem and the cache line is not
written by i_size_read() and it should work on all architechtures.
I've tested this on a two proc system.

Let me know what you think,

Daniel

--- linux-2.4.19-rc2aa1/include/linux/fs.h	Fri Jul 19 15:22:08 2002
+++ linux-2.4.19-rc2aa1.new/include/linux/fs.h	Fri Jul 19 15:22:25 2002
@@ -501,6 +501,8 @@
 	atomic_t		i_writecount;
 	unsigned int		i_attr_flags;
 	__u32			i_generation;
+	volatile short		i_attr_version1;
+	volatile short		i_attr_version2;
 	union {
 		struct minix_inode_info		minix_i;
 		struct ext2_inode_info		ext2_i;
@@ -539,7 +541,23 @@
 static inline loff_t i_size_read(struct inode * inode)
 {
 #if BITS_PER_LONG==32
-	return (loff_t) read_64bit((unsigned long long *) &inode->i_size);
+	short v1;
+	short v2;
+	loff_t i_size;
+
+	/*
+	 * retry if i_size was possibly modified while sampling.
+	 */
+	do {
+		v1 = inode->i_attr_version1;
+		v2 = inode->i_attr_version2;
+		rmb();
+		i_size = inode->i_size;
+		rmb();
+	} while (v1 != v2 ||
+		 v1 != inode->i_attr_version1 ||
+		 v1 != inode->i_attr_version2);
+	return i_size;
 #elif BITS_PER_LONG==64
 	return inode->i_size;
 #endif
@@ -548,8 +566,12 @@
 static inline void i_size_write(struct inode * inode, loff_t i_size)
 {
 #if BITS_PER_LONG==32
-	set_64bit((unsigned long long *) &inode->i_size,
-		  (unsigned long long) i_size);
+	inode->i_attr_version1++;       /* changing i_size */
+	wmb();
+	inode->i_size = i_size;
+	wmb();
+	inode->i_attr_version2++;       /* done with change */
+	wmb();
 #elif BITS_PER_LONG==64
 	inode->i_size = i_size;
 #endif


  reply	other threads:[~2002-07-19 22:53 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1026949132.20314.0.camel@joe2.pdx.osdl.net>
     [not found] ` <1026951041.2412.38.camel@IBM-C>
     [not found]   ` <20020718103511.GG994@dualathlon.random>
2002-07-19  0:09     ` 2.4.19rc2aa1 i_size atomic access Daniel McNeil
2002-07-19  9:23       ` Andrea Arcangeli
2002-07-19 22:56         ` Daniel McNeil [this message]
2002-07-23 16:56           ` Andrea Arcangeli
2002-07-23 17:08           ` Andrea Arcangeli
2002-07-23 17:47             ` Andrea Arcangeli
2002-07-23 18:15               ` Maciej W. Rozycki
2002-07-23 19:20                 ` Andrea Arcangeli
2002-07-24 14:19                   ` Maciej W. Rozycki
2002-07-24 14:26                     ` Andrea Arcangeli
2002-07-29 18:37               ` Bob Miller
2002-07-29 18:47                 ` Andrea Arcangeli
2002-07-30  0:34             ` Daniel McNeil
2002-07-30  1:12               ` Andrea Arcangeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1027119396.2629.16.camel@IBM-C \
    --to=daniel@osdl.org \
    --cc=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox