Skip to contentSkip to conversation

FastWalk to reduce cacheline bouncing in Dcache

PATCH New Hanna Linder 1 participant 1 message Apr 23, 2002 VFS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 FastWalk to reduce cacheline bouncing in Dcache

Please consider this patch for inclusion in 2.5.X. I have
made changes to reduce cacheline bouncing when a dentry is in the cache based on suggestions you made.
Specifically, the d_count reference counter is not incremented
and decremented for every dentry in a path during path walking if the dentry is in the dcache. Execcisve atomic inc/dec's are expensive on SMP systems due to the cachline bouncing.
The patch can also be found at:
http://prdownloads.sf.net/lse/fast_walkA1-2.5.9.patch

Hanna Linder
[email protected]
IBM Linux Technology Center
--------

fs/dcache.c +10 -3
diff -Nru -Xdontdiff linux-2.5.9/fs/dcache.c linux-fastwalk/fs/dcache.c
@@ -846,13 +846,22 @@
  
 struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
 {
+	struct dentry * dentry;
+	spin_lock(&dcache_lock);
+	dentry = __d_lookup(parent,name);
+	spin_unlock(&dcache_lock);
+	return dentry;
+}
+
+struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)  
+{
+
 	unsigned int len = name->len;
 	unsigned int hash = name->hash;
 	const unsigned char *str = name->name;
 	struct list_head *head = d_hash(parent,hash);
 	struct list_head *tmp;
 
-	spin_lock(&dcache_lock);
 	tmp = head->next;
 	for (;;) {
 		struct dentry * dentry = list_entry(tmp, struct dentry, d_hash);
@@ -874,10 +883,8 @@
 		}
 		__dget_locked(dentry);
 		dentry->d_vfs_flags |= DCACHE_REFERENCED;
-		spin_unlock(&dcache_lock);
 		return dentry;
 	}
-	spin_unlock(&dcache_lock);
 	return NULL;
 }
 
fs/namei.c +113 -6

199 lines not on this page · raw message

include/linux/dcache.h +1 -0
diff -Nru -Xdontdiff linux-2.5.9/include/linux/dcache.h linux-fastwalk/include/linux/dcache.h
@@ -229,6 +229,7 @@
 
 /* appendix may either be NULL or be used for transname suffixes */
 extern struct dentry * d_lookup(struct dentry *, struct qstr *);
+extern struct dentry * __d_lookup(struct dentry *, struct qstr *);
 
 /* validate "insecure" dentry pointer */
 extern int d_validate(struct dentry *, struct dentry *);
include/linux/fs.h +4 -7
diff -Nru -Xdontdiff linux-2.5.9/include/linux/fs.h linux-fastwalk/include/linux/fs.h
@@ -1386,12 +1386,15 @@
  *  - require a directory
  *  - ending slashes ok even for nonexistent files
  *  - internal "there are more path compnents" flag
+ *  - locked when lookup done with dcache_lock held
  */
 #define LOOKUP_FOLLOW		(1)
 #define LOOKUP_DIRECTORY	(2)
 #define LOOKUP_CONTINUE		(4)
 #define LOOKUP_PARENT		(16)
 #define LOOKUP_NOALT		(32)
+#define LOOKUP_LOCKED		(64)
+
 /*
  * Type of the last component on LOOKUP_PARENT
  */
@@ -1421,14 +1424,8 @@
 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(path_walk(const char *, struct nameidata *));
+extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
-static inline int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
-{
-	int error = 0;
-	if (path_init(path, flags, nd))
-		error = path_walk(path, nd);
-	return error;
-}
 extern void path_release(struct nameidata *);
 extern int follow_down(struct vfsmount **, struct dentry **);
 extern int follow_up(struct vfsmount **, struct dentry **);