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: 28+ 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:36 ` kernel test robot
2021-03-24 23:57 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.