Re: Linux UVC driver can not handle urb_submit error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Alan,

Ok, I will apply patch and test again. Since time difference issue, I
can not do test now. It will be done when I back to office.
In advance, the question:
get_cpu_cycles() just get current count, right?
it is not necessary to do calculation of (exit point - enter point), right?
or it also do the calculation then retrun the count?

Thanks!

Soho


2011/6/3 Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>:
> On Fri, 3 Jun 2011, Soho Soho123 wrote:
>
>> Dear Alan,
>>
>>
>> the attached is log file about cpu cycle measurement. there are 2
>> files included in tar file.
>> 1. 0603_log_3.txt is cpu cycle data that I dump when urb submit error occur
>> 2. scan_periodic.c is the code that shows where I put enter point and
>> exit point.
>> I set a flag to disable update CPU Cycle count when urb submit error.
>> the data is saved into array .
>> "big for loop" ,"restart label","itd_complete" has a 4096 elements
>> array to save data, respectively.
>> the data type is :
>> struct for_loop_stat{
>>       unsigned long long cpu_cycle_count;
>>       unsigned int now_uframe;
>>       unsigned int clock;
>>       unsigned int modified;
>> };
>> the element "modified" is used for restart_lable only.
>> if modified is "1", it means the data from "restart" to "goto restart"
>> in 0603_log_3.txt, the first line shows the index of each array when
>> the error is occur.
>
> Unfortunately the data in your file doesn't make much sense to me.
> Since you stop collecting data when the submit error occurs, each of
> the three arrays should end with the same value for now_uframe (or
> almost the same value).  But they don't.  The "big for loop" array ends
> with now_uframe = 2319, the "restart label" array ends with now_uframe
> = 201, and the "itd_complete" array ends with now_uframe = 1240.
>
> Anyway, this wasn't what I wanted you to do.  I'd like to see the data
> all in a single array.  The patch below shows how to arrange it.
>
> You have a routine to get the current CPU cycle counter, right?  I
> don't know what its name is, so in the patch it's called
> get_cpu_cycles().  You'll have to fix that up.
>
> Alan Stern
>
>
>
> Index: usb-3.0/drivers/usb/host/ehci-sched.c
> ===================================================================
> --- usb-3.0.orig/drivers/usb/host/ehci-sched.c
> +++ usb-3.0/drivers/usb/host/ehci-sched.c
> @@ -19,6 +19,56 @@
>
>  /* this file is part of ehci-hcd.c */
>
> +struct counter_stat {
> +       unsigned long long cpu_cycle_count;
> +       unsigned now_uframe;
> +       unsigned clock;
> +       int where;
> +};
> +
> +#define MAX_COUNTER_STAT       4000
> +
> +static struct counter_stat stats[MAX_COUNTER_STAT];
> +static int next_stat;
> +static int stats_flag = 1;
> +
> +static void update_counter_stats(unsigned now_uframe, unsigned clock,
> +               int where)
> +{
> +       static unsigned long long cpu_cycles;
> +       unsigned long long c2;
> +       extern unsigned long long get_cpu_cycles(void);
> +
> +       if (!stats_flag)
> +               return;
> +
> +       c2 = get_cpu_cycles();
> +       stats[next_stat].cpu_cycle_count = c2 - cpu_cycles;
> +       cpu_cycles = c2;
> +       stats[next_stat].now_uframe = now_uframe;
> +       stats[next_stat].clock = clock;
> +       stats[next_stat].where = where;
> +
> +       if (++next_stat == MAX_COUNTER_STAT)
> +               next_stat = 0;
> +}
> +
> +static void dump_stats(void)
> +{
> +       int i = next_stat;
> +
> +       do {
> +               printk(KERN_DEBUG "stat[%d]: now_uframe %u clock %u"
> +                               " where %d cycles %llu\n",
> +                               i, stats[i].now_uframe,
> +                               stats[i].clock,
> +                               stats[i].where,
> +                               stats[i].cpu_cycle_count);
> +               if (++i == MAX_COUNTER_STAT)
> +                       i = 0;
> +       } while (i != next_stat);
> +}
> +
>  /*-------------------------------------------------------------------------*/
>
>  /*
> @@ -1496,6 +1546,10 @@ iso_stream_schedule (
>                                urb, start - now, span - period,
>                                mod - 2 * SCHEDULE_SLOP);
>                status = -EFBIG;
> +               if (stats_flag) {
> +                       stats_flag = 0;
> +                       dump_stats();
> +               }
>                goto fail;
>        }
>
> @@ -2293,6 +2347,8 @@ scan_periodic (struct ehci_hcd *ehci)
>        clock_frame = clock >> 3;
>        ++ehci->periodic_stamp;
>
> +       update_counter_stats(now_uframe, clock, 1);
> +
>        for (;;) {
>                union ehci_shadow       q, *q_p;
>                __hc32                  type, *hw_p;
> @@ -2301,6 +2357,7 @@ scan_periodic (struct ehci_hcd *ehci)
>                frame = now_uframe >> 3;
>
>  restart:
> +               update_counter_stats(now_uframe, clock, 2);
>                /* scan each element in frame's queue for completions */
>                q_p = &ehci->pshadow [frame];
>                hw_p = &ehci->periodic [frame];
> @@ -2378,6 +2435,7 @@ restart:
>                                type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
>                                wmb();
>                                modified = itd_complete (ehci, q.itd);
> +                               update_counter_stats(now_uframe, clock, 3);
>                                q = *q_p;
>                                break;
>                        case Q_TYPE_SITD:
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux