From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Pavel Hofman <pavel.hofman@ivitera.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>
Subject: [PATCH 3.10 14/17] ALSA: ak411x: Fix stall in work callback
Date: Mon, 9 Feb 2015 16:33:41 +0800 [thread overview]
Message-ID: <20150209083041.024282821@linuxfoundation.org> (raw)
In-Reply-To: <20150209083039.240170510@linuxfoundation.org>
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit 4161b4505f1690358ac0a9ee59845a7887336b21 upstream.
When ak4114 work calls its callback and the callback invokes
ak4114_reinit(), it stalls due to flush_delayed_work(). For avoiding
this, control the reentrance by introducing a refcount. Also
flush_delayed_work() is replaced with cancel_delayed_work_sync().
The exactly same bug is present in ak4113.c and fixed as well.
Reported-by: Pavel Hofman <pavel.hofman@ivitera.com>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Tested-by: Pavel Hofman <pavel.hofman@ivitera.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/sound/ak4113.h | 2 +-
include/sound/ak4114.h | 2 +-
sound/i2c/other/ak4113.c | 17 ++++++++---------
sound/i2c/other/ak4114.c | 18 ++++++++----------
4 files changed, 18 insertions(+), 21 deletions(-)
--- a/include/sound/ak4113.h
+++ b/include/sound/ak4113.h
@@ -286,7 +286,7 @@ struct ak4113 {
ak4113_write_t *write;
ak4113_read_t *read;
void *private_data;
- unsigned int init:1;
+ atomic_t wq_processing;
spinlock_t lock;
unsigned char regmap[AK4113_WRITABLE_REGS];
struct snd_kcontrol *kctls[AK4113_CONTROLS];
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -168,7 +168,7 @@ struct ak4114 {
ak4114_write_t * write;
ak4114_read_t * read;
void * private_data;
- unsigned int init: 1;
+ atomic_t wq_processing;
spinlock_t lock;
unsigned char regmap[7];
unsigned char txcsb[5];
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -56,8 +56,7 @@ static inline unsigned char reg_read(str
static void snd_ak4113_free(struct ak4113 *chip)
{
- chip->init = 1; /* don't schedule new work */
- mb();
+ atomic_inc(&chip->wq_processing); /* don't schedule new work */
cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *c
chip->write = write;
chip->private_data = private_data;
INIT_DELAYED_WORK(&chip->work, ak4113_stats);
+ atomic_set(&chip->wq_processing, 0);
for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
chip->regmap[reg] = pgm[reg];
@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak41
void snd_ak4113_reinit(struct ak4113 *chip)
{
- chip->init = 1;
- mb();
- flush_delayed_work(&chip->work);
+ if (atomic_inc_return(&chip->wq_processing) == 1)
+ cancel_delayed_work_sync(&chip->work);
ak4113_init_regs(chip);
/* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
+ if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
}
EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_str
{
struct ak4113 *chip = container_of(work, struct ak4113, work.work);
- if (!chip->init)
+ if (atomic_inc_return(&chip->wq_processing) == 1)
snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
- schedule_delayed_work(&chip->work, HZ / 10);
+ if (atomic_dec_and_test(&chip->wq_processing))
+ schedule_delayed_work(&chip->work, HZ / 10);
}
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak41
static void snd_ak4114_free(struct ak4114 *chip)
{
- chip->init = 1; /* don't schedule new work */
- mb();
+ atomic_inc(&chip->wq_processing); /* don't schedule new work */
cancel_delayed_work_sync(&chip->work);
kfree(chip);
}
@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *c
chip->write = write;
chip->private_data = private_data;
INIT_DELAYED_WORK(&chip->work, ak4114_stats);
+ atomic_set(&chip->wq_processing, 0);
for (reg = 0; reg < 7; reg++)
chip->regmap[reg] = pgm[reg];
@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak41
void snd_ak4114_reinit(struct ak4114 *chip)
{
- chip->init = 1;
- mb();
- flush_delayed_work(&chip->work);
+ if (atomic_inc_return(&chip->wq_processing) == 1)
+ cancel_delayed_work_sync(&chip->work);
ak4114_init_regs(chip);
/* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
+ if (atomic_dec_and_test(&chip->wq_processing))
schedule_delayed_work(&chip->work, HZ / 10);
}
@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_str
{
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
- if (!chip->init)
+ if (atomic_inc_return(&chip->wq_processing) == 1)
snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
-
- schedule_delayed_work(&chip->work, HZ / 10);
+ if (atomic_dec_and_test(&chip->wq_processing))
+ schedule_delayed_work(&chip->work, HZ / 10);
}
EXPORT_SYMBOL(snd_ak4114_create);
next prev parent reply other threads:[~2015-02-09 8:35 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-09 8:33 [PATCH 3.10 00/17] 3.10.69-stable review Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 01/17] gpio: sysfs: fix memory leak in gpiod_export_link Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 02/17] gpio: sysfs: fix memory leak in gpiod_sysfs_set_active_low Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 03/17] PCI: Add NEC variants to Stratus ftServer PCIe DMI check Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 04/17] MIPS: IRQ: Fix disable_irq on CPU IRQs Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 05/17] MIPS: Fix kernel lockup or crash after CPU offline/online Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 06/17] mm: pagewalk: call pte_hole() for VM_PFNMAP during walk_page_range Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 07/17] lib/checksum.c: fix carry in csum_tcpudp_nofold Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 08/17] nilfs2: fix deadlock of segment constructor over I_SYNC flag Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 09/17] arm64: Fix up /proc/cpuinfo Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 10/17] ext4: prevent bugon on race between write/fcntl Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 11/17] lib/checksum.c: fix build for generic csum_tcpudp_nofold Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 12/17] ASoC: atmel_ssc_dai: fix start event for I2S mode Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 13/17] ASoC: sgtl5000: add delay before first I2C access Greg Kroah-Hartman
2015-02-09 8:33 ` Greg Kroah-Hartman [this message]
2015-02-09 8:33 ` [PATCH 3.10 15/17] smpboot: Add missing get_online_cpus() in smpboot_register_percpu_thread() Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 16/17] kvm: vmx: handle invvpid vm exit gracefully Greg Kroah-Hartman
2015-02-09 8:33 ` [PATCH 3.10 17/17] x86,kvm,vmx: Preserve CR4 across VM entry Greg Kroah-Hartman
2015-02-09 16:37 ` [PATCH 3.10 00/17] 3.10.69-stable review Guenter Roeck
2015-02-09 21:38 ` Greg Kroah-Hartman
2015-02-09 18:21 ` Shuah Khan
2015-02-09 21:37 ` Greg Kroah-Hartman
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=20150209083041.024282821@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pavel.hofman@ivitera.com \
--cc=perex@perex.cz \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.de \
/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