Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp1208557rwb; Thu, 8 Dec 2022 07:57:35 -0800 (PST) X-Google-Smtp-Source: AA0mqf74lgUZ0i4NgqKCt/qPq4zx7Ko/pZKLBh9JlZsjeT1Aqsb2Ik42yKyCRRX18o00qyS6A1+C X-Received: by 2002:aa7:c7d5:0:b0:44e:bee5:4242 with SMTP id o21-20020aa7c7d5000000b0044ebee54242mr70412371eds.128.1670515055756; Thu, 08 Dec 2022 07:57:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670515055; cv=none; d=google.com; s=arc-20160816; b=nzxv5QCUgaFswopNJtTbfZxlxU8Axi8NJjM9DCisHPrmARf2YvuB3atSDHaxEGCNfs EriJm753tfln90N4tQHw5sxj33TJfPXyrP7tw1ddjlqsp8phXDeUBNEiN41qREkcQeC+ WzLSraqj/C/fim1eANn3dXlNg8A5BkNaj0OKCqWENldX0pLdICc1R7sk7cEjwhc0erJW RTte6p+VV2u2wC4TwHQkby8OuZ0kbTFJn/F6FlsQs9fNegPleG38Fp4hBQyKwY9yG/1D 6Kofe7M2hmGagBx2gezYlbfMo1bxodyOitpkiEl8eMRVgOkUMhkEPUBOPDSFaKBUV/7I 36Hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version; bh=9um/CJ6zRIOkXvilsnHll/Sh2DZ2yqw/uWXa4YFjEDM=; b=sDw2CMCIN2xRY4I9Utz7pw36Gt49Q/tVV8g2luMuOwInUFB2nuiz5ytiwjb5yFy0Il ZwITdM0RpytA4/NzDL3s2AIo2XuwlA2ehxg6FSolo9XHN1UpPYhyQHiDovgTfCCX0ru2 TpOdfYwDvTBziW3E8fj3t3ZdzXGWCfncZazc7xpVaUKvzB6THgoCI0e6hBzlKNgmgKTe p/XRDK8/4TysUY5AwIDSnjLdXC6SiDBnrcoO1Q574Djc60yHbTkhe6y6pUtA1LlDmRjU APDloeUYzBu1icegpOWL2skozXbS9fZKZHuxFL2EWmXiqbvXJ/BEksN2fUd4qGl9xb5K gaLA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j13-20020aa7ca4d000000b00467c3cbab04si6276992edt.66.2022.12.08.07.57.17; Thu, 08 Dec 2022 07:57:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230013AbiLHPpQ (ORCPT + 73 others); Thu, 8 Dec 2022 10:45:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229982AbiLHPpI (ORCPT ); Thu, 8 Dec 2022 10:45:08 -0500 Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CEE015E9FB; Thu, 8 Dec 2022 07:45:03 -0800 (PST) Received: by mail-pj1-f44.google.com with SMTP id hd14-20020a17090b458e00b0021909875bccso6019738pjb.1; Thu, 08 Dec 2022 07:45:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9um/CJ6zRIOkXvilsnHll/Sh2DZ2yqw/uWXa4YFjEDM=; b=ppKMzZtR7U2SX3eLo2jxEZm1jMYhkoNMcmIlktkQ1QdUm+vfTi1IxZPm6Ro595eveB aT1FBP7APhP9bYSxtCEZYw/cvLfqODc77Y/MONqraHS6i//3K0zWKwzih/Ip9cquqmsr UUm76O24CdgUNXrj+JkOE9E+1i4XMolQHH0fjemd46d9sN+WfP0h33+t7puZ7d/FidSK N5rxzif8eOUEnPcveMqqZILyM24pS8GZDJDReLoSUv4rfeNCtcfO/VcpQe7qW1QnvDwV ul84vNy64lUItDP8TmBsCAa3hnzo145yy6C/hAfwUzELPAqYpVUsvHxqcaZTca6X+yfM ALfA== X-Gm-Message-State: ANoB5plFcWlNRtM63UAwNi39uCDnFL9YrzdRv9QX/DEYnDn0IHS9A7Dm eL3uJS+oAQbhRl9fm8srg1tDo3r/4d96u2j//AU= X-Received: by 2002:a17:903:452:b0:189:6574:7ac2 with SMTP id iw18-20020a170903045200b0018965747ac2mr64784125plb.65.1670514303196; Thu, 08 Dec 2022 07:45:03 -0800 (PST) MIME-Version: 1.0 References: <20221203133159.94414-1-mailhol.vincent@wanadoo.fr> <9493232b-c8fa-5612-fb13-fccf58b01942@suse.com> In-Reply-To: From: Vincent MAILHOL Date: Fri, 9 Dec 2022 00:44:51 +0900 Message-ID: Subject: Re: [PATCH 0/8] can: usb: remove all usb_set_intfdata(intf, NULL) in drivers' disconnect() To: Oliver Neukum Cc: Marc Kleine-Budde , linux-can@vger.kernel.org, Wolfgang Grandegger , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Frank Jungclaus , socketcan@esd.eu, Yasushi SHOJI , =?UTF-8?Q?Stefan_M=C3=A4tje?= , Hangyu Hua , Oliver Hartkopp , Peter Fink , Jeroen Hofstee , =?UTF-8?Q?Christoph_M=C3=B6hring?= , John Whittington , Vasanth Sadhasivan , Jimmy Assarsson , Anssi Hannula , Pavel Skripkin , Stephane Grosjean , Wolfram Sang , "Gustavo A . R . Silva" , Julia Lawall , Dongliang Mu , Sebastian Haas , Maximilian Schneider , Daniel Berglund , Olivier Sobrie , =?UTF-8?B?UmVtaWdpdXN6IEtvxYLFgsSFdGFq?= , Jakob Unterwurzacher , Martin Elshuber , Bernd Krumboeck , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Alan Stern , linux-usb@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu. 8 Dec. 2022 at 20:04, Oliver Neukum wrote: > On 08.12.22 10:00, Vincent MAILHOL wrote: > > On Mon. 5 Dec. 2022 at 17:39, Oliver Neukum wrote: > >> On 03.12.22 14:31, Vincent Mailhol wrote: > > Good Morning! Good night! (different time zone :)) > > ACK, but I do not see the connection. > Well, useless checks are bad. In particular, we should always > make it clear whether a pointer may or may not be NULL. > That is, I have no problem with what you were trying to do > with your patch set. It is a good idea and possibly slightly > overdue. The problem is the method. > > > I can see that cdc-acm sets acm->control and acm->data to NULL in his > > disconnect(), but it doesn't set its own usb_interface to NULL. > > You don't have to, but you can. I was explaining the two patterns for doing so. > > >> which claim secondary interfaces disconnect() will be called a second time > >> for. > > > > Are you saying that the disconnect() of those CAN USB drivers is being > > called twice? I do not see this in the source code. The only caller of > > usb_driver::disconnect() I can see is: > > > > https://elixir.bootlin.com/linux/v6.0/source/drivers/usb/core/driver.c#L458 > > If they use usb_claim_interface(), yes it is called twice. Once per > interface. That is in the case of ACM once for the originally probed > interface and a second time for the claimed interface. > But not necessarily in that order, as you can be kicked off an interface > via sysfs. Yet you need to cease operations as soon as you are disconnected > from any interface. That is annoying because it means you cannot use a > refcount. From that stems the widespread use of intfdata as a flag. Thank you for the details! I better understand this part now. > >> In addition, a driver can use setting intfdata to NULL as a flag > >> for disconnect() having proceeded to a point where certain things > >> can no longer be safely done. > > > > Any reference that a driver can do that? This pattern seems racy. > > Technically that is exactly what drivers that use usb_claim_interface() > do. You free everything at the first call and use intfdata as a flag > to prevent a double free. > The race is prevented by usbcore locking, which guarantees that probe() > and disconnect() have mutual exclusion. > If you use intfdata in sysfs, yes additional locking is needed. ACK for the mutual exclusion. My question was about what you said in your previous message: | In addition, a driver can use setting intfdata to NULL as a flag | for *disconnect() having proceeded to a point* where certain things | can no longer be safely done. How do you check that disconnect() has proceeded *to a given point* using intf without being racy? You can check if it has already completed once but not check how far it has proceeded, right? > > What makes you assume that I didn't check this in the first place? Or > > do you see something I missed? > > That you did not put it into the changelogs. > That reads like the drivers are doing something obsolete or stupid. > They do not. They copied something that is necessary only under > some circumstances. > > And that you did not remove the checks. > > >> which is likely, then please also remove checks like this: > >> > >> struct ems_usb *dev = usb_get_intfdata(intf); > >> > >> usb_set_intfdata(intf, NULL); > >> > >> if (dev) { > > Here. If you have a driver that uses usb_claim_interface(). > You need this check or you unregister an already unregistered > netdev. Sorry, but with all my best intentions, I still do not get it. During the second iteration, inft is NULL and: /* equivalent to dev = intf->dev.data. Because intf is NULL, * this is a NULL pointer dereference */ struct ems_usb *dev = usb_get_intfdata(intf); /* OK, intf is already NULL */ usb_set_intfdata(intf, NULL); /* follows a NULL pointer dereference so this is undefined * behaviour */ if (dev) { How is this a valid check that you entered the function for the second time? If intf is the flag, you should check intf, not dev? Something like this: struct ems_usb *dev; if (!intf) return; dev = usb_get_intfdata(intf); /* ... */ I just can not see the connection between intf being NULL and the if (dev) check. All I see is some undefined behaviour, sorry. > The way this disconnect() method is coded is extremely defensive. > Most drivers do not need this check. But it is never > wrong in the strict sense. > > Hence doing a mass removal with a change log that does > not say that this driver is using only a single interface > hence the check can be dropped to reduce code size > is not good. > > Regards > Oliver