All of lore.kernel.org
 help / color / mirror / Atom feed
* dcache shrink list corruption?
@ 2014-04-29 16:01 Miklos Szeredi
  2014-04-29 17:43 ` Linus Torvalds
  2014-04-29 17:56 ` Al Viro
  0 siblings, 2 replies; 61+ messages in thread
From: Miklos Szeredi @ 2014-04-29 16:01 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds, linux-kernel, linux-fsdevel

This was reported by IBM for 3.12, but if my analysis is right, it affects
current kernel as well as older ones.

So the question is: does anything protect the shrink list from concurrent
modification by one or more dput() instances?

E.g. two dentries are on the shrink list, for both dget(), d_drop() and dput()
are called.  dput() -> dentry_kill() -> dentry_lru_del() -> d_shrink_del() ->
list_del_init().  Unlike the LRU list this is only protected with d_lock on the
individual dentries, which is not enough to prevent list corruption:

list->next = a, list->prev = b
a->next = b, a->prev = list
b->next = list, b->prev = a

CPU1: list_del_init(b)
        __list_del(a, list)
             a->next = list ...
CPU2: list_del_init(a)
        __list_del(list, list)
             list->next = list
             list->prev = list
CPU1: (continuing list_del_init(b))
             list->prev = a

Attached patch is just a starting point (untested).  Not sure how to minimize
contention without adding too much complexity.

Thanks,
Miklos


diff --git a/fs/dcache.c b/fs/dcache.c
index 40707d88a945..5e0719292e3e 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -357,10 +357,14 @@ static void d_lru_del(struct dentry *dentry)
 	WARN_ON_ONCE(!list_lru_del(&dentry->d_sb->s_dentry_lru, &dentry->d_lru));
 }
 
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_shrink_lock);
+
 static void d_shrink_del(struct dentry *dentry)
 {
 	D_FLAG_VERIFY(dentry, DCACHE_SHRINK_LIST | DCACHE_LRU_LIST);
+	spin_lock(&dcache_shrink_lock);
 	list_del_init(&dentry->d_lru);
+	spin_unlock(&dcache_shrink_lock);
 	dentry->d_flags &= ~(DCACHE_SHRINK_LIST | DCACHE_LRU_LIST);
 	this_cpu_dec(nr_dentry_unused);
 }
@@ -368,7 +372,9 @@ static void d_shrink_del(struct dentry *dentry)
 static void d_shrink_add(struct dentry *dentry, struct list_head *list)
 {
 	D_FLAG_VERIFY(dentry, 0);
+	spin_lock(&dcache_shrink_lock);
 	list_add(&dentry->d_lru, list);
+	spin_unlock(&dcache_shrink_lock);
 	dentry->d_flags |= DCACHE_SHRINK_LIST | DCACHE_LRU_LIST;
 	this_cpu_inc(nr_dentry_unused);
 }
@@ -391,7 +397,9 @@ static void d_lru_shrink_move(struct dentry *dentry, struct list_head *list)
 {
 	D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
 	dentry->d_flags |= DCACHE_SHRINK_LIST;
+	spin_lock(&dcache_shrink_lock);
 	list_move_tail(&dentry->d_lru, list);
+	spin_unlock(&dcache_shrink_lock);
 }
 
 /*

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

end of thread, other threads:[~2014-05-06 19:15 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-29 16:01 dcache shrink list corruption? Miklos Szeredi
2014-04-29 17:43 ` Linus Torvalds
2014-04-29 18:03   ` Miklos Szeredi
2014-04-29 18:16     ` Al Viro
2014-04-29 19:10       ` Al Viro
2014-04-29 21:18         ` Dave Chinner
2014-04-29 21:48           ` Al Viro
2014-04-29 23:04             ` Linus Torvalds
2014-04-29 23:20               ` Al Viro
2014-04-30  2:31                 ` Al Viro
2014-04-30  2:56                   ` Linus Torvalds
2014-04-30  4:04                     ` Al Viro
2014-04-30 15:49                       ` Miklos Szeredi
2014-04-30 15:56                         ` Miklos Szeredi
2014-04-30 16:03                         ` Al Viro
2014-04-30 17:33                           ` Miklos Szeredi
2014-04-30 18:36                             ` Al Viro
2014-04-30 18:42                               ` Miklos Szeredi
2014-04-30 19:02                                 ` Al Viro
2014-04-30 19:59                                   ` Al Viro
2014-04-30 20:23                                     ` Linus Torvalds
2014-04-30 20:38                                       ` Al Viro
2014-04-30 20:57                                         ` Linus Torvalds
2014-04-30 21:12                                           ` Al Viro
2014-04-30 22:12                                             ` Al Viro
2014-04-30 23:04                                               ` Linus Torvalds
2014-04-30 23:14                                                 ` Linus Torvalds
2014-04-30 23:43                                                   ` Al Viro
2014-05-01  0:18                                                     ` Linus Torvalds
2014-05-01  2:51                                                       ` Al Viro
2014-05-01  2:59                                                         ` Linus Torvalds
2014-05-01  3:12                                                           ` Al Viro
2014-05-01  9:42                                                             ` Miklos Szeredi
2014-05-01 14:34                                                               ` Al Viro
2014-05-01 21:02                                                                 ` Al Viro
2014-05-01 21:05                                                                   ` Al Viro
2014-05-01 22:52                                                                     ` Linus Torvalds
2014-05-02  8:43                                                                 ` Szeredi Miklos
2014-05-02 21:04                                                                 ` Linus Torvalds
2014-04-30 23:38                                                 ` Al Viro
2014-04-30  9:15                     ` Miklos Szeredi
2014-05-02  5:51                       ` Al Viro
2014-05-02  9:00                         ` Szeredi Miklos
2014-05-02 21:02                           ` Miklos Szeredi
2014-05-02 21:08                           ` Miklos Szeredi
2014-05-02 21:18                             ` Linus Torvalds
2014-05-02 22:40                               ` Al Viro
2014-05-02 23:06                                 ` Al Viro
2014-05-03  4:26                                 ` Al Viro
2014-05-03 18:07                                   ` Linus Torvalds
2014-05-03 18:25                                     ` Al Viro
2014-05-03 18:21                                   ` Al Viro
2014-05-04  6:29                                     ` Al Viro
2014-05-06 10:17                                       ` Miklos Szeredi
2014-05-06 14:53                                         ` Linus Torvalds
2014-05-06 16:52                                           ` Al Viro
2014-05-06 17:01                                             ` Linus Torvalds
2014-05-06 19:15                                               ` Al Viro
2014-05-02 22:32                             ` Al Viro
2014-04-29 18:17     ` Linus Torvalds
2014-04-29 17:56 ` Al Viro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.