Oops, forgot to "Reply All"...

- Rob

________________________________
From: Tivy, Robert
Sent: Wednesday, December 30, 2009 10:57 AM
To: 'Erez Kinarti'
Subject: RE: Cmem address translation when working with Codec Engine

Erez,

Thanks for your detailed explanation, it allows me to understand your problem 
and the solution.

The bottom line is that you should be using CE's Memory module to allocate CMEM 
memory.  This will alleviate your wrong phys addr to the DSP.  If you want to 
continue using CMEM_alloc/free, then you can remove CE's cached virt->phys 
translation with:
    Memory_unregisterContigBuf(virtAddr, 258048);

The reason you need to use CE's Memory module is because the codec class stub 
file is using it to get the phys addr of a virt buffer.  What happens when you 
allocate outside of Memory is the following:
    - allocate with CMEM_alloc(), which causes the kernel to create the 
virt-phys mapping (there is no table in CMEM).
    - pass this buffer to <CODECCLASS>_process()
    - <CODECCLASS>_process() calls Memory_getBufferPhysicalAddress(virtAddr)
    - the Memory module keeps a cache of virt->phys mappings, and since Memory 
hasn't seen this buffer before, it asks CMEM with CMEM_getPhys().
    - CMEM returns the correct phys addr and Memory caches this mapping.
    - you free the buffer, which frees the kernel mapping for it, then allocate 
a new one, and the Linux kernel creates a new mapping
    - the Linux kernel decides to reuse the same virt addr from before, but 
this time with a different phys addr
    - <CODECCLASS>_process() calls Memory_getBufferPhysicalAddress(virtAddr)
    - since Memory module didn't know about the freeing of the previous buffer, 
it uses its old cached translation.

To allocate CMEM through Memory:
      Memory_AllocParams params;

    params.type = Memory_CONTIGPOOL;
    params.flags = Memory_CACHED; // or Memory_NONCACHED if so desired
    addr = Memory_alloc(258048, &params);
    ...
    Memory_free(addr, 258048, &params);

Regards,

- Rob



________________________________
From: Erez Kinarti [mailto:[email protected]]
Sent: Wednesday, December 30, 2009 12:10 AM
To: Tivy, Robert; Amit Klir; [email protected]
Subject: RE: Cmem address translation when working with Codec Engine

Hello Rob,

I'm working with Amit on the same problem.
Thank you very much for your quick answer and willing to help.

We take the buffers directly from Cmem pool.
We have a pool of 3x258048 in cmem (three buffers with size 258048), and we 
take one of the buffers from CMEM directly using CMEM_alloc.
We do it only once for the speech codec, and this buffer is the only buffer 
used by us as for output buffer.
After we close the codec (SPHENC_delete), we release the buffer back to CMEM 
directly using CMEM_free.
All the CMEM allocation and free is done directly with CMEM and NOT via 
CodecEngine.

In our case, after closing the codec and releasing the buffer, we want to 
reopen the codec.
What we do is getting a new buffer from CMEM directly using CMEM_alloc, and 
then opening the codec using SPHENC_create.

Another issue that is important is that in the second time, we get from CMEM a 
buffer with the same virtual address as the first buffer, just with different 
physical address. It seems like CMEM changed the virtual to physical mapping.
However, when calling the DSP, it seems like CE is using the same mapping as in 
the first time which is no longer valid, and the DSP codec is getting a pointer 
to the physical buffer used in the first time.

Is it possible that CMEM is changing the address translation mapping and CE is 
not synchronized with it and is using its old virt-to-phy mapping.


Our main question:
===============
What action should we do in order to synchronize the virt-to-phys cache in CE's 
Memory module with the CMEM virtual to physical mapping?
Is there any CE command that tells CE to invalidate its virt-to-phys cache and 
take the updated values from CMEM?

Thanks,
Erez



From: Tivy, Robert [mailto:[email protected]]
Sent: Tuesday, December 29, 2009 7:52 PM
To: Amit Klir; [email protected]
Cc: Erez Kinarti
Subject: RE: Cmem address translation when working with Codec Engine

How are you "returning CMEM buf to the pool" for each codec thread?

CE contains a virt-to-phys cache in CE's Memory module, and a CE codec class 
stubs file will use the Memory module to translate the virt addr to a phys 
addr.  If CMEM buffer allocation is happening through the Memory module but 
CMEM buffer freeing is done through just CMEM then this situation can happen.

There is no known problem in CMEM 2.10 of this sort, however CMEM 2.10 is older 
and I believe you could upgrade to LinuxUtils 2.25 which contains a later CMEM. 
 There is also a CE 2.25 that you could upgrade to.

In order for me to tell more of what's going on I would need to see some trace 
output from your application.  Later CE releases contain support for an 
environment variable called CE_DEBUG that can be set to 1|2|3.  Setting it to 3 
will generate lots of useful output (and lots of "noise" too, unfortunately).  
I don't recall if 2.10 supports CE_DEBUG or if that came after 2.10, if not 
then you would have to use CE_TRACE instead (which is documented).  If you can 
run your app with this trace output enabled and send it to me I can take a look.

Regards,

- Rob

________________________________
From: [email protected] 
[mailto:[email protected]] On Behalf Of 
Amit Klir
Sent: Tuesday, December 29, 2009 7:26 AM
To: [email protected]
Cc: Erez Kinarti
Subject: Cmem address translation when working with Codec Engine

Hello,

I'm working with DaVinci DM6467, using ARM running linux, and CodecEngine as 
the interface between ARM and DSP.

My application is doing audio and video encoding in parallel in two different 
threads.

I'm also using CMEM version 2.10 for continuous buffers allocation.

The problem is that, in some situation, the CMEM buffer physical address viewed 
by ARM (using CMEM_getPhys()) is different than the physical address sent to 
DSP (translated by CodecEngine).

Scenario where ArmPhyAddr != DspPhyAddr:

===================================

In my application, I open CodecEngine and then open two codecs on the DSP: 
VIDENC1 and SPHENC1.

In the beginning both codecs are running in two different threads, and for each 
of them we keep a CMEM buffers pool in ARM for their IO buffers.

When the app starts running, for each Codec it take a single buffer from the 
relevant Cmem pool, and use only this buffer for all the run.

In the beginning the physical addresses viewed by ARM and DSP are equal.

After a while, we do the following sequence of closing and opening the codecs:

1.      Close and open the video codec

-       VIDENC1_delete()

-       Return the CMEM buf of VIDENC to the pool.

-       Take a new CMEM buffer from the pool to be used for VIDENC.

-       VIDENC_create()

-       Running video processing of a stream ...

2.      Close and open the speech codec:

-       SPHENC1_delete()

-       Return the CMEM buf of SPHENC to the pool.

-       Take a new CMEM buffer from the pool to be used for SPHENC.

-       SPHENC_create()

-       Running speech processing of a stream ...

After doing this sequence and continue running the video and audio processing.

Now on the SPHENC codec,  the CMEM buffer physical address viewed by ARM is 
different than the one viewed by the DSP for the same buffer.

In addition I see that there is a constant offset between them which is the 
size of a CMEM buffer used for the speech (in our case 258048).

That means that the same virtual address in the ARM is translated in ARM to 
different physical address than the one translated by CodecEngine.

It seems like two different translation tables are used, and they are not 
synchronized.

Our CMEM pool for the speech usage is made of 3 buffers of size 258048.


Does anyone know what can cause this problem? To me it seems like CMEM problem, 
however, when checking in TI site I see that version 2_10 that I'm using is 
currently the official version.

Thanks in advance for any help,




_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to