From: Mauro Carvalho Chehab <m.chehab@samsung.com>
To: "Frank Schäfer" <fschaefer.oss@googlemail.com>
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>,
Linux Media Mailing List <linux-media@vger.kernel.org>,
Mauro Carvalho Chehab <mchehab@infradead.org>
Subject: Re: [PATCH v4 21/22] [media] em28xx-audio: allocate URBs at device driver init
Date: Sun, 05 Jan 2014 19:25:57 -0200 [thread overview]
Message-ID: <20140105192557.7feefa69@samsung.com> (raw)
In-Reply-To: <52C9C870.3050006@googlemail.com>
Em Sun, 05 Jan 2014 22:02:40 +0100
Frank Schäfer <fschaefer.oss@googlemail.com> escreveu:
> Am 04.01.2014 11:55, schrieb Mauro Carvalho Chehab:
> > From: Mauro Carvalho Chehab <mchehab@redhat.com>
> Is this line still correct ? ;)
>
> > Instead of allocating/deallocating URBs and transfer buffers
> > every time stream is started/stopped, just do it once.
> >
> > That reduces the memory allocation pressure and makes the
> > code that start/stop streaming a way simpler.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
> > Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
> Two Signed-off-by lines ? ;)
>
> > ---
> > drivers/media/usb/em28xx/em28xx-audio.c | 128 ++++++++++++++++++--------------
> > 1 file changed, 73 insertions(+), 55 deletions(-)
> >
> > diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
> > index e5120430ec80..30ee389a07f0 100644
> > --- a/drivers/media/usb/em28xx/em28xx-audio.c
> > +++ b/drivers/media/usb/em28xx/em28xx-audio.c
> > @@ -3,7 +3,7 @@
> > *
> > * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com>
> > *
> > - * Copyright (C) 2007-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
> > + * Copyright (C) 2007-2014 Mauro Carvalho Chehab
> > * - Port to work with the in-kernel driver
> > * - Cleanups, fixes, alsa-controls, etc.
> > *
> > @@ -70,16 +70,6 @@ static int em28xx_deinit_isoc_audio(struct em28xx *dev)
> > usb_kill_urb(urb);
> > else
> > usb_unlink_urb(urb);
> > -
> > - usb_free_coherent(dev->udev,
> > - urb->transfer_buffer_length,
> > - dev->adev.transfer_buffer[i],
> > - urb->transfer_dma);
> > -
> > - dev->adev.transfer_buffer[i] = NULL;
> > -
> > - usb_free_urb(urb);
> > - dev->adev.urb[i] = NULL;
> > }
> >
> > return 0;
> > @@ -174,53 +164,14 @@ static void em28xx_audio_isocirq(struct urb *urb)
> > static int em28xx_init_audio_isoc(struct em28xx *dev)
> > {
> > int i, errCode;
> > - const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
> > - EM28XX_AUDIO_MAX_PACKET_SIZE;
> >
> > dprintk("Starting isoc transfers\n");
> >
> > + /* Start streaming */
> > for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
> > - struct urb *urb;
> > - int j, k;
> > - void *buf;
> > -
> > - urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
> > - if (!urb) {
> > - em28xx_errdev("usb_alloc_urb failed!\n");
> > - for (j = 0; j < i; j++) {
> > - usb_free_urb(dev->adev.urb[j]);
> > - kfree(dev->adev.transfer_buffer[j]);
> > - }
> > - return -ENOMEM;
> > - }
> > -
> > - buf = usb_alloc_coherent(dev->udev, sb_size, GFP_ATOMIC,
> > - &urb->transfer_dma);
> > - if (!buf)
> > - return -ENOMEM;
> > - dev->adev.transfer_buffer[i] = buf;
> > - memset(buf, 0x80, sb_size);
> > -
> > - urb->dev = dev->udev;
> > - urb->context = dev;
> > - urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
> > - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
> > - urb->transfer_buffer = dev->adev.transfer_buffer[i];
> > - urb->interval = 1;
> > - urb->complete = em28xx_audio_isocirq;
> > - urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
> > - urb->transfer_buffer_length = sb_size;
> > -
> > - for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
> > - j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
> > - urb->iso_frame_desc[j].offset = k;
> > - urb->iso_frame_desc[j].length =
> > - EM28XX_AUDIO_MAX_PACKET_SIZE;
> > - }
> > - dev->adev.urb[i] = urb;
> > - }
> > + memset(dev->adev.transfer_buffer[i], 0x80,
> > + dev->adev.urb[i]->transfer_buffer_length);
> >
> > - for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
> > errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
> > if (errCode) {
> > em28xx_errdev("submit of audio urb failed\n");
> > @@ -643,13 +594,36 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = {
> > .page = snd_pcm_get_vmalloc_page,
> > };
> >
> > +static void em28xx_audio_free_urb(struct em28xx *dev)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
> > + struct urb *urb = dev->adev.urb[i];
> > +
> > + if (!dev->adev.urb[i])
> > + continue;
> > +
> > + usb_free_coherent(dev->udev,
> > + urb->transfer_buffer_length,
> > + dev->adev.transfer_buffer[i],
> > + urb->transfer_dma);
> > +
> > + usb_free_urb(urb);
> > + dev->adev.urb[i] = NULL;
> > + dev->adev.transfer_buffer[i] = NULL;
> > + }
> > +}
> > +
> > static int em28xx_audio_init(struct em28xx *dev)
> > {
> > struct em28xx_audio *adev = &dev->adev;
> > struct snd_pcm *pcm;
> > struct snd_card *card;
> > static int devnr;
> > - int err;
> > + int err, i;
> > + const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
> > + EM28XX_AUDIO_MAX_PACKET_SIZE;
> >
> > if (!dev->has_alsa_audio || dev->audio_ifnum < 0) {
> > /* This device does not support the extension (in this case
> > @@ -662,7 +636,8 @@ static int em28xx_audio_init(struct em28xx *dev)
> >
> > printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
> > "Rechberger\n");
> > - printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2007-2011 Mauro Carvalho Chehab\n");
> > + printk(KERN_INFO
> > + "em28xx-audio.c: Copyright (C) 2007-2014 Mauro Carvalho Chehab\n");
> >
> > err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
> > &card);
> > @@ -704,6 +679,47 @@ static int em28xx_audio_init(struct em28xx *dev)
> > em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER);
> > }
> >
> > + /* Alloc URB and transfer buffers */
> > + for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
> > + struct urb *urb;
> > + int j, k;
> > + void *buf;
> > +
> > + urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
> > + if (!urb) {
> > + em28xx_errdev("usb_alloc_urb failed!\n");
> > + em28xx_audio_free_urb(dev);
> > + return -ENOMEM;
> > + }
> > + dev->adev.urb[i] = urb;
> > +
> > + buf = usb_alloc_coherent(dev->udev, sb_size, GFP_ATOMIC,
> > + &urb->transfer_dma);
> > + if (!buf) {
> > + em28xx_errdev("usb_alloc_coherent failed!\n");
> > + em28xx_audio_free_urb(dev);
> > + return -ENOMEM;
> > + }
> > + dev->adev.transfer_buffer[i] = buf;
> > +
> > + urb->dev = dev->udev;
> > + urb->context = dev;
> > + urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
> > + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
> > + urb->transfer_buffer = dev->adev.transfer_buffer[i];
> > + urb->interval = 1;
> > + urb->complete = em28xx_audio_isocirq;
> > + urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
> > + urb->transfer_buffer_length = sb_size;
> > +
> > + for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
> > + j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
> > + urb->iso_frame_desc[j].offset = k;
> > + urb->iso_frame_desc[j].length =
> > + EM28XX_AUDIO_MAX_PACKET_SIZE;
> > + }
> > + }
> > +
> > err = snd_card_register(card);
> > if (err < 0) {
> > snd_card_free(card);
> > @@ -728,6 +744,8 @@ static int em28xx_audio_fini(struct em28xx *dev)
> > return 0;
> > }
> >
> > + em28xx_audio_free_urb(dev);
> > +
> > if (dev->adev.sndcard) {
> > snd_card_free(dev->adev.sndcard);
> > dev->adev.sndcard = NULL;
> I don't get it.
> How does this patch reduce the memory allocation pressure ?
> You are still allocating the same amount of memory.
True, but it is not de-allocating/reallocating the same amount of
memory every time, for every start/stop trigger. Depending on the
userspace and the amount of available RAM, this could cause memory
fragmentation.
If you take a look at xHCI logs, you'll see that those operations
are very expensive, and that it occurs too often.
> The only differences is that you already do this when the device isn't
> used yet and don't free it when gets unused again.
> IMHO that makes things worse, not better.
Why is it worse?
FYI, we're currently allocating DVB buffers at the device init too,
due to the memory fragmentation problems. This is actually critical
if you try to use it on an ARM with limited amount of RAM.
> And yes, it makes the code that starts/stops streaming a way simpler.
> But at the same time it makes the module initialization code the same
> amount more complicated.
--
Cheers,
Mauro
next prev parent reply other threads:[~2014-01-05 21:26 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-04 10:55 [PATCH v4 00/22] em28xx: split analog part into a separate module Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 01/22] [media] em28xx: move some video-specific functions to em28xx-video Mauro Carvalho Chehab
2014-01-05 10:11 ` Frank Schäfer
2014-01-05 13:28 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 02/22] [media] em28xx: some cosmetic changes Mauro Carvalho Chehab
2014-01-05 10:13 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 03/22] [media] em28xx: move analog-specific init to em28xx-video Mauro Carvalho Chehab
2014-01-05 10:26 ` Frank Schäfer
2014-01-05 14:40 ` Mauro Carvalho Chehab
2014-01-06 21:28 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 04/22] [media] em28xx: make em28xx-video to be a separate module Mauro Carvalho Chehab
2014-01-05 10:47 ` Frank Schäfer
2014-01-05 12:56 ` Mauro Carvalho Chehab
2014-01-05 15:18 ` Mauro Carvalho Chehab
2014-01-06 21:35 ` Frank Schäfer
2014-01-06 17:38 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 05/22] [media] em28xx: initialize analog I2C devices at the right place Mauro Carvalho Chehab
2014-01-05 10:48 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 06/22] [media] em28xx: add warn messages for timeout Mauro Carvalho Chehab
2014-01-05 10:51 ` Frank Schäfer
2014-01-05 13:05 ` Mauro Carvalho Chehab
2014-01-05 13:25 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 07/22] [media] em28xx: improve extension information messages Mauro Carvalho Chehab
2014-01-05 10:55 ` Frank Schäfer
2014-01-05 13:08 ` Mauro Carvalho Chehab
2014-01-05 15:31 ` Mauro Carvalho Chehab
2014-01-06 17:44 ` Frank Schäfer
2014-01-06 18:17 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 08/22] [media] em28xx: convert i2c wait completion logic to use jiffies Mauro Carvalho Chehab
2014-01-05 11:03 ` Frank Schäfer
2014-01-05 13:10 ` Mauro Carvalho Chehab
2014-01-06 17:48 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 09/22] [media] tvp5150: make read operations atomic Mauro Carvalho Chehab
2014-01-05 11:07 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 10/22] [media] tuner-xc2028: remove unused code Mauro Carvalho Chehab
2014-01-05 11:07 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 11/22] [media] em28xx: check if a device has audio earlier Mauro Carvalho Chehab
2014-01-05 11:12 ` Frank Schäfer
2014-01-05 13:22 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 12/22] [media] em28xx: properly implement AC97 wait code Mauro Carvalho Chehab
2014-01-05 11:19 ` Frank Schäfer
2014-01-05 13:20 ` Mauro Carvalho Chehab
2014-01-05 15:44 ` Mauro Carvalho Chehab
2014-01-07 16:50 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 13/22] [media] em28xx: initialize audio latter Mauro Carvalho Chehab
2014-01-05 11:29 ` Frank Schäfer
2014-01-05 13:17 ` Mauro Carvalho Chehab
2014-01-07 17:00 ` Frank Schäfer
2014-01-08 14:29 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 14/22] [media] em28xx: unify module version Mauro Carvalho Chehab
2014-01-05 11:33 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 15/22] [media] em28xx: Fix em28xx deplock Mauro Carvalho Chehab
2014-01-05 11:38 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 16/22] [media] em28xx: use a better value for I2C timeouts Mauro Carvalho Chehab
2014-01-05 20:38 ` Frank Schäfer
2014-01-05 20:57 ` Mauro Carvalho Chehab
2014-01-07 17:15 ` Frank Schäfer
2014-01-08 14:39 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 17/22] [media] em28xx-i2c: Fix error code for I2C error transfers Mauro Carvalho Chehab
2014-01-05 20:40 ` Frank Schäfer
2014-01-06 9:55 ` Mauro Carvalho Chehab
2014-01-07 17:28 ` Frank Schäfer
2014-01-08 11:55 ` Mauro Carvalho Chehab
2014-01-08 19:37 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 18/22] [media] em28xx: don't return -ENODEV for I2C xfer errors Mauro Carvalho Chehab
2014-01-05 20:49 ` Frank Schäfer
2014-01-06 10:37 ` Mauro Carvalho Chehab
2014-01-04 10:55 ` [PATCH v4 19/22] [media] em28xx: cleanup I2C debug messages Mauro Carvalho Chehab
2014-01-05 20:54 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 20/22] [media] em28xx: use usb_alloc_coherent() for audio Mauro Carvalho Chehab
2014-01-05 20:57 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 21/22] [media] em28xx-audio: allocate URBs at device driver init Mauro Carvalho Chehab
2014-01-05 21:02 ` Frank Schäfer
2014-01-05 21:25 ` Mauro Carvalho Chehab [this message]
2014-01-06 16:25 ` Mauro Carvalho Chehab
2014-01-07 17:03 ` Frank Schäfer
2014-01-08 14:10 ` Mauro Carvalho Chehab
2014-01-08 19:14 ` Frank Schäfer
2014-01-04 10:55 ` [PATCH v4 22/22] [media] em28xx: retry read operation if it fails Mauro Carvalho Chehab
2014-01-05 21:06 ` Frank Schäfer
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=20140105192557.7feefa69@samsung.com \
--to=m.chehab@samsung.com \
--cc=fschaefer.oss@googlemail.com \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@infradead.org \
--cc=mchehab@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).