On 02/06/2012 07:25 PM, Jan Kara wrote: > When discovery of lots of disks happen in parallel, we call > invalidate_bh_lrus() once for each disk from partitioning code resulting in a > storm of IPIs and causing a softlockup detection to fire (it takes several > *minutes* for a machine to execute all the invalidate_bh_lrus() calls). > > Fix the issue by allowing only single invalidation to run using a mutex and let > waiters for mutex figure out whether someone invalidated LRUs for them while > they were waiting. > > Signed-off-by: Jan Kara <jack@xxxxxxx> > --- > fs/buffer.c | 23 ++++++++++++++++++++++- > 1 files changed, 22 insertions(+), 1 deletions(-) > > I feel this is slightly hacky approach but it works. If someone has better > idea, please speak up. > Something related that you might be interested in: https://lkml.org/lkml/2012/2/5/109 (This is part of Gilad's patchset that tries to reduce cross-CPU IPI interference.) Regards, Srivatsa S. Bhat > diff --git a/fs/buffer.c b/fs/buffer.c > index 1a30db7..56b0d2b 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -1384,10 +1384,31 @@ static void invalidate_bh_lru(void *arg) > } > put_cpu_var(bh_lrus); > } > - > + > +/* > + * Invalidate all buffers in LRUs. Since we have to signal all CPUs to > + * invalidate their per-cpu local LRU lists this is rather expensive operation. > + * So we optimize the case of several parallel calls to invalidate_bh_lrus() > + * which happens from partitioning code when lots of disks appear in the > + * system during boot. > + */ > void invalidate_bh_lrus(void) > { > + static DEFINE_MUTEX(bh_invalidate_mutex); > + static long bh_invalidate_sequence; > + > + long my_bh_invalidate_sequence = bh_invalidate_sequence; > + > + mutex_lock(&bh_invalidate_mutex); > + /* Someone did bh invalidation while we were sleeping? */ > + if (my_bh_invalidate_sequence != bh_invalidate_sequence) > + goto out; > + bh_invalidate_sequence++; > + /* Inc of bh_invalidate_sequence must happen before we invalidate bhs */ > + smp_wmb(); > on_each_cpu(invalidate_bh_lru, NULL, 1); > +out: > + mutex_unlock(&bh_invalidate_mutex); > } > EXPORT_SYMBOL_GPL(invalidate_bh_lrus); > -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html