Robin Getz | 14 Jul 2008 04:40
Favicon

get_user & put_user accessing L1

If no one has any objections, this adds L1 instruction support for 
put_user and get_user macros.

Index: asm-blackfin/uaccess.h
===================================================================
--- asm-blackfin/uaccess.h      (revision 4802)
+++ asm-blackfin/uaccess.h      (working copy)
 <at>  <at>  -18,6 +18,8  <at>  <at> 
 # include <asm/bfin-global.h>
 #endif

+#include <asm/dma.h>
+
 #define get_ds()        (KERNEL_DS)
 #define get_fs()        (current_thread_info()->addr_limit)

 <at>  <at>  -99,6 +101,10  <at>  <at> 
                if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
                        _err = -EFAULT;                         \
                }                                               \
+               else if ( unlikely(L1_CODE_LENGTH != 0 &&       \
+                                  (unsigned int)p >= L1_CODE_START &&  \
+                                  (unsigned int)p <= L1_CODE_START + L1_CODE_LENGTH))  \
+                       dma_memcpy(_p, &_x, sizeof (*(_p)));    \
                else {                                          \
                switch (sizeof (*(_p))) {                       \
                case 1:                                         \
 <at>  <at>  -156,6 +162,10  <at>  <at> 
                if (!access_ok(VERIFY_READ, _p, sizeof(*(_p)))) {       \
                        _err = -EFAULT;                                 \
(Continue reading)

Mike Frysinger | 15 Jul 2008 03:22
Picon

Re: get_user & put_user accessing L1

On Sun, Jul 13, 2008 at 10:40 PM, Robin Getz wrote:
> If no one has any objections, this adds L1 instruction support for
> put_user and get_user macros.
>
> Index: asm-blackfin/uaccess.h
> ===================================================================
> --- asm-blackfin/uaccess.h      (revision 4802)
> +++ asm-blackfin/uaccess.h      (working copy)
>  <at>  <at>  -18,6 +18,8  <at>  <at> 
>  # include <asm/bfin-global.h>
>  #endif
>
> +#include <asm/dma.h>
> +
>  #define get_ds()        (KERNEL_DS)
>  #define get_fs()        (current_thread_info()->addr_limit)
>
>  <at>  <at>  -99,6 +101,10  <at>  <at> 
>                if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
>                        _err = -EFAULT;                         \
>                }                                               \
> +               else if ( unlikely(L1_CODE_LENGTH != 0 &&       \
> +                                  (unsigned int)p >= L1_CODE_START &&  \
> +                                  (unsigned int)p <= L1_CODE_START + L1_CODE_LENGTH))  \
> +                       dma_memcpy(_p, &_x, sizeof (*(_p)));    \
>                else {                                          \
>                switch (sizeof (*(_p))) {                       \
>                case 1:                                         \
>  <at>  <at>  -156,6 +162,10  <at>  <at> 
>                if (!access_ok(VERIFY_READ, _p, sizeof(*(_p)))) {       \
(Continue reading)

Robin Getz | 15 Jul 2008 21:58
Favicon

Re: get_user & put_user accessing L1

On Mon 14 Jul 2008 21:22, Mike Frysinger pondered:
> On Sun, Jul 13, 2008 at 10:40 PM, Robin Getz wrote:
> > If no one has any objections, this adds L1 instruction support for
> > put_user and get_user macros.
> >
> > Index: asm-blackfin/uaccess.h
> > ===================================================================
> > --- asm-blackfin/uaccess.h      (revision 4802)
> > +++ asm-blackfin/uaccess.h      (working copy)
> >  <at>  <at>  -18,6 +18,8  <at>  <at> 
> >  # include <asm/bfin-global.h>
> >  #endif
> >
> > +#include <asm/dma.h>
> > +
> >  #define get_ds()        (KERNEL_DS)
> >  #define get_fs()        (current_thread_info()->addr_limit)
> >
> >  <at>  <at>  -99,6 +101,10  <at>  <at> 
> >                if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
> >                        _err = -EFAULT;                         \
> >                }                                               \
> > +               else if ( unlikely(L1_CODE_LENGTH != 0 &&       \
> > +                                  (unsigned int)p >= L1_CODE_START &&  \
> > +                                  (unsigned int)p <= L1_CODE_START + 
L1_CODE_LENGTH))  \
> > +                       dma_memcpy(_p, &_x, sizeof (*(_p)));    \
> >                else {                                          \
> >                switch (sizeof (*(_p))) {                       \
> >                case 1:                                         \
(Continue reading)

Mike Frysinger | 16 Jul 2008 01:48
Picon

Re: get_user & put_user accessing L1

On Tue, Jul 15, 2008 at 3:58 PM, Robin Getz wrote:
> On Mon 14 Jul 2008 21:22, Mike Frysinger pondered:
>> On Sun, Jul 13, 2008 at 10:40 PM, Robin Getz wrote:
>> > If no one has any objections, this adds L1 instruction support for
>> > put_user and get_user macros.
>> >
>> > Index: asm-blackfin/uaccess.h
>> > ===================================================================
>> > --- asm-blackfin/uaccess.h      (revision 4802)
>> > +++ asm-blackfin/uaccess.h      (working copy)
>> >  <at>  <at>  -18,6 +18,8  <at>  <at> 
>> >  # include <asm/bfin-global.h>
>> >  #endif
>> >
>> > +#include <asm/dma.h>
>> > +
>> >  #define get_ds()        (KERNEL_DS)
>> >  #define get_fs()        (current_thread_info()->addr_limit)
>> >
>> >  <at>  <at>  -99,6 +101,10  <at>  <at> 
>> >                if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
>> >                        _err = -EFAULT;                         \
>> >                }                                               \
>> > +               else if ( unlikely(L1_CODE_LENGTH != 0 &&       \
>> > +                                  (unsigned int)p >= L1_CODE_START &&  \
>> > +                                  (unsigned int)p <= L1_CODE_START +
> L1_CODE_LENGTH))  \
>> > +                       dma_memcpy(_p, &_x, sizeof (*(_p)));    \
>> >                else {                                          \
>> >                switch (sizeof (*(_p))) {                       \
(Continue reading)

Robin Getz | 15 Jul 2008 21:54
Favicon

Re: get_user & put_user accessing L1

On Mon 14 Jul 2008 21:22, Mike Frysinger pondered:
>
> i worry about relying on the dma function when it lacks locking ...
> our current code does irq enable/disable, but clearly that's no good
> if we're proposing calling it from a function which can be called from
> exception context ...

I was a little concerned about that as well - I was going to ask Michael who 
did alot of this initial work...

We have a safe_dma_memcpy() - but when I looked at it - it didn't appear to be 
very safe (or very different) than the dma_memcpy()...

void *safe_dma_memcpy(void *dest, const void *src, size_t size)
{
        void *addr;
        addr = dma_memcpy(dest, src, size);
        return addr;
}
EXPORT_SYMBOL(safe_dma_memcpy);

Isn't any more safe than dma_memcpy... (that I can tell) Why have two 
functions?

static void *__dma_memcpy(void *dest, const void *src, size_t size)
{
        int direction;  /* 1 - address decrease, 0 - address increase */
        int flag_align; /* 1 - address aligned,  0 - address unaligned */
        int flag_2D;    /* 1 - 2D DMA needed,    0 - 1D DMA needed */
        unsigned long flags;
(Continue reading)

Jie Zhang | 17 Jul 2008 11:31
Favicon

Re: get_user & put_user accessing L1

Robin Getz wrote:
> On Mon 14 Jul 2008 21:22, Mike Frysinger pondered:
>> i worry about relying on the dma function when it lacks locking ...
>> our current code does irq enable/disable, but clearly that's no good
>> if we're proposing calling it from a function which can be called from
>> exception context ...
> 
> I was a little concerned about that as well - I was going to ask Michael who 
> did alot of this initial work...
> 
> 
> We have a safe_dma_memcpy() - but when I looked at it - it didn't appear to be 
> very safe (or very different) than the dma_memcpy()...
> 
> void *safe_dma_memcpy(void *dest, const void *src, size_t size)
> {
>         void *addr;
>         addr = dma_memcpy(dest, src, size);
>         return addr;
> }
> EXPORT_SYMBOL(safe_dma_memcpy);
> 
> Isn't any more safe than dma_memcpy... (that I can tell) Why have two 
> functions?
> 
Before r3094, there was no local_irq_save or local_irq_restore in 
dma_memcpy. But safe_dma_memcpy had them. With r3094, Michael moved them 
into dma_memcpy.

Revision 3094 - (view) (download) (annotate) - [select for diffs]
(Continue reading)

Hennerich, Michael | 17 Jul 2008 11:39
Favicon

Re: get_user & put_user accessing L1

Before r3094, there was no local_irq_save or local_irq_restore in
dma_memcpy. But safe_dma_memcpy had them. With r3094, Michael moved them
into dma_memcpy.

I remember this was done because dma_inX and dma_outX may be called from
interrupt context.

-Michael

>-----Original Message-----
>From: Jie Zhang [mailto:jie.zhang@...]
>Sent: Thursday, July 17, 2008 11:32 AM
>To: Robin Getz
>Cc: Mike Frysinger; uclinux-dist-devel@...; Hennerich,
>Michael
>Subject: Re: [Uclinux-dist-devel] get_user & put_user accessing L1
>
>Robin Getz wrote:
>> On Mon 14 Jul 2008 21:22, Mike Frysinger pondered:
>>> i worry about relying on the dma function when it lacks locking ...
>>> our current code does irq enable/disable, but clearly that's no good
>>> if we're proposing calling it from a function which can be called
from
>>> exception context ...
>>
>> I was a little concerned about that as well - I was going to ask
Michael
>who
>> did alot of this initial work...
>>
(Continue reading)

Bernd Schmidt | 17 Jul 2008 18:11
Picon
Favicon

Re: get_user & put_user accessing L1

Hennerich, Michael wrote:
> Before r3094, there was no local_irq_save or local_irq_restore in
> dma_memcpy. But safe_dma_memcpy had them. With r3094, Michael moved them
> into dma_memcpy.
> 
> I remember this was done because dma_inX and dma_outX may be called from
> interrupt context.

Well, DMA setup could be protected by something like:

take a spinlock
wait for any previous DMA to finish
start our own DMA
give up the spinlock

In that case, we wouldn't need to disable interrupts, and if the second 
step was done by polling, we could even start a dma_memcpy inside the 
exception handler.  We'd just need to provide a way to wait for the 
finish of a DMA transaction.

Bernd
--

-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Robin Getz | 17 Jul 2008 17:58
Favicon

Re: get_user & put_user accessing L1

On Thu 17 Jul 2008 05:39, Hennerich, Michael pondered:
> Before r3094, there was no local_irq_save or local_irq_restore in
> dma_memcpy. But safe_dma_memcpy had them. With r3094, Michael moved them
> into dma_memcpy.
> 
> I remember this was done because dma_inX and dma_outX may be called from
> interrupt context.

But wouldn't a spinlock be just as good - this would also have the added 
benefit of not blocking other interrupts when this dma transactions is 
occurring, and would just protect the dma (which is really want we want to 
do - isn't it?)
Hennerich, Michael | 17 Jul 2008 18:44
Favicon

Re: get_user & put_user accessing L1

AFAIK spinlocks on none SMP are NO-Ops.

A poll/wait while current DMA runs at the beginning of mem_dmacpy,
dma_inX, dma_outX would be just as good. We need to prevent interrupt
context to start using the running channel before it terminated.

-Michael

>-----Original Message-----
>From: Robin Getz [mailto:rgetz@...]
>Sent: Thursday, July 17, 2008 5:59 PM
>To: Hennerich, Michael
>Cc: Jie Zhang; Mike Frysinger; uclinux-dist-devel@...
>Subject: Re: [Uclinux-dist-devel] get_user & put_user accessing L1
>
>On Thu 17 Jul 2008 05:39, Hennerich, Michael pondered:
>> Before r3094, there was no local_irq_save or local_irq_restore in
>> dma_memcpy. But safe_dma_memcpy had them. With r3094, Michael moved
them
>> into dma_memcpy.
>>
>> I remember this was done because dma_inX and dma_outX may be called
from
>> interrupt context.
>
>But wouldn't a spinlock be just as good - this would also have the
added
>benefit of not blocking other interrupts when this dma transactions is
>occurring, and would just protect the dma (which is really want we want
to
(Continue reading)

Robin Getz | 17 Jul 2008 19:22
Favicon

Re: get_user & put_user accessing L1

On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
> AFAIK spinlocks on none SMP are NO-Ops.

OK - if we follow the logic...

include/linux/spinlock.h

 *   (included on UP-non-debug builds:)
 *
 *  linux/spinlock_api_up.h:
 *                        builds the _spin_*() APIs.
 *
 *  linux/spinlock.h:     builds the final spin_*() APIs.

include/linux/spinlock_api_up.h

/*
 * In the UP-nondebug case there's no real locking going on, so the
 * only thing we have to do is to keep the preempt counts and irq
 * flags straight, to supress compiler warnings of unused lock
 * variables, and to add the proper checker annotations:
 */

#define _spin_lock(lock)                        __LOCK(lock)

#define __LOCK(lock) \
  do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

include/linux/compiler.h

(Continue reading)

Mike Frysinger | 18 Jul 2008 04:06
Picon

Re: get_user & put_user accessing L1

On Thu, Jul 17, 2008 at 1:22 PM, Robin Getz wrote:
> On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
>> A poll/wait while current DMA runs at the beginning of mem_dmacpy,
>> dma_inX, dma_outX would be just as good. We need to prevent interrupt
>> context to start using the running channel before it terminated.
>
> OK - why not just spin on the DMA hardware?

because you arent just protecting the dma that has already started,
you need to protect the programming of settings as well.

consider this: user space runs dma_memcpy(), finds that no DMA is
running, and then starts programming the DMA registers.  before it
finishes, an interrupt goes off.  the interrupt finds no DMA running,
so it programs its own settings and starts the DMA.  user space
resumes, finishes programming where it left off, but when it starts,
it has only partially correct settings and settings left over from the
interrupt.  the irq locking prevents this today.

same problem would occur with an exception occurring at any time ...
whether dma is running in user space or interrupt context.  i dont
think there is any complete solution here.  if we wish to do DMA's
from exception context, then we need a dedicated channel, or we just
make it a soft failure.  in other words, we add a mutex to the
function inside of the irq enable/disable but only around programming
of the configuration registers.  we then check this mutex if in
exception context.  if the mutex is taken, then we abort and just have
the higher levels say "oh well, data is not available at this time,
tough luck".  if it isnt taken, we know that it is safe to utilize the
channel without screwing up user space or an interrupt.
(Continue reading)

Bernd Schmidt | 20 Jul 2008 12:30
Picon
Favicon

Re: get_user & put_user accessing L1

Mike Frysinger wrote:
> On Thu, Jul 17, 2008 at 1:22 PM, Robin Getz wrote:
>> On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
>>> A poll/wait while current DMA runs at the beginning of mem_dmacpy,
>>> dma_inX, dma_outX would be just as good. We need to prevent interrupt
>>> context to start using the running channel before it terminated.
>> OK - why not just spin on the DMA hardware?
> 
> because you arent just protecting the dma that has already started,
> you need to protect the programming of settings as well.

So, just turn off interrupts while programming the registers for the 
next DMA.  That should be only a small amount of time.

> pseudo code:
> int dma_memcpy(...) {
>     local_irq_save(flags);
> 
>     if (in_exception()) {
>         /* if dma config in progress, tough luck */
>         if (mutex_trylock(&lock))
>             return 1;
>     } else
>         mutex_lock(&lock);

I doubt you need the mutex with interrupts disabled at this point?  If 
anything, this should be outside the local_irq_save.

> 
>     /* wait for any existing dma to finish */
(Continue reading)

Mike Frysinger | 20 Jul 2008 15:44
Picon

Re: get_user & put_user accessing L1

On Sun, Jul 20, 2008 at 6:30 AM, Bernd Schmidt wrote:
> Mike Frysinger wrote:
>> On Thu, Jul 17, 2008 at 1:22 PM, Robin Getz wrote:
>>> On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
>>>> A poll/wait while current DMA runs at the beginning of mem_dmacpy,
>>>> dma_inX, dma_outX would be just as good. We need to prevent interrupt
>>>> context to start using the running channel before it terminated.
>>>
>>> OK - why not just spin on the DMA hardware?
>>
>> because you arent just protecting the dma that has already started,
>> you need to protect the programming of settings as well.
>
> So, just turn off interrupts while programming the registers for the next
> DMA.  That should be only a small amount of time.

moving the first dma wait out of the irq disabled to before should be
ok i think ... the idea was that that code shouldnt be executed too
often anyways ...

then again this depends largely on how the last dma wait is structured ...

>> pseudo code:
>> int dma_memcpy(...) {
>>    local_irq_save(flags);
>>
>>    if (in_exception()) {
>>        /* if dma config in progress, tough luck */
>>        if (mutex_trylock(&lock))
>>            return 1;
(Continue reading)

Robin Getz | 19 Jul 2008 17:04
Favicon

Re: get_user & put_user accessing L1

On Thu 17 Jul 2008 22:06, Mike Frysinger pondered:
> On Thu, Jul 17, 2008 at 1:22 PM, Robin Getz wrote:
> > On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
> >> A poll/wait while current DMA runs at the beginning of mem_dmacpy,
> >> dma_inX, dma_outX would be just as good. We need to prevent interrupt
> >> context to start using the running channel before it terminated.
> >
> > OK - why not just spin on the DMA hardware?
> 
> because you arent just protecting the dma that has already started,
> you need to protect the programming of settings as well.

yes - you are correct - I missed that.

> consider this: user space runs dma_memcpy(), finds that no DMA is
> running, and then starts programming the DMA registers.  before it
> finishes, an interrupt goes off.  the interrupt finds no DMA running,
> so it programs its own settings and starts the DMA.  user space
> resumes, finishes programming where it left off, but when it starts,
> it has only partially correct settings and settings left over from the
> interrupt.  the irq locking prevents this today.
> 
> same problem would occur with an exception occurring at any time ...
> whether dma is running in user space or interrupt context.  i dont
> think there is any complete solution here.  if we wish to do DMA's
> from exception context, then we need a dedicated channel, or we just
> make it a soft failure.  in other words, we add a mutex to the
> function inside of the irq enable/disable but only around programming
> of the configuration registers.  we then check this mutex if in
> exception context.  if the mutex is taken, then we abort and just have
(Continue reading)

Mike Frysinger | 19 Jul 2008 18:50
Picon

Re: get_user & put_user accessing L1

On Sat, Jul 19, 2008 at 11:04 AM, Robin Getz wrote:
> On Thu 17 Jul 2008 22:06, Mike Frysinger pondered:
>> On Thu, Jul 17, 2008 at 1:22 PM, Robin Getz wrote:
>> > On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
>> >> A poll/wait while current DMA runs at the beginning of mem_dmacpy,
>> >> dma_inX, dma_outX would be just as good. We need to prevent interrupt
>> >> context to start using the running channel before it terminated.
>> >
>> > OK - why not just spin on the DMA hardware?
>>
>> because you arent just protecting the dma that has already started,
>> you need to protect the programming of settings as well.
>
> yes - you are correct - I missed that.
>
>> consider this: user space runs dma_memcpy(), finds that no DMA is
>> running, and then starts programming the DMA registers.  before it
>> finishes, an interrupt goes off.  the interrupt finds no DMA running,
>> so it programs its own settings and starts the DMA.  user space
>> resumes, finishes programming where it left off, but when it starts,
>> it has only partially correct settings and settings left over from the
>> interrupt.  the irq locking prevents this today.
>>
>> same problem would occur with an exception occurring at any time ...
>> whether dma is running in user space or interrupt context.  i dont
>> think there is any complete solution here.  if we wish to do DMA's
>> from exception context, then we need a dedicated channel, or we just
>> make it a soft failure.  in other words, we add a mutex to the
>> function inside of the irq enable/disable but only around programming
>> of the configuration registers.  we then check this mutex if in
(Continue reading)

Robin Getz | 20 Jul 2008 08:57
Favicon

Re: get_user & put_user accessing L1

On Sat 19 Jul 2008 12:50, Mike Frysinger pondered:
> as long as we dont do large DMA transfers in the kernel, there really
> shouldnt be much of a problem.

I think people are already starting to run into this - and others places we 
turn off interrupts too long - the most common complaint today is when they 
say that their LCD is flickering.

If other interrupts get held off too long - it doesn't take long for PPI to 
cause visual effects....

If we can spend some time thinking about things (like we are) and determine 
the "best" tradeoff - it is time well spent.

If we look at your code again....

> int dma_memcpy(...) {

	/* if called from userspace, don't turn off interrupts until
	   we have a good idea we can grab the lock */
	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)
	   && from_userspace())
		yield();

>      local_irq_save(flags);
>
>      if (in_exception()) {
>          /* if dma config in progress, tough luck */
>          if (mutex_trylock(&lock))
>              return 1;
(Continue reading)

Mike Frysinger | 20 Jul 2008 09:15
Picon

Re: get_user & put_user accessing L1

On Sun, Jul 20, 2008 at 2:57 AM, Robin Getz wrote:
> On Sat 19 Jul 2008 12:50, Mike Frysinger pondered:
>> as long as we dont do large DMA transfers in the kernel, there really
>> shouldnt be much of a problem.
>
> I think people are already starting to run into this - and others places we
> turn off interrupts too long - the most common complaint today is when they
> say that their LCD is flickering.
>
> If other interrupts get held off too long - it doesn't take long for PPI to
> cause visual effects....
>
> If we can spend some time thinking about things (like we are) and determine
> the "best" tradeoff - it is time well spent.

people arent using dma_memcpy() to do the large transfers though.  for
things like PPI and such, they should be using their own dedicated dma
channel.

and the proposed interface does locking around programming of
registers, so there is no irq-offs while we wait for the dma to
finish.

> If we look at your code again....
>
>> int dma_memcpy(...) {
>
>        /* if called from userspace, don't turn off interrupts until
>           we have a good idea we can grab the lock */
>        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)
(Continue reading)

Robin Getz | 20 Jul 2008 10:21
Favicon

Re: get_user & put_user accessing L1

On Sun 20 Jul 2008 03:15, Mike Frysinger pondered:
> On Sun, Jul 20, 2008 at 2:57 AM, Robin Getz wrote:
> > On Sat 19 Jul 2008 12:50, Mike Frysinger pondered:
> >> as long as we dont do large DMA transfers in the kernel, there really
> >> shouldnt be much of a problem.
> >
> > I think people are already starting to run into this - and others places
> > we turn off interrupts too long - the most common complaint today is 
> > when they say that their LCD is flickering.
> >
> > If other interrupts get held off too long - it doesn't take long for 
> > PPI to cause visual effects....
> >
> > If we can spend some time thinking about things (like we are) and
> > determine the "best" tradeoff - it is time well spent.
> 
> people arent using dma_memcpy() to do the large transfers though.  for
> things like PPI and such, they should be using their own dedicated dma
> channel.

What I ment - is that other userspace/kernel dma_memcpy is messing up other 
DMA transfers since the window between getting the PPI DMA done interrupt and 
setting up the next DMA transaction is normally short to none.

Some of the time we turn interrupts off today can be pretty long - and this is 
one of the places...

> and the proposed interface does locking around programming of
> registers, so there is no irq-offs while we wait for the dma to
> finish.
(Continue reading)

Hennerich, Michael | 20 Jul 2008 21:18
Favicon

Re: get_user & put_user accessing L1

None of the fb driver uses interrupts, except for ERROR detecting and
recovering.
The DMA uses either autobuffer mode or ring chained DMA descriptor
lists.

Disabling IRQ's doesn't have any effect on LCD update.

-Michael

>-----Original Message-----
>From: Robin Getz [mailto:rgetz@...]
>Sent: Sunday, July 20, 2008 10:22 AM
>To: Mike Frysinger
>Cc: Hennerich, Michael; Jie Zhang;
uclinux-dist-devel@...
>Subject: Re: [Uclinux-dist-devel] get_user & put_user accessing L1
>
>On Sun 20 Jul 2008 03:15, Mike Frysinger pondered:
>> On Sun, Jul 20, 2008 at 2:57 AM, Robin Getz wrote:
>> > On Sat 19 Jul 2008 12:50, Mike Frysinger pondered:
>> >> as long as we dont do large DMA transfers in the kernel, there
really
>> >> shouldnt be much of a problem.
>> >
>> > I think people are already starting to run into this - and others
>places
>> > we turn off interrupts too long - the most common complaint today
is
>> > when they say that their LCD is flickering.
>> >
(Continue reading)

Robin Getz | 22 Jul 2008 20:57
Favicon

Re: get_user & put_user accessing L1

On Sun 20 Jul 2008 15:18, Hennerich, Michael pondered:
> None of the fb driver uses interrupts, except for ERROR detecting and
> recovering.
> The DMA uses either autobuffer mode or ring chained DMA descriptor
> lists.
> 
> Disabling IRQ's doesn't have any effect on LCD update.

Not on our drivers - but people would not be complaining about things when 
using ethernet and usb so much with our ins.S functions which turn off 
interrupts for so long otherwise...

-Robin
Mike Frysinger | 20 Jul 2008 11:32
Picon

Re: get_user & put_user accessing L1

On Sun, Jul 20, 2008 at 4:21 AM, Robin Getz wrote:
> On Sun 20 Jul 2008 03:15, Mike Frysinger pondered:
>> On Sun, Jul 20, 2008 at 2:57 AM, Robin Getz wrote:
>> > On Sat 19 Jul 2008 12:50, Mike Frysinger pondered:
>> >> as long as we dont do large DMA transfers in the kernel, there really
>> >> shouldnt be much of a problem.
>> >
>> > I think people are already starting to run into this - and others places
>> > we turn off interrupts too long - the most common complaint today is
>> > when they say that their LCD is flickering.
>> >
>> > If other interrupts get held off too long - it doesn't take long for
>> > PPI to cause visual effects....
>> >
>> > If we can spend some time thinking about things (like we are) and
>> > determine the "best" tradeoff - it is time well spent.
>>
>> people arent using dma_memcpy() to do the large transfers though.  for
>> things like PPI and such, they should be using their own dedicated dma
>> channel.
>
> What I ment - is that other userspace/kernel dma_memcpy is messing up other
> DMA transfers since the window between getting the PPI DMA done interrupt and
> setting up the next DMA transaction is normally short to none.
>
> Some of the time we turn interrupts off today can be pretty long - and this is
> one of the places...

right

(Continue reading)

Hennerich, Michael | 17 Jul 2008 21:44
Favicon

Re: get_user & put_user accessing L1

Totally agree except the user space use case.

Kernel uses dma_memcpy only to put things into L1, e.g. when we load a
kernel module.
Dma_inX and dma_outX are called never larger than a USB packet or
Ethernet packet size.

We don't want to delay any kernel interrupt when user space thinks it
needs to copy 10 MB from A to B.

I suggest we use MDMA_1 handled by the DMA kernel driver for user space
dma_memcpy. In case the channel is not available we should put the user
process waiting to sleep.

-Michael

>-----Original Message-----
>From: Robin Getz [mailto:rgetz@...]
>Sent: Thursday, July 17, 2008 7:22 PM
>To: Hennerich, Michael
>Cc: Jie Zhang; Mike Frysinger; uclinux-dist-devel@...
>Subject: Re: [Uclinux-dist-devel] get_user & put_user accessing L1
>
>On Thu 17 Jul 2008 12:44, Hennerich, Michael pondered:
>> AFAIK spinlocks on none SMP are NO-Ops.
>
>OK - if we follow the logic...
>
>include/linux/spinlock.h
>
(Continue reading)

Robin Getz | 17 Jul 2008 22:23
Favicon

Re: get_user & put_user accessing L1

On Thu 17 Jul 2008 15:44, Hennerich, Michael pondered:
> Totally agree except the user space use case.
> 
> Kernel uses dma_memcpy only to put things into L1, e.g. when we load a
> kernel module.

The kernel uses it any time it needs to access L1 instruction (like ptrace/gdb 
setting a break point, getting disassembly, etc).

> Dma_inX and dma_outX are called never larger than a USB packet or
> Ethernet packet size.
> 
> We don't want to delay any kernel interrupt when user space thinks it
> needs to copy 10 MB from A to B.
> 
> I suggest we use MDMA_1 handled by the DMA kernel driver for user space
> dma_memcpy. In case the channel is not available we should put the user
> process waiting to sleep.

Or in dmamemcpy() check both, and use the free one. - I'm not sure which would 
be easier to do.

Gmane