From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Lunn Subject: Re: [PATCH net-next] net: phy: mdio-boardinfo: Allow recursive mdiobus_register() Date: Thu, 19 Apr 2018 02:33:18 +0200 Message-ID: <20180419003318.GA16866@lunn.ch> References: <1524096047-16823-1-git-send-email-andrew@lunn.ch> <5966673b-f091-a180-71b1-96d35f845e17@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: David Miller , netdev , Vivien Didelot To: Florian Fainelli Return-path: Received: from vps0.lunn.ch ([185.16.172.187]:33318 "EHLO vps0.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752326AbeDSAdX (ORCPT ); Wed, 18 Apr 2018 20:33:23 -0400 Content-Disposition: inline In-Reply-To: <5966673b-f091-a180-71b1-96d35f845e17@gmail.com> Sender: netdev-owner@vger.kernel.org List-ID: On Wed, Apr 18, 2018 at 05:14:36PM -0700, Florian Fainelli wrote: > On 04/18/2018 05:00 PM, Andrew Lunn wrote: > > mdiobus_register will search for any mdiobus board info registered for > > the bus being registered. If found, it will probe devices on the bus. > > That device, if for example it is an ethernet switch, may then try to > > register an mdio bus. Thus we need to allow recursive calls to > > mdiobus_register. > > > > Holding the mdio_board_lock will cause a deadlock during this > > recursion. Release the lock and use list_for_each_entry_safe. > > > > Signed-off-by: Andrew Lunn > > --- > > drivers/net/phy/mdio-boardinfo.c | 5 ++++- > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/net/phy/mdio-boardinfo.c b/drivers/net/phy/mdio-boardinfo.c > > index 1861f387820d..863496fa5d13 100644 > > --- a/drivers/net/phy/mdio-boardinfo.c > > +++ b/drivers/net/phy/mdio-boardinfo.c > > @@ -30,17 +30,20 @@ void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus, > > struct mdio_board_info *bi)) > > { > > struct mdio_board_entry *be; > > + struct mdio_board_entry *tmp; > > struct mdio_board_info *bi; > > int ret; > > > > mutex_lock(&mdio_board_lock); > > Don't you need to drop that lock here? > > > - list_for_each_entry(be, &mdio_board_list, list) { > > + list_for_each_entry_safe(be, tmp, &mdio_board_list, list) { > > bi = &be->board_info; > > > > if (strcmp(bus->id, bi->bus_id)) > > continue; > > > > + mutex_unlock(&mdio_board_lock); > > ret = cb(bus, bi); > > + mutex_lock(&mdio_board_lock); > > if (ret) > > continue; > > > > And conversely drop the unlock from the end of this function? No. The recursion happens inside the ret = cb(bus, bi). We need the lock to be available during that. The lock itself is protecting the list, so we need to hold the lock while using the list. > Also, would you rather target "net" for this change since this appears > to be a bug fix? As far as i know, there is no in tree driver which can trigger this. It requires the use of a switch instantiated using mdio_board info, and the switch then needs to add another mdio bus in its probe function. The only in tree code doing anything like this is dsa_loop, and it does not register an mdio bus. However, later this cycle i plan to add support for Zodiac's SCU3, and it does trigger this deadlock. So net-next is sufficient for my. Andrew