Re: DVB core enhancements - comments please?

2012-07-03 Thread Marko Ristola


Moikka Antti.


On 07/01/2012 02:11 PM, Antti Palosaari wrote:

Moikka Marko,


-- snip --


Hmm, I did some initial suspend / resume changes for DVB USB when I rewrote it 
recently. On suspend, it just kills all ongoing urbs used for streaming. And on 
resume it resubmit those urbs in order to resume streaming. It just works as it 
doesn't hang computer anymore. What I tested applications continued to show 
same television channels on resume.

The problem for that solution is that it does not have any power management as 
power management is DVB-core responsibility. So it continues eating current 
because chips are not put sleep and due to that those DVB-core changes are 
required.


I think that runtime (RT) frontend power saving is a different thing.
It isn't necessarily suspend/resume thing.

I implemented runtime Frontend power saving in 2007 on that patch I referenced.
I used dvb-core's existing functionality. Maybe this concept is applicable for 
you too.

I added into Mantis bridge device initialization following functions:
+   mantis-fe-ops.tuner_ops.sleep = 
mantis_dvb_tuner_sleep;
+   mantis-fe-ops.tuner_ops.init = mantis_dvb_tuner_init;
tuner_ops.{sleep,init} modification had to be the last one.

I maintained in mantis-has_power the frontend's power status.
Maybe I could have read the active status from PCI context too.

The concept was something like:
- dvb-core has responsibility to call tuner_ops.sleep() and tuner_ops.init() 
when applicable.
- Mantis PCI Bridge driver (or specific USB driver) has responsibility
  to provide sleep and init implementations for the specific device.
- Mantis bridge device will do the whole task of frontend power management, by 
calling Frontend's
  tear down / initialization functions when necessary.




- What changes encrypted channels need?


I think none?


regards
Antti




Regards,
Marko
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: DVB core enhancements - comments please?

2012-06-30 Thread Marko Ristola


Hi Antti.

My suspend / resume patch implemented Kaffeine continues viewing channel after 
resume.
Some of the ideas could be still useful: 
http://www.spinics.net/lists/linux-dvb/msg19651.html

Rest of this email has a more thorough description.

Regards,
Marko Ristola

On 06/28/2012 03:33 AM, Antti Palosaari wrote:

Here is my list of needed DVB core related changes. Feel free to comment - what 
are not needed or what you would like to see instead. I will try to implement 
what I can (and what I like most interesting :).


...

suspend / resume support
--
* support is currently quite missing, all what is done is on interface drivers
* needs power management
* streaming makes it hard
* quite a lot work to get it working in case of straming is ongoing



I've implemented Suspend/Resume for Mantis cu1216 in 2007 (PCI DVB-C device):
Kaffeine continued viewing the channel after resume.
When Tuner was idle too long, it was powered off too.

According to Manu Abraham at that time, somewhat smaller patch would have 
sufficed.
That patch contais nonrelated fixes too, and won't compile now.

Here is the reference (with Manu's answer):
Start of the thread: http://www.spinics.net/lists/linux-dvb/msg19532.html
The patch: http://www.spinics.net/lists/linux-dvb/msg19651.html
Manu's answer: http://www.spinics.net/lists/linux-dvb/msg19668.html

Thoughts about up-to-date implementation
- Bridge (PCI) device must implement suspend/resume callbacks.
- Frontend might need some change (power off / power on callbacks)?
- save Tuner / DMA transfer state to memory might be addable to dvb_core.
- Bridge device supporting suspend/resume needs to have a (non-regression)
  fallback for (frontend) devices that don't have a full tested Kaffeine works
  suspend/resume implementation yet.
- What changes encrypted channels need?

Marko
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] drxk: change it to use request_firmware_nowait()

2012-06-22 Thread Marko Ristola


Hi Mauro

I think that your __i2c_transfer() solution is elegant for DVB-C frontend tuner 
reprogramming sleep cases:
TDA6650 programming manual, page 9 states:

Main divider data are valid only if no new I2C-bus transmission
is started (START condition) during the computation
period of 50 μs.
http://www.datasheetcatalog.org/datasheet/philips/TDA6650.pdf

It states that after TDA6650 frontend programming, the whole I2C bus
(for any I2C transfer into any I2C device) must be quiet at least 50μs.

My main point for __i2c_transfer() elegance can be seen easilly
from the code examples below.

-

An elegant way to solve only the 50μs TDA6650 sleep problem (not gate control 
issue),
is to solve it in tda665x.c's tda665x_set_state():

static int tda665x_set_state(struct dvb_frontend *fe,
 enum tuner_param param,
 struct tuner_state *tstate)
{
...
i2c_lock_adapter(state-i2c);
/* Set params without taking I2C lock ( uses __i2c_transfer() ) */
err = __tda665x_write(state, buf, 5);
usleep(50);
i2c_unlock_adapter(state-i2c);
...
}


Ugly robust way to solveonly the 50μs TDA6650 sleep problem (not gate control 
issue,
is to teach I2C transfer code TDA6650's requirements:
-- warning: ugly --
saa7146_i2c_transfer(..) {
  ...
  mutex_lock_interruptible(dev-i2c_lock);
  ...
  send_i2c_messages();
  if (num == 5  is_tda665())
usleep(50);
  mutex_unlock(dev-i2c_lock);
}


Here is a robust version with __i2c_transfer(). Main idea is to
protect the whole communicating with I2C Frontend device with I2C lock:
- Open I2C Gate so that you can talk to DVB Frontend Tuner.
- Send 5 bytes into DVB-C Frontend tuner.
- Quiesce I2C bus by sleeping 50μs to protect the Frontend Tuner  message.
- Close I2C Gate so that DVB Frontend Tuner isn't reachable by I2C bus.

static int tda665x_set_state(struct dvb_frontend *fe,
 enum tuner_param param,
 struct tuner_state *tstate)
{
...
i2c_lock_adapter(state-i2c);
__open_i2c_gate(state);
/* Set params without taking I2C lock ( uses __i2c_transfer() ) */
err = __tda665x_write(state, buf, 5);
usleep(50);
__close_i2c_gate(state);
i2c_unlock_adapter(state-i2c);
...
}


-- Ugly solution for the same full problem in SAA7146 I2C transfer function 
itself (code with some unsolved problems) --
saa7146_i2c_transfer(..) {
  ...
  mutex_lock_interruptible(dev-i2c_lock);
  if (is_tda665(addr))
send_msg_tda665_gate_open(dev);
  ...
  send_i2c_messages();
  if (num == 5  is_tda665())
usleep(50);
  if (is_tda665(addr))
send_msg_tda665_gate_close(dev);
  mutex_unlock(dev-i2c_lock);
}

Regards,
Marko Ristola

On 06/21/2012 10:10 PM, Mauro Carvalho Chehab wrote:

Em 21-06-2012 10:36, Mauro Carvalho Chehab escreveu:

The firmware blob may not be available when the driver probes.

Instead of blocking the whole kernel use request_firmware_nowait() and
continue without firmware.

This shouldn't be that bad on drx-k devices, as they all seem to have an
internal firmware. So, only the firmware update will take a little longer
to happen.


While thinking on converting another DVB frontend driver, I just realized
that a patch like that won't work fine.

As most of you know, there are _several_ I2C chips that don't tolerate any
usage of the I2C bus while a firmware is being loaded (I dunno if this is the
case of drx-k, but I won't doubt).

The current approach makes the device probe() logic is serialized. So, there's
no chance that two different I2C drivers to try to access the bus at the same
time, if the bridge driver is properly implemented.

However, now that firmware is loaded asynchronously, several other I2C drivers
may be trying to use the bus at the same time. So, events like IR (and CI) 
polling,
tuner get_status, etc can happen during a firmware transfer, causing the 
firmware
to not load properly.

A fix for that will require to lock the firmware load I2C traffic into a single
transaction.

So, the code that sends the firmware to the board need to be changed to 
something like:

static int DownloadMicrocode(struct drxk_state *state,
 const u8 pMCImage[], u32 Length)
{

...
i2c_lock_adapter(state-i2c);
...
for (i = 0; i  nBlocks; i += 1) {
...

status =  __i2c_transfer(state-i2c, ...);
...
}
i2c_unlock_adapter(state-i2c);
return status;
}

where __i2c_transfer() would be a variant of i2c_transfer() that won't take the
I2C lock.

Other drivers that load firmware at I2C and use request_firmware_nowait() will 
also
need a similar approach.

Jean,

What do you think?

Regards,
Mauro



Cc: Antti Palosaari cr...@iki.fi
Cc: Kay Sievers k...@redhat.com
Signed-off-by: Mauro Carvalho Chehab mche...@redhat.com
---
   drivers/media/dvb

Re: [PATCH 04/11] Show timeouts on I2C transfers.

2012-04-04 Thread Marko Ristola

I had a plan to rework I2C handling a lot more,
than log the changes.

I wrote a patch that uses I2C IRQ.
I had a feeling that it worked well (with old single CPU desktop computer):
framerate with HDTV was low, but it was glitchless.

Do you want to have the patch to be sent for you?
I think that I solved in the patch robust I2C command + exact IRQ response for 
that command,
so that those two will not get out of sync.

I tried to rework the patch to make a bit smaller patch,
but I couldn't test the new one: hardware is too broken.

Regards,
Marko

01.04.2012 18:53, Steinar H. Gunderson kirjoitti:
 From: Steinar H. Gunderson se...@samfundet.no
 
 On I2C reads and writes, show if we had any timeouts in the debug output.
 
 Signed-off-by: Steinar H. Gunderson se...@samfundet.no
 ---
  drivers/media/dvb/mantis/mantis_i2c.c |   26 --
  1 file changed, 24 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/media/dvb/mantis/mantis_i2c.c 
 b/drivers/media/dvb/mantis/mantis_i2c.c
 index e779451..ddd1922 100644
 --- a/drivers/media/dvb/mantis/mantis_i2c.c
 +++ b/drivers/media/dvb/mantis/mantis_i2c.c
 @@ -38,6 +38,7 @@
  static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg 
 *msg)
  {
   u32 rxd, i, stat, trials;
 + u32 timeouts = 0;
  
   dprintk(MANTIS_INFO, 0, %s:  Address=[0x%02x] R[ ,
   __func__, msg-addr);
 @@ -60,6 +61,9 @@ static int mantis_i2c_read(struct mantis_pci *mantis, const 
 struct i2c_msg *msg)
   if (stat  MANTIS_INT_I2CDONE)
   break;
   }
 + if (trials == TRIALS) {
 + ++timeouts;
 + }
  
   dprintk(MANTIS_TMG, 0, I2CDONE: trials=%d\n, trials);
  
 @@ -69,6 +73,9 @@ static int mantis_i2c_read(struct mantis_pci *mantis, const 
 struct i2c_msg *msg)
   if (stat  MANTIS_INT_I2CRACK)
   break;
   }
 + if (trials == TRIALS) {
 + ++timeouts;
 + }
  
   dprintk(MANTIS_TMG, 0, I2CRACK: trials=%d\n, trials);
  
 @@ -76,7 +83,11 @@ static int mantis_i2c_read(struct mantis_pci *mantis, 
 const struct i2c_msg *msg)
   msg-buf[i] = (u8)((rxd  8)  0xFF);
   dprintk(MANTIS_INFO, 0, %02x , msg-buf[i]);
   }
 - dprintk(MANTIS_INFO, 0, ]\n);
 + if (timeouts) {
 + dprintk(MANTIS_INFO, 0, ] %d timeouts\n, timeouts);
 + } else {
 + dprintk(MANTIS_INFO, 0, ]\n);
 + }
  
   return 0;
  }
 @@ -85,6 +96,7 @@ static int mantis_i2c_write(struct mantis_pci *mantis, 
 const struct i2c_msg *msg
  {
   int i;
   u32 txd = 0, stat, trials;
 + u32 timeouts = 0;
  
   dprintk(MANTIS_INFO, 0, %s: Address=[0x%02x] W[ ,
   __func__, msg-addr);
 @@ -108,6 +120,9 @@ static int mantis_i2c_write(struct mantis_pci *mantis, 
 const struct i2c_msg *msg
   if (stat  MANTIS_INT_I2CDONE)
   break;
   }
 + if (trials == TRIALS) {
 + ++timeouts;
 + }
  
   dprintk(MANTIS_TMG, 0, I2CDONE: trials=%d\n, trials);
  
 @@ -117,10 +132,17 @@ static int mantis_i2c_write(struct mantis_pci *mantis, 
 const struct i2c_msg *msg
   if (stat  MANTIS_INT_I2CRACK)
   break;
   }
 + if (trials == TRIALS) {
 + ++timeouts;
 + }
  
   dprintk(MANTIS_TMG, 0, I2CRACK: trials=%d\n, trials);
   }
 - dprintk(MANTIS_INFO, 0, ]\n);
 + if (timeouts) {
 + dprintk(MANTIS_INFO, 0, ] %d timeouts\n, timeouts);
 + } else {
 + dprintk(MANTIS_INFO, 0, ]\n);
 + }
  
   return 0;
  }

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Various nits, fixes and hacks for mantis CA support on SMP

2012-03-23 Thread Marko Ristola
03.03.2012 01:21, Steinar H. Gunderson kirjoitti:
 On Sat, Mar 03, 2012 at 12:42:19AM +0200, Marko Ristola wrote:
 I'm not happy with I2CDONE busy looping either.
 I've tried twice lately to swith into I2C IRQ, but those patches have caused 
 I2CDONE timeouts.
 
 Note that there are already timeouts with the current polling code, but they
 are ignored (my patch makes them at least be printed with verbose=5). I can't
 immediately recall if it's on RACK, DONE or both.

I think that occasional timeouts belong to the picture (RACK missing means: 
packet lost).
If I2CDONE comes immediately when I2C command has been emitted,
it is a driver software bug (some earlier I2C command).

 
 Do my following I2C logic thoughts make any sense?
 
 Well, note first of all that I know next to nothing about I2C, and I've never
 seen any hardware documentation on the Mantis card (is there any?). But
 generally it makes sense to me, except that I've never heard of the demand of
 radio silence for 10 ms before.
Ok. Radio silence for 10 ms isn't your problem: when you have a FE_LOCK,
10 ms requirement is no more relevant.

 
 There might be race conditions, that the driver possibly manages:
 1. If two threads talk into DVB frontend, one could turn off the I2C gate, 
 while the other is talking to DVB frontend.
This would case lack of I2CRACK: only way to recover would be to turn
the I2C gate on, and then redo the I2C transfer.
 
 Note that I've tried putting mutexes around the I2C functions, and it didn't
 help on the I2C timeouts; however, that was largely on a single-character
 level, so it might not be enough. (You can see these mutexes being commented
 out in my patch.)

I have now a new idea for what to try with I2C interrupts.
It all depends, whether I understand the driver coding well enough.

 
 /* Steinar */

I have also a low interest for Mantis coding:
Ideas come fast, and if the new code doesn't work right away,
I back up the code somewhere and drop it.

Some years ago during Summer Holiday time I could get something done
and even patches got applied into Linux kernel.

Marko Ristola
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Various nits, fixes and hacks for mantis CA support on SMP

2012-03-02 Thread Marko Ristola


Hi

Nice work. I looked your code very shortly.

I'm not happy with I2CDONE busy looping either.
I've tried twice lately to swith into I2C IRQ, but those patches have caused 
I2CDONE timeouts.

Do my following I2C logic thoughts make any sense?

I2C bus might have some underlying requirements:
1. When driver wants to talk to a DVB frontend, it first opens up an I2C gate, 
then talks, and finally closes the I2C gate. This is ok.
2. After setting up DVB frontend frequency etc. I2C bus should be quiet 10ms 
(radio silence, to fasten taking DVB TS lock). This is ok.

There might be race conditions, that the driver possibly manages:
1. If two threads talk into DVB frontend, one could turn off the I2C gate, 
while the other is talking to DVB frontend.
   This would case lack of I2CRACK: only way to recover would be to turn the 
I2C gate on, and then redo the I2C transfer.
2. Thread 1 turns I2C gate into DVB frontend and sets up frequency. It waits 
10ms. Thread 2 will talk to some I2C device, thus breaking the silence. This 
case would not be so bad, because it would just delay taking the wanted DVB TS 
lock.

Regards,
Marko Ristola

28.02.2012 03:03, Steinar H. Gunderson kirjoitti:
 Hi,
 
 This patch, against 3.3-rc4, is basically a conglomerate of patches that
 together seem to make CA support on mantis working and stable, even on SMP
 systems. (I'm using a Terratec Cinergy DVB-S2 card with a Conax CAM, with
 mumudvb as userspace.) There are a few fixes from this mailing list and some
 of my own; the end result is too ugly to include, and there are still things
 I don't understand at all, but I hope it can be useful for some.
 
 Below is the list of what the patch does:
 
  - I've followed the instructions from some post on this mailing list
to enable CAM support in the first place (mantis_set_direction move
to mantis_pci.c, uncomment mantis_ca_init).
 
  - The MANTIS_GPIF_STATUS fix from http://patchwork.linuxtv.org/patch/8776/.
Not that it seems to change a lot for me, but it makes sense.
 
  - I've fixed a ton of SMP-related bugs. Basically a lot of the members of
mantis_ca were accessed from several threads without a mutex, which is a
big no-no; I've mostly changed to using atomic operations here, although
I also added some locks were it made sense (e.g. when resetting the CAM).
The ca_lock is replaced by a more general int_stat_lock, which ideally
is held when banging on MANTIS_INT_STAT. (I have no hardware
documentation, so I'm afraid I don't really know the specifics here.)
 
  - mantis_hif_write_wait() would never clear MANTIS_SBUF_OPDONE_BIT,
leading to a lot of operations never actually waiting for the callback.
I've added many such fixes, as well as debugging output when the
bit is in a surprising state (e.g., MANTIS_SBUF_OPDONE_BIT set before the
beginning of an operation, where it really should be cleared).
 
  - Some operations check for timeout by testing if wait_event_timeout()
return -ERESTARTSYS. However, wait_event_timeout() can can never
do this; the return value for timeout is zero. I've fixed this
(well, I seemingly forgot one; have to do that in the next version :-) ).
Unfortunately, this make the problems in the next point a _lot_ worse,
since timeouts are now actually percolated up the stack.
 
  - As others have noticed, sometimes, especially during DMA transfers,
the IRQ0 flag is never properly set and thus reads never return.
(The typical case for this is when we've just done a write and the
en50221 thread is waiting for the CAM status word to signal STATUSREG_DA;
if this doesn't happen in a reasonable amount of time, the upstream
libdvben50221.so will report errors back to mumudvb.) I have no idea why
this happens more often on SMP systems than on UMP systems, but they
really seem to do. I haven't found any reasonable workaround for reliable
polling either, so I'm making a hack -- if there's nothing returned in two
milliseconds, the read is simply assumed to have completed. This is an
unfortunate hack, but in practice it's identical to the previous behavior
except with a shorter timeout.
 
  - A hack to fix a mutex issue in the DVB layer; dvb_usercopy(), which is
called on all ioctls, not only copies data to and from userspace,
but also takes a lock on the file descriptor, which means that only one 
 ioctl 
can run at a time. This means that if one thread of mumudvb is busy trying
to get, say, the SNR from the frontend (which can hang due to the issue
above), the CAM thread's ioctl(fd, CA_GET_SLOT_INFO, ...) will hang,
even though it doesn't need to communicate with the hardware at all.
This obviously requires a better fix, but I don't know the generic DVB
layer well enough to say what it is. Maybe it's some sort of remnant
of from when all ioctl()s took the BKL. Note that on UMP kernels without
preemption, mutex_lock

[PATCH] Mantis and Hopper: Fix CAM hangup caused by losing GPIF status

2011-12-14 Thread Marko Ristola


Mantis and Hopper drivers: Fix CAM hangup problem,
where interrupt handler clears GPIF status, even though
GPIF interrupt isn't active.

Manuel  reported that this patch fixes his problem:
http://www.spinics.net/lists/linux-media/msg41473.html
(CAM hangs up about once per 20 minutes, each hangup takes about 3-5s.)

Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi

diff --git a/drivers/media/dvb/mantis/hopper_cards.c 
b/drivers/media/dvb/mantis/hopper_cards.c
index 71622f6..c2084e9 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -84,15 +84,6 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
if (!(stat  mask))
return IRQ_NONE;
 
-	rst_mask  = MANTIS_GPIF_WRACK  |

-   MANTIS_GPIF_OTHERR |
-   MANTIS_SBUF_WSTO   |
-   MANTIS_GPIF_EXTIRQ;
-
-   rst_stat  = mmread(MANTIS_GPIF_STATUS);
-   rst_stat = rst_mask;
-   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
mantis-mantis_int_stat = stat;
mantis-mantis_int_mask = mask;
dprintk(MANTIS_DEBUG, 0, \n-- Stat=%02x Mask=%02x --, stat, mask);
@@ -101,6 +92,16 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_IRQ0) {
dprintk(MANTIS_DEBUG, 0, %s, label[1]);
+
+   rst_mask  = MANTIS_GPIF_WRACK  |
+   MANTIS_GPIF_OTHERR |
+   MANTIS_SBUF_WSTO   |
+   MANTIS_GPIF_EXTIRQ;
+
+   rst_stat  = mmread(MANTIS_GPIF_STATUS);
+   rst_stat = rst_mask;
+   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
mantis-gpif_status = rst_stat;
wake_up(ca-hif_write_wq);
schedule_work(ca-hif_evm_work);
diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c
index c2bb90b..109a5fb 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -92,15 +92,6 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
if (!(stat  mask))
return IRQ_NONE;
 
-	rst_mask  = MANTIS_GPIF_WRACK  |

-   MANTIS_GPIF_OTHERR |
-   MANTIS_SBUF_WSTO   |
-   MANTIS_GPIF_EXTIRQ;
-
-   rst_stat  = mmread(MANTIS_GPIF_STATUS);
-   rst_stat = rst_mask;
-   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
mantis-mantis_int_stat = stat;
mantis-mantis_int_mask = mask;
dprintk(MANTIS_DEBUG, 0, \n-- Stat=%02x Mask=%02x --, stat, mask);
@@ -109,6 +100,15 @@ static irqreturn_t mantis_irq_handler(int irq, void 
*dev_id)
}
if (stat  MANTIS_INT_IRQ0) {
dprintk(MANTIS_DEBUG, 0, %s, label[1]);
+   rst_mask  = MANTIS_GPIF_WRACK  |
+   MANTIS_GPIF_OTHERR |
+   MANTIS_SBUF_WSTO   |
+   MANTIS_GPIF_EXTIRQ;
+
+   rst_stat  = mmread(MANTIS_GPIF_STATUS);
+   rst_stat = rst_mask;
+   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
mantis-gpif_status = rst_stat;
wake_up(ca-hif_write_wq);
schedule_work(ca-hif_evm_work);
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Multiple Mantis devices gives me glitches

2011-12-13 Thread Marko Ristola

13.12.2011 20:11, Vidar Tyldum kirjoitti:

13.12.2011 08:31, Marko Ristola:


Hi

Here is a patch that went into Linus GIT this year.
It reduces the number of DMA transfer interrupts into one third.
Linus released 2.6.38.8 doesn't seem to have this patch yet


Good news, combining this patch with IRQ management fixes the problem for me.

Status:
  * Stock 2.6.38.8 mantis, no IRQ management: glitches
  * Stock 2.6.38.8 mantis, with IRQ management:   glitches
  * Patched 2.6.38.8 mantis, no IRQ management:   glitches (less)
  * Patched 2.6.38.8 mantis, with IRQ management: very few glitches
  * Same as above, but latency_timer set to 0xff: no glitches in one hour

The patch was applied to 2.6.38.8 (in Ubuntu terms: 2.6.38-13-generic-pae).
Tests involved having VDR record on three different transponders at the same
time, which means lots of IO and all three cards active at once.

For IRQ management I tried both 'irqbalancer' and manual setting with IRQ
affinity (which is basicly what irqbalancer does).

I tried playing with the latency timer on the other scenarios, not only the
last one, but all had glitches anyways.

Not sure what to conclude with:
  - Unfortunate IRQ handling on this CPU (two and two share IRQ handling)?
  - Too many interrupts generated by driver (design issues)?
  - Driver not handling SMP gracefully?
...or a combination?

Your patch is definately needed. Is there anything I can do to help getting
it in?


Here is a reference for Linu's master GIT tree for
the patch that went in:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=79d06d4dff733ee472e1f8933a33317a18195c0c
It will be in Linux 3.2 kernel release.
Ubuntu will take it in some day when they grab a kernel with number at least 
3.2.

If you describe your problem into Ubuntu bug report system with
There is a fix already accepted upstream. Here is a reference for the patch.,
there is a chance that you get it backported too.

I tested the patch originally very thoroughly. It improves things, but doesn't 
break any.
VDR wants data from the DVB card in large chunks to avoid unnecessary CPU 
context switching.
DVB 16KB patch is designed so, that DVB card has always some data to be 
delivered for VDR,
but at the same time it avoids doing unnecessary many interrupts.

Here is another patch that I wrote for my DVB HDTV network delivery glitches 
problem.
It might help you a bit also:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=38e009aac9e02d2c30fd9a5e979ab31433e7d578
It tries to copy DMA buffer data as fast as possible into DVB-CORE's internal 
128K buffer.
Thus it prevents from Mantis DMA 64K buffer from being overrun.
It helps lots if the original dvb_dmx_swfilter(_204) is very slow, which
I saw with perf top tool.
Later I detected that it helps with some computers a lot, and with some other 
computers the patch doesn't help so much.

That patch doesn't guarantee glitch free data delivery either.
Next question is, which buffer overruns now? Mantis 64K DMA buffer? DVB-CORE's 
128K buffer?
VDR reads from DVB-CORE's 128K buffer.

dvb_dmx_swfilter(_204) in media/dvb-core/dvb_demux.c is designed to drop data 
if DVB-CORE's 128K buffer
becomes full.

Maybe we could add into mantis_dma.c some logic:
Mantis DMA transfer delivers data into DVB-CORE's 128K buffer in 16K chunks, 
avoiding the 128K buffer overrun.
If DVB-CORE's buffer would overrun, Mantis DMA transfer sends data, if also 
Mantis 64K DMA buffer is
becoming full.

I suspect I2C latency problem to be a root cause for these glitches,
but there isn't a patch to test it yet. I2C latency should not be a problem
with quad core CPU: it should affect most with a single CPU computer.
perf top shows easilly some CPU hogs.

Regards,
Marko Ristola






--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Mantis CAM not SMP safe / Activating CAM on Technisat Skystar HD2 (DVB-S2)

2011-12-12 Thread Marko Ristola

On 12/10/2011 01:57 AM, Ninja wrote:

Hi,

has anyone an idea how the SMP problems could be fixed?


You could turn on Mantis Kernel module's debug messages.
It could tell you the emitted interrupts.

One risky thing with the Interrupt handler code is that
MANTIS_GPIF_STATUS is cleared, even though IRQ0 isn't active yet.
This could lead to a rare starvation of the wait queue you described.
I supplied a patch below. Does it help?


I did some further investigation. When comparing the number of interrupts with 
all cores enabled and the interrupts with only one core enabled it seems like 
only the IRQ0 changed, the other IRQs and the total number stays quite the same:

4 Cores:
All IRQ/sec: 493
Masked IRQ/sec: 400
Unknown IRQ/sec: 0
DMA/sec: 400
IRQ-0/sec: 143
IRQ-1/sec: 0
OCERR/sec: 0
PABRT/sec: 0
RIPRR/sec: 0
PPERR/sec: 0
FTRGT/sec: 0
RISCI/sec: 258
RACK/sec: 0

1 Core:
All IRQ/sec: 518
Masked IRQ/sec: 504
Unknown IRQ/sec: 0
DMA/sec: 504
IRQ-0/sec: 246
IRQ-1/sec: 0
OCERR/sec: 0
PABRT/sec: 0
RIPRR/sec: 0
PPERR/sec: 0
FTRGT/sec: 0
RISCI/sec: 258
RACK/sec: 0

So, where might be the problem?

Turning on Mantis debug messages, might tell the difference between these 
interrupts.



I hope somebody can help, because I think we are very close to a fully 
functional CAM here.
I ran out of things to test to get closer to the solution :(
Btw: Is there any documentation available for the mantis PCI bridge?

Not that I know.



Manuel








--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html




Regards,
Marko Ristola

--- PATCH --
Mantis/Hopper: Check and clear GPIF status bits only when IRQ0 bit is active.

Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi

diff --git a/drivers/media/dvb/mantis/hopper_cards.c 
b/drivers/media/dvb/mantis/hopper_cards.c
index 71622f6..c2084e9 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -84,15 +84,6 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
if (!(stat  mask))
return IRQ_NONE;
 
-	rst_mask  = MANTIS_GPIF_WRACK  |

-   MANTIS_GPIF_OTHERR |
-   MANTIS_SBUF_WSTO   |
-   MANTIS_GPIF_EXTIRQ;
-
-   rst_stat  = mmread(MANTIS_GPIF_STATUS);
-   rst_stat = rst_mask;
-   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
mantis-mantis_int_stat = stat;
mantis-mantis_int_mask = mask;
dprintk(MANTIS_DEBUG, 0, \n-- Stat=%02x Mask=%02x --, stat, mask);
@@ -101,6 +92,16 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_IRQ0) {
dprintk(MANTIS_DEBUG, 0, %s, label[1]);
+
+   rst_mask  = MANTIS_GPIF_WRACK  |
+   MANTIS_GPIF_OTHERR |
+   MANTIS_SBUF_WSTO   |
+   MANTIS_GPIF_EXTIRQ;
+
+   rst_stat  = mmread(MANTIS_GPIF_STATUS);
+   rst_stat = rst_mask;
+   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
mantis-gpif_status = rst_stat;
wake_up(ca-hif_write_wq);
schedule_work(ca-hif_evm_work);
diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c
index c2bb90b..109a5fb 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -92,15 +92,6 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
if (!(stat  mask))
return IRQ_NONE;
 
-	rst_mask  = MANTIS_GPIF_WRACK  |

-   MANTIS_GPIF_OTHERR |
-   MANTIS_SBUF_WSTO   |
-   MANTIS_GPIF_EXTIRQ;
-
-   rst_stat  = mmread(MANTIS_GPIF_STATUS);
-   rst_stat = rst_mask;
-   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
mantis-mantis_int_stat = stat;
mantis-mantis_int_mask = mask;
dprintk(MANTIS_DEBUG, 0, \n-- Stat=%02x Mask=%02x --, stat, mask);
@@ -109,6 +100,15 @@ static irqreturn_t mantis_irq_handler(int irq, void 
*dev_id)
}
if (stat  MANTIS_INT_IRQ0) {
dprintk(MANTIS_DEBUG, 0, %s, label[1]);
+   rst_mask  = MANTIS_GPIF_WRACK  |
+   MANTIS_GPIF_OTHERR |
+   MANTIS_SBUF_WSTO   |
+   MANTIS_GPIF_EXTIRQ;
+
+   rst_stat  = mmread(MANTIS_GPIF_STATUS);
+   rst_stat = rst_mask;
+   mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
mantis-gpif_status = rst_stat;
wake_up(ca-hif_write_wq);
schedule_work(ca-hif_evm_work);
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo

Re: Multiple Mantis devices gives me glitches

2011-12-12 Thread Marko Ristola


Hi

Here is a patch that went into Linus GIT this year.
It reduces the number of DMA transfer interrupts into one third.
Linus released 2.6.38.8 doesn't seem to have this patch yet.

I had a single Mantis card and a single CPU.
I used VDR to deliver HDTV channel via network
into a faster computer for viewing.

One known latency point with Mantis is I2C transfer.
With my measure, latency is about 0.33ms per I2C transfer byte.
Basic read / write (address+value) minimal latency is thus 0.66ms.
Latency amount depends on I2C bus speed on the card.
I don't have a working patch to fix this yet though.

Regards, Marko Ristola

---

Refactor Mantis DMA transfer to deliver 16Kb TS data per interrupt


https://patchwork.kernel.org/patch/107036/

With VDR streaming HDTV into network, generating an interrupt once per 16kb,
implemented in this patch, seems to support more robust throughput with HDTV.

Fix leaking almost 64kb data from the previous TS after changing the TS.
One effect of the old version was, that the DMA transfer and driver's
DMA buffer access might happen at the same time - a race condition.

Signed-off-by: Marko M. Ristola marko.rist...@kolumbus.fi

Regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/hopper_cards.c 
b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc7..3b7e376 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-   mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+   mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
tasklet_schedule(mantis-tasklet);
}
if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39f..8f048d5 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-   mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+   mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
tasklet_schedule(mantis-tasklet);
}
if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h 
b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a..23b23b7 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -122,11 +122,8 @@ struct mantis_pci {
unsigned intnum;
 
 	/*	RISC Core		*/

-   u32 finished_block;
+   u32 busy_block;
u32 last_block;
-   u32 line_bytes;
-   u32 line_count;
-   u32 risc_pos;
u8  *buf_cpu;
dma_addr_t  buf_dma;
u32 *risc_cpu;
diff --git a/drivers/media/dvb/mantis/mantis_dma.c 
b/drivers/media/dvb/mantis/mantis_dma.c
index 46202a4..c61ca7d 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -43,13 +43,17 @@
 #define RISC_IRQ   (0x01  24)
 
 #define RISC_STATUS(status)	~status)  0x0f)  20) | ((status  0x0f)  16))

-#define RISC_FLUSH()   (mantis-risc_pos = 0)
-#define RISC_INSTR(opcode) (mantis-risc_cpu[mantis-risc_pos++] = 
cpu_to_le32(opcode))
+#define RISC_FLUSH(risc_pos)   (risc_pos = 0)
+#define RISC_INSTR(risc_pos, opcode)   (mantis-risc_cpu[risc_pos++] = 
cpu_to_le32(opcode))
 
 #define MANTIS_BUF_SIZE		(64 * 1024)

-#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE  4)
-#define MANTIS_BLOCK_COUNT (1  4)
-#define MANTIS_RISC_SIZE   PAGE_SIZE
+#define MANTIS_BLOCK_BYTES  (MANTIS_BUF_SIZE / 4)
+#define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */
+#define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
+
+#define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
+/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k 
RISC cmd buffer) */
+#define MANTIS_RISC_SIZE   PAGE_SIZE /* RISC program must fit here. */
 
 int mantis_dma_exit(struct mantis_pci *mantis)

 {
@@ -124,27 +128,6 @@ err:
return -ENOMEM;
 }
 
-static inline int mantis_calc_lines(struct mantis_pci *mantis)

-{
-   mantis-line_bytes = MANTIS_BLOCK_BYTES;
-   mantis-line_count = MANTIS_BLOCK_COUNT;
-
-   while (mantis-line_bytes  4095) {
-   mantis-line_bytes = 1;
-   mantis-line_count = 1;
-   }
-
-   dprintk(MANTIS_DEBUG, 1, Mantis

Re: USB mini-summit at LinuxCon Vancouver

2011-08-09 Thread Marko Ristola

Hi

I've been thinking about the Kernel driver side.
Mauro and others emailed requirements on Jun or July.

I'm sorry for this spam: maybe you have thought this already.

A linked list of read/write locks as the solution for these protections could be
a base for the general solution. Locks could be accessed either by name string 
name
or by an integer identifier.

The bridge driver would be the container of the lock list.
Lock take / release handles would be changeable by Bridge driver at driver init.
This way bridge could tune the lock taking actions. Sub devices would not have
to know the details of the bridge device.

When implemented as a library .ko module, this could be
used by all related kernel drivers. The locking code would be very general.
Maybe adding a lock list into each PCI bus device would solve the device export 
problem to KVM too.

If some module wouldn't handle the proper locking yet,
it would not deliver the protection, but it would work as before: no 
regressions.

The library could also be called so that a driver would ask three locks at the 
same time.
If the driver would get all three locks, it would return success.
If the driver would not get all three locks, it would not lock any of them 
(with _trylock case).

I don't have time to implement this feature.

Happy meeting for all of you,
Marko Ristola
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFCv2 PATCH 0/5] tuner-core: fix s_std and s_tuner

2011-07-07 Thread Marko Ristola

Hi.

IMO, your thoughts about core resource locking mechanism sound good.
I say here some thoughts and examples how the resource locking mechanism might 
work.

IMHO, It's good enough now if we are heading to a solution.
At least I would not alone find a proper concept.

07.07.2011 18:14, Mauro Carvalho Chehab kirjoitti:
 Em 06-07-2011 16:59, Marko Ristola escreveu:
 06.07.2011 21:17, Devin Heitmueller kirjoitti:
 On Wed, Jul 6, 2011 at 1:53 PM, Marko Ristola marko.rist...@kolumbus.fi 
 wrote:

 
 IMO, the proper solution is to provide a core resource locking mechanism, 
 that will keep
 track about what device resources are in usage (tuner, analog audio/video 
 demods, digital
 demods, sec, radio reception, i2c buses, etc), and some mechanisms like the 
 above that will
 power the subdevice off when it is not being used for a given amount of time 
 (a Kconfig option
 can be added so set the time to X minutes or to disable such mechanism, in 
 order to preserve
 back compatibility).
 

 One special case for the locking mechanisms that may or may not be covered by 
 such core
 resource locking is the access to the I2C buses. Currently, the DVB, V4L and 
 remote controller
 stacks may try to use resources behind I2C at the same time. The I2C core has 
 a locking schema,
 but it works only if a transaction is atomically commanded. So, if it 
 requires multiple I2C 
 transfers, all of them need to be grouped into one i2c xfer call. Complex 
 operations like firmware
 transfers are protected by the I2C locking, so one driver might be generating 
 RC polling events
 while a firmware is being transferring, causing it to fail.

A generic locking schema could have shared/exclusive locks by name (device 
name, pointer ?).
A generic resource set of named locks could contain these locks.

Firmware load would take an exclusive lock on I2C master for the whole 
transfer.
RC polling would take a shared lock on I2C master and an exclusive lock on 
RC UART device.
Or if there is no need to share I2C device, RC polling would just take 
exclusive lock on I2C Master.

If I2C bus must be quiesced for 10ms after frontend's tuning action, I2C 
master exclusive lock
could be held 10ms after last I2C transfer. i2c/bridge1 state should be 
protected if the frontend
is behind an I2C bridge.

The existing I2C xfer mutex would be as it is now: it is a lower level lock, no 
regressions to come.

Taking a shared lock of tuner_power_switch would mark that the device must 
not be turned off.
While holding the shared lock, no deferred watch would be needed.
While releasing tuner_power_switch lock, usage timestamp on that name should 
be updated.
If there are no more tuner_power_switch holders, delayed task could be 
activated and
run after 3 minutes to power the device off if needed.

Bridge drivers that don't have full runtime power saving support, would
not introduce a callback which a delayed task would run to turn power off / 
on.

 
 Regards,
 Mauro

IMO, suspend / resume code must be a separate thing.

We might want to suspend the laptop while watching a DVB channel.
We don't want to have runtime power management active while watching a DVB 
channel.

Suspend quiesces the device possibly in one phase. It needs to have the device
in a good state before suspending: take an exclusive I2C Master
lock before going to suspend. While resuming, release I2C Master lock.

So even though these details are incomplete, suspend/resume could perhaps
be integrated with the generic advanced locking scheme.

Regards,
Marko
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFCv2 PATCH 0/5] tuner-core: fix s_std and s_tuner

2011-07-06 Thread Marko Ristola

Hi.

I think that you could reuse lots of code with smart suspend / resume.

What do you think about this DVB power saving case (about the concept, don't 
look at details, please):

- One device has responsibility to do the power off when it can be done 
(mantis_core.ko)
- In my case there is only one frontend tda10021.ko to take care of.

- dvb_frontend.c would call fe-sleep(fe). The callback goes into 
mantis_core.ko.
- mantis_core.ko will traverse all devices on it's responsibility, all 
(tda10021.ko) are idle.
= suspend tda10021.ko by calling tda10021-sleep() and do additional power off 
things.

- When dvb_frontend.c wants tuner to be woken up,
  mantis_core.ko does hardware resets and power on first and then resumes 
tda10021-init(fe).

I implemented something that worked a few years ago with suspend / resume.
In mantis_dvb.c's driver probe function I modified tuner_ops to enable these 
runtime powersaving features:
+   mantis-fe-ops.tuner_ops.sleep = 
mantis_dvb_tuner_sleep;
+   mantis-fe-ops.tuner_ops.init = mantis_dvb_tuner_init;

That way mantis_core.ko had all needed details to do any advanced power savings 
I wanted.

Suspend / resume worked well: During resume there was only a glitch at the 
picture and sound
and the TV channel watching continued. tda10021 (was cu1216 at that time)
restored the original TV channel. It took DVB FE_LOCK during resume.
Suspended DMA transfer was recovered before returning into userspace.

So I think that you need a single device (mantis_core.ko) that can see the 
whole picture,
in what states the subdevices are: can you touch the power button?.
With DVB this is easy because dvb_frontend.c tells when a frontend is idle and 
when it is not.

The similar idea of some kind of watchdog that is able to track when a single 
device (frontend) is used and when it is not used, would be sufficient.

The topmost driver (mantis_core.ko in my case) would then be responsible to 
track multiple frontends
(subdevices), if they all are idle or not, with suitable mutex protection.
Then this driver could easilly suspend/resume these subdevices and press power 
switch when necessary.


So the clash between DVB and V4L devices would be solved:
Both DVB and V4L calls a (different) sleep() function on mantis_core.ko
mantis_core.ko will turn power off when both frontends are sleeping.
If only one sleeps, the one can be put to sleep or suspended, but power
button can't be touched.

What do you think?

I did this easy case mantis_core.ko solution in about Summer 2007.
It needs a rewrite and testing, if I take it from the dust.

Regards,
Marko Ristola

16.06.2011 15:51, Devin Heitmueller wrote:
 On Thu, Jun 16, 2011 at 7:14 AM, Mauro Carvalho Chehab
 mche...@redhat.com wrote:
 One possible logic that would solve the scripting would be to use a watchdog
 to monitor ioctl activities. If not used for a while, it could send a s_power
 to put the device to sleep, but this may not solve all our problems.

 So, I agree with Devin: we need to add an option to explicitly control the
 power management logic of the device, having 3 modes of operation:
POWER_AUTO - use the watchdogs to poweroff
POWER_ON - explicitly powers on whatever subdevices are needed in
   order to make the V4L ready to stream;
POWER_OFF - Put all subdevices to power-off if they support it.

 After implementing such logic, and keeping the default as POWER_ON, we may
 announce that the default will change to POWER_AUTO, and give some time for
 userspace apps/scripts that need to use a different mode to change their
 behaviour. That means that, for example, radio -qf will need to change to
 POWER_ON mode, and radio -m should call POWER_OFF.
 
 I've considered this idea before, and it's not bad in theory.  The one
 thing you will definitely have to watch out for is causing a race
 between DVB and V4L for hybrid tuners.  In other words, you can have a
 user switching from analog to digital and you don't want the tuner to
 get powered down a few seconds after they started streaming video from
 DVB.
 
 Any such solution would have to take the above into account.  We've
 got a history of race conditions like this and I definitely don't want
 to see a new one introduced.
 
 Devin
 

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFCv2 PATCH 0/5] tuner-core: fix s_std and s_tuner

2011-07-06 Thread Marko Ristola
06.07.2011 21:17, Devin Heitmueller kirjoitti:
 On Wed, Jul 6, 2011 at 1:53 PM, Marko Ristola marko.rist...@kolumbus.fi 
 wrote:

 
 All that said, I believe that you are correct in that the business
 logic needs to ultimately be decided by the bridge driver, rather than
 having the dvb/tuner core blindly calling the sleep routines against
 the tuner and demod drivers without a full understanding of what
 impact it has on the board as a whole.

You wrote it nicely and compactly.

What do you think about tracking coarse last busy time rather than figuring out 
accurate idle time?

dvb_frontend.c and V4L side would just poll the device:
bridge-wake(). wake() will just store current busy timestamp to the bridge 
device
with coarse accuracy, if subdevices are already at active state.
If subdevices are powered off, it will first power them on and resume them, and 
then store busy timestamp.

Bridge device would have a delayed task: Check after 3 minutes: If I haven't 
been busy
for three minutes, I'll go to sleep. I'll suspend the subdevices and power them 
off.

The delayed task would refresh itself: check again after last awake time + 3 
minutes.

Delayed task could be further developed to support multiple suspend states.

 
 Cheers,
 
 Devin
 


Marko
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Refactor Mantis DMA transfer to deliver 16Kb TS data per interrupt

2011-06-05 Thread Marko Ristola

Hi Mauro and Manu

I think that the patch is robust enough to be accepted.
Please Mauro accept this patch at appropriate time.

Would you Manu, please, read my lengthy detailed description
of this patch when you have time? Then you know what it does and why.

I provided a descriptive table of the garbage generating problem,
if you want to have a quick look.

Regards,
Marko Ristola



When I wrote this patch, I took lots of time to understand
the RISC processor's commands from Manu's existing code and from
Manu's old Internet references found by Google.

I have verified thoroughly that the code is correct.
It doesn't do any new assumptions on the RISC processor or DMA transfer
in addition to Manu's existing assumptions. Users know by experience
that this patch work.




Why this increases performance so much?

Mantis I2C transfer (and thus Hopper too) does busy looping, reserving the CPU
for the entire I2C transfer time (under 1ms, big single latency point).
So having a faster CPU doesn't solve this latency problem, but
having more than one CPU helps. Easiest way to reduce these IRQ
activated latencies is to generate the IRQ less often.



Reduce interrupts by emitting IRQ less often

I wanted to reduce IRQs into one third (one per 16K instead of one per 4K).
So instead of RISC processor doing two 2048 byte DMA transfers per IRQ I do 
16384 / 2048 = 8 DMA transfers and then emit IRQ.

The RISC processor can do DMA transfers up to 4095 bytes per RISC instruction.
That's why Manu's code does single DMA transfer per 2048 bytes and emits
IRQ on every second instruction.


DMA transfer garbage problem

DMA transfer garbage problem is another thing that this patch fixes.

When Mantis/Hopper tunes into a TS,
first DMA transfer will deliver almost the whole 64K DMA buffer into 
dvb_dmx_swfilter(_204).
This has caused application crashes and delays on tuning into the channel and 
occurrences
of wrong audio/video on application.
Over these years application robustness has improved.


Here is original buggy code's DMA transfer variables as a table:

Table: Garbage generating block iteration without my patch
linebuf_pos finished_block_by_IRQ  original_last_block 
last_block_after_driver_processing
0   0   15 015 ( driver 
processes garbage 4K blocks indexed 0 - 14).
1   2048
2   40960  15   0 ( driver 
processes garbage 4K block at index 15).
3   6144
4   81921  01 (first valid 
4K data block at index 0).
snip

- line   goes from 0 to 31: one RISC CPU DMA transfer 
instruction per line.
- buf_postracks pointer where RISC CPU will copy 2048 bytes 
with the DMA transfer.
- finished_block_by_IRQ  RISC CPU reports via IRQ: I have finished block 15, 
driver can process it.
- original_last_blockDriver will copy this 4K block first, until just 
before finished_block_by_IRQ.
- last_block_after_driver_processing The value of last_block after driver has 
processed 4K DMA buffer blocks.

I fix this by thinking it in another way:
RISC CPU doesn't report what is the previous acceptable block. It reports:
I'm writing into block XXX. Don't touch it!

The fix is here:
 + RISC_INSTR(risc_pos, RISC_WRITE |
 +RISC_IRQ |
 +RISC_STATUS(line) |
 +MANTIS_DMA_TR_BYTES);
RISC CPU informs Mantis/Hopper driver that 16K buffer at line will be 
overwritten.


Table: Working block iteration after my patch
linestepbuf_pos busy_block  original_last_block 
last_block_after_driver_processing
0   0   0   0   0   0 (kernel 
driver wakened, block 0 is busy, do nothing)
0   1   2048
snip
0   6   12288   
0   7   14336   
1   0   16384   1   0   1 (kernel 
driver writes valid 16K block at index 0, block 1 is busy)
1   1   18432   
snip
1   7   30720   
2   0   32768   2   1   2 (kernel 
driver writes valid 16K block at index 1, block 2 is busy)
2   1   34816   
snip

- line  goes from 0 to 3. It counts 16K blocks.
- step  goes from 0 to 8. It counts 2K blocks within a 16K 
block.
- buf_pos   goes from 0 to under 64K, in 2K byte steps.
- busy_blockRISC IRQ reports via IRQ: I will write to block X. 
Don't touch it. (index is between 0 and 3).
- original_last_block   Driver will copy this 16K block first, until the block 
before busy block

Re: AW: Remote control not working for Terratec Cinergy C (2.6.37 Mantis driver)

2011-05-21 Thread Marko Ristola

I noticed that too on the C code:

If keypress comes from the remote control,
driver does both push down and release immediately.

Some years ago I made a version that did something like this:

I measured that a remote control sends key pressed in about 20ms cycles.

Thus I decided that the driver can do following:

Whe key '1' is pressed initially, send key 1 pressed to input layer.

If within 30ms a '1 pressed' comes from the remote control, driver keeps '1' as 
pressed (do nothing for input layer).
If there won't come a '1 pressed' from remote within 30ms, then driver sends 
key 1 unpressed to input layer.

I don't know if there is any reusable algorithm (easilly usable code) for 
remote control drivers for this.

Regards,
Marko Ristola


21.05.2011 10:23, Adrian C. kirjoitti:
 Haven't noticed earlier that every button press is executed twice, until 
 I did some testing with Oxine. Not sure how much Lirc is to blame for 
 this, and for button 0 not working. I will move to the Lirc list.
 
 Thanks again for the patch.
 

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Remote control not working for Terratec Cinergy C (2.6.37 Mantis driver)

2011-05-06 Thread Marko Ristola
04.05.2011 01:42, Adrian C. kirjoitti:
 On Wed, 2 Mar 2011, Marko Ristola wrote:
 
 So this means, that my remote control works, pressing key with hex 
 value 0x26 works.
 
 It works.
 
 Unfortunately mantis_uart.c doesn't have IR input initialization at 
 all
 
 But it does not work. How can it work and not work at the same time?
The hardware device is active (it is enabled, messages are sent from
the remote to the Kernel Mantis software driver.
The bytes can be logged into /var/log/messages file.

That's all the driver is designed to do at this point.

 
 
 I have the Skystar HD2 (b), subsystem: 1ae4:0003 now, same chipset as 
 Cinergy S2 and some others, VP-1041. Lirc failed with my old COM 
 receiver so I tried to use the cards IR as fall-back, and of course I 
 failed again. This was on 2.6.38.4.
 
 Only information I found is 1 year old[1]. IR was in flux but it still 
 doesn't work even though mantis pulls in all those ir-* modules, no 
 input device is created.
 
 Can someone fill us in, please, will it be supported this year?
Would you please ask from Manu Abraham. Maybe he gets paid for doing it.
I have experimented with my remote control too a few years ago,
but I think it is good if Manu gets it as a job.

Regards,
Marko Ristola

 
 
 1. http://www.mail-archive.com/linux-media@vger.kernel.org/msg14641.html
 --
 To unsubscribe from this list: send the line unsubscribe linux-media in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Speed up DVB TS stream delivery from DMA buffer into dvb-core's buffer

2011-04-08 Thread Marko Ristola
Avoid unnecessary DVB TS 188 sized packet copying from DMA buffer into stack.
Backtrack one 188 sized packet just after some garbage bytes when possible.
This obsoletes patch https://patchwork.kernel.org/patch/118147/

Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c 
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 4a88a3e..faa3671 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, 
const u8 *buf,
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int find_next_packet(const u8 *buf, int pos, size_t count,
+  const int pktsize)
 {
-   int p = 0, i, j;
+   int start = pos, lost;
 
-   spin_lock(demux-lock);
-
-   if (demux-tsbufp) {
-   i = demux-tsbufp;
-   j = 188 - i;
-   if (count  j) {
-   memcpy(demux-tsbuf[i], buf, count);
-   demux-tsbufp += count;
-   goto bailout;
-   }
-   memcpy(demux-tsbuf[i], buf, j);
-   if (demux-tsbuf[0] == 0x47)
-   dvb_dmx_swfilter_packet(demux, demux-tsbuf);
-   demux-tsbufp = 0;
-   p += j;
+   while (pos  count) {
+   if (buf[pos] == 0x47 ||
+   (pktsize == 204  buf[pos] == 0xB8))
+   break;
+   pos++;
}
 
-   while (p  count) {
-   if (buf[p] == 0x47) {
-   if (count - p = 188) {
-   dvb_dmx_swfilter_packet(demux, buf[p]);
-   p += 188;
-   } else {
-   i = count - p;
-   memcpy(demux-tsbuf, buf[p], i);
-   demux-tsbufp = i;
-   goto bailout;
-   }
-   } else
-   p++;
+   lost = pos - start;
+   if (lost) {
+   /* This garbage is part of a valid packet? */
+   int backtrack = pos - pktsize;
+   if (backtrack = 0  (buf[backtrack] == 0x47 ||
+   (pktsize == 204  buf[backtrack] == 0xB8)))
+   return backtrack;
}
 
-bailout:
-   spin_unlock(demux-lock);
+   return pos;
 }
 
-EXPORT_SYMBOL(dvb_dmx_swfilter);
-
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
+/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
+   size_t count, const int pktsize)
 {
int p = 0, i, j;
-   u8 tmppack[188];
+   const u8 *q;
 
spin_lock(demux-lock);
 
-   if (demux-tsbufp) {
+   if (demux-tsbufp) { /* tsbuf[0] is now 0x47. */
i = demux-tsbufp;
-   j = 204 - i;
+   j = pktsize - i;
if (count  j) {
memcpy(demux-tsbuf[i], buf, count);
demux-tsbufp += count;
goto bailout;
}
memcpy(demux-tsbuf[i], buf, j);
-   if ((demux-tsbuf[0] == 0x47) || (demux-tsbuf[0] == 0xB8)) {
-   memcpy(tmppack, demux-tsbuf, 188);
-   if (tmppack[0] == 0xB8)
-   tmppack[0] = 0x47;
-   dvb_dmx_swfilter_packet(demux, tmppack);
-   }
+   if (demux-tsbuf[0] == 0x47) /* double check */
+   dvb_dmx_swfilter_packet(demux, demux-tsbuf);
demux-tsbufp = 0;
p += j;
}
 
-   while (p  count) {
-   if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
-   if (count - p = 204) {
-   memcpy(tmppack, buf[p], 188);
-   if (tmppack[0] == 0xB8)
-   tmppack[0] = 0x47;
-   dvb_dmx_swfilter_packet(demux, tmppack);
-   p += 204;
-   } else {
-   i = count - p;
-   memcpy(demux-tsbuf, buf[p], i);
-   demux-tsbufp = i;
-   goto bailout;
-   }
-   } else {
-   p++;
+   while (1) {
+   p = find_next_packet(buf, p, count, pktsize);
+   if (p = count)
+   break;
+   if (count - p  pktsize)
+   break;
+
+   q = buf[p];
+
+   if (pktsize == 204  (*q == 0xB8

Re: [PATCH] Speed up DVB TS stream delivery from DMA buffer into dvb-core's buffer

2011-04-08 Thread Marko Ristola

Here is some statistics without likely and with likely functions.

It seems that using likely() gives better performance with Phenom I too.

%   Plain knl % No likely   %   With likely %
dvb_ringbuffer_write5,9 62,88,7 81,35,7 79,2
dvb_dmx_swfilter_packet 1,2 12,80,7 6,5 0,8 11,1
dvb_dmx_swfilter_2042,3 24,51,3 12,10,7 9,7


Here Plain knl % is perf top -d 30 percentage.
24,5 12,1 and 9,7 are percentages without a patch, with basic patch
and last is with likely functions using patch.

Regards,
Marko Ristola


08.04.2011 18:40, Marko Ristola kirjoitti:
 Avoid unnecessary DVB TS 188 sized packet copying from DMA buffer into stack.
 Backtrack one 188 sized packet just after some garbage bytes when possible.
 This obsoletes patch https://patchwork.kernel.org/patch/118147/
 
 Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi
 diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c 
 b/drivers/media/dvb/dvb-core/dvb_demux.c
 index 4a88a3e..faa3671 100644
 --- a/drivers/media/dvb/dvb-core/dvb_demux.c
 +++ b/drivers/media/dvb/dvb-core/dvb_demux.c
 @@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, 
 const u8 *buf,
  
  EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
  
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Pending dvb_dmx_swfilter(_204)() patch tested enough

2011-03-29 Thread Marko Ristola


Hello Andreas and Mauro

Thank you for looking at the patch.
Than you Mauro for giving the likely() unlikely() GCC assembly example
and remind of scripts/checkpatch.pl.

28.03.2011 15:07, Andreas Oberritter wrote:

Hello Marko,

On 03/26/2011 09:20 PM, Marko Ristola wrote:

Following patch has been tested enough since last Summer 2010:

Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function
https://patchwork.kernel.org/patch/118147/
It modifies both dvb_dmx_swfilter_204() and dvb_dmx_swfilter()  functions.


sorry, I didn't know about your patch. Can you please resubmit it with
the following changes?

- Don't use camelCase (findNextPacket)

I'll rename it as find_next_packet().



- Remove disabled printk() calls.

I'll do that.



- Only one statement per line.
if (unlikely(lost = pos - start)) {
while (likely((p = findNextPacket(buf, p, count, pktsize))  count)) {


I'll alter while() line as:

while (1) {
p = find_next_packet(buf, p, count, pktsize);
if (p = count)
break;
if (count - p  pktsize)
break;





- Add white space between while and the opening brace.
while(likely(pos  count)) {

Thanks.



- Use unsigned data types for pos and pktsize:
static inline int findNextPacket(const u8 *buf, int pos, size_t count,
const int pktsize)


I'll change them.



The CodingStyle[1] document can serve as a guideline on how to properly
format kernel code.

Thanks. I have read it, but reading again is always good for learning.


Does the excessive use of likely() and unlikely() really improve the
performance or is it just a guess?


I'll try to measure performance difference next weekend: I haven't tested the 
effect
on likely/unlikely operations. I have tested the effect of the whole patch only.
I selected likely and unlikely() sentences very carefully, so they should be 
correct.



I'm not sure if recovering a packet by backtracking is worth it on my patch:
If recovered packets are typically discarded by dvb_dmx_swfilter_packet() 
later, I'll drop the code.

Here is a description of the problem as I saw it last Summer:

My DVB card seemed to lose a few packets somewhere in the DMA transfer buffer 
and then had a short packet
(less than 204 garbage bytes) and then normal good packets.

Backtracking use case (deliver 16K bytes of data for dvb_dmx_swfilter_204() per 
call):
1. DVB card loses a few packets.
2. DVB card delivers less than 204 bytes garbage, containing packet start byte 
in the middle.
3. dvb_dmx_swfilter_204() finds start byte from garbage. Deliver 204 sized 
garbage packet into dvb_dmx_swfilter_packet().
4. dvb_dmx_swfilter_204() detects that packet at (3) was garbage. One good 
packet can be restored by buffer backtracking.
5. dvb_dmx_swfilter_204() delivers restored packet into 
dvb_dmx_swfilter_packet().
6. dvb_dmx_swfilter_204() continues to deliver 204 sized packets into 
dvb_dmx_swfilter_packet().

I suspect that on (5), the restored packet is discarded by 
dvb_dmx_swfilter_packet() because of
packet counter sequencing error. There is no benefit with recovering the packet 
in this (typical) case.
dvb_dmx_swfilter_packet() will discard packets until it finds a next group of 
packets with group
start identifier. Is this correct?

Regards,
Marko Ristola



Regards,
Andreas

[1]
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/CodingStyle
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Pending dvb_dmx_swfilter(_204)() patch tested enough

2011-03-26 Thread Marko Ristola


Hi Mauro.

Following patch has been tested enough since last Summer 2010:

Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function
https://patchwork.kernel.org/patch/118147/
It modifies both dvb_dmx_swfilter_204() and dvb_dmx_swfilter()  functions.

I Myself tested dvb_dmx_swfilter_204() with terrestrial DVB-C, using 204 sized 
packets.
Some other Mantis users have satellite receiver equipment, using 188 sized 
packets, thus
using dvb_dmx_swfilter().

The patch has been in yaVDR/testing branch and used there.

So both functions are tested enough during one half year period.
I was asked by a person this week that if the patch could go forward.

Regards,
Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Remote control not working for Terratec Cinergy C (2.6.37 Mantis driver)

2011-03-01 Thread Marko Ristola

28.02.2011 19:26, Jonas Hanschke kirjoitti:

Hi,

despite lots of time spent tinkering around and looking for help on
the web, I've had no success in getting to work the remote control of
my DVB-C card.

It is a Terratec Cinergy C:
http://linuxtv.org/wiki/index.php/TerraTec_Cinergy_C_DVB-C

and am using the Mantis driver. Since it was merged into the kernel
tree in 2.6.33, watching TV works without patches, but the remote
control does not, although it is supposed to be supported, according
to the link above.

Kernel is a vanilla 2.6.37.2 with custom configuration on an old AMD
Athlon XP machine, running debian Squeeze.


When I modprobe the Mantis driver, the following IR-modules are pulled
in automagically:
ir_lirc_codec
lirc_dev
ir_core

However, no input device is created during module loading. dmesg output:
Mantis :01:0a.0: PCI INT A -  Link[APC1] -  GSI 16 (level, high) -  IRQ 
16
DVB: registering new adapter (Mantis DVB adapter)
IR LIRC bridge handler initialized
DVB: registering adapter 0 frontend 0 (Philips TDA10023 DVB-C)...

Am I missing some additional modules? Are there any dependencies on
other kernel config options that are not handled automatically by make
menuconf?

If additional information is needed, I will be happy to provide it.
However, I am not sure what is useful and what is not and did not want
to bloat this message.


Before merging into v4l-dvb, doing modprobe mantis was enough.
I don't know how it should work with recent kernels.
I haven't seen remote control working lately.

Turning mantis module debug options on gives some information
what is happening into /var/log/messages.

Regards,
Marko Ristola



Thanks in advance,

Jonas
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Summary of the pending patches up to Dec, 31 (26 patches)

2011-01-04 Thread Marko Ristola

Dear Developers,

Happy New Year.

I'll try to describe my patches so that they would be more understandable.
First comment is for all dvb_dmx_swfilter() and dvb_dmx_swfilter_204() users: 
please test the performance improvement.
The second comment is mostly to convince Manu Abraham, but the concept might be 
useful for others too. Please read.

31.12.2010 14:41, Mauro Carvalho Chehab wrote:
 Dear Developers,
 
   == Need more tests/acks from DVB users == 
 
 Aug, 7 2010: Avoid unnecessary data copying inside dvb_dmx_swfilter_204() 
 function  http://patchwork.kernel.org/patch/118147  Marko Ristola 
 marko.rist...@kolumbus.fi

This patch affects equally for both dvb_dmx_swfilter() and 
dvb_dmx_swfilter_204().
The resulting performance and functionality is similar with 
dvb_dmx_swfilter_packets().
dvb_dmx_swfilter(_204)() have robustness checks. Devices without such need
can still use dvb_dmx_swfilter_packets().

My performance patch helps especially with high volume 256-QAM TS streams 
containing for example HDTV
content by removing one unnecessary stream copy.
With perf top, dvb_dmx_swfilter_204()'s CPU consumption reduced in the 
following way:

Without the patch dvb_dmx_swfilter_204() and dvb_dmx_swfilter_packet() took 
about equal amounts of CPU.
With the patch dvb_dmx_swfilter_204()'s CPU consumption went into 1/5 or 1/10 
of the original (resulting minor CPU consumption).
dvb_dmx_swfilter_packet()'s CPU time was about as before.

Test environment was Fedora with VDR streaming HDTV into network.
I have tested the patch thoroughly (see for example 
https://patchwork.kernel.org/patch/108274).

The patch assumes that dvb_dmx_swfilter_packet() can eat data stream fast 
enough so that
the DVB card's DMA engine will not replace buffer content underneath of 
dvb_dmx_swfilter_204().

It would be helpful if someone using dvb_dmx_swfilter() could try the patch 
too: maybe nobody has tried it.
The benefit would be, that dvb_dmx_swfilter() is almost equally fast as the 
existing blatantly fast dvb_dmx_swfilter_packets() :)

 
 
 * I want to see people testing the above patch, as it seems to improve *
 * DVB performance by avoiding data copy.   *
 
 
   == mantis patches - Waiting for Manu Abraham 
 abraham.m...@gmail.com == 
 
 Jun,20 2010: [2/2] DVB/V4L: mantis: remove unused files   
   http://patchwork.kernel.org/patch/107062  Bjørn Mork bj...@mork.no
 Jul,19 2010: Twinhan DTV Ter-CI (3030 mantis) 
   http://patchwork.kernel.org/patch/112708  Niklas Claesson 
 nicke.claes...@gmail.com
 Aug, 7 2010: Refactor Mantis DMA transfer to deliver 16Kb TS data per 
 interrupt http://patchwork.kernel.org/patch/118173  Marko Ristola 
 marko.rist...@kolumbus.fi

16Kb TS stream improvement: What do you think about this, Manu Abraham?

If high volume TS stream (256-QAM) with 50Mbits/s generates one interrupt
once per 4096 bytes, you have a problem.
Mantis driver copies 4096 bytes with one interrupt, into dvb_core's 128K buffer.
VDR reads data in big pieces (as much data as you get).
Network layer receives data in about 100K - 300K pieces from VDR.

So I think that it is unnecessary to interrupt other processes once per 4096 
bytes, for 56Mbit/s streams.
With 16K / interrupt you reduce the number of interrupts into one quarter, 
without affecting VDR at all,
lessening unnecessary interrupts and giving CPU time to other processes.

The CPU might have some other things to do without wanting to get interrupted 
once per  (displaying HDTV, delivering HDTV stream to network). Mantis/Hopper 
kernel driver must process the whole high volume TS stream, although it might 
deliver only one radio channel forward.

I saw glitches with HDTV (followed by stream halt) even though the Mantis DVB 
card only delivered the data into the local network via VDR.
I don't have such single CPU computer anymore though.

16K comes from the fact that it is not good to try to overload dvb_core's 128K 
buffer. 3/4 of the interrupts are gone.
DVB driver does at least twice the number of interrupts compared to VDR reading 
the stream:
dvb_core's buffer is never empty when VDR asks more data.

Best regards,
Marko Ristola
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Thoughts about suspending DVB C PCI device transparently

2010-11-23 Thread Marko Ristola


Hi.

Thank you for noticing my old email.

My observation of working suspend/resume implementation was,
that the needed amount of code for suspend and resume functions
was very small and easy. I reorganized mantis_pci.c so that both
module initialization and suspend/resume could use the same
functions for DVB device initialization.

Mantis structure needed maintenance of status before suspend
so that the status could be restored afterwards:
- power state (had feature to turn tuner off when idle).
- get_frontend(fe, param) content.
- number of feeds before suspend.

Each sub-device (C-file) needed it's own suspend() and resume() function
and these functions had to be called in the right order, starting
from mantis_pci.c's functions, some maintained IRQ states. After powering
and initializing all hardware, frontend was tuned back to state before suspend,
FE lock waited and DMA transfer turned back on.

Other kernel parts (the framework) took care that
no user space program will interfere during the resume process.

Media/dvb-core didn't need any changes for this to work.

Regards,
Marko Ristola

20.11.2010 14:57, Richard Zidlicky wrote:

Hi,

found this old email when searching for suspend issues, seems like a good idea.
Just wondering - how many eg dvb drivers are there with working 
suspend/hibernate
(all buses, not just PCI)? Me thinks only a small fraction, the rest will crash
unless blacklisted by pm-utils?

I don't know any that works, but maybe there are a few of them.


Would it be worth to code a generic approach working around drivers that need 
to be
blacklisted? It seems that because of eg firmware loading this might be the 
only way
to get dvb drivers behave?

Sharing the approach would work, but code sharing might not be worth it.
Maybe putting some knowledge into small functions to ease up bus initialization
would help: driver developer would need as few knowledge from the bus as 
possible.
A document and a reference implementation would help others to add 
suspend/resume
into their simple drivers. Maybe users and developers want nicer suspend/resume
implementation now compared to the old times. Is the demand high enough now?


Richard


Once in a time I wrote into Mantis driver Suspend / resume
code. The idea was, that bridge driver (mantis_dvb.c) will
handle the suspend / resume transparently to the application.

With a PCI device this was rather easy to achieve.
With xine, there was just a glitch with video and audio
after resume.

So after suspend, frontend was tuned into the original
frequency, and the DMA transfer state was restored.

Suspend:
1. Turn off possible DMA transfer if active (feeds  0)
2. Remember tuner power on state.
3. Do tuner and fronted power off.

Resume:
1. Restore frontend and tuner power.
2. (feeds  0)? Set frequency for the tuner.
3. (feeds  0)? Restore DMA transfer into previous state.

What do you think about this?
I need some feedback: is it worth coding?
Other needed code is usual suspend / resume stuff.

Is it worth powering off the tuner, if it isn't
used?

For my current usage, powering off the unused tuner
gives more power savings than implementing suspend/resume.

Marko Ristola

--

// suspend to standby, ram or disk.
int mantis_dvb_suspend(struct mantis_pci *mantis, pm_message_t
 prevState, pm_message_t mesg)
{
 if (mantis-feeds  0)
mantis_dma_stop(mantis);

 if (mantis-has_power)
 mantis_fe_powerdown(mantis); // power off tuner.

 return 0;
}

void mantis_dvb_resume(struct mantis_pci *mantis, pm_message_t prevMesg)
{
// power on frontend and tuner.
mantis_frontend_tuner_init(mantis);

if (mantis-feeds  0  mantis-fe-ops.tuner_ops.init)
 (mantis-fe-ops.init)(mantis-fe);

 if (mantis-feeds  0) {
 (mantis-fe-ops.set_frontend)(mantis-fe, NULL);
mantis_dma_start(mantis);
 }
}

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PATCHES FOR 2.6.38] mantis for_2.6.38

2010-11-17 Thread Marko Ristola

Hi Bjørn Mork and Mauro Carvalho Chehab.

The following patch was an experiment and wasn't actually meant for inclusion 
into the Kernel.

 Jul,10 2010: Mantis driver patch: use interrupt for I2C traffic instead of 
 busy reg http://patchwork.kernel.org/patch/111245  Marko Ristola 
 marko.rist...@kolumbus.fi

Would you please drop it from the Patchwork?
Would you Bjørn remove it from your Git repository?
The patch is ugly and it doesn't work, the broken part is active only with 
vp2033.

I'm sorry for the hassle.
Cheers, Marko Ristola

13.11.2010 16:26, Mauro Carvalho Chehab wrote:
 Em 12-11-2010 12:43, Bjørn Mork escreveu:
 Hello, 

 I've been waiting for this list of patchwork patches to be included for
 quite a while, and have now taken the liberty to clean them up as
 necessary and add them to a git tree, based on the current media_tree
 for_v2.6.38 branch, with exceptions as noted below:

 == mantis patches - Waiting for Manu Abraham 
 abraham.m...@gmail.com == 

 Jul,10 2010: Mantis driver patch: use interrupt for I2C traffic instead of 
 busy reg http://patchwork.kernel.org/patch/111245  Marko Ristola 
 marko.rist...@kolumbus.fi

 The following changes since commit 

 af9f14f7fc31f0d7b7cdf8f7f7f15a3c3794aea3[media] IR: add tv power 
 scancode to rc6 mce keymap

 are available in the git repository at:

   git://git.mork.no/mantis.git for_2.6.38
 
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function

2010-08-07 Thread Marko Ristola

Hi.

This patch is like the original, but without mangled spaces.
I found Documentation/email-clients.txt to be useful for tuning Thunderbird.

DVB-S2 users with high volume stream data are interested in trying this patch 
too.

Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi

diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c 
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba..b71d77d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,97 +478,96 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, 
const u8 *buf,
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int findNextPacket(const u8 *buf, int pos, size_t count,
+  const int pktsize)
 {
-   int p = 0, i, j;
+   int start = pos, lost;
 
-   spin_lock(demux-lock);
-
-   if (demux-tsbufp) {
-   i = demux-tsbufp;
-   j = 188 - i;
-   if (count  j) {
-   memcpy(demux-tsbuf[i], buf, count);
-   demux-tsbufp += count;
-   goto bailout;
-   }
-   memcpy(demux-tsbuf[i], buf, j);
-   if (demux-tsbuf[0] == 0x47)
-   dvb_dmx_swfilter_packet(demux, demux-tsbuf);
-   demux-tsbufp = 0;
-   p += j;
+   while(likely(pos  count)) {
+   if (likely(buf[pos] == 0x47 ||
+   (pktsize == 204  buf[pos] == 0xB8)))
+   break;
+   pos++;
}
 
-   while (p  count) {
-   if (buf[p] == 0x47) {
-   if (count - p = 188) {
-   dvb_dmx_swfilter_packet(demux, buf[p]);
-   p += 188;
-   } else {
-   i = count - p;
-   memcpy(demux-tsbuf, buf[p], i);
-   demux-tsbufp = i;
-   goto bailout;
-   }
-   } else
-   p++;
+   if (unlikely(lost = pos - start)) {
+   /* This garbage is part of a valid packet? */
+   int backtrack = pos - pktsize;
+   if (backtrack = 0  (buf[backtrack] == 0x47 ||
+   (pktsize == 204  buf[backtrack] == 0xB8))) {
+   /* printk(demux: backtracked %d bytes
+* \n, start - backtrack); */
+   return backtrack;
+   }
+   /*printk(demux: skipped %d bytes at %d\n, lost, start); */
}
 
-bailout:
-   spin_unlock(demux-lock);
+   return pos;
 }
 
-EXPORT_SYMBOL(dvb_dmx_swfilter);
-
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
+/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
+   size_t count, const int pktsize)
 {
int p = 0, i, j;
-   u8 tmppack[188];
+   const u8 *q;
 
spin_lock(demux-lock);
 
-   if (demux-tsbufp) {
+   if (likely(demux-tsbufp)) { /* tsbuf[0] is now 0x47. */
i = demux-tsbufp;
-   j = 204 - i;
-   if (count  j) {
+   j = pktsize - i;
+   if (unlikely(count  j)) {
memcpy(demux-tsbuf[i], buf, count);
demux-tsbufp += count;
goto bailout;
}
memcpy(demux-tsbuf[i], buf, j);
-   if ((demux-tsbuf[0] == 0x47) || (demux-tsbuf[0] == 0xB8)) {
-   memcpy(tmppack, demux-tsbuf, 188);
-   if (tmppack[0] == 0xB8)
-   tmppack[0] = 0x47;
-   dvb_dmx_swfilter_packet(demux, tmppack);
-   }
+   if (likely(demux-tsbuf[0] == 0x47)) /* double check */
+   dvb_dmx_swfilter_packet(demux, demux-tsbuf);
demux-tsbufp = 0;
p += j;
}
 
-   while (p  count) {
-   if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
-   if (count - p = 204) {
-   memcpy(tmppack, buf[p], 188);
-   if (tmppack[0] == 0xB8)
-   tmppack[0] = 0x47;
-   dvb_dmx_swfilter_packet(demux, tmppack);
-   p += 204;
-   } else {
-   i = count - p;
-   memcpy(demux-tsbuf, buf[p], i);
-   demux-tsbufp = i;
-   goto bailout;
-   }
-   } else {
-   p++;
+   while (likely((p

Re: [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function

2010-08-07 Thread Marko Ristola

Hi

The old patch with broken spaces is https://patchwork.kernel.org/patch/108274/
The one with good patch and bad introduction is 
https://patchwork.kernel.org/patch/118147/

Regards,
Marko Ristola

07.08.2010 12:47, Marko Ristola wrote:
 
 Hi.
 
 This patch is like the original, but without mangled spaces.
 I found Documentation/email-clients.txt to be useful for tuning Thunderbird.
 
 DVB-S2 users with high volume stream data are interested in trying this patch 
 too.
 
 Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi
 
[ snip ]

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Refactor Mantis DMA transfer to deliver 16Kb TS data per interrupt

2010-08-07 Thread Marko Ristola

This patch obsoletes patch with broken spaces
https://patchwork.kernel.org/patch/107036/

With VDR streaming HDTV into network, generating an interrupt once per 16kb,
implemented in this patch, seems to support more robust throughput with HDTV.

Fix leaking almost 64kb data from the previous TS after changing the TS.
One effect of the old version was, that the DMA transfer and driver's
DMA buffer access might happen at the same time - a race condition.

Signed-off-by: Marko M. Ristola marko.rist...@kolumbus.fi

Regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/hopper_cards.c 
b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc7..3b7e376 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-   mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+   mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
tasklet_schedule(mantis-tasklet);
}
if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39f..8f048d5 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
}
if (stat  MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-   mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+   mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
tasklet_schedule(mantis-tasklet);
}
if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h 
b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a..23b23b7 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -122,11 +122,8 @@ struct mantis_pci {
unsigned intnum;
 
/*  RISC Core   */
-   u32 finished_block;
+   u32 busy_block;
u32 last_block;
-   u32 line_bytes;
-   u32 line_count;
-   u32 risc_pos;
u8  *buf_cpu;
dma_addr_t  buf_dma;
u32 *risc_cpu;
diff --git a/drivers/media/dvb/mantis/mantis_dma.c 
b/drivers/media/dvb/mantis/mantis_dma.c
index 46202a4..c61ca7d 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -43,13 +43,17 @@
 #define RISC_IRQ   (0x01  24)
 
 #define RISC_STATUS(status)~status)  0x0f)  20) | ((status  0x0f) 
 16))
-#define RISC_FLUSH()   (mantis-risc_pos = 0)
-#define RISC_INSTR(opcode) (mantis-risc_cpu[mantis-risc_pos++] = 
cpu_to_le32(opcode))
+#define RISC_FLUSH(risc_pos)   (risc_pos = 0)
+#define RISC_INSTR(risc_pos, opcode)   (mantis-risc_cpu[risc_pos++] = 
cpu_to_le32(opcode))
 
 #define MANTIS_BUF_SIZE(64 * 1024)
-#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE  4)
-#define MANTIS_BLOCK_COUNT (1  4)
-#define MANTIS_RISC_SIZE   PAGE_SIZE
+#define MANTIS_BLOCK_BYTES  (MANTIS_BUF_SIZE / 4)
+#define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */
+#define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
+
+#define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
+/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k 
RISC cmd buffer) */
+#define MANTIS_RISC_SIZE   PAGE_SIZE /* RISC program must fit here. */
 
 int mantis_dma_exit(struct mantis_pci *mantis)
 {
@@ -124,27 +128,6 @@ err:
return -ENOMEM;
 }
 
-static inline int mantis_calc_lines(struct mantis_pci *mantis)
-{
-   mantis-line_bytes = MANTIS_BLOCK_BYTES;
-   mantis-line_count = MANTIS_BLOCK_COUNT;
-
-   while (mantis-line_bytes  4095) {
-   mantis-line_bytes = 1;
-   mantis-line_count = 1;
-   }
-
-   dprintk(MANTIS_DEBUG, 1, Mantis RISC block bytes=[%d], line 
bytes=[%d], line count=[%d],
-   MANTIS_BLOCK_BYTES, mantis-line_bytes, mantis-line_count);
-
-   if (mantis-line_count  255) {
-   dprintk(MANTIS_ERROR, 1, Buffer size error);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 int mantis_dma_init(struct mantis_pci *mantis)
 {
int err = 0;
@@ -158,12 +141,6 @@ int mantis_dma_init(struct mantis_pci *mantis)
 
goto err;
}
-   err = mantis_calc_lines(mantis);
-   if (err  0) {
-   dprintk(MANTIS_ERROR, 1, Mantis calc lines failed);
-
-   goto err;
-   }
 
return 0;
 err:
@@ -174,31

Re: [RFC/PATCH v3 06/10] media: Entities, pads and links enumeration

2010-08-05 Thread Marko Ristola

 05.08.2010 12:38, Laurent Pinchart wrote:

Hi Marko,

On Wednesday 04 August 2010 21:28:22 Marko Ristola wrote:

Hi Hans and Laurent.

I hope my thoughts help you further.

Thank you for sharing them.

Thank you for taking time to answer for me.

[ snip ]


There's probably some confusion here.

The media controller aims at giving userspace the ability to discover the
internal device topology. This includes various information about the
entities, such as a name, a version number, ...

The I2C data you mention are low-level information required by the kernel to
talk to the I2C device, but I don't think they're useful to userspace at all.
That kind of information come either from platform data or from the I2C device
driver and get used internally in the kernel.

Do you see any need to expose such information to userspace ?


I don't see any needs to expose such information into userspace.
I have some thoughts about I2C hardware problems,
but that is of course off topic. I wrote them here only
because I tried to draw some bigger picture how this entity, pads
and links thing relates to the whole driver.

[ snip ]


With I2C, an array of I2C slave devices that are reachable via I2C bus
would work for controlling the device rather nicely.

Higher abstraction level

So detailed descriptions and bus knowledge is needed for controlling each
entity and pad.

It's needed to control them inside the kernel, but I don't think it's needed
in userspace.


I agree: The detailed information needs to be internal to the driver,
and userspace needs only the information that is needed for being
able to decide how to configure the streams over many drivers,
and how each driver must be asked to do the configuration for it,
without driver needing knowledge about other related drivers.

Maybe a pad could have a list of pads that it can connect to.
Each destination pad reference could have a link as a property
if the link is mandatory for binding the pads together.

A list of open links without pads might be usable too, enabling binding
different drivers to pass data to each other with pad-link-pad binding.
Driver could be a property of a pad for being able to do binding over 
drivers.


You have of course a better picture and understanding about these,
and you will need to come up with the best solution together on your own.

Maybe I just need to do something else and go and buy another motherboard
from Helsinki Ruoholahti to replace my overheated one, walking by some
Nokia Research Center buildings.

Best regards from the summerish Finland.
Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH v3 06/10] media: Entities, pads and links enumeration

2010-08-04 Thread Marko Ristola


Hi Hans and Laurent.

I hope my thoughts help you further.

03.08.2010 12:22, Laurent Pinchart wrote:

Hi Hans,

On Monday 02 August 2010 23:01:55 Hans Verkuil wrote:

On Monday 02 August 2010 16:35:54 Laurent Pinchart wrote:

On Sunday 01 August 2010 13:58:20 Hans Verkuil wrote:

On Thursday 29 July 2010 18:06:39 Laurent Pinchart wrote:

[snip]


[snip]

It's a possibility, but it's always a bit of a hassle in an application to
work with group IDs. I wonder if there is a more elegant method.

The problem is a bit broader than just showing relationships between video
nodes and ALSA devices. We also need to show relationships between lens/flash
controllers and sensors for instance. Group IDs sound easy, but I'm open to
suggestions.


Low level example

DVB I2C bus is easy: get all I2C devices from an entity (DVB demuxer).
Some external chip (entity, the tuner) might be behind some I2C bridge 
device.


With I2C you need to know the characteristics, how you talk with
the destination device via the bus (extra sleeps, clock speed,
quiesce the whole bus for 50ms after talking to the slave device).
I'd like that each device would describe how it should be
talked to via the bus.

On i2c_transfer you could hide opening and closing the I2C bridge, and hide
the callbacks for extra sleeps so that the main driver and core 
framework code is free from such ugly details.
By storing entity's special requirements inside of it, you could reuse 
the callbacks with another product variant.


With I2C, an array of I2C slave devices that are reachable via I2C bus 
would work for controlling the device

rather nicely.

Higher abstraction level

So detailed descriptions and bus knowledge is needed for controlling 
each entity and pad.
That hierarchy is a bit different than optimal hierarchy of how the 
streams can flow
into, within and out from the entity (the driver). Buses are the 
gateways for the data stream flows,

shared by two or more entities/pads by links.

Thus I'd suggest to separate these two hierarchies (initialization time 
hierarchy and

stream flow capability hierarchy) at necessary points, and use buses
to bind the entities/pads by links to each other.

A single wire with just two end points can also be thought like a bus.

Regards,
Marko Ristola

[ snip ]

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Q]: any DVB-S2 card which is 45MS/s capable?

2010-08-02 Thread Marko Ristola


Hi.

I have written some Mantis bandwidth related
DMA transfer optimizations on June/July this year.
They are now waiting for approval by Manu Abraham.

Those reduce CPU pressure, increasing the bandwidth
that can be received from the DVB card. 45MS/s bandwidth
support will surely benefit from those patches.

Main features:
1. Do one CPU interrupt per 16KB data instead per 4KB data.
My implementation benefits only Mantis cards.
https://patchwork.kernel.org/patch/107036/

2. Remove unnecessary big CPU overhead, when data is delivered
from the DVB card's DMA buffer into Linux kernel's DVB subsystem.
Number 2 reduces the CPU pressure by almost 50%.
This implementation benefits many other Linux supported DVB cards too.
http://patchwork.kernel.org/patch/108274/

Those helped with my older single CPU Core computer with 256-QAM,
delivering HDTV channel into the network and watching the
HDTV channel with a faster computer.

The performance bottlenecks could be seen on the
command line with perf top.

I had to increase PCI bus latency setting into 64 too from the BIOS.
Moving DVB device into separate IRQ line with Ethernet card helped too,
because Ethernet card did an interrupt per ethernet packet.

So if the hardware can deliver 45MS/s data fast enough, software side 
can be optimized up
to some point. My patches contain the most easy major optimizations that 
I found.
If you can test some of those patches, it might help to get them into 
Linux kernel

faster.

Best regards,
Marko Ristola

27.07.2010 18:11, VDR User wrote:

On Tue, Jul 27, 2010 at 5:52 AM, Emmanueleall...@gmail.com  wrote:

VDR User a écrit :

Look at the vp-1041 I think.

 From what I gathered it is not able to do 45MS/s for DVB-S2.
Thanks anyway,

You may want to ask Manu Abraham (author of the mantis driver) about
that to be sure.  It seems I recall him telling me it could quite some
time ago.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Thoughts about suspending DVB C PCI device transparently

2010-07-11 Thread Marko Ristola


Hi all.

Once in a time I wrote into Mantis driver Suspend / resume
code. The idea was, that bridge driver (mantis_dvb.c) will
handle the suspend / resume transparently to the application.

With a PCI device this was rather easy to achieve.
With xine, there was just a glitch with video and audio
after resume.

So after suspend, frontend was tuned into the original
frequency, and the DMA transfer state was restored.

Suspend:
1. Turn off possible DMA transfer if active (feeds  0)
2. Remember tuner power on state.
3. Do tuner and fronted power off.

Resume:
1. Restore frontend and tuner power.
2. (feeds  0)? Set frequency for the tuner.
3. (feeds  0)? Restore DMA transfer into previous state.

What do you think about this?
I need some feedback: is it worth coding?
Other needed code is usual suspend / resume stuff.

Is it worth powering off the tuner, if it isn't
used?

For my current usage, powering off the unused tuner
gives more power savings than implementing suspend/resume.

Marko Ristola

--

// suspend to standby, ram or disk.
int mantis_dvb_suspend(struct mantis_pci *mantis, pm_message_t
prevState, pm_message_t mesg)
{
if (mantis-feeds  0)
mantis_dma_stop(mantis);

if (mantis-has_power)
mantis_fe_powerdown(mantis); // power off tuner.

return 0;
}

void mantis_dvb_resume(struct mantis_pci *mantis, pm_message_t prevMesg)
{
   // power on frontend and tuner.
   mantis_frontend_tuner_init(mantis);

   if (mantis-feeds  0  mantis-fe-ops.tuner_ops.init)
(mantis-fe-ops.init)(mantis-fe);

if (mantis-feeds  0) {
(mantis-fe-ops.set_frontend)(mantis-fe, NULL);
mantis_dma_start(mantis);
}
}

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Mantis driver patch: use interrupt for I2C traffic instead of busy registry polling

2010-07-10 Thread Marko Ristola


Hi

Here is a maybe too ugly patch for direct inclusion:
The code should be reworked to be nicer first.
This seems to work though.

What do you think the idea?

Problem:

I figured out that Mantis I2C read and write functions do busy waiting,
by reading via PCI bus a 32 bit word about 350 times in a tight loop.

I suspected that PCI DMA transfer from Mantis card to
CPU memory might get disturbed (FRTG DMA error message by Mantis)
because this heavy polling might cause the RISC processor's
DMA transfer to slow down so much, that there
comes glitches into the DVB stream (some internal FIFO gets full).

So that's why I wrote this patch: by reducing PCI bus contention,
the RISC DMA transfer should be more robust.

The heavy I2C command seems to be that dvb_core checks whether FE_LOCK 
still holds.

I think that DVB card's I2C transfers aren't so performance critical,
that the heavy PCI contention by polling is justified. Or is it?

I looked at saa7146_i2c.c from Linux kernel, how to use 
wait_event_interruptible_timeout.

Signed-off-by: Marko M Ristola marko.rist...@kolumbus.fi

Regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c

index cf4b39f..56c5c30 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -58,7 +58,7 @@ static int devs;

 #define DRIVER_NAMEMantis

-static char *label[10] = {
+static char *label[11] = {
 DMA,
 IRQ-0,
 IRQ-1,
@@ -68,6 +68,7 @@ static char *label[10] = {
 PPERR,
 FTRGT,
 RISCI,
+I2CDONE,
 RACK
 };

@@ -137,8 +138,15 @@ static irqreturn_t mantis_irq_handler(int irq, void 
*dev_id)

 mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
 tasklet_schedule(mantis-tasklet);
 }
-if (stat  MANTIS_INT_I2CDONE) {
-dprintk(MANTIS_DEBUG, 0, %s, label[9]);
+if (stat  (MANTIS_INT_I2CDONE | MANTIS_INT_I2CRACK)) {
+if (stat  MANTIS_INT_I2CDONE) {
+dprintk(MANTIS_DEBUG, 0, %s, label[9]);
+mantis-i2c_status |= MANTIS_INT_I2CDONE;
+}
+if (stat  MANTIS_INT_I2CRACK) {
+dprintk(MANTIS_DEBUG, 0, %s, label[10]);
+mantis-i2c_status |= MANTIS_INT_I2CRACK;
+}
 wake_up(mantis-i2c_wq);
 }
 mmwrite(stat, MANTIS_INT_STAT);
diff --git a/drivers/media/dvb/mantis/mantis_common.h 
b/drivers/media/dvb/mantis/mantis_common.h

index d0b645a..3773ad0 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -77,7 +77,8 @@

 enum mantis_i2c_mode {
 MANTIS_PAGE_MODE = 0,
-MANTIS_BYTE_MODE,
+MANTIS_BYTE_MODE = 1,
+MANTIS_IRQ_PAGE_MODE = 2,
 };

 struct mantis_pci;
@@ -136,6 +137,7 @@ struct mantis_pci {

 struct i2c_adapteradapter;
 inti2c_rc;
+inti2c_status;
 wait_queue_head_ti2c_wq;
 struct mutexi2c_lock;

diff --git a/drivers/media/dvb/mantis/mantis_i2c.c 
b/drivers/media/dvb/mantis/mantis_i2c.c

index 7870bcf..76de8f8 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.c
+++ b/drivers/media/dvb/mantis/mantis_i2c.c
@@ -38,6 +38,8 @@
 static int mantis_i2c_read(struct mantis_pci *mantis, const struct 
i2c_msg *msg)

 {
 u32 rxd, i, stat, trials;
+u32 intstat;
+long timeout;

 dprintk(MANTIS_INFO, 0, %s:  Address=[0x%02x] R[ ,
 __func__, msg-addr);
@@ -51,27 +53,53 @@ static int mantis_i2c_read(struct mantis_pci 
*mantis, const struct i2c_msg *msg)

 if (i == (msg-len - 1))
 rxd = ~MANTIS_I2C_STOP;

-mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
+mantis-i2c_status = 0;
+intstat = MANTIS_INT_I2CDONE | MANTIS_INT_I2CRACK;
+mmwrite(intstat, MANTIS_INT_STAT);
 mmwrite(rxd, MANTIS_I2CDATA_CTL);

 /* wait for xfer completion */
-for (trials = 0; trials  TRIALS; trials++) {
-stat = mmread(MANTIS_INT_STAT);
-if (stat  MANTIS_INT_I2CDONE)
-break;
+if (mantis-hwconfig-i2c_mode == MANTIS_IRQ_PAGE_MODE) {
+timeout = HZ / 64;
+timeout = wait_event_interruptible_timeout(mantis-i2c_wq, 
mantis-i2c_status  MANTIS_INT_I2CDONE, timeout);

+if (timeout == -ERESTARTSYS) {
+dprintk(MANTIS_DEBUG, 1, Mantis I2C read: got 
-ERESTARTSYS.\n);

+return -ERESTARTSYS;
+} if (timeout == 0L) {
+dprintk(MANTIS_DEBUG, 1, Mantis I2C read: waiting 
I2CDONE failed.\n);

+return -EIO;
+}
+dprintk(MANTIS_TMG, 0, I2CDONE: time remained %ld/%d 
jiffies\n, timeout, HZ / 64);

+} else {
+for (trials = 0; trials  TRIALS; trials++) {
+stat = mmread(MANTIS_INT_STAT);
+if (stat  MANTIS_INT_I2CDONE)
+break;
+}
+dprintk(MANTIS_TMG, 0, I2CDONE: trials=%d\n, trials

Re: [PATCH] Mantis: append tasklet maintenance for DVB stream delivery

2010-07-09 Thread Marko Ristola

Resending into linux-media, for confirming authorship:

I have personally done this patch.
Acked-by: Marko M Ristola marko.rist...@kolumbus.fi

Regards,
Marko

20.06.2010 16:51, Bjørn Mork kirjoitti:
 Note that mantis_core_exit() is never called.  Unless I've missed
 something, the drivers/media/dvb/mantis/mantis_core.{h,c} files can
 just be deleted.  They look like some development leftovers?


I see. mantis_core.ko kernel module exists though.
Maybe the mantis/Makefile references for mantis_core.c, mantis.c and hopper.c 
are just some leftovers too.

I moved tasklet_enable/disable calls into mantis_dvb.c where almost all other 
tasklet code is located.

So the following reasoning still holds:

1. dvb_dmxdev_filter_stop() calls mantis_dvb_stop_feed: mantis_dma_stop()
2. dvb_dmxdev_filter_stop() calls release_ts_feed() or some other filter 
freeing function.
3. tasklet: mantis_dma_xfer calls dvb_dmx_swfilter to copy DMA buffer's content 
into freed memory, accessing freed spinlocks.
This case might occur while tuning into another frequency.
Perhaps cdurrhau has found some version from this bug at 
http://www.linuxtv.org/pipermail/linux-dvb/2010-June/032688.html:
 This is what I get on the remote console via IPMI:
 40849.442492] BUG: soft lockup - CPU#2 stuck for 61s! [section
 handler:4617]


New reasoning for the patch (same as the one above, but from higher level):
After dvb-core has called mantis-fe-stop_feed(dvbdmxfeed) the last time (count 
to zero),
no data should ever be copied with dvb_dmx_swfilter() by a tasklet: the target 
structure might be in an unusable state.
Caller of mantis_fe-stop_feed() assumes that feeding is stopped after 
stop_feed() has been called, ie. dvb_dmx_swfilter()
isn't running, and won't be called.

There is a risk that dvb_dmx_swfilter() references freed resources (memory or 
spinlocks or ???) causing instabilities.
Thus tasklet_disable(mantis-tasklet) must be called inside of 
mantis-fe-stop_feed(dvbdmxfeed) when necessary.

Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi

Marko

diff --git a/drivers/media/dvb/mantis/mantis_dvb.c 
b/drivers/media/dvb/mantis/mantis_dvb.c
index 99d82ee..a9864f7 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed 
*dvbdmxfeed)
 if (mantis-feeds == 1) {
 dprintk(MANTIS_DEBUG, 1, mantis start feed  dma);
 mantis_dma_start(mantis);
+tasklet_enable(mantis-tasklet);
 }

 return mantis-feeds;
@@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed 
*dvbdmxfeed)
 mantis-feeds--;
 if (mantis-feeds == 0) {
 dprintk(MANTIS_DEBUG, 1, mantis stop feed and dma);
+tasklet_disable(mantis-tasklet);
 mantis_dma_stop(mantis);
 }

@@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)

 dvb_net_init(mantis-dvb_adapter, mantis-dvbnet, mantis-demux.dmx);
 tasklet_init(mantis-tasklet, mantis_dma_xfer, (unsigned long) mantis);
+tasklet_disable(mantis-tasklet);
 if (mantis-hwconfig) {
 result = config-frontend_init(mantis, mantis-fe);
 if (result  0) {

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Mantis DMA transfer cleanup, fixes data corruption and a race, improves performance. (signed-off this time)

2010-07-08 Thread Marko Ristola

Hi

This is a resend of the exactly same patch
than I sent 2010-06-20, to sign off it.

Signed-off-by: Marko M Ristola marko.rist...@kolumbus.fi

Regards,
Marko Ristola

-

Here is another version of the DMA transfer fix.
Please try it. Comments?

The current DMA code with drivers/media/dvb/mantis/mantis_dma.c has user
visible problems:
- about 1500 interrupts per second. One CPU can't copy h.264 data over
the network for me (vdr, streamdev).
- 64K garbage at start of the data stream, part of which goes into User
land application.
The garbage data is partly from the same stream (given twice), and
partly from previous tuned frequency (buffer
uninitialized at DMA start).
- Race condition: Memory copying from DMA buffer is done at the same
time as there is DMA transfer going on to the same bytes.
Can this race cause harware problems?

Current DMA code is not clear:
Current DMA RISC coding creates one DMA transfer per 2048 bytes.
Risc command generating code has mantis-line_count=32.
mantis-last_block and mantis-finished_block iterates over [0 to 16].

These counters are confusing. It takes lots of time to look and debug to
understand
what is happening there even for me :(

Basic example how the 64K garbage generation happens:
At mantis_dma_start, mantis-last_block = mantis-finished_block = 0
1st DMA transfer (2048 bytes) generates interrupt, sets
mantis-finished_block=15.
Tasklet will call mantis_dma_xfer(), which iterates from
mantis-last_block = 0 to mantis-finished_block = 14. Set last_block=15.
2nd DMA transfer of 2048 bytes goes quietly (no interrupt generated),
race with the tasklet above here.
3rd DMA transfer sets mantis-finished_block = 0, mantis_dma_xfer()
copies mantis-finished_block = 15. Set last_block=0.
After this copying continues from block 0, so the content is valid,
although block 0 was already partly copied.

Because the current looping implementation is too hard to understand,
I decided to rewrite it and not give you any small patch that fixes the
issue but nobody else understands it.
This doesn't have the alignment stuff at all that I mentioned in earlier
emails last week.

Basic idea:
Keep DMA buffer of size 64k, but generate interrupts four times, thus
one interrupt per 16k.
Rename mantis-finished_block to be mantis-busy_block, because that
keeps mantis_dma_xfer() simple:
while(mantis-last_block != mantis-busy_block) { do copy, last_block =
(last_block + 1) mod 4.
last_block is thus incremented until last_block == busy_block, which
can't be copied yet.

DMA RISC code generation: outer loop iterates over blocks from 0 to 4.
Inner loop iterates over DMA transfer units from 0 to
MANTIS_DMA_TR_UNITS, each DMA transfer is 2048 bytes.
The interrupt is generated at block[0], DMA unit 0: the block 0 is now
busy :)

mantis-line_bytes, mantis-line_count and mantis-risc_pos
were used only for DMA risc code generation.
Removed them from the structure.

Benefits of this code:
- Removes the 64k garbage issue.
- Remove race condition with concurrent DMA transfer and memory copy.
- Lessen interrupts to about 350 per second (seen by powertop) by
  moving 16k bytes per interrupt, instead of 4k per interrupt.
  The number of interrupts gets much smaller, and it becomes possible
with single core AMD cpu to
  deliver h.264 data over the network from vdr via streamdev.
- Mantis DMA code is more understandable for reviewers and others.

My patch is GPLv2.
The patch is made against GIT linuxtv/master, applies cleanly to
Mercurial v4l-dvb too.

Best regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/hopper_cards.c
b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc7..3b7e376 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void
*dev_id)
 }
 if (stat  MANTIS_INT_RISCI) {
 dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
 tasklet_schedule(mantis-tasklet);
 }
 if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c
b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39f..8f048d5 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void
*dev_id)
 }
 if (stat  MANTIS_INT_RISCI) {
 dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
 tasklet_schedule(mantis-tasklet);
 }
 if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h
b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a..23b23b7 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis

Re: buffer management

2010-06-30 Thread Marko Ristola
23.06.2010 15:43, Steven Toth kirjoitti:
 Now, on each video interrupt, I know which SG list i need to read
 from. At this stage i do need to copy the
 buffers associated with each of the SG lists at once. In this
 scenario, I don't see how videobuf could be used,
 while I keep getting this feeling that a simple copy_to_user of the
 entire buffer could do the whole job in a
 better way, since the buffers themselves are already managed and
 initialized already. Am I correct in thinking
 so, or is it that I am overlooking something ?

I've thought this a bit. I didn't find any good easy solution for
copying directly into users pace.


Here are the easiest trivial speed improvements I found:
dvb_core: dvb_dmx_swfilter(_204) functions:
- avoid unnecessary packet copying.
- I emailed those patches. You can see the difference with perf top
easilly
  (Fedora at least has perf).
  So with this the copying into ringbuffer remains as an unnecessary thing.
Mantis: Don't do busy looping on mantis_i2c.c


Harder algorithm that does only copy_to_user(), but avoids ring buffer
copying too:

Here is an algorithm that how you could do just the copy_to_user() from
the DMA buffer directly rather safely.
The algorithm is for 204 sized packets, but is
trivial to convert for 188 sized packets too.

I don't know if this is worth it though.

I found with Mantis that packets from DMA aren't always sized as 204
bytes (random sized garbage).
Even with this, you could do 204 - 188 conversion, without moving data:
1. Reserve first 256 bytes of each 4K DMA buffer page outside of the DMA
transfer.
2. DMA of buf[0][256 - 4095].
3. Do 204 - 188 conversion for buf[0][256 - 4095].
4. Copy remaining overflowed 45 bytes into buf[1][256 - 45], just
before second DMA start.
5. Deliver an array of pointers for 188 sized packets for
dvb_dmx_swfilter_nocopy_packets().
6. DMA of buf[1][256 - 4095].
7. Do 204 - 188 conversion for buf[1][(256 - 45) - 4095].
8. Copy remaining overflowed 25 bytes into buf[2][256 - 25], just
before third DMA start.
9. Deliver a second array of pointers for 188 sized packets for
dvb_dmx_swfilter_nocopy_packets().

dvb_dmx_swfilter_nocopy_packets would then have to deliver just the
pointers with sizes
into a new style ring buffer.

Then you would wake up the waiting ringbuffer reader, and it would
do the copy_to_user() as is done now.

Some or most of the DMA buffer management could be in dvb_core/ side,
because it is so generic.
On Mantis side, you must grab DMA interrupt and call a function like
dvb_dmabuf_set_busy_buf(bufno).
Other thing is, that you must traverse DMA buffers for RISC programming,
like:
for (i=0; i  dvb_dmabuf_count(dmabuf); i++) {
RISC_DMA(dvb_dmabuf_dma_pos(dmabuf, i) | MAKE_IRQ);
}
RISC_JUMP(risc_dma);
   
Other buffer management code isn't driver specific.

One possible problem that remains with this approach, is that what if
the DMA buffer gets overwritten?
Then the pointers in the ringbuffer might become garbage.

Another possible (cache coherency) problem is, that in this scenario
you both read and write to the DMA buffer.
Maybe with x86 computers this isn't a problem:
you never have to modify the same cache line
from both the DMA side and tasklet side at the same time.

Best regards,
Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Mantis DMA interrupt with FTRGT flag?

2010-06-28 Thread Marko Ristola

Hi Manu.

Here is Mantis debug messages at verbose level 7:

Jun 28 20:01:53 koivu kernel: -- Stat=3c0a Mask=802
--DMAFTRGTRISCIUnknown Stat=3000 Mask=802
Jun 28 20:01:53 koivu kernel: mantis_dma_xfer (0): last block=[2]
finished block=[3]
Jun 28 20:01:53 koivu kernel: demux: skipped 148 bytes at 9497: 00 ..
Jun 28 20:01:53 koivu kernel: TS packet counter mismatch. PID=0x2b2
expected 0xa got 0xb

What FTRGT message means?

Those errors come seemingly randomly at blocks 0, 1, 2 and 3:
56 Stat=2000
68
71 Stat=1000
73 Stat=3000

So above, Stat= is hidden.

With bttv, FTRGT means something like FIFO overflow.
How can I make the error more rare?

Regards,
Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function

2010-06-27 Thread Marko Ristola

Hi

Here is an improved version of the original patch:
The original patch removed unnecessary copying for 204 sized packets only.
This patch improves performance for 188 sized packets too.

Unnecessary copying means: if dvb_dmx_swfilter(_204)() doesn't have to
modify
the source packet, the source packet is delivered for
dvb_dmx_swfilter_packet()
without copying.

This assumes, that a DMA transfer won't modify the accepted 188/204 sized
packet underneath while dvb_dmx_swfilter_packet() processes it.
The assumption is already in dvb_dmx_swfilter_packets().

With tasklets the risk for breaking the assumption is low. If there
would be
a normal thread instead of a tasklet, copying from the DMA buffer might
come too late.

Could someone test this patch who uses the dvb_dmx_swfilter() function
(188 sized)?

So _dvb_dmx_swfilter is now common for both 188 and 204 sized packet
parsing.
The measure was done during recording of H.264 steram under VDR,
using perf top -d 10

   PerfTop:  62 irqs/sec  kernel:80.6% [1000Hz cycles],  (all, 1 CPUs)

 samples  pcnt
functionDSO

  339.00 18.1%
dvb_dmx_swfilter_packet
[dvb_core]   
  315.00 16.9%
acpi_pm_read   
[kernel.kallsyms]
   70.00  3.7%
_ZN2SI5CRC325crc32EPKcij   
/usr/sbin/vdr
   53.00  2.8%
mantis_i2c_xfer
[mantis_core]
   53.00  2.8%
__mktime_internal  
/lib64/libc-2.12.so  
   39.00  2.1%
_ZN14cAudioRepacker6RepackEP17cRingBufferLinearPKhi
/usr/sbin/vdr
   33.00  1.8%
delay_tsc  
[kernel.kallsyms]
   30.00  1.6%
dvb_dmx_memcopy
[dvb_core]   
   28.00  1.5%
dvb_ringbuffer_write   
[dvb_core]   
   28.00  1.5%
_dvb_dmx_swfilter  
[dvb_core]   


diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba..2dd 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,95 +478,78 @@ void dvb_dmx_swfilter_packets(struct dvb_demux
*demux, const u8 *buf,
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int findNextSyncByte(const u8 *buf, int pos, size_t
count, const int pktsize)
+{
+while(likely(pos  count)) {
+if (likely(buf[pos] == 0x47 || (pktsize == 204  buf[pos] ==
0xB8)))
+break;
+pos++;
+}
+
+return pos;
+}
+
+/* pktsize must be either 204 or 188. If pktsize is 204, 0xB8 must be
accepted for SYNC byte too, but then convert it into 0x47.
+ * Designed pktsize so, that compiler would remove 204 related code
during inlining. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8
*buf, size_t count, const int pktsize)
 {
 int p = 0, i, j;
+const u8 *q;
 
 spin_lock(demux-lock);
 
-if (demux-tsbufp) {
+if (likely(demux-tsbufp)) { /* tsbuf[0] is now 0x47. */
 i = demux-tsbufp;
-j = 188 - i;
-if (count  j) {
+j = pktsize - i;
+if (unlikely(count  j)) {
 memcpy(demux-tsbuf[i], buf, count);
 demux-tsbufp += count;
 goto bailout;
 }
 memcpy(demux-tsbuf[i], buf, j);
-if (demux-tsbuf[0] == 0x47)
+if (likely(demux-tsbuf[0] == 0x47)) /* double check */
 dvb_dmx_swfilter_packet(demux, demux-tsbuf);
 demux-tsbufp = 0;
 p += j;
 }
 
-while (p  count) {
-if (buf[p] == 0x47) {
-if (count - p = 188) {
-dvb_dmx_swfilter_packet(demux, buf[p]);
-p += 188;
-} else {
-i = count - p;
-memcpy(demux-tsbuf, buf[p], i);
-demux-tsbufp = i;
-goto bailout;
-}
-} else
-p++;
+while (likely((p = findNextSyncByte(buf, p, count, pktsize)) 
count)) {
+if (unlikely(count - p  pktsize))
+break;
+
+q = buf[p];
+
+if (unlikely(pktsize == 204  (*q == 0xB8))) {
+memcpy(demux-tsbuf, q, 188);
+demux-tsbuf[0] = 0x47;
+q = demux-tsbuf;
+}
+

Re: TS discontinuity with TT S-2300

2010-06-27 Thread Marko Ristola
27.06.2010 15:37, Oliver Endriss wrote:
 Hi,

 On Sunday 27 June 2010 01:05:57 Jaroslav Klaus wrote:
   
 Hi,

 I'm loosing TS packets in my dual CAM premium TT S-2300 card 
 (av7110+saa7146).

 I use dvblast to select 4 TV channels (~ 16 PIDs) from multiplex,
 descramble them and stream them to network. Dvblast reports TS
 discontinuity across all video PIDs only (no audio) usually every
 1-3 minutes ~80 packets. But sometimes it goes well for tens of
 minutes (up to 1-2hours). Everything seems to be ok with 3 TV channels.

 
 The full-featured cards are not able to deliver the full bandwidth of a
 transponder. It is a limitaion of the board design, not a firmware or
 driver issue.
   
I noticed that saa7146 uses dvb_dmx_swfilter_packets().

I planned using of that function too for
Mantis 16K buffer delivery, but I found out that
hardware delivers sometimes additional bytes (corrupted partially lost
packets?)
between the full sized 204 byte packets:

Jun 26 16:20:37 koivu kernel: demux: skipped 49 bytes at position 3379
Jun 26 16:20:37 koivu kernel: demux: skipped 18 bytes at position 9868
Jun 26 16:20:37 koivu kernel: demux: skipped 30 bytes at position 10090
Jun 26 16:20:38 koivu kernel: demux: skipped 14 bytes at position 7208
Jun 26 16:20:38 koivu kernel: demux: skipped 114 bytes at position 7426

So dvb_dmx_swfilter(_204)() is needed to skip
these unwanted bytes. With simple usage of
dvb_dmx_swfilter_packets() the rest of the buffer
would have been lost. I wrote a faster version of these
functions, also for 188 sized packets today:
Re: [PATCH] Avoid unnecessary data copying inside
dvb_dmx_swfilter_204() function

CU
Marko


--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function

2010-06-27 Thread Marko Ristola

Hi

dvb_dmx_swfilter(_204) performance improvement, with packet recovery.

Remove unnecessary copying of 188 and 204 sized packets within
dvb_dmx_swfilter() and dvb_dmx_swfilter_204() functions.
Recover one packet by backtracking, when there is a short packet
with a correct SYNC byte in the middle.



This patch tries to recover with backtracking one 188 / 204
sized packet if some garbage is found.

The backtracking recovery case, DVB data:
Packet Num, Packet data
10x47 +  99 bytes garbage
20x47 + 187 bytes data
30x47 + 187 bytes data

Recovery algorithm:
First packet 1's 0x47 is found. Process it, advance 188 bytes.
Find next SYNC byte, packet 3 found.
Check packet 3 position - 188: is there a packet?
yes, return packet 2.
Advance 188 bytes, return packet 3.

Jun 27 20:44:59 koivu kernel: demux: backtracked 137 bytes into position 442
Jun 27 20:44:59 koivu kernel: demux: backtracked 28 bytes into position 2250
Jun 27 20:45:02 koivu kernel: demux: backtracked 35 bytes into position 2634
Jun 27 20:45:02 koivu kernel: demux: backtracked 12 bytes into position 1398
Jun 27 20:45:03 koivu kernel: demux: skipped 146 bytes at position 378: 
09 93 ...
Jun 27 20:45:03 koivu kernel: demux: backtracked 177 bytes into position 551
Jun 27 20:45:03 koivu kernel: demux: skipped 14 bytes at position 959: 
6c 1e ...
Jun 27 20:45:03 koivu kernel: demux: backtracked 191 bytes into position 986

Regards,
Marko Ristola

diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba..b71d77d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,97 +478,96 @@ void dvb_dmx_swfilter_packets(struct dvb_demux
*demux, const u8 *buf,
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int findNextPacket(const u8 *buf, int pos, size_t count,
+   const int pktsize)
 {
-int p = 0, i, j;
+int start = pos, lost;
 
-spin_lock(demux-lock);
-
-if (demux-tsbufp) {
-i = demux-tsbufp;
-j = 188 - i;
-if (count  j) {
-memcpy(demux-tsbuf[i], buf, count);
-demux-tsbufp += count;
-goto bailout;
-}
-memcpy(demux-tsbuf[i], buf, j);
-if (demux-tsbuf[0] == 0x47)
-dvb_dmx_swfilter_packet(demux, demux-tsbuf);
-demux-tsbufp = 0;
-p += j;
+while(likely(pos  count)) {
+if (likely(buf[pos] == 0x47 ||
+(pktsize == 204  buf[pos] == 0xB8)))
+break;
+pos++;
 }
 
-while (p  count) {
-if (buf[p] == 0x47) {
-if (count - p = 188) {
-dvb_dmx_swfilter_packet(demux, buf[p]);
-p += 188;
-} else {
-i = count - p;
-memcpy(demux-tsbuf, buf[p], i);
-demux-tsbufp = i;
-goto bailout;
-}
-} else
-p++;
+if (unlikely(lost = pos - start)) {
+/* This garbage is part of a valid packet? */
+int backtrack = pos - pktsize;
+if (backtrack = 0  (buf[backtrack] == 0x47 ||
+(pktsize == 204  buf[backtrack] == 0xB8))) {
+/* printk(demux: backtracked %d bytes
+ * \n, start - backtrack); */
+return backtrack;
+}
+/*printk(demux: skipped %d bytes at %d\n, lost, start); */
 }
 
-bailout:
-spin_unlock(demux-lock);
+return pos;
 }
 
-EXPORT_SYMBOL(dvb_dmx_swfilter);
-
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
size_t count)
+/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8
*buf,
+size_t count, const int pktsize)
 {
 int p = 0, i, j;
-u8 tmppack[188];
+const u8 *q;
 
 spin_lock(demux-lock);
 
-if (demux-tsbufp) {
+if (likely(demux-tsbufp)) { /* tsbuf[0] is now 0x47. */
 i = demux-tsbufp;
-j = 204 - i;
-if (count  j) {
+j = pktsize - i;
+if (unlikely(count  j)) {
 memcpy(demux-tsbuf[i], buf, count);
 demux-tsbufp += count;
 goto bailout;
 }
 memcpy(demux-tsbuf[i], buf, j);
-if ((demux-tsbuf[0] == 0x47) || (demux-tsbuf[0] == 0xB8)) {
-memcpy(tmppack, demux-tsbuf, 188);
-if (tmppack[0] == 0xB8)
-tmppack[0] = 0x47;
-dvb_dmx_swfilter_packet(demux, tmppack);
-}
+if (likely(demux-tsbuf[0] == 0x47)) /* double check */
+dvb_dmx_swfilter_packet(demux, demux-tsbuf);
 demux-tsbufp = 0;
 p += j;
 }
 
-while (p  count) {
-if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
-if (count - p = 204

Re: TS discontinuity with TT S-2300

2010-06-27 Thread Marko Ristola
27.06.2010 21:25, Oliver Endriss wrote:
 Are you sure that Mantis driver delivers garbage, not partial packets?
 Please note that the dvb_dmx_swfilter[_204]() routines must accept
 partial packets, i.e. the rest of the packet will be dellivered with the
 next call.
   
Yes, I'm sure that the garbage comes from the PCI device itself:
garbage should be found at less than 204 byte position otherwise.

My latest mailed patch that I use makes sure 0x47 is found at
demux-tsbufp[0],
if there is at least one spared byte. Otherwise the resulting 188 sized
packet would be discarded eventually.

It would be good if Mauro would accept my patch for dvb_dmx_swfilter(_204)
functions some day. It increases robustness with garbage input, and
performance by avoiding unnecessary packet copying.

 dvb_dmx_swfilter_packets() expects complete TS packets from the driver.
 The saa7146 does so. It does not deliver garbage data. (Otherwise this
 would have been noticed a long time ago. The ttpci drivers are the
 oldest DVB drivers and are very well tested.)
   
I'm very sorry I even questioned ttpci's and the hardware's robustness.

I'm delighted to hear that ttpci is so well implemented and tested and
so long :)
I was very impressed in the quality of the code with
dvb_dmx_swfilter_packets():
so simple and efficient.

Unfortunately I have had lots of problems with Mantis.
But because of that, I've learned DVB driver programming.

H.264 works now mostly in one TV channel without crashing Xine with
remote vdr.
I had to modify streamdev plugin too for vdr.

CU
Marko

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Avoid unnecessary data copying inside dvb_dmx_swfilter_204() function

2010-06-26 Thread Marko Ristola

Hi Mauro Carvalho Chehab.

I'm sorry for sending this twice. I Don't know yet how to disable HTML
formatting permanently.

This patch does a significant performance improvement (for the function
involved)
by avoiding move of 188 sized packets during 204 to 188 packet conversion.
Also this has a robustness fix at discontinuity points of DMA transfer
blocks.
I have tested that this code works.


While using perf top, I noticed that there were two functions that
used CPU:
One was dvb_dmx_swfilter_packet and the other was dvb_dmx_swfilter_204.

dvb_dmx_swfilter_204 converts the packets from 204 byte format into 188
format.
It does so by copying the packet before modifications to it. I noticed
that it was a very rare case
(usually at most once in 16K data) when the SYNC byte had to be modified
from 0xB8 to 0x47.

So my modification does following things:
* Take a copy of the 188 or 204 bytes only if the packet must be
modified or backed up.
* Backing up last  204 bytes: store only data with the 1st byte as the
SYNC byte (0xB8 or 0x47).
   This is the robustness fix: back up a beginning of a real packet, not
some unknown data block.

During my testing, this loses some bytes occassionally because of some
garbage in DMA transferred data:
I measured the number of lost bytes in the inline function that searches
the next SYNC byte.
So the algorithm seems to work, usually there aren't many bursts of
skipped bytes after the stream has stabilized.
I wanted to know how many bytes are skipped and in which positions in
16K block:

Jun 26 16:20:37 koivu kernel: demux: skipped 49 bytes at position 3379
Jun 26 16:20:37 koivu kernel: demux: skipped 18 bytes at position 9868
Jun 26 16:20:37 koivu kernel: demux: skipped 30 bytes at position 10090
Jun 26 16:20:38 koivu kernel: demux: skipped 14 bytes at position 7208
Jun 26 16:20:38 koivu kernel: demux: skipped 114 bytes at position 7426
Jun 26 16:20:38 koivu kernel: demux: skipped 103 bytes at position 12920
Jun 26 16:20:38 koivu kernel: demux: skipped 72 bytes at position 13431
Jun 26 16:20:38 koivu kernel: demux: skipped 1 bytes at position 13707
Jun 26 16:20:45 koivu kernel: demux: skipped 140 bytes at position 8476
Jun 26 16:20:46 koivu kernel: demux: skipped 70 bytes at position 11396
Jun 26 16:20:46 koivu kernel: demux: skipped 8 bytes at position 11670
Jun 26 16:20:46 koivu kernel: demux: skipped 2 bytes at position 11882

I measured performance improvement with Perf top. The CPU was probably
mostly at 1Ghz and sometimes at 2Ghz,
so the actual number of samples changed randomly, but the relative
performance change between
unaltered dvb_dmx_swfilter_packet() and dvb_dmx_swfilter_204() is
significant (unrelated rows removed):
Testing was done with H.264 channel recording, and with Mercurial
version of v4l-dvb branch.
The patch below is done against v4l-dvb GIT version.

Original performance:
 samples  pcnt
functionDSO
   66.00 14.1%
dvb_dmx_swfilter_packet
[dvb_core]  
   59.00 12.6%
dvb_dmx_swfilter_204   
[dvb_core]  
   11.00  2.4%
mantis_i2c_xfer
[mantis_core]   

Performance after patching:
 samples  pcnt
functionDSO
   81.00 29.0%
dvb_dmx_swfilter_packet
[dvb_core] 
   14.00  5.0%
mantis_i2c_xfer
[mantis_core]  
8.00  2.9%
dvb_dmx_swfilter_204   
[dvb_core] 

So the relative performance has increased by a mangditude for
dvb_dmx_swfilter_204().

This patch is a modified version of the original dvb_dmx_swfilter_204().
I can give this patch for the Linux Kernel with license:

* This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.

as the original license in that file.

Patch written by: Marko Ristola marko.rist...@kolumbus.fi


Regards,
Marko Ristola


diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c
b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba..627d103 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -520,49 +520,60 @@ bailout:
 
 EXPORT_SYMBOL(dvb_dmx_swfilter);
 
+static inline int find204Sync(const u8 *buf, int pos, size_t count)
+{
+while(likely(pos  count)) {
+if (likely(buf[pos] == 0x47 || buf[pos] == 0xB8))
+break;
+pos

Re: [linux-dvb] Cinergy C PCI HD with current v4l-dvb - PATCH for review/pull included

2010-06-24 Thread Marko Ristola
22.06.2010 22:27, Yannick K wrote:
 On 6/19/10 15:56 , Marko Ristola wrote:

 Hello all interested in a robust Mantis driver.
 hi Marko,

 is there a hg/git branch where your (and possibly Bjorn Morks) recent
 patches are already in?
 since i had difficulties to apply some of them.

Unfortunately there isn't a private Git tree. I've now figured out that
Manu is the maintainer who
could take the patches in from me first.
Manu has some ongoing work to modify the DMA transfer by using different
buffering scheme.
So he will do the rework, and the changes will go into jusst.de. It
seems that my version won't
go in.

What hg/Git tree you tried to use to apply our patches?
I can send you another patch against that.

 further more, is there a way/patch for the current tree which gives us
 a working remote control?
Maybe Manu's jusst.de HG tree? I have been trying to get a working H.264
picture,
and the remote control isn't so urgent for me.

Regards,
Marko

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: buffer management

2010-06-23 Thread Marko Ristola

23.06.2010 15:43, Steven Toth kirjoitti:

Now, on each video interrupt, I know which SG list i need to read
from. At this stage i do need to copy the
buffers associated with each of the SG lists at once. In this
scenario, I don't see how videobuf could be used,
while I keep getting this feeling that a simple copy_to_user of the
entire buffer could do the whole job in a
better way, since the buffers themselves are already managed and
initialized already. Am I correct in thinking
so, or is it that I am overlooking something ?


How to activate DMA transfers only if there is empty space for the DMA 
transfer?


Regards,
Marko



Manu,

SAA7164 suffers from this. If you find a solution I'd love to hear it.

Regards,

- Steve



--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Mantis, hopper: use MODULE_DEVICE_TABLE use the macro to make modules auto-loadable

2010-06-21 Thread Marko Ristola

21.06.2010 19:51, Bjørn Mork wrote:

VDR Useruser@gmail.com  writes:

   

Instead of copypaste patches from Manu's tree, maybe it's better to
just wait for him to push all the changes into v4l.
 
   


I'm Manu sorry about trying to put patches directly into v4-dvb, if 
those should go onto your branch first.


So, what Manu do you think about my DMA patch or other patches I sent 
into linux-media mailing list this weekend?

Is it okay to generate one interrupt once per 16k bytes,
or are the interrupts too rare?

At least VDR reads the DVB stream rarely, so I think
that it is enough if the DVB card has always something
to be delivered when VDR or MythTV asks more data,
so if the number of DMA transfer IRQs is twice than the
number of times VDR or MythTV asks more data per second,
then the context switches are in balance.

Understandable DMA RISC programming should be easier to maintain, and it 
removes the initial garbage from the stream too.


How about the tasklet enable/disable patch I wrote?

What needs to be done for these patches to be accepted?

Best regards,
Marko


--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Mantis DMA transfer cleanup, fixes data corruption and a race, improves performance.

2010-06-20 Thread Marko Ristola


Hi

Here is another version of the DMA transfer fix.
Please try it. Comments?

The current DMA code with drivers/media/dvb/mantis/mantis_dma.c has user 
visible problems:
- about 1500 interrupts per second. One CPU can't copy h.264 data over 
the network for me (vdr, streamdev).
- 64K garbage at start of the data stream, part of which goes into User 
land application.
The garbage data is partly from the same stream (given twice), and 
partly from previous tuned frequency (buffer

uninitialized at DMA start).
- Race condition: Memory copying from DMA buffer is done at the same 
time as there is DMA transfer going on to the same bytes.

Can this race cause harware problems?

Current DMA code is not clear:
Current DMA RISC coding creates one DMA transfer per 2048 bytes.
Risc command generating code has mantis-line_count=32.
mantis-last_block and mantis-finished_block iterates over [0 to 16].

These counters are confusing. It takes lots of time to look and debug to 
understand

what is happening there even for me :(

Basic example how the 64K garbage generation happens:
At mantis_dma_start, mantis-last_block = mantis-finished_block = 0
1st DMA transfer (2048 bytes) generates interrupt, sets 
mantis-finished_block=15.
Tasklet will call mantis_dma_xfer(), which iterates from 
mantis-last_block = 0 to mantis-finished_block = 14. Set last_block=15.
2nd DMA transfer of 2048 bytes goes quietly (no interrupt generated), 
race with the tasklet above here.
3rd DMA transfer sets mantis-finished_block = 0, mantis_dma_xfer() 
copies mantis-finished_block = 15. Set last_block=0.
After this copying continues from block 0, so the content is valid, 
although block 0 was already partly copied.


Because the current looping implementation is too hard to understand,
I decided to rewrite it and not give you any small patch that fixes the 
issue but nobody else understands it.
This doesn't have the alignment stuff at all that I mentioned in earlier 
emails last week.


Basic idea:
Keep DMA buffer of size 64k, but generate interrupts four times, thus 
one interrupt per 16k.
Rename mantis-finished_block to be mantis-busy_block, because that 
keeps mantis_dma_xfer() simple:
while(mantis-last_block != mantis-busy_block) { do copy, last_block = 
(last_block + 1) mod 4.
last_block is thus incremented until last_block == busy_block, which 
can't be copied yet.


DMA RISC code generation: outer loop iterates over blocks from 0 to 4.
Inner loop iterates over DMA transfer units from 0 to 
MANTIS_DMA_TR_UNITS, each DMA transfer is 2048 bytes.
The interrupt is generated at block[0], DMA unit 0: the block 0 is now 
busy :)


mantis-line_bytes, mantis-line_count and mantis-risc_pos
were used only for DMA risc code generation.
Removed them from the structure.

Benefits of this code:
- Removes the 64k garbage issue.
- Remove race condition with concurrent DMA transfer and memory copy.
- Lessen interrupts to about 350 per second (seen by powertop) by
  moving 16k bytes per interrupt, instead of 4k per interrupt.
  The number of interrupts gets much smaller, and it becomes possible 
with single core AMD cpu to

  deliver h.264 data over the network from vdr via streamdev.
- Mantis DMA code is more understandable for reviewers and others.

My patch is GPLv2.
The patch is made against GIT linuxtv/master, applies cleanly to 
Mercurial v4l-dvb too.


Best regards,
Marko Ristola

diff --git a/drivers/media/dvb/mantis/hopper_cards.c 
b/drivers/media/dvb/mantis/hopper_cards.c

index 09e9fc7..3b7e376 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void 
*dev_id)

 }
 if (stat  MANTIS_INT_RISCI) {
 dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
 tasklet_schedule(mantis-tasklet);
 }
 if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c 
b/drivers/media/dvb/mantis/mantis_cards.c

index cf4b39f..8f048d5 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void 
*dev_id)

 }
 if (stat  MANTIS_INT_RISCI) {
 dprintk(MANTIS_DEBUG, 0, %s, label[8]);
-mantis-finished_block = (stat  MANTIS_INT_RISCSTAT)  28;
+mantis-busy_block = (stat  MANTIS_INT_RISCSTAT)  28;
 tasklet_schedule(mantis-tasklet);
 }
 if (stat  MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h 
b/drivers/media/dvb/mantis/mantis_common.h

index d0b645a..23b23b7 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -122,11 +122,8 @@ struct mantis_pci {
 unsigned intnum;

 /*RISC Core*/
-u32finished_block;
+u32

[PATCH] Mantis: append tasklet maintenance for DVB stream delivery

2010-06-20 Thread Marko Ristola


Hi

I have a patch that should fix possible memory corruption problems in 
Mantis drivers

with tasklets after DMA transfer has been stopped.
In the patch tasklet is enabled only for DVB stream delivery, at end of 
DVB stream delivery tasklet is disabled again.
The lack of tasklet maintenance might cause problems with following 
schedulings:


1. dvb_dmxdev_filter_stop() calls mantis_dvb_stop_feed: mantis_dma_stop()
2. dvb_dmxdev_filter_stop() calls release_ts_feed() or some other filter 
freeing function.
3. tasklet: mantis_dma_xfer calls dvb_dmx_swfilter to copy DMA buffer's 
content into freed memory, accessing freed spinlocks.

This case might occur while tuning into another frequency.
Perhaps cdurrhau has found some version from this bug at 
http://www.linuxtv.org/pipermail/linux-dvb/2010-June/032688.html:

 This is what I get on the remote console via IPMI:
 40849.442492] BUG: soft lockup - CPU#2 stuck for 61s! [section
 handler:4617]


The following schedule might also be a problem:
1. mantis_core_exit: mantis_dma_stop()
2. mantis_core_exit: mantis_dma_exit().
3. run tasklet (with another CPU?), accessing memory freed by 
mantis_dma_exit().

This case might occur with rmmod.

The following patch tries to deactivate the tasklet in mantis_dma_stop 
and activate it in mantis_dma_start, thus avoiding these cases.


Marko Ristola


diff --git a/drivers/media/dvb/mantis/mantis_dma.c 
b/drivers/media/dvb/mantis/mantis_dma.c

index 46202a4..cf502a6 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -217,12 +217,14 @@ void mantis_dma_start(struct mantis_pci *mantis)
 mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN
| MANTIS_RISC_EN, MANTIS_DMA_CTL);

+tasklet_enable(mantis-tasklet);
 }

 void mantis_dma_stop(struct mantis_pci *mantis)
 {
 u32 stat = 0, mask = 0;

+tasklet_disable(mantis-tasklet);
 stat = mmread(MANTIS_INT_STAT);
 mask = mmread(MANTIS_INT_MASK);
 dprintk(MANTIS_DEBUG, 1, Mantis Stop DMA engine);
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c 
b/drivers/media/dvb/mantis/mantis_dvb.c

index 99d82ee..0c29f01 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -216,6 +216,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)

 dvb_net_init(mantis-dvb_adapter, mantis-dvbnet, 
mantis-demux.dmx);
 tasklet_init(mantis-tasklet, mantis_dma_xfer, (unsigned long) 
mantis);

+tasklet_disable_nosync(mantis-tasklet);
 if (mantis-hwconfig) {
 result = config-frontend_init(mantis, mantis-fe);
 if (result  0) {
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Mantis: append tasklet maintenance for DVB stream delivery

2010-06-20 Thread Marko Ristola

20.06.2010 16:51, Bjørn Mork kirjoitti:

Note that mantis_core_exit() is never called.  Unless I've missed
something, the drivers/media/dvb/mantis/mantis_core.{h,c} files can
just be deleted.  They look like some development leftovers?

   

I see. mantis_core.ko kernel module exists though.
Maybe the mantis/Makefile references for mantis_core.c, mantis.c and 
hopper.c are just some leftovers too.


I moved tasklet_enable/disable calls into mantis_dvb.c where almost all 
other tasklet code is located.


So the following reasoning still holds:

1. dvb_dmxdev_filter_stop() calls mantis_dvb_stop_feed: mantis_dma_stop()
2. dvb_dmxdev_filter_stop() calls release_ts_feed() or some other filter 
freeing function.
3. tasklet: mantis_dma_xfer calls dvb_dmx_swfilter to copy DMA buffer's 
content into freed memory, accessing freed spinlocks.

This case might occur while tuning into another frequency.
Perhaps cdurrhau has found some version from this bug at 
http://www.linuxtv.org/pipermail/linux-dvb/2010-June/032688.html:

 This is what I get on the remote console via IPMI:
 40849.442492] BUG: soft lockup - CPU#2 stuck for 61s! [section
 handler:4617]


New reasoning for the patch (same as the one above, but from higher level):
After dvb-core has called mantis-fe-stop_feed(dvbdmxfeed) the last time 
(count to zero),
no data should ever be copied with dvb_dmx_swfilter() by a tasklet: the 
target structure might be in an unusable state.
Caller of mantis_fe-stop_feed() assumes that feeding is stopped after 
stop_feed() has been called, ie. dvb_dmx_swfilter()

isn't running, and won't be called.

There is a risk that dvb_dmx_swfilter() references freed resources 
(memory or spinlocks or ???) causing instabilities.
Thus tasklet_disable(mantis-tasklet) must be called inside of 
mantis-fe-stop_feed(dvbdmxfeed) when necessary.


Signed-off-by: Marko Ristola marko.rist...@kolumbus.fi

Marko

diff --git a/drivers/media/dvb/mantis/mantis_dvb.c 
b/drivers/media/dvb/mantis/mantis_dvb.c

index 99d82ee..a9864f7 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct 
dvb_demux_feed *dvbdmxfeed)

 if (mantis-feeds == 1) {
 dprintk(MANTIS_DEBUG, 1, mantis start feed  dma);
 mantis_dma_start(mantis);
+tasklet_enable(mantis-tasklet);
 }

 return mantis-feeds;
@@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct 
dvb_demux_feed *dvbdmxfeed)

 mantis-feeds--;
 if (mantis-feeds == 0) {
 dprintk(MANTIS_DEBUG, 1, mantis stop feed and dma);
+tasklet_disable(mantis-tasklet);
 mantis_dma_stop(mantis);
 }

@@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)

 dvb_net_init(mantis-dvb_adapter, mantis-dvbnet, 
mantis-demux.dmx);
 tasklet_init(mantis-tasklet, mantis_dma_xfer, (unsigned long) 
mantis);

+tasklet_disable(mantis-tasklet);
 if (mantis-hwconfig) {
 result = config-frontend_init(mantis, mantis-fe);
 if (result  0) {

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Cinergy C PCI HD with current v4l-dvb - PATCH for review/pull included

2010-06-19 Thread Marko Ristola

Hi Bjørn,

Thank you for your answer.

19.06.2010 18:34, Bjørn Mork kirjoitti:

[ I think this should have been posted to linux-media@vger.kernel.org instead ]

Marko Ristolamarko.rist...@kolumbus.fi  writes:

   

I am now subscribed into that list too, but maybe I start with the
small patches instead of the big patch.


Hello all interested in a robust Mantis driver.

I have done some Mantis DMA fixes about two to four years ago
into v4l-dvb/linux/drivers/dvb/media/mantis/mantis_dma.c,
but they were discarded then, but the problems remained.
Those fixes helped at least one individual with Cinergy C PCI HD card
too by lessening the number
of artifacts and making the card usable. I sent the patches for many
Finnish people at those years.
 

I find this very interesting.  I have two DVB-C cards, where one of them
is a Terratec Cinergy C, and I do see the occasional stuck CPUs.  Never
realized that the mantis driver might be the cause of that.
   

I can't see the spin lock bug because I have now only one CPU.
tasklet disable/enable is an easy thing to start bug exclusion.


For Mauro and other maintainers - the patch in this email is now
against current Mercurial http://linuxtv.org/hg/v4l-dvb branch.
What do you think about this patch? Could you apply it?
I accept that this code may be added to Linux Kernel, or somewhere
else, licensed as GPLv2.
This code is fully written by me (Marko Ristola).
Signed-off-by: Marko Ristolamarko.rist...@kolumbus.fi
 

I am not Mauro (or other maintainers :-), but I guess you will have a
much better chance getting this properly reviewed if you move to git,
split up the patch according to your very good 4 point description, and
use that description as a commit message for the patches.

This will also allow the rest of us to test the effect of each issue
independently.
   

Probably Mauro doesn't even be on the old list any more.
   

The patch does two things (other two things are just thoughts, related
to robustness):
1. Don't flush 64K garbage at stream start, occurs if mantis_dma_start
is run more than once.
This fix could be done with altering only about two lines of code by
fixing the broken DMA RISC program code.
(Bug description: At line[0] RISC IRQ will store line=15 on current
code, causing copying of lines between 0 and 14, and next time 15 from
previous DVB TS stream (total 64K garbage). After that line=0 contains
current stream, no garbage.
Bug fix description: RISC program must store at interrupt the active
line variable's value, instead of ( (line - 1) mod 16)).
 


This sounds like a real bug.  Maybe a candidate for stable as well?
   

Yes, this is a bug and it is easy to fix.

   

On my patch, it seems, that risc_step=0 point could be used for the
interrupt instead of risc_step=1, thus making the code a bit easier to
understand.

2. Alter DMA transfer so, that each DMA transfer copies only complete
packets (either 188 or 204 bytes) with each DMA transfer.
The hypothesis is that if a DMA transfer transfers only a part of the
188/204 sized packet,
that packet gets corrupted (last bytes of 2048 sized block).
My DMA transfers are aligned by 64 bytes in CPU memory (DMA buffer
start + multiple of 16x(188 or 204)).
 

I cannot really understand how such corruption could happen, unless
there are other bugs here?  And if there are, then anything hiding them
would be bad...
   

Mantis PCI card receives by radio 188/204 byte sized packets.
If there are CRC errors with those, they are counted by the PCI card.
If there are zero fatal CRC errors counted, but even then some packets 
are missing from a recording,

there is a serious problem between the radio and the disk storage.

The DMA transfer from PCI to CPU DMA buffer and the copying from CPU DMA 
buffer to generic v4l-dvb code
are the only Mantis specific tasks. All other is used so much, that they 
should be seen by everyone.


I'll try to proof it. If I can't prove it, no code is needed to fix it.

   

3. tasklet_enable/ tasklet_disable for DMA start/stop is commented out
on my patch.
I think that tasklet enabling maintenance should be done at these
points, but I don't know
whether the lack of those might cause spin lock failures. Lack of
these might
cause problems while switching channels (EPG search switches frequency).
 

Sounds reasonable.  Did you try it?

   

I didn't have time yet, thus I commented it out.

   

4. There is some problem with rmmod mantis, do lsmod:
Module  Size  Used by
tda100215486  4294967291
modprobe mantis
tda100215486  4294967292 mantis
So the reference count from mantis to tda10021 gets corrupted at rmmod.
I have Fedora 13 kernel, 2.6.33.5-124.fc13.x86_64
 

FWIW, I do not see this running a Debian kernel (2.6.32-5-amd64) with a
backported mantis driver (from 2.6.35-rc1).

Module  Size  Used by
tda100214774  1 mantis
# rmmod mantis
tda100214774  0
# modprobe

Re: Cinergy C PCI HD with current v4l-dvb - PATCH for review/pull included

2010-06-19 Thread Marko Ristola


Proving the DMA transfer alignment problem existence isn't easy.
So maybe it doesn't exist.

I saw only very rare packet losses on picture quality (didn't test h264 
this time).

I couldn't do the record test though. Too much work.

Marko Ristola

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html