From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: "Alexander.Deucher@amd.com" <Alexander.Deucher@amd.com>,
alsa-devel@alsa-project.org,
Sergei Miroshnichenko <s.miroshnichenko@yadro.com>,
"Christian.Koenig@amd.com" <Christian.Koenig@amd.com>
Subject: Re: Adding movable PCIe BARs support in snd_hda_intel
Date: Fri, 26 Mar 2021 17:27:26 -0400 [thread overview]
Message-ID: <7788be67-e78f-4738-0ffe-27d4717c6f58@amd.com> (raw)
In-Reply-To: <s5hwntvkx2c.wl-tiwai@suse.de>
[-- Attachment #1: Type: text/plain, Size: 2169 bytes --]
Attached.
Andrey
On 2021-03-25 12:38 p.m., Takashi Iwai wrote:
> On Thu, 25 Mar 2021 17:13:41 +0100,
> Andrey Grodzovsky wrote:
>>
>>
>>
>> On 2021-03-25 2:58 a.m., Takashi Iwai wrote:
>>> On Wed, 24 Mar 2021 22:43:24 +0100,
>>> Andrey Grodzovsky wrote:
>>>>
>>>> Few comments -
>>>>
>>>> 1) Why we don't use snd_power_wait_and_ref in patch 3 in the common
>>>> handler ?
>>>> Don't we want the PCI rescan sequence to 'wait for' any in flight
>>>> taks that might be accessing registers and not only read/write/tlv
>>>> accesses ?
>>>
>>> Right, we don't need to block all ioctls, but only the ones that may
>>> access the hardware. So basically the patches 3-5 can be dropped if
>>> we take the patch 6. The current patch was written on top of the
>>> previous series, that's why it has both.
>>>
>>>> 2) Possible deadlock -
>>>> In azx_rescan_prepare - you put the card into SNDRV_CTL_POWER_D3hot
>>>> first and then 'wait for' all in flight tasks with the refcount.
>>>> The in flight tasks on the other hand, using snd_power_wait_and_ref,
>>>> may have already bumped up the refcount and now 'wait for' the card
>>>> to go into SNDRV_CTL_POWER_D0 which can't happen since PCI rescan
>>>> waits for the refocunt to drop to 0 before proceeding.
>>>>
>>>> Instead of snd_power_wait_and_ref can't we just call snd_power_ref
>>>> in common IOCTL before checking for power_state != SNDRV_CTL_POWER_D0 ?
>>>> Or is it because you don't want to fail IOCTLs ?
>>>
>>> No, this is the intended behavior and should work as-is because
>>> snd_power_wait_and_ref() drops the refcount in the loop before
>>> sleeping. The inc before the state check is a must for covering the
>>> possible race, and ditto for changing the power_state to D3hot before
>>> syncing.
>>
>> Ohh, missed the refcount dec in the wait loop... My bad.
>>
>> On boot the latest patch-set was throwing refcount warnings since
>> u are not supposed to inc from zerro count and so I fixed
>> with the attached patch. That way seems to work fine.
>
> Ah, I completely forgot about the oddness of refcount_t.
> Then I guess it's simpler to replace with atomic_*() instead.
>
>
> thanks,
>
> Takashi
>
[-- Attachment #2: 0001-ALSA-Fix-refcount-splat.patch --]
[-- Type: text/x-patch, Size: 6429 bytes --]
From 0347ad666d2f0a20d1074a64dc5a1f6d9cec44b2 Mon Sep 17 00:00:00 2001
From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Date: Thu, 25 Mar 2021 12:07:38 -0400
Subject: ALSA: Fix refcount splat
Righ on boot bellow WARN observed
Fix by setting refcount to 1 and also
drop the optimization in snd_power_unref
since I can't rely on atomic refcount_sub_and_test
anymore.
v2: Switch to atomic type instead of refcount
[ 41.710577 < 0.000078>] ------------[ cut here ]------------
[ 41.710580 < 0.000003>] refcount_t: addition on 0; use-after-free.
[ 41.710603 < 0.000023>] WARNING: CPU: 10 PID: 2781 at lib/refcount.c:25 refcount_warn_saturate+0x86/0x110
[ 41.710614 < 0.000011>] Modules linked in: snd_hda_codec_hdmi(OE) snd_hda_intel(OE) snd_intel_dspcfg(OE) snd_hda_codec(OE) snd_hda_core(OE) snd_pcm(OE) snd_seq_midi(OE) snd_seq_midi_event(OE) snd_rawmidi(OE) snd_seq(OE) snd_seq_device(OE) snd_timer(OE) snd(OE) input_leds led_class joydev kvm k10temp drm(OE) drm_panel_orientation_quirks(OE) igb i2c_algo_bit pinctrl_amd
[ 41.710679 < 0.000065>] CPU: 10 PID: 2781 Comm: alsactl Tainted: G OE 5.11.0-rc3-pci-bars+ #7
[ 41.710685 < 0.000006>] Hardware name: System manufacturer System Product Name/PRIME X470-PRO, BIOS 4406 02/28/2019
[ 41.710689 < 0.000004>] RIP: 0010:refcount_warn_saturate+0x86/0x110
[ 41.710696 < 0.000007>] Code: dc dd 27 02 01 e8 22 92 9f 00 0f 0b eb d9 80 3d cb dd 27 02 00 75 d0 48 c7 c7 40 f0 d9 83 c6 05 bb dd 27 02 01 e8 02 92 9f 00 <0f> 0b eb b9 80 3d ad dd 27 02 00 75 b0 48 c7 c7 a0 ef d9 83 c6 05
[ 41.710701 < 0.000005>] RSP: 0018:ffff888259bcfb98 EFLAGS: 00010286
[ 41.710707 < 0.000006>] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 0000000000000000
[ 41.710711 < 0.000004>] RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffffed104b379f65
[ 41.710715 < 0.000004>] RBP: ffff88816a60ef40 R08: ffffffff822b270e R09: ffffed10df33e014
[ 41.710719 < 0.000004>] R10: ffff8886f99f009b R11: ffffed10df33e013 R12: 0000000000000001
[ 41.710723 < 0.000004>] R13: 1ffff1104b379f79 R14: ffff88816a60ef40 R15: 0000000000000000
[ 41.710728 < 0.000005>] FS: 00007f0e1817e440(0000) GS:ffff8886f9800000(0000) knlGS:0000000000000000
[ 41.710732 < 0.000004>] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 41.710736 < 0.000004>] CR2: 00007f0e185f7000 CR3: 00000001532fa000 CR4: 00000000003506e0
[ 41.710740 < 0.000004>] Call Trace:
[ 41.710744 < 0.000004>] snd_power_wait_and_ref+0x315/0x320 [snd]
[ 41.710768 < 0.000024>] ? snd_card_new+0x5e0/0x5e0 [snd]
[ 41.710790 < 0.000022>] ? lock_acquire+0xee/0x570
[ 41.710797 < 0.000007>] ? lock_acquire+0xee/0x570
[ 41.710804 < 0.000007>] ? lock_acquired+0xb4/0x5a0
[ 41.710810 < 0.000006>] ? snd_ctl_ioctl+0x240/0xb60 [snd]
[ 41.710832 < 0.000022>] ? snd_ctl_find_id+0x161/0x180 [snd]
[ 41.710855 < 0.000023>] snd_ctl_elem_write+0x1c4/0x350 [snd]
[ 41.710878 < 0.000023>] ? copy_ctl_value_from_user+0x2f0/0x2f0 [snd]
[ 41.710901 < 0.000023>] ? down_write+0x16c/0x2e0
[ 41.710907 < 0.000006>] ? snd_ctl_ioctl+0x240/0xb60 [snd]
[ 41.710929 < 0.000022>] ? rwsem_down_read_slowpath+0x5f0/0x5f0
[ 41.710935 < 0.000006>] ? _copy_from_user+0xa0/0xf0
[ 41.710942 < 0.000007>] snd_ctl_ioctl+0x24e/0xb60 [snd]
[ 41.710965 < 0.000023>] ? snd_ctl_elem_add_user+0x150/0x150 [snd]
[ 41.710988 < 0.000023>] ? selinux_capable+0x20/0x20
[ 41.710995 < 0.000007>] ? kmem_cache_free+0x145/0x390
[ 41.711001 < 0.000006>] ? lockdep_hardirqs_on_prepare+0xe/0x210
[ 41.711007 < 0.000006>] ? blkcg_maybe_throttle_current+0x7f/0x7f0
[ 41.711014 < 0.000007>] ? call_rcu+0x20b/0x3a0
[ 41.711024 < 0.000010>] __x64_sys_ioctl+0xe0/0x120
[ 41.711029 < 0.000005>] ? syscall_trace_enter.isra.0+0xc9/0x270
[ 41.711036 < 0.000007>] do_syscall_64+0x33/0x80
[ 41.711042 < 0.000006>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 41.711048 < 0.000006>] RIP: 0033:0x7f0e183eb50b
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
---
include/sound/core.h | 6 +++---
sound/core/init.c | 3 ++-
sound/pci/hda/hda_intel.c | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/sound/core.h b/include/sound/core.h
index 0b220bfe001b..8ac6647bc39a 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -126,7 +126,7 @@ struct snd_card {
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
wait_queue_head_t power_sleep;
- refcount_t power_ref;
+ atomic_t power_ref;
wait_queue_head_t power_ref_sleep;
#endif
@@ -152,12 +152,12 @@ static inline void snd_power_change_state(struct snd_card *card, unsigned int st
static inline void snd_power_ref(struct snd_card *card)
{
- refcount_inc(&card->power_ref);
+ atomic_inc(&card->power_ref);
}
static inline void snd_power_unref(struct snd_card *card)
{
- if (refcount_dec_and_test(&card->power_ref))
+ if (atomic_dec_and_test(&card->power_ref))
wake_up(&card->power_ref_sleep);
}
diff --git a/sound/core/init.c b/sound/core/init.c
index cb0ad0883329..d26f904e9d45 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -215,8 +215,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
mutex_init(&card->memory_mutex);
#ifdef CONFIG_PM
init_waitqueue_head(&card->power_sleep);
- refcount_set(&card->power_ref, 0);
init_waitqueue_head(&card->power_ref_sleep);
+ atomic_set(&card->power_ref, 0);
#endif
init_waitqueue_head(&card->remove_sleep);
card->sync_irq = -1;
@@ -1007,6 +1007,7 @@ int snd_power_wait_and_ref(struct snd_card *card, bool ref)
/* fastpath */
if (ref)
snd_power_ref(card);
+
if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0)
return 0;
init_waitqueue_entry(&wait, current);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b6d118c2b75b..11138b47fc73 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2457,7 +2457,7 @@ static void azx_rescan_prepare(struct pci_dev *pdev)
azx_prepare(&pdev->dev);
azx_suspend_streams(chip);
wait_event(card->power_ref_sleep,
- !refcount_read(&card->power_ref));
+ !atomic_read(&card->power_ref));
list_for_each_codec(codec, &chip->bus) {
pm_runtime_suspend(hda_codec_dev(codec));
pm_runtime_disable(hda_codec_dev(codec));
--
2.25.1
next prev parent reply other threads:[~2021-03-26 21:28 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-19 21:22 Adding movable PCIe BARs support in snd_hda_intel Andrey Grodzovsky
2021-03-23 11:23 ` Andrey Grodzovsky
2021-03-23 11:39 ` Takashi Iwai
2021-03-23 14:22 ` Andrey Grodzovsky
2021-03-23 14:54 ` Takashi Iwai
2021-03-23 16:11 ` Andrey Grodzovsky
2021-03-23 16:50 ` Takashi Iwai
2021-03-23 17:08 ` Andrey Grodzovsky
2021-03-23 17:29 ` Takashi Iwai
2021-03-23 18:25 ` Andrey Grodzovsky
2021-03-24 10:00 ` Takashi Iwai
2021-03-24 14:53 ` Andrey Grodzovsky
2021-03-24 15:06 ` Takashi Iwai
2021-03-24 15:43 ` Andrey Grodzovsky
2021-03-24 20:36 ` Takashi Iwai
2021-03-24 21:43 ` Andrey Grodzovsky
2021-03-25 6:58 ` Takashi Iwai
2021-03-25 16:13 ` Andrey Grodzovsky
2021-03-25 16:38 ` Takashi Iwai
2021-03-26 21:27 ` Andrey Grodzovsky [this message]
2021-03-27 8:17 ` Takashi Iwai
2021-03-29 14:47 ` Andrey Grodzovsky
2021-03-29 14:52 ` Takashi Iwai
2021-03-29 14:57 ` Andrey Grodzovsky
2021-03-24 23:36 ` [PATCH v2 1/8] ALSA: hda: Re-add dropped snd_poewr_change_state() kernel test robot
2021-03-24 23:57 ` kernel test robot
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=7788be67-e78f-4738-0ffe-27d4717c6f58@amd.com \
--to=andrey.grodzovsky@amd.com \
--cc=Alexander.Deucher@amd.com \
--cc=Christian.Koenig@amd.com \
--cc=alsa-devel@alsa-project.org \
--cc=s.miroshnichenko@yadro.com \
--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