Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp1319508ybp; Fri, 11 Oct 2019 12:19:49 -0700 (PDT) X-Google-Smtp-Source: APXvYqyA8icoDfCCeClYAI2Y95JaQlUlQGlHcWe6NtWBaYXUWNFc+RRDBt+5LfJxe/qh5EL3poC6 X-Received: by 2002:a17:906:556:: with SMTP id k22mr15474251eja.66.1570821589027; Fri, 11 Oct 2019 12:19:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570821589; cv=none; d=google.com; s=arc-20160816; b=Q2QHTGe87Kxr9iLu6MehIJJUxXWTWoeq0nv1upRyiYxZ6hV83lfFu54swOmGHaedQv Hh4vTwOhl0l+2vmw1wqhQXYB+nz1BB7h9T5jeZuX2hXNEggxCBB9Q9zjFAFxcfN2DLEg OCJLRwZTiyVHTgb8zi40RpIB7Y6diMTqzOmeIMlha9dMVsCuOatVeKwCma0Sik21jz/W awZd9ci6AFcIgZUE2NxbS92VS9BjPVQRqls96I3NxEsZFjL4GEzuytigHJ33btHzsV1Z Gt9gLqB/kNCk+cNQYbD84zis/j+vY9SUUr/mmQXllE7BlvpLc6jtf9rUY8tD+PUAO9lo G1Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=PmD2iXZzRm5TWXHP4u2nvAta0M6In2JXUUfSGIBG8L8=; b=o44rF2UEO4NBWl3F5CKliatv0vNsW/A71jlbSKfjt6+lbA3UwihmH2NVNrXOW4u9vc NJJE/AjqoTf1Zsj8FvcTH7pR5w1jhn6Gwi9F21/wB3C4bmwcIZGDfw9JG0U4df0fShbc D/1WvP9WR92FMoYD2wAgWv04XuP7gTyMbuFMTAPNfMCMvv/yHZehiN2ac7N3tJU+mzPC z35dmSkyKYW+olD2UppK4c/IICCqD3Ty+9hYAaxxZUNN3FSmRF4zeeXGGHOqeVjqOjDx s2COp1oLYXIqm+Ebx9ZybKt6RtjyWC2hA8Jkq9HrCruNNCBaqU58rKBkyysXEnbg7pb6 LE7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=T+VCQifx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5si5844659edb.324.2019.10.11.12.19.24; Fri, 11 Oct 2019 12:19:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=T+VCQifx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729005AbfJKTQj (ORCPT + 99 others); Fri, 11 Oct 2019 15:16:39 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:53922 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728895AbfJKTQj (ORCPT ); Fri, 11 Oct 2019 15:16:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1570821396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PmD2iXZzRm5TWXHP4u2nvAta0M6In2JXUUfSGIBG8L8=; b=T+VCQifxZXipUDp/ymQcuAoXlwp5yh7UC+5nYFW0gQSoW/dE4ASr/6AeOtBk3lCtx7ZLo7 HuDhbet+cV2TN3+Bab7VIJVFBIk++LJgHKtxajQEmE4VOeyKlWELbiDY2Rw4myhEAhSqTm O3V+Ku2zB+wH0UmZAkdX3hXdWPeTNT0= Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-85-ONszeOFzP4WdL5rwc9zcTg-1; Fri, 11 Oct 2019 15:16:32 -0400 Received: by mail-qt1-f198.google.com with SMTP id n59so10416909qtd.8 for ; Fri, 11 Oct 2019 12:16:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=DuLUVOIQimNSFcqes+0fEHnQr+0Rr+pI9L1erbmu+/Y=; b=Y1iVy4lXAB0BLA0NSs54he9AsNua/bW5kPoqikQqyj1okVW9esKHceQpgXho5BS2yf kCptAnYul3zSRyqiTPiwa1vreHhMsuq4yfQb/UlCoVNONFES7Y4DiwzyjEDhDzWzqqmW oE/k1Tfp+eBQNBblLeJqGYw4uIp+j0CE0xAYRh/neNbgaiDAPyiLIT0OvBxZoPjamzSi D2sW0GpPVXY9GMbZxnYDcR7+JCsG12qFw21Wu9KdJpIUNmzjU5NrrktlWrrsn3ZBdxld gh1ADnVZ2U+t36SCpzHTCXBUH7VAaudDRXEpEM5750S3K1KLZTXmMrZ5MWRaPS+BVWQZ x1aw== X-Gm-Message-State: APjAAAVPP+kFiy4pZw7tMl/0Cr5DboWp4rvguiIGh7m3RjZNMPpbs9lH n/7Z7H50sIWe9Mh689+6oAzLKeUOUwF6ZsM+x6rOIHt8dkm5KWojRnaNvuiviP6XpEsI7TrINEd p6WIL0b5yvDIu0TPE2erPffQjL/OHEughjUlmUL3a X-Received: by 2002:ae9:f306:: with SMTP id p6mr17452675qkg.169.1570821391796; Fri, 11 Oct 2019 12:16:31 -0700 (PDT) X-Received: by 2002:ae9:f306:: with SMTP id p6mr17452643qkg.169.1570821391424; Fri, 11 Oct 2019 12:16:31 -0700 (PDT) MIME-Version: 1.0 References: <20191007051240.4410-1-andrew.smirnov@gmail.com> <20191007051240.4410-2-andrew.smirnov@gmail.com> In-Reply-To: From: Benjamin Tissoires Date: Fri, 11 Oct 2019 21:16:19 +0200 Message-ID: Subject: Re: [PATCH 1/3] HID: logitech-hidpp: use devres to manage FF private data To: Andrey Smirnov Cc: Dmitry Torokhov , "open list:HID CORE LAYER" , Jiri Kosina , Henrik Rydberg , Sam Bazely , "Pierre-Loup A . Griffais" , Austin Palmer , lkml , "3.8+" X-MC-Unique: ONszeOFzP4WdL5rwc9zcTg-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Andrey, On Fri, Oct 11, 2019 at 8:19 PM Andrey Smirnov w= rote: > > On Fri, Oct 11, 2019 at 7:52 AM Benjamin Tissoires > wrote: > > > > Hi Andrey, > > > > On Mon, Oct 7, 2019 at 7:13 AM Andrey Smirnov wrote: > > > > > > To simplify resource management in commit that follows as well as to > > > save a couple of extra kfree()s and simplify hidpp_ff_deinit() switch > > > driver code to use devres to manage the life-cycle of FF private data= . > > > > > > Signed-off-by: Andrey Smirnov > > > Cc: Jiri Kosina > > > Cc: Benjamin Tissoires > > > Cc: Henrik Rydberg > > > Cc: Sam Bazely > > > Cc: Pierre-Loup A. Griffais > > > Cc: Austin Palmer > > > Cc: linux-input@vger.kernel.org > > > Cc: linux-kernel@vger.kernel.org > > > Cc: stable@vger.kernel.org > > > > This patch doesn't seem to fix any error, is there a reason to send it > > to stable? (besides as a dependency of the rest of the series). > > > > Dependency is the only reason for this patch, but it is a pretty big > reason. Prior to patches 1/3 and 2/3 FF private data was both > allocated and passed off to FF layer via ff->private =3D data in a span > of a few lines of code within hidpp_ff_init()/g920_get_config(). > After, said pair is effectively split into two different functions, > both needing access to FF private data, but called quite far apart in > hidpp_probe(). Alternatives to patch 1/3 would be to either make sure > that every error path in hidpp_prob() after the call to > g920_allocate() is aware of allocated FF data, which seems like a > nightmare, or, to create a temporary FF data, fill it in > g920_get_config() and memdup() it in hidpp_ff_init(). Is that (the > latter) the path that you prefer to take? Hmm, I don't have a strong opinion on that. The point I don't like with the devres version is that it seems like a half-backed solution, as part of the driver would use devres while parts for the same purpose will not. I do not consider your code untrusted, but this is usually a reasonable source of leakages, so as a rule a thumb, devres should be used in a all or nothing fashion. Basically, both alternative solutions would be OK with me, as long as the scope of each patch is reduced to the minimum (and having more than one is OK too). > > > > --- > > > drivers/hid/hid-logitech-hidpp.c | 53 +++++++++++++++++-------------= -- > > > 1 file changed, 29 insertions(+), 24 deletions(-) > > > > > > diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logit= ech-hidpp.c > > > index 0179f7ed77e5..58eb928224e5 100644 > > > --- a/drivers/hid/hid-logitech-hidpp.c > > > +++ b/drivers/hid/hid-logitech-hidpp.c > > > @@ -2079,6 +2079,11 @@ static void hidpp_ff_destroy(struct ff_device = *ff) > > > struct hidpp_ff_private_data *data =3D ff->private; > > > > > > kfree(data->effect_ids); > > > > Is there any reasons we can not also devm alloc data->effect_ids? > > No, but I was trying to limit the scope of this patch. > > > > > > + /* > > > + * Set private to NULL to prevent input_ff_destroy() from > > > + * freeing our devres allocated memory > > > > Ouch. There is something wrong here: input_ff_destroy() calls > > kfree(ff->private), when the data has not been allocated by > > input_ff_create(). This seems to lack a little bit of symmetry. > > > > I agree, I think it's a wart in FF API design. Yep, see Dmitry's answer for ideas :) > > > > + */ > > > + ff->private =3D NULL; > > > } > > > > > > static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_inde= x) > > > @@ -2090,7 +2095,7 @@ static int hidpp_ff_init(struct hidpp_device *h= idpp, u8 feature_index) > > > const u16 bcdDevice =3D le16_to_cpu(udesc->bcdDevice); > > > struct ff_device *ff; > > > struct hidpp_report response; > > > - struct hidpp_ff_private_data *data; > > > + struct hidpp_ff_private_data *data =3D hidpp->private_data; > > > int error, j, num_slots; > > > u8 version; > > > > > > @@ -2129,18 +2134,13 @@ static int hidpp_ff_init(struct hidpp_device = *hidpp, u8 feature_index) > > > return error; > > > } > > > > > > - data =3D kzalloc(sizeof(*data), GFP_KERNEL); > > > - if (!data) > > > - return -ENOMEM; > > > data->effect_ids =3D kcalloc(num_slots, sizeof(int), GFP_KERN= EL); > > > - if (!data->effect_ids) { > > > - kfree(data); > > > + if (!data->effect_ids) > > > return -ENOMEM; > > > - } > > > + > > > data->wq =3D create_singlethread_workqueue("hidpp-ff-sendqueu= e"); > > > if (!data->wq) { > > > kfree(data->effect_ids); > > > - kfree(data); > > > return -ENOMEM; > > > } > > > > > > @@ -2199,28 +2199,15 @@ static int hidpp_ff_init(struct hidpp_device = *hidpp, u8 feature_index) > > > return 0; > > > } > > > > > > -static int hidpp_ff_deinit(struct hid_device *hid) > > > +static void hidpp_ff_deinit(struct hid_device *hid) > > > { > > > - struct hid_input *hidinput =3D list_entry(hid->inputs.next, s= truct hid_input, list); > > > - struct input_dev *dev =3D hidinput->input; > > > - struct hidpp_ff_private_data *data; > > > - > > > - if (!dev) { > > > - hid_err(hid, "Struct input_dev not found!\n"); > > > - return -EINVAL; > > > - } > > > + struct hidpp_device *hidpp =3D hid_get_drvdata(hid); > > > + struct hidpp_ff_private_data *data =3D hidpp->private_data; > > > > > > hid_info(hid, "Unloading HID++ force feedback.\n"); > > > - data =3D dev->ff->private; > > > - if (!data) { > > > > I am pretty sure we might need to keep a test on data not being null. > > > > OK, sure. Could you be more explicit in your reasoning next time > though? I am assuming this is because hid_hw_stop() might be called > before? Honestly, I don't have a good reason for it. I have seen enough of automatic static/dynamic checks with the same patterns to let my guts express that we need to check on the value of a pointer stored in private_data before dereferencing it. If you are absolutely sure this is not need, a simple comment in the code is enough :) > > > > - hid_err(hid, "Private data not found!\n"); > > > - return -EINVAL; > > > - } > > > > > > destroy_workqueue(data->wq); > > > device_remove_file(&hid->dev, &dev_attr_range); > > > - > > > - return 0; > > > } > > > > This whole hunk seems unrelated to the devm change. > > Can you extract a patch that just stores hidpp_ff_private_data in > > hidpp->private_data and then cleans up hidpp_ff_deinit() before > > switching it to devm? (or maybe not, see below) > > Well it appears you are against the idea of leveraging devres in this > series, so discussing the fate of said hunk seems moot. Well, I really value your work and I am very happy of it. It's just that for a patch/series aimed at stable, I rather have the patch series following the stable rules, which are that we should fix one thing only, and have the most simplest patch possible. I truly believe adding devres to cleanup the error path is the thing to do, but maybe not in this series. > > > > > After a few more thoughts, I don't think this mixing of devm and non > > devm is a good idea: > > we could say that the hidpp_ff_private_data and its effect_ids are > > both children of the input_dev, not the hid_device. And we would > > expect the whole thing to simplify with devm, but it's not, because ff > > is not supposed to be used with devm. > > > > I have a feeling the whole ff logic is wrong in term of where things > > should be cleaned up, but I can not come up with a good hint on where > > to start. For example, destroy_workqueue() is called in > > hidpp_ff_deinit() where it might be racy, and maybe we should call it > > in hidpp_ff_destroy()... > > > > Yeah, it probably should be moved to hidpp_ff_destroy(). Out of scope > for this series though, I'll deal with it in a separate submission. As per Dmitry's suggestion of removing hidpp_ff_destroy() maybe we should keep it that way, I am not entirely sure about how the races can happen (I don't think I even have one FF device I could test against). > > > Last, you should base this patch on top of the for-next branch, we > > recently merged a fix for the FF drivers in the HID subsystem: > > https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git/commit/?h= =3Dfor-next&id=3Dd9d4b1e46d9543a82c23f6df03f4ad697dab361b > > > > Sure will do. thanks \o/ > > > Would it be too complex to drop this patch from the series and do a > > proper follow up cleanup series that might not need to go to stable? > > > > No it's alright. I'll submit a v2 of this series with only two patches > and send a follow up after. > And thanks a lot again. Cheers, Benjamin