From: Takashi Iwai <tiwai@suse.de>
To: Stefan Sauer <st.kost@gmail.com>
Cc: alsa-devel@alsa-project.org
Subject: Re: slow snd_rawmidi_drain() for VirMidi devcies
Date: Wed, 05 Jan 2022 15:13:47 +0100 [thread overview]
Message-ID: <s5hlezui82s.wl-tiwai@suse.de> (raw)
In-Reply-To: <CAJ4JBRMKsrJ54ee0gPwRTeScghA4SB8m2iOWybQA=6584ejG-g@mail.gmail.com>
On Wed, 05 Jan 2022 14:39:05 +0100,
Stefan Sauer wrote:
>
> - 28,78% 0,00% rawmidi_alsa [snd_rawmidi] [k]
> snd_rawmidi_drain_output
> - snd_rawmidi_drain_output
> - 26,59% msleep
> schedule_timeout
> schedule
> + __schedule
> + 2,13% schedule_timeout
>
> Seems to be because of:
> https://github.com/torvalds/linux/blob/master/sound/core/rawmidi.c#L244
> if (substream->ops->drain)
> substream->ops->drain(substream);
> else
> msleep(50);
>
> It see what fileops have no drain impl:
> https://github.com/torvalds/linux/blob/master/sound/core/rawmidi.c#L1708
> and I see
> https://github.com/torvalds/linux/blob/master/sound/core/seq/seq_virmidi.c#L329
> that define no drain op. Not which ones are actually used here :/
>
> The docs confirm teh 50 ms wait though:
> https://github.com/torvalds/linux/blob/master/Documentation/sound/kernel-api/writing-an-alsa-driver.rst#drain-callback
>
> would it make sense to have a dummy drain function for the seq_virmidi output
> ops?
Yes, a proper drain implementation is definitely better.
I guess just calling flush_work(&vmidi->output_work) there would
suffice.
thanks,
Takashi
>
> Stefan
>
> Am Di., 4. Jan. 2022 um 16:54 Uhr schrieb Takashi Iwai <tiwai@suse.de>:
>
> On Sat, 01 Jan 2022 12:49:13 +0100,
> Stefan Sauer wrote:
> >
> > hi,
> >
> > I've tried to link BitwigStudio to the webapp cables.gl over virmidi.
> > Unfortunately Bitwig Studio only supports rawmidi. What I discovered is
> > that there is a strange slowness when sending data to virmidi caused
> > by snd_rawmidi_drain().
> >
> > I've posted two tiny, self-contained c apps to:
> > https://gist.github.com/ensonic/c7588b87fa6c1fa94a8f753b1e0aa394
> > See some examples below. 2 observations:
> > * snd_rawmidi_type() is *not* reporting virmidi as VIRTUAL
> > * snd_rawmidi_drain() takes about 60ms! on virtual vs. less that 0.1 ms
> on
> > usb midi (I checked all my hw midi and the worst was avg=1ms on physical
> > midi image unitor8)
> >
> > When comparing the implementations:
> >
> https://github.com/alsa-project/alsa-lib/blob/master/src/rawmidi/rawmidi_virt.c#L173
> >
> https://github.com/alsa-project/alsa-lib/blob/master/src/rawmidi/rawmidi_hw.c#L164
> > I see that the hw one results in an IOCTL which I can see when striking
> the
> > code and I wonder if this is the root cause? Why is rawmidi_virt.c not
> used
> > for virmidi?
> > >From poking at snd_rawmidi_open_conf() I have not yet figured where
> this is
> > decided ....
> >
> > Stefan
> >
> > > amidi -l
> > Dir Device Name
> > IO hw:0,0,0 Scarlett 18i20 USB MIDI 1
> > IO hw:3,0,0 nanoKEY2 nanoKEY2 _ KEYBOARD
> > IO hw:5,0,0 nanoKONTROL nanoKONTROL _ SLIDE
> > IO hw:10,0 Virtual Raw MIDI (16 subdevices)
> > IO hw:11,0 Virtual Raw MIDI (16 subdevices)
> >
> > # using direct i/o to virmidi - all good
> > > ./rawmidi_oss /dev/midi11 0
> > Using device '/dev/midi11' without draining
> > write took min= 0.0015 ms, avg= 0.0016 ms, max= 0.0110 ms
> > > ./rawmidi_oss /dev/midi11 1
> > Using device '/dev/midi11' with draining
> > write took min= 0.0015 ms, avg= 0.0017 ms, max= 0.0101 ms
> > drain took min= 0.0001 ms, avg= 0.0001 ms, max= 0.0008 ms
> >
> > # using snd_rawmidi to virmidi - slow drain operations
> > > ./rawmidi_alsa hw:11,0 0
> > Using device 'hw:11,0' without draining
> > SND_RAWMIDI_TYPE_HW
> > write took min= 0.0010 ms, avg= 0.0011 ms, max= 0.0056 ms
> > > ./rawmidi_alsa hw:11,0 1
> > Using device 'hw:11,0' with draining
> > SND_RAWMIDI_TYPE_HW
> > write took min= 0.0016 ms, avg= 0.0040 ms, max= 0.0077 ms
> > drain took min= 55.9951 ms, avg= 60.4330 ms, max= 64.0653 ms
> >
> > # using snd_rawmidi to usb hw - all good
> > > ./rawmidi_alsa hw:3,0 0
> > Using device 'hw:3,0' without draining
> > SND_RAWMIDI_TYPE_HW
> > write took min= 0.0012 ms, avg= 0.0015 ms, max= 0.0121 ms
> > > ./rawmidi_alsa hw:3,0 1
> > Using device 'hw:3,0' with draining
> > SND_RAWMIDI_TYPE_HW
> > write took min= 0.0024 ms, avg= 0.0032 ms, max= 0.0110 ms
> > drain took min= 0.0293 ms, avg= 0.0636 ms, max= 0.2277 ms
>
> This kind of thing needs profiling. You can try perf or whatever
> available, and identify which call takes long. My wild guess is
> something about snd_seq_sync_output_queue(), maybe poll syscall takes
> unexpected long.
>
> thanks,
>
> Takashi
>
>
next prev parent reply other threads:[~2022-01-05 14:14 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-01 11:49 slow snd_rawmidi_drain() for VirMidi devcies Stefan Sauer
2022-01-04 15:54 ` Takashi Iwai
2022-01-05 13:39 ` Stefan Sauer
2022-01-05 14:13 ` Takashi Iwai [this message]
2022-01-05 19:53 ` Stefan Sauer
2022-01-05 20:20 ` Takashi Iwai
2022-01-05 20:47 ` [PATCH] ALSA: seq: virmidi: Add a drain operation Stefan Sauer
2022-01-07 20:37 ` Geraldo Nascimento
-- strict thread matches above, loose matches on Subject: below --
2022-01-02 10:18 slow snd_rawmidi_drain() for VirMidi devcies Stefan Sauer
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=s5hlezui82s.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=st.kost@gmail.com \
/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.