Thierry Merle a écrit : > Lennart Sorensen a écrit : >> On Tue, Sep 11, 2007 at 04:53:41AM -0700, Thierry Merle wrote: >> >>> I am using a Terratec Cinergy T2 USB tuner on my 266MHz NSLU2. >>> When I am recording a DVB-T stream, it takes around 33% CPU (zapdvb >>> process, >>> the tool I use to record) but surprisingly, my NSLU2 is much less >>> responsive >>> for other tasks (big latencies for ssh, fetchmail, imap and other >>> things >>> that run on my box). >>> Nevertheless, the recorded file contains the entire stream (video is >>> fluid). >>> Do you think this is a CPU related problem? >>> >> >> Isn't DVB-T mpeg? That would be a lot less work than a raw captured tv >> signal (the driver in question mentioned needing 170MBit per second on >> the USB port per tuner, which sounds like an awful lot more data than an >> mpeg stream would generate). That would need much more bandwidth from >> the cpu, and if the cpu now has to compress the video it would take >> quite a lot of cpu. Even the disk access to write 170MBit/s starts to >> add up, especially since the disk is almost certainly on another USB >> port. I am assuming your tuner has hardware encoding to mpeg or that it >> is receiving an existing mpeg stream from some other DVB device. >> >> So yes I could see it being simply a CPU issue. >> >> -- >> Len Sorensen >> >> >> > Right, DVB-T mpeg-2 TS for both cinergyT2 and em28xx based tuners. > To inform you the current state of the investigation: > - I wired a serial-to-usb cable to get the serial console (I used a > DKU-5 data cable containing a ark3116 chip, works perfectly for this > usage, and very cheap). > - by lowering the number of URB allocated in em28xx, I succeeded in > going further... to another bug :) > I have now the following error on console, so frequently that the NSLU2 > cannot respond to any sollicitation (need to hard-shutdown it) : > BUG: warning at arch/arm/mm/consistent.c:363/dma_free_coherent() > BUG: warning at arch/arm/mm/consistent.c:363/dma_free_coherent() > BUG: warning at arch/arm/mm/consistent.c:363/dma_free_coherent() > [...] > This warning is caused by: WARN_ON(irqs_disabled()); in > dma_free_coherent. > The function comment says: * Must not be called with IRQs disabled. > I suggested that a dma_free_coherent has been indirectly called in a > critical section... > So we need to analyze that with the em28xx maintainer that does his best > to help me with the poor information I can give to him. > > Thierry > > > Hello, I proposed a patch on the linux-arm ML (you will find at the end of this message) to correct the dma_free_coherent calls when IRQ are disabled. This allows the tuner to tune frequencies without kernel freezes, but the streaming is corrupted, I need to investigate on this now. This patches the kernel, the dmabounce part; this corrects a very rare bug I think, so nobody commented it yet. Do someone encountered a kernel freeze on the NSLU2 using a USB device?
Cheers, Thierry --- linux-source-2.6.22.orig/arch/arm/common/dmabounce.c 2007-10-12 21:51:54.000000000 +0200 +++ linux-source-2.6.22/arch/arm/common/dmabounce.c 2007-10-10 19:16:36.000000000 +0200 @@ -29,7 +29,7 @@ #include <linux/dma-mapping.h> #include <linux/dmapool.h> #include <linux/list.h> - +#include <linux/interrupt.h> #include <asm/cacheflush.h> #undef STATS @@ -51,6 +51,7 @@ struct safe_buffer { int direction; /* safe buffer info */ + struct device *dev; struct dmabounce_pool *pool; void *safe; dma_addr_t safe_dma_addr; @@ -125,6 +126,7 @@ alloc_safe_buffer(struct dmabounce_devic return NULL; } + buf->dev = device_info->dev; buf->ptr = ptr; buf->size = size; buf->direction = dir; @@ -180,6 +182,39 @@ find_safe_buffer(struct dmabounce_device return rb; } +/* The free safe buffer part. dma_free_coherent cannot be called irq disabled. + To cope with that, a tasklet (do_free) does the job upon request */ +static DEFINE_SPINLOCK(buflock); +static LIST_HEAD(buffers); + +static void do_free(unsigned long ignored) +{ + spin_lock_irq(&buflock); + while (!list_empty(&buffers)) { + struct safe_buffer *buf; + + buf = list_entry(buffers.next, + struct safe_buffer, + node); + list_del(&buf->node); + spin_unlock_irq(&buflock); + + if (buf->pool) + dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr); + else + dma_free_coherent(buf->dev, buf->size, buf->safe, + buf->safe_dma_addr); + + kfree(buf); + + spin_lock_irq(&buflock); + + } + spin_unlock_irq(&buflock); +} + +static DECLARE_TASKLET(deferred_free, do_free, 0); + static inline void free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf) { @@ -193,13 +228,12 @@ free_safe_buffer(struct dmabounce_device write_unlock_irqrestore(&device_info->lock, flags); - if (buf->pool) - dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr); - else - dma_free_coherent(device_info->dev, buf->size, buf->safe, - buf->safe_dma_addr); + /* pass the safe buffer to the tasklet */ + spin_lock_irqsave(&buflock, flags); + list_add_tail(&buf->node, &buffers); + tasklet_schedule(&deferred_free); + spin_unlock_irqrestore(&buflock, flags); - kfree(buf); } /* ************************************************** */ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]