From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Jarod Wilson <jarod@redhat.com>,
Mauro Carvalho Chehab <mchehab@redhat.com>
Subject: [patch 24/38] [media] imon: add conditional locking in change_protocol
Date: Thu, 05 May 2011 17:10:56 -0700 [thread overview]
Message-ID: <20110506001209.680029807@clark.kroah.org> (raw)
In-Reply-To: <20110506001225.GA10547@kroah.com>
2.6.38-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jarod Wilson <jarod@redhat.com>
commit 23ef710e1a6c4d6b9ef1c2fa19410f7f1479401e upstream.
The imon_ir_change_protocol function gets called two different ways, one
way is from rc_register_device, for initial protocol selection/setup,
and the other is via a userspace-initiated protocol change request,
either by direct sysfs prodding or by something like ir-keytable.
In the rc_register_device case, the imon context lock is already held,
but when initiated from userspace, it is not, so we must acquire it,
prior to calling send_packet, which requires that the lock is held.
Without this change, there's an easily reproduceable deadlock when
another function calls send_packet (such as either of the display write
fops) after a userspace-initiated change_protocol.
With a lock-debugging-enabled kernel, I was getting this:
[ 15.014153] =====================================
[ 15.015048] [ BUG: bad unlock balance detected! ]
[ 15.015048] -------------------------------------
[ 15.015048] ir-keytable/773 is trying to release lock (&ictx->lock) at:
[ 15.015048] [<ffffffff814c6297>] mutex_unlock+0xe/0x10
[ 15.015048] but there are no more locks to release!
[ 15.015048]
[ 15.015048] other info that might help us debug this:
[ 15.015048] 2 locks held by ir-keytable/773:
[ 15.015048] #0: (&buffer->mutex){+.+.+.}, at: [<ffffffff8119d400>] sysfs_write_file+0x3c/0x144
[ 15.015048] #1: (s_active#87){.+.+.+}, at: [<ffffffff8119d4ab>] sysfs_write_file+0xe7/0x144
[ 15.015048]
[ 15.015048] stack backtrace:
[ 15.015048] Pid: 773, comm: ir-keytable Not tainted 2.6.38.4-20.fc15.x86_64.debug #1
[ 15.015048] Call Trace:
[ 15.015048] [<ffffffff81089715>] ? print_unlock_inbalance_bug+0xca/0xd5
[ 15.015048] [<ffffffff8108b35c>] ? lock_release_non_nested+0xc1/0x263
[ 15.015048] [<ffffffff814c6297>] ? mutex_unlock+0xe/0x10
[ 15.015048] [<ffffffff814c6297>] ? mutex_unlock+0xe/0x10
[ 15.015048] [<ffffffff8108b67b>] ? lock_release+0x17d/0x1a4
[ 15.015048] [<ffffffff814c6229>] ? __mutex_unlock_slowpath+0xc5/0x125
[ 15.015048] [<ffffffff814c6297>] ? mutex_unlock+0xe/0x10
[ 15.015048] [<ffffffffa02964b6>] ? send_packet+0x1c9/0x264 [imon]
[ 15.015048] [<ffffffff8108b376>] ? lock_release_non_nested+0xdb/0x263
[ 15.015048] [<ffffffffa0296731>] ? imon_ir_change_protocol+0x126/0x15e [imon]
[ 15.015048] [<ffffffffa024a334>] ? store_protocols+0x1c3/0x286 [rc_core]
[ 15.015048] [<ffffffff81326e4e>] ? dev_attr_store+0x20/0x22
[ 15.015048] [<ffffffff8119d4cc>] ? sysfs_write_file+0x108/0x144
...
The original report that led to the investigation was the following:
[ 1679.457305] INFO: task LCDd:8460 blocked for more than 120 seconds.
[ 1679.457307] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1679.457309] LCDd D ffff88010fcd89c8 0 8460 1 0x00000000
[ 1679.457312] ffff8800d5a03b48 0000000000000082 0000000000000000 ffff8800d5a03fd8
[ 1679.457314] 00000000012dcd30 fffffffffffffffd ffff8800d5a03fd8 ffff88010fcd86f0
[ 1679.457316] ffff8800d5a03fd8 ffff8800d5a03fd8 ffff88010fcd89d0 ffff8800d5a03fd8
[ 1679.457319] Call Trace:
[ 1679.457324] [<ffffffff810ff1a5>] ? zone_statistics+0x75/0x90
[ 1679.457327] [<ffffffff810ea907>] ? get_page_from_freelist+0x3c7/0x820
[ 1679.457330] [<ffffffff813b0a49>] __mutex_lock_slowpath+0x139/0x320
[ 1679.457335] [<ffffffff813b0c41>] mutex_lock+0x11/0x30
[ 1679.457338] [<ffffffffa0d54216>] display_open+0x66/0x130 [imon]
[ 1679.457345] [<ffffffffa01d06c0>] usb_open+0x180/0x310 [usbcore]
[ 1679.457349] [<ffffffff81143b3b>] chrdev_open+0x1bb/0x2d0
[ 1679.457350] [<ffffffff8113d93d>] __dentry_open+0x10d/0x370
[ 1679.457352] [<ffffffff81143980>] ? chrdev_open+0x0/0x2d0
...
Bump the driver version here so its easier to tell if people have this
locking fix or not, and also make locking during probe easier to follow.
Reported-by: Benjamin Hodgetts <ben@xnode.org>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/media/rc/imon.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -46,7 +46,7 @@
#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
#define MOD_NAME "imon"
-#define MOD_VERSION "0.9.2"
+#define MOD_VERSION "0.9.3"
#define DISPLAY_MINOR_BASE 144
#define DEVICE_NAME "lcd%d"
@@ -451,8 +451,9 @@ static int display_close(struct inode *i
}
/**
- * Sends a packet to the device -- this function must be called
- * with ictx->lock held.
+ * Sends a packet to the device -- this function must be called with
+ * ictx->lock held, or its unlock/lock sequence while waiting for tx
+ * to complete can/will lead to a deadlock.
*/
static int send_packet(struct imon_context *ictx)
{
@@ -982,12 +983,21 @@ static void imon_touch_display_timeout(u
* the iMON remotes, and those used by the Windows MCE remotes (which is
* really just RC-6), but only one or the other at a time, as the signals
* are decoded onboard the receiver.
+ *
+ * This function gets called two different ways, one way is from
+ * rc_register_device, for initial protocol selection/setup, and the other is
+ * via a userspace-initiated protocol change request, either by direct sysfs
+ * prodding or by something like ir-keytable. In the rc_register_device case,
+ * the imon context lock is already held, but when initiated from userspace,
+ * it is not, so we must acquire it prior to calling send_packet, which
+ * requires that the lock is held.
*/
static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
int retval;
struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
+ bool unlock = false;
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
@@ -1020,6 +1030,11 @@ static int imon_ir_change_protocol(struc
memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
+ if (!mutex_is_locked(&ictx->lock)) {
+ unlock = true;
+ mutex_lock(&ictx->lock);
+ }
+
retval = send_packet(ictx);
if (retval)
goto out;
@@ -1028,6 +1043,9 @@ static int imon_ir_change_protocol(struc
ictx->pad_mouse = false;
out:
+ if (unlock)
+ mutex_unlock(&ictx->lock);
+
return retval;
}
@@ -2125,6 +2143,7 @@ static struct imon_context *imon_init_in
goto rdev_setup_failed;
}
+ mutex_unlock(&ictx->lock);
return ictx;
rdev_setup_failed:
@@ -2196,6 +2215,7 @@ static struct imon_context *imon_init_in
goto urb_submit_failed;
}
+ mutex_unlock(&ictx->lock);
return ictx;
urb_submit_failed:
@@ -2290,6 +2310,8 @@ static int __devinit imon_probe(struct u
usb_set_intfdata(interface, ictx);
if (ifnum == 0) {
+ mutex_lock(&ictx->lock);
+
if (product == 0xffdc && ictx->rf_device) {
sysfs_err = sysfs_create_group(&interface->dev.kobj,
&imon_rf_attr_group);
@@ -2300,13 +2322,14 @@ static int __devinit imon_probe(struct u
if (ictx->display_supported)
imon_init_display(ictx, interface);
+
+ mutex_unlock(&ictx->lock);
}
dev_info(dev, "iMON device (%04x:%04x, intf%d) on "
"usb<%d:%d> initialized\n", vendor, product, ifnum,
usbdev->bus->busnum, usbdev->devnum);
- mutex_unlock(&ictx->lock);
mutex_unlock(&driver_lock);
return 0;
next prev parent reply other threads:[~2011-05-06 0:13 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-06 0:12 [patch 00/38] 2.6.38.6-stable review Greg KH
2011-05-06 0:10 ` [patch 01/38] [SCSI] pmcraid: reject negative request size Greg KH
2011-05-06 0:10 ` [patch 02/38] [SCSI] mpt2sas: prevent heap overflows and unchecked reads Greg KH
2011-05-06 0:10 ` [patch 03/38] [SCSI] scsi_dh: fix reference counting in scsi_dh_activate error path Greg KH
2011-05-06 0:10 ` [patch 04/38] [SCSI] put stricter guards on queue dead checks Greg KH
2011-05-06 14:54 ` Jim Schutt
2011-05-06 16:17 ` [stable] " Greg KH
2011-05-06 16:33 ` James Bottomley
2011-05-07 8:46 ` [Stable-review] " Chuck Ebbert
2011-05-09 20:43 ` [stable] [Stable-review] " Greg KH
2011-05-06 0:10 ` [patch 05/38] ALSA: HDA: Fix automute for Gateway NV79 Greg KH
2011-05-06 0:10 ` [patch 06/38] Revert "ALSA: hda - Fix pin-config of Gigabyte mobo" Greg KH
2011-05-06 0:10 ` [patch 07/38] ALSA: hda - Fix Realteks chained fixup checks Greg KH
2011-05-06 0:10 ` [patch 08/38] i2c-parport: Fix adapter list handling Greg KH
2011-05-06 0:10 ` [patch 09/38] workqueue: fix deadlock in worker_maybe_bind_and_lock() Greg KH
2011-05-06 0:10 ` [patch 10/38] iwlwifi: fix skb usage after free Greg KH
2011-05-06 0:10 ` [patch 11/38] iwlagn: fix "Received BA when not expected" Greg KH
2011-05-06 0:10 ` [patch 12/38] atl1c: Fix work event interrupt/task races Greg KH
2011-05-06 0:10 ` [patch 13/38] UBIFS: do not free write-buffers when in R/O mode Greg KH
2011-05-06 0:10 ` [patch 14/38] UBIFS: seek journal heads to the latest bud in replay Greg KH
2011-05-06 0:10 ` [patch 15/38] mmc: fix a race between card-detect rescan and clock-gate work instances Greg KH
2011-05-06 0:10 ` [patch 16/38] mmc: sdhci-pci: Fix error case in sdhci_pci_probe_slot() Greg KH
2011-05-06 0:10 ` [patch 17/38] mmc: sdhci: Check mrq->cmd in sdhci_tasklet_finish Greg KH
2011-05-06 0:10 ` [patch 18/38] mmc: sdhci: Check mrq != NULL " Greg KH
2011-05-06 0:10 ` [patch 19/38] drm/radeon: fix regression on atom cards with hardcoded EDID record Greg KH
2011-05-06 0:10 ` [patch 20/38] USB: fix regression in usbip by setting has_tt flag Greg KH
2011-05-06 0:10 ` [patch 21/38] firewire: Fix for broken configrom updates in quick succession Greg KH
2011-05-06 0:10 ` [patch 22/38] usbnet: add support for some Huawei modems with cdc-ether ports Greg KH
2011-05-06 0:10 ` [patch 23/38] [media] v4l: make sure drivers supply a zeroed struct v4l2_subdev Greg KH
2011-05-06 0:10 ` Greg KH [this message]
2011-05-06 0:10 ` [patch 25/38] flex_array: flex_array_prealloc takes a number of elements, not an end Greg KH
2011-05-06 0:10 ` [patch 26/38] flex_arrays: allow zero length flex arrays Greg KH
2011-05-06 0:10 ` [patch 27/38] x86, AMD: Fix APIC timer erratum 400 affecting K8 Rev.A-E processors Greg KH
2011-05-06 0:11 ` [patch 28/38] ath9k: fix the return value of ath_stoprecv Greg KH
2011-05-06 0:11 ` [patch 29/38] mac80211: fix SMPS debugfs locking Greg KH
2011-05-06 0:11 ` [patch 30/38] af_unix: Only allow recv on connected seqpacket sockets Greg KH
2011-05-06 0:11 ` [patch 31/38] ARM: 6891/1: prevent heap corruption in OABI semtimedop Greg KH
2011-05-07 1:49 ` [Stable-review] " Ben Hutchings
2011-05-09 20:09 ` Jesper Juhl
2011-05-09 21:07 ` Ben Hutchings
2011-05-06 0:11 ` [patch 32/38] XZ decompressor: Fix decoding of empty LZMA2 streams Greg KH
2011-05-06 0:11 ` [patch 33/38] Open with O_CREAT flag set fails to open existing files on non writable directories Greg KH
2011-05-06 0:11 ` [patch 34/38] can: Add missing socket check in can/bcm release Greg KH
2011-05-06 7:16 ` [Stable-review] " Chuck Ebbert
2011-05-06 7:24 ` David Miller
2011-05-09 20:41 ` [stable] " Greg KH
2011-05-06 0:11 ` [patch 35/38] fs/partitions/ldm.c: fix oops caused by corrupted partition table Greg KH
2011-05-07 2:24 ` [Stable-review] " Ben Hutchings
2011-05-09 15:13 ` Timo Warns
2011-05-06 0:11 ` [patch 36/38] [media] cx88: Fix HVR4000 IR keymap Greg KH
2011-05-06 0:11 ` [patch 37/38] KVM: SVM: check for progress after IRET interception Greg KH
2011-05-06 0:11 ` [patch 38/38] drm/radeon/kms: add some new pci ids Greg KH
2011-05-09 16:38 ` [stable] [patch 00/38] 2.6.38.6-stable review Chuck Ebbert
2011-05-09 20:44 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110506001209.680029807@clark.kroah.org \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=jarod@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mchehab@redhat.com \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®