On Tue 08-10-19 09:43:57, Petr Mladek wrote:
> On Mon 2019-10-07 16:49:37, Michal Hocko wrote:
> > [Cc s390 maintainers - the lockdep is 
> > http://lkml.kernel.org/r/1570228005-24979-1-git-send-email-...@lca.pw
> >  Petr has explained it is a false positive
> >  http://lkml.kernel.org/r/20191007143002.l37bt2lzqtnqj...@pathway.suse.cz]
> > On Mon 07-10-19 16:30:02, Petr Mladek wrote:
> > [...]
> > > I believe that it cannot really happen because:
> > > 
> > >   static int __init
> > >   sclp_console_init(void)
> > >   {
> > >   [...]
> > >           rc = sclp_rw_init();
> > >   [...]
> > >           register_console(&sclp_console);
> > >           return 0;
> > >   }
> > > 
> > > sclp_rw_init() is called before register_console(). And
> > > console_unlock() will never call sclp_console_write() before
> > > the console is registered.
> > > 
> > > AFAIK, lockdep only compares existing chain of locks. It does
> > > not know about console registration that would make some
> > > code paths mutually exclusive.
> > > 
> > > I believe that it is a false positive. I do not know how to
> > > avoid this lockdep report. I hope that it will disappear
> > > by deferring all printk() calls rather soon.
> > 
> > Thanks a lot for looking into this Petr. I have also checked the code
> > and I really fail to see why the allocation has to be done under the
> > lock in the first place. sclp_read_sccb and sclp_init_sccb are global
> > variables but I strongly suspect that they need a synchronization during
> > early init, callbacks are registered only later IIUC:
> 
> Good idea. It would work when the init function is called only once.
> But see below.
> 
> > diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
> > index d2ab3f07c008..4b1c033e3255 100644
> > --- a/drivers/s390/char/sclp.c
> > +++ b/drivers/s390/char/sclp.c
> > @@ -1169,13 +1169,13 @@ sclp_init(void)
> >     unsigned long flags;
> >     int rc = 0;
> >  
> > +   sclp_read_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
> > +   sclp_init_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
> >     spin_lock_irqsave(&sclp_lock, flags);
> >     /* Check for previous or running initialization */
> >     if (sclp_init_state != sclp_init_state_uninitialized)
> >             goto fail_unlock;
> 
> It seems that sclp_init() could be called several times in parallel.
> I see it called from sclp_register() and sclp_initcall().

Interesting. Something for s390 people to answer I guess.
Anyway, this should be quite trivial to workaround by a cmpxch or alike.

-- 
Michal Hocko
SUSE Labs

Reply via email to