Message ID | 1515110659-20145-8-git-send-email-brad@nextdimension.cc (mailing list archive) |
---|---|
State | Accepted, archived |
Headers |
Received: from vger.kernel.org ([209.132.180.67]) by www.linuxtv.org with esmtp (Exim 4.84_2) (envelope-from <linux-media-owner@vger.kernel.org>) id 1eXFVk-0000lu-KQ; Fri, 05 Jan 2018 00:05:25 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751276AbeAEAFU (ORCPT <rfc822;mkrufky@linuxtv.org> + 1 other); Thu, 4 Jan 2018 19:05:20 -0500 Received: from hapkido.dreamhost.com ([66.33.216.122]:43542 "EHLO hapkido.dreamhost.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751240AbeAEAFS (ORCPT <rfc822; linux-media@vger.kernel.org>); Thu, 4 Jan 2018 19:05:18 -0500 Received: from homiemail-a116.g.dreamhost.com (sub5.mail.dreamhost.com [208.113.200.129]) by hapkido.dreamhost.com (Postfix) with ESMTP id 08ABF8ED96 for <linux-media@vger.kernel.org>; Thu, 4 Jan 2018 16:05:18 -0800 (PST) Received: from homiemail-a116.g.dreamhost.com (localhost [127.0.0.1]) by homiemail-a116.g.dreamhost.com (Postfix) with ESMTP id AC4D560001342; Thu, 4 Jan 2018 16:05:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=nextdimension.cc; h=from :to:cc:subject:date:message-id:in-reply-to:references; s= nextdimension.cc; bh=C2Dh0ifRB7OYid/wqJyiGWvDKZY=; b=AcA9ck6ms4q FxJ172JiuDMdBcquprCxVkuax61xLhflCBbydB5/LaHiJ6ei/D/4lIRtJt9yp/wK oyI+U7A4kSHc8YADR7pIGwELF3dxUFrKurb6HAoVzSiCgz9sQsffjjoOUd++/c8O 6dCubUU6044oyPH9YGERLDvNGCpgwSII= Received: from localhost.localdomain (66-90-189-166.dyn.grandenetworks.net [66.90.189.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: brad@nextdimension.ws) by homiemail-a116.g.dreamhost.com (Postfix) with ESMTPSA id 5DD7B60001C0A; Thu, 4 Jan 2018 16:05:17 -0800 (PST) From: Brad Love <brad@nextdimension.cc> To: linux-media@vger.kernel.org Cc: Brad Love <brad@nextdimension.cc> Subject: [PATCH 7/9] lgdt3306a: Set fe ops.release to NULL if probed Date: Thu, 4 Jan 2018 18:04:17 -0600 Message-Id: <1515110659-20145-8-git-send-email-brad@nextdimension.cc> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515110659-20145-1-git-send-email-brad@nextdimension.cc> References: <1515110659-20145-1-git-send-email-brad@nextdimension.cc> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: <linux-media.vger.kernel.org> X-Mailing-List: linux-media@vger.kernel.org |
Commit Message
Brad Love
Jan. 5, 2018, 12:04 a.m. UTC
If release is part of frontend ops then it is called in the
course of dvb_frontend_detach. The process also decrements
the module usage count. The problem is if the lgdt3306a
driver is reached via i2c_new_device, then when it is
eventually destroyed remove is called, which further
decrements the module usage count to negative. After this
occurs the driver is in a bad state and no longer works.
Also fixed by NULLing out the release callback is a double
kfree of state, which introduces arbitrary oopses/GPF.
This problem is only currently reachable via the em28xx driver.
On disconnect of Hauppauge SoloHD before:
lsmod | grep lgdt3306a
lgdt3306a 28672 -1
i2c_mux 16384 1 lgdt3306a
On disconnect of Hauppauge SoloHD after:
lsmod | grep lgdt3306a
lgdt3306a 28672 0
i2c_mux 16384 1 lgdt3306a
Signed-off-by: Brad Love <brad@nextdimension.cc>
---
drivers/media/dvb-frontends/lgdt3306a.c | 1 +
1 file changed, 1 insertion(+)
Comments
On Thu, Jan 4, 2018 at 7:04 PM, Brad Love <brad@nextdimension.cc> wrote: > If release is part of frontend ops then it is called in the > course of dvb_frontend_detach. The process also decrements > the module usage count. The problem is if the lgdt3306a > driver is reached via i2c_new_device, then when it is > eventually destroyed remove is called, which further > decrements the module usage count to negative. After this > occurs the driver is in a bad state and no longer works. > Also fixed by NULLing out the release callback is a double > kfree of state, which introduces arbitrary oopses/GPF. > This problem is only currently reachable via the em28xx driver. > > On disconnect of Hauppauge SoloHD before: > > lsmod | grep lgdt3306a > lgdt3306a 28672 -1 > i2c_mux 16384 1 lgdt3306a > > On disconnect of Hauppauge SoloHD after: > > lsmod | grep lgdt3306a > lgdt3306a 28672 0 > i2c_mux 16384 1 lgdt3306a > > Signed-off-by: Brad Love <brad@nextdimension.cc> > --- > drivers/media/dvb-frontends/lgdt3306a.c | 1 + > 1 file changed, 1 insertion(+) > Brad, We won't be able to apply this one. The symptom that you're trying to fix is indicative of some other problem, probably in the em28xx driver. NULL'ing the release callback is not the right thing to do. -Mike Krufky > diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c > index 6356815..d2477ed 100644 > --- a/drivers/media/dvb-frontends/lgdt3306a.c > +++ b/drivers/media/dvb-frontends/lgdt3306a.c > @@ -2177,6 +2177,7 @@ static int lgdt3306a_probe(struct i2c_client *client, > > i2c_set_clientdata(client, fe->demodulator_priv); > state = fe->demodulator_priv; > + state->frontend.ops.release = NULL; > > /* create mux i2c adapter for tuner */ > state->muxc = i2c_mux_alloc(client->adapter, &client->dev, > -- > 2.7.4 >
On 2018-01-04 18:19, Michael Ira Krufky wrote: > On Thu, Jan 4, 2018 at 7:04 PM, Brad Love <brad@nextdimension.cc> wrote: >> If release is part of frontend ops then it is called in the >> course of dvb_frontend_detach. The process also decrements >> the module usage count. The problem is if the lgdt3306a >> driver is reached via i2c_new_device, then when it is >> eventually destroyed remove is called, which further >> decrements the module usage count to negative. After this >> occurs the driver is in a bad state and no longer works. >> Also fixed by NULLing out the release callback is a double >> kfree of state, which introduces arbitrary oopses/GPF. >> This problem is only currently reachable via the em28xx driver. >> >> On disconnect of Hauppauge SoloHD before: >> >> lsmod | grep lgdt3306a >> lgdt3306a 28672 -1 >> i2c_mux 16384 1 lgdt3306a >> >> On disconnect of Hauppauge SoloHD after: >> >> lsmod | grep lgdt3306a >> lgdt3306a 28672 0 >> i2c_mux 16384 1 lgdt3306a >> >> Signed-off-by: Brad Love <brad@nextdimension.cc> >> --- >> drivers/media/dvb-frontends/lgdt3306a.c | 1 + >> 1 file changed, 1 insertion(+) >> > Brad, > > We won't be able to apply this one. The symptom that you're trying to > fix is indicative of some other problem, probably in the em28xx > driver. NULL'ing the release callback is not the right thing to do. > > -Mike Krufky Hey Mike, Redacting this patch to deal with individually. I will separately send to the list an example of another bridge driver which exhibits the same issue, when using the lgdt3306a driver similarly. I don't think this is solely an em28xx issue. I will also send a patch fixing only the double free, as that seems to be most important. Cheers, Brad >> diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c >> index 6356815..d2477ed 100644 >> --- a/drivers/media/dvb-frontends/lgdt3306a.c >> +++ b/drivers/media/dvb-frontends/lgdt3306a.c >> @@ -2177,6 +2177,7 @@ static int lgdt3306a_probe(struct i2c_client *client, >> >> i2c_set_clientdata(client, fe->demodulator_priv); >> state = fe->demodulator_priv; >> + state->frontend.ops.release = NULL; >> >> /* create mux i2c adapter for tuner */ >> state->muxc = i2c_mux_alloc(client->adapter, &client->dev, >> -- >> 2.7.4 >>
Am 05.01.2018 um 01:19 schrieb Michael Ira Krufky: > On Thu, Jan 4, 2018 at 7:04 PM, Brad Love <brad@nextdimension.cc> wrote: >> If release is part of frontend ops then it is called in the >> course of dvb_frontend_detach. The process also decrements >> the module usage count. The problem is if the lgdt3306a >> driver is reached via i2c_new_device, then when it is >> eventually destroyed remove is called, which further >> decrements the module usage count to negative. After this >> occurs the driver is in a bad state and no longer works. >> Also fixed by NULLing out the release callback is a double >> kfree of state, which introduces arbitrary oopses/GPF. >> This problem is only currently reachable via the em28xx driver. >> >> On disconnect of Hauppauge SoloHD before: >> >> lsmod | grep lgdt3306a >> lgdt3306a 28672 -1 >> i2c_mux 16384 1 lgdt3306a >> >> On disconnect of Hauppauge SoloHD after: >> >> lsmod | grep lgdt3306a >> lgdt3306a 28672 0 >> i2c_mux 16384 1 lgdt3306a >> >> Signed-off-by: Brad Love <brad@nextdimension.cc> >> --- >> drivers/media/dvb-frontends/lgdt3306a.c | 1 + >> 1 file changed, 1 insertion(+) >> > > Brad, > > We won't be able to apply this one. The symptom that you're trying to > fix is indicative of some other problem, probably in the em28xx > driver. NULL'ing the release callback is not the right thing to do. > Hi Mike, Why do you nak this perfectly fine patch? Let me start to explain. dvb_attach style drivers have an attach function and for unloading a .release callback. i2c-style drivers have a probe and a remove function. Mixed style drivers must be constructed, that either release or remove is called, never both. They both do the same thing, but with different signature. Now checking lgdt3306a driver: dvb attach style: In lgdt3306a_attach the release callback is set to lgdt3306a_release and no remove exists. Fine. i2c style probe: struct i2c_driver contains lgdt3306a_probe and lgdt3306a_remove. lgdt3306a_probe shares code and calls lgdt3306a_attach, but afterwards the release callback field must be set to NULL. This is/was done exactly like this in multiple other drivers as long as they have been multiple style attachable. Regards Matthias > >> diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c >> index 6356815..d2477ed 100644 >> --- a/drivers/media/dvb-frontends/lgdt3306a.c >> +++ b/drivers/media/dvb-frontends/lgdt3306a.c >> @@ -2177,6 +2177,7 @@ static int lgdt3306a_probe(struct i2c_client *client, >> >> i2c_set_clientdata(client, fe->demodulator_priv); >> state = fe->demodulator_priv; >> + state->frontend.ops.release = NULL; >> >> /* create mux i2c adapter for tuner */ >> state->muxc = i2c_mux_alloc(client->adapter, &client->dev, >> -- >> 2.7.4 >> >
On Tue, Jan 9, 2018 at 12:17 AM, Matthias Schwarzott <zzam@gentoo.org> wrote: > Am 05.01.2018 um 01:19 schrieb Michael Ira Krufky: >> On Thu, Jan 4, 2018 at 7:04 PM, Brad Love <brad@nextdimension.cc> wrote: >>> If release is part of frontend ops then it is called in the >>> course of dvb_frontend_detach. The process also decrements >>> the module usage count. The problem is if the lgdt3306a >>> driver is reached via i2c_new_device, then when it is >>> eventually destroyed remove is called, which further >>> decrements the module usage count to negative. After this >>> occurs the driver is in a bad state and no longer works. >>> Also fixed by NULLing out the release callback is a double >>> kfree of state, which introduces arbitrary oopses/GPF. >>> This problem is only currently reachable via the em28xx driver. >>> >>> On disconnect of Hauppauge SoloHD before: >>> >>> lsmod | grep lgdt3306a >>> lgdt3306a 28672 -1 >>> i2c_mux 16384 1 lgdt3306a >>> >>> On disconnect of Hauppauge SoloHD after: >>> >>> lsmod | grep lgdt3306a >>> lgdt3306a 28672 0 >>> i2c_mux 16384 1 lgdt3306a >>> >>> Signed-off-by: Brad Love <brad@nextdimension.cc> >>> --- >>> drivers/media/dvb-frontends/lgdt3306a.c | 1 + >>> 1 file changed, 1 insertion(+) >>> >> >> Brad, >> >> We won't be able to apply this one. The symptom that you're trying to >> fix is indicative of some other problem, probably in the em28xx >> driver. NULL'ing the release callback is not the right thing to do. >> > > Hi Mike, > Why do you nak this perfectly fine patch? > Let me start to explain. > > dvb_attach style drivers have an attach function and for unloading a > .release callback. > > i2c-style drivers have a probe and a remove function. > > Mixed style drivers must be constructed, that either release or remove > is called, never both. > They both do the same thing, but with different signature. > > > Now checking lgdt3306a driver: > > dvb attach style: > In lgdt3306a_attach the release callback is set to lgdt3306a_release and > no remove exists. Fine. > > i2c style probe: > struct i2c_driver contains lgdt3306a_probe and lgdt3306a_remove. > lgdt3306a_probe shares code and calls lgdt3306a_attach, but afterwards > the release callback field must be set to NULL. > > This is/was done exactly like this in multiple other drivers as long as > they have been multiple style attachable. > > Regards > Matthias > >> >>> diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c >>> index 6356815..d2477ed 100644 >>> --- a/drivers/media/dvb-frontends/lgdt3306a.c >>> +++ b/drivers/media/dvb-frontends/lgdt3306a.c >>> @@ -2177,6 +2177,7 @@ static int lgdt3306a_probe(struct i2c_client *client, >>> >>> i2c_set_clientdata(client, fe->demodulator_priv); >>> state = fe->demodulator_priv; >>> + state->frontend.ops.release = NULL; >>> >>> /* create mux i2c adapter for tuner */ >>> state->muxc = i2c_mux_alloc(client->adapter, &client->dev, >>> -- >>> 2.7.4 >>> >> > Brad & Matthias, It makes sense. This is just a result of a transitional period where there are multiple APIs for attaching the driver. Hopefully we can consolidate soon. I will look at the other drivers when I have time later on, but you're probably right, and we will likely end up merging this one after all. I'll try to get a PR out to Mauro by the weekend. -Mike
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 6356815..d2477ed 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -2177,6 +2177,7 @@ static int lgdt3306a_probe(struct i2c_client *client, i2c_set_clientdata(client, fe->demodulator_priv); state = fe->demodulator_priv; + state->frontend.ops.release = NULL; /* create mux i2c adapter for tuner */ state->muxc = i2c_mux_alloc(client->adapter, &client->dev,