Bug 215792 - Focusrite Scarlett 18i8 3rd gen - pipewire - no input
Summary: Focusrite Scarlett 18i8 3rd gen - pipewire - no input
Status: RESOLVED CODE_FIX
Alias: None
Product: Drivers
Classification: Unclassified
Component: Sound(ALSA) (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Jaroslav Kysela
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-04-02 06:31 UTC by michael
Modified: 2022-04-20 14:53 UTC (History)
3 users (show)

See Also:
Kernel Version: 5.16.15-76051615-generic
Subsystem:
Regression: No
Bisected commit-id:


Attachments
Alsa logs about this issue (1.60 KB, text/plain)
2022-04-02 06:31 UTC, michael
Details
Jack is loaded - stream0 of my Scarlett (1.90 KB, text/plain)
2022-04-02 09:37 UTC, michael
Details
Jack is loaded - capture sub0 SW/HW params (395 bytes, application/octet-stream)
2022-04-02 09:39 UTC, michael
Details
Pipewire is loaded - stream 0 of my card (1.74 KB, application/octet-stream)
2022-04-02 09:40 UTC, michael
Details
Pipewire is loaded - capture sub0 SW/HW params (130 bytes, text/plain)
2022-04-02 09:41 UTC, michael
Details
pw-dump output (423.18 KB, text/plain)
2022-04-02 09:44 UTC, michael
Details
output of kernel messages using aplay followed by arecord on scarlett 18i8 (2.58 KB, text/plain)
2022-04-07 11:17 UTC, Claudio Cabral
Details
output of kernel messages using arecord followed by aplay (2.78 KB, text/plain)
2022-04-07 11:21 UTC, Claudio Cabral
Details
Output of /proc/asound for working and non working case at 48khz (4.27 KB, text/plain)
2022-04-07 12:04 UTC, Claudio Cabral
Details
Output of /proc/asound for working and non working case at 44.1khz (4.27 KB, text/plain)
2022-04-07 12:06 UTC, Claudio Cabral
Details
Output of /proc/asound with propsed patch applied (2.13 KB, text/plain)
2022-04-07 14:09 UTC, Claudio Cabral
Details
Test fix patch (5.43 KB, patch)
2022-04-07 15:53 UTC, Takashi Iwai
Details | Diff
Alternative fix patch (to use max time instead of bytes) (1.53 KB, patch)
2022-04-10 11:07 UTC, Takashi Iwai
Details | Diff

Description michael 2022-04-02 06:31:25 UTC
Created attachment 300680 [details]
Alsa logs about this issue

Distro : Pop!_OS 22.04 LTS

Hi,

After kernel upgrade from 5.10.x to any newer, my Focusrite Scarlett 18i8 3rd gen  is working badly. Inputs doesn't work at all from my own experience hang This affects also other multiple input audio interfaces (Focusrite 18i24 and so on), there is few tickets of mine about this issue on the issue tracker for Scarlett cards (on github) and the Gitlab for Pipewire :
- https://github.com/Focusrite-Scarlett-on-Linux/sound-usb-kernel-module/issues/13
- https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1626


According the main pipewire dev, it's an Alsa issue : 
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1948#note_1227101

Someone tried to dissect the kernel but found nothing.

It looks affecting many cards (other than mine Scarlett 18i8 mk3) : 
- Focusrite Scarlett 4i4 mk3 https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1948 and https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1044


Strangely, this card works well with Jack + Pulse audio. 

If we boot Linux on 5.10.x (tested up to 5.10.95) kernel everything is OK, all inputs are working continuously. This is input only problem with Pipewire, output works well (and, again, according the main dev. from pipewire it looks like an alsa issue)

Regards,
Michael
Comment 1 Takashi Iwai 2022-04-02 08:30:34 UTC
If it happens only on pipewire, it might come from the pipewire's specific way to configure the PCM parameters.

The recent relevant change was the restriction of available parameters for the implicit feedback mode and the shared clock source.  In both changes, the secondary opened stream is restricted only to the parameters that are aligned with the first one.  The sample rate, the channels or whatever.

If that's the case, the fact it worked before was a casual case that shouldn't have been supported but was just ignored.

So, for further debugging, you need to show which exact parameters are being set up for which streams in which timing.
Comment 2 michael 2022-04-02 09:37:50 UTC
Created attachment 300681 [details]
Jack is loaded - stream0 of my Scarlett
Comment 3 michael 2022-04-02 09:39:26 UTC
Created attachment 300682 [details]
Jack is loaded - capture sub0 SW/HW params
Comment 4 michael 2022-04-02 09:40:19 UTC
Created attachment 300683 [details]
Pipewire is loaded - stream 0 of my card
Comment 5 michael 2022-04-02 09:41:39 UTC
Created attachment 300684 [details]
Pipewire is loaded - capture sub0 SW/HW params
Comment 6 michael 2022-04-02 09:44:03 UTC
Created attachment 300685 [details]
pw-dump output

It contains detail about how pipewire try to configure the alsa device.
Comment 7 michael 2022-04-02 09:50:20 UTC
From the line 191 of the pipewire state dump (attachment 300685 [details] ) There is the Scarlett 18i8 config with the error : "Start error: Invalid argument"
Comment 8 michael 2022-04-02 09:53:27 UTC
@Takashi Iwai
About the "timing" to set the parameter, I believe you mean what's the chronology to set parameter to the alsa device ? 
If it's the case, I can't answer easily by myself unless you have a trick for that. On this case, I would ask the Pipewire developer to answer your request.
Comment 9 michael 2022-04-02 09:57:56 UTC
(In reply to michael from comment #7)
> From the line 191 of the pipewire state dump (attachment 300685 [details] )
> There is the Scarlett 18i8 config with the error : "Start error: Invalid
> argument"

Sorry it's at the line 5222 to retrieve how Pipewire try to configure Alsa.
Comment 10 Takashi Iwai 2022-04-02 13:03:25 UTC
Well, you need to show what function call failed.  It shows only EINVAL error and it alone doesn't mean anything useful.  If pw shows which ALSA-library call failed with which parameter, it would be more understanding.

As you see in comment 4, the playback stream is already set up for interface 1 altset 1, which is bound with the capture stream interface 2 altset 1.
And this capture setup (interface 2 altset 1) is restricted to channels = 20, and you must open all those channels no matter how many you need out of them.
Comment 11 Wim Taymans 2022-04-02 18:27:51 UTC
> Well, you need to show what function call failed.

It is in both cases this function call:

        CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");

And

        CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration for playback: no configurations available");

https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/alsa/alsa-pcm.c#L1363

We call this before we find a compatible format to set.
Comment 12 Takashi Iwai 2022-04-03 07:18:51 UTC
Interesting.  It means that setting the playback stream restricts too much on the capture side.

We need to know exactly which parameters are set up to the playback stream instead.  This defines the restriction.  My wild guess is that it brought too big capture period size or unaligned size due to the difference of the channels in both playback and capture streams.  Often using 48000 Hz helps in such a case.

Also, in sound/usb/pcm.c, add '#define HW_CONST_DEBUG 1' at the beginning of the file, and rebuild the kernel module.  Then boot with snd_usb_audio.dyndbg=+p boot option.  This will enable the debug prints.  And you'll see a bit more detailed debug messages around the hw_params problems.
Comment 13 Claudio Cabral 2022-04-07 11:17:30 UTC
Created attachment 300708 [details]
output of kernel messages using aplay followed by arecord on scarlett 18i8
Comment 14 Claudio Cabral 2022-04-07 11:19:15 UTC
Comment on attachment 300708 [details]
output of kernel messages using aplay followed by arecord on scarlett 18i8

I can reproduce this issue using aplay followed by arecord
If I invoke both commands in reverse order everything works as expected.
Comment 15 Claudio Cabral 2022-04-07 11:21:31 UTC
Created attachment 300709 [details]
output of kernel messages using arecord followed by aplay

Launching arecord first works fine and both streams coexist withtout issues
Comment 16 Takashi Iwai 2022-04-07 11:59:14 UTC
Could you give the parameters (found in proc files, at least /proc/asound/card*/pcm*/sub*/hw_params and /proc/asound/card*/stream* files) in both working and non-working cases?  That's the missing information.

And, build the module with with '#define HW_CONST_DEBUG 1' at the beginning of sound/usb/pcm.c.  This will give more verbose outputs.

Last but not least, please test both in 44.1k and 48k.  The behavior may differ for both.
Comment 17 Claudio Cabral 2022-04-07 12:04:45 UTC
Created attachment 300710 [details]
Output of /proc/asound for working and non working case at 48khz

Hi Takashi,

here's the output or 48khz for both cases, will try out 44.1khz now
Kernel compiling will have to wait until the weekend/next week unfortunately
Comment 18 Claudio Cabral 2022-04-07 12:06:56 UTC
Created attachment 300711 [details]
Output of /proc/asound for working and non working case at 44.1khz

Here you go.
do you also need the output of the kernel debug messages?
Comment 19 Takashi Iwai 2022-04-07 12:14:49 UTC
Thanks.  Could you give the hw_params proc also from the capture stream (while it's working), too?

And yes, the rebuilt kernel with the define will reveal why the hw_params is not accepted.  You'd need to rebuild the kernel in anyway when a fix patch is provided :)
Comment 20 Takashi Iwai 2022-04-07 12:21:38 UTC
(In reply to Takashi Iwai from comment #19)
> Thanks.  Could you give the hw_params proc also from the capture stream
> (while it's working), too?

Never mind, I see that the output has both, just concatenate.
Comment 21 Claudio Cabral 2022-04-07 12:23:27 UTC
Exactly, sorry if the output was confusing.

The problem with rebuilding the kernel is just time, I have never added a custom kernel to my distribution and don't have  VM ready for testing.
All that said, I'll give it a shot later tonight.
What extra logs are you interested in? Kernel logs when opening the capture card fails?
Comment 22 Takashi Iwai 2022-04-07 12:30:48 UTC
The likely cause is the buffer size.  In the working case, it reaches to 1MB for the capture stream, which is the hard limit defined in the driver.
OTOH, in the non-working case, the playback buffer (that has only 8 channels) assign a large buffer size.  Since the period size is tied in both playback and capture streams, the minimum buffer size of the capture stream would exceed over 1MB limit, hence the driver returns as -EINVAL.

So, the easiest workaround would be to increase the 1MB limit in the driver, simply put, the following oneliner:

--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -669,7 +669,7 @@ static const struct snd_pcm_hardware snd_usb_hardware =
                                SNDRV_PCM_INFO_PAUSE,
        .channels_min =         1,
        .channels_max =         256,
-       .buffer_bytes_max =     1024 * 1024,
+       .buffer_bytes_max =     4 * 1024 * 1024,
        .period_bytes_min =     64,
        .period_bytes_max =     512 * 1024,
        .periods_min =          2,
Comment 23 Takashi Iwai 2022-04-07 12:53:00 UTC
... though, the above change might still not work, if the application tries to allocate even bigger buffer because of the available size.  Let's see.

We need the additional hw_params constraint to limit the size for the counter-part stream if it's tied with implicit fb.
Comment 24 Claudio Cabral 2022-04-07 14:05:52 UTC
(In reply to Takashi Iwai from comment #22)
> The likely cause is the buffer size.  In the working case, it reaches to 1MB
> for the capture stream, which is the hard limit defined in the driver.
> OTOH, in the non-working case, the playback buffer (that has only 8
> channels) assign a large buffer size.  Since the period size is tied in both
> playback and capture streams, the minimum buffer size of the capture stream
> would exceed over 1MB limit, hence the driver returns as -EINVAL.
> 
> So, the easiest workaround would be to increase the 1MB limit in the driver,
> simply put, the following oneliner:
> 
> --- a/sound/usb/pcm.c
> +++ b/sound/usb/pcm.c
> @@ -669,7 +669,7 @@ static const struct snd_pcm_hardware snd_usb_hardware =
>                                 SNDRV_PCM_INFO_PAUSE,
>         .channels_min =         1,
>         .channels_max =         256,
> -       .buffer_bytes_max =     1024 * 1024,
> +       .buffer_bytes_max =     4 * 1024 * 1024,
>         .period_bytes_min =     64,
>         .period_bytes_max =     512 * 1024,
>         .periods_min =          2,

built a custom kernel with this patch and it does fix the issue.
I can build another one with the debug logging if you think it's necessary.
thanks for the support in this!
Comment 25 Claudio Cabral 2022-04-07 14:09:18 UTC
Created attachment 300712 [details]
Output of /proc/asound with propsed patch applied

Here's the output of
cat /proc/asound/USB/pcm*/sub*/hw_params && echo '' && cat /proc/asound/USB/stream*
after doing
aplay -D hw:USB -r 48000 -f S32_LE -c 8 /dev/zero
arecord -D hw:USB -r 48000 -f S32_LE -c 20 out.wav
Comment 26 Wim Taymans 2022-04-07 14:21:39 UTC
I pushed a PipeWire patch that limits the requested buffer_frames to (with default settings) 8192 * 4 samples. That should be 8192 * 4 * 4 * 8 = 1048576 bytes for 8 channels, 32 bit samples. That's probably better than asking for as much as possible.
Comment 27 Takashi Iwai 2022-04-07 15:52:09 UTC
(In reply to Wim Taymans from comment #26)
> I pushed a PipeWire patch that limits the requested buffer_frames to (with
> default settings) 8192 * 4 samples. That should be 8192 * 4 * 4 * 8 =
> 1048576 bytes for 8 channels, 32 bit samples. That's probably better than
> asking for as much as possible.

Thanks, that sounds better, at least for the operation like pipewire.
Comment 28 Takashi Iwai 2022-04-07 15:53:22 UTC
Since my guess seemed correct, below is a more comprehensive fix patch.
Claudio, could you revert the buffer byte change, and test this patch instead?
Comment 29 Takashi Iwai 2022-04-07 15:53:53 UTC
Created attachment 300713 [details]
Test fix patch
Comment 30 Jaroslav Kysela 2022-04-07 18:05:36 UTC
If I am correct then this patch does not exceed the 1MB buffer limit, right?

I am not convinced, if it's good for all cases, because simple calculation for 10 channels (GoXLR for example) with 3 bytes per sample ends with:

   (1024*1024) / (10 * 3) = 34952  .... frames

If you take in account the sampling frequency 192kHz, it's buffer only for 182ms.

We should allow a bigger buffers for this hw (multichannel & 24-bit).
Comment 31 Claudio Cabral 2022-04-07 18:50:47 UTC
(In reply to Takashi Iwai from comment #28)
> Since my guess seemed correct, below is a more comprehensive fix patch.
> Claudio, could you revert the buffer byte change, and test this patch
> instead?

The new patch works nicely for the Scarlett 18i8.
Let me know if there's anything else you need me to do or test.
Comment 32 Takashi Iwai 2022-04-07 21:05:07 UTC
(In reply to Jaroslav Kysela from comment #30)
> If I am correct then this patch does not exceed the 1MB buffer limit, right?

Yes but only if the streams are tied in the implicit feedback mode.

> I am not convinced, if it's good for all cases, because simple calculation
> for 10 channels (GoXLR for example) with 3 bytes per sample ends with:
> 
>    (1024*1024) / (10 * 3) = 34952  .... frames
> 
> If you take in account the sampling frequency 192kHz, it's buffer only for
> 182ms.
> 
> We should allow a bigger buffers for this hw (multichannel & 24-bit).

The current definitions of the max buffer and period sizes are just "some" software limit, which we thought it'd be large enough in 20 years ago :)
Surely it's time to increase the sizes.  But it's basically a different issue.
Even if we increase the sizes, the same problem would hit again unless we add the correction of the buffer size reduction by channels.

(Note that the increase of buffer_bytes_max worked around this case because we increased only the buffer size, and not the period size.)
Comment 33 Takashi Iwai 2022-04-08 07:01:40 UTC
The fix patch submitted to upsteram:
  https://lore.kernel.org/r/20220407211657.15087-1-tiwai@suse.de

The increase of the max buffer size was also submitted:
  https://lore.kernel.org/r/20220407212740.17920-1-tiwai@suse.de

Both will be merged sooner or later, and will be included in 5.18-rc3 pull request.
Comment 34 Takashi Iwai 2022-04-10 11:06:27 UTC
Meanwhile, it might be cleaner to rather have restrictions via PERIOD_TIME or BUFFER_TIME and drop the limit of bytes instead.

Could you try the patch below instead of the previous fixes (also drop the increase of buffer_bytes_max) and check whether it also works around the problem with your device?
Comment 35 Takashi Iwai 2022-04-10 11:07:20 UTC
Created attachment 300738 [details]
Alternative fix patch (to use max time instead of bytes)
Comment 36 michael 2022-04-10 11:25:49 UTC
I just tried this path and it works flawlessly for me ! https://bugzilla.kernel.org/attachment.cgi?id=300713&action=diff
Comment 37 Takashi Iwai 2022-04-20 14:53:54 UTC
The fixes went into 5.18-rc3 and backported to stable trees.

Note You need to log in before you can comment on or make changes to this bug.