aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-03-28 04:34:45 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:47 -0400
commitad0992e97c5416e431e19dcfd4f6c84448dc1bc2 (patch)
treeea90956680289c0797b715422e9d1c889f38f3d5
parentbe9cbb7c559eddea19604abafb89faf9c8666715 (diff)
V4L/DVB (7699): pvrusb2: Implement statistics for USB I/O performance / tracking
Implement a mechanism in the pvrusb2 driver for gathering statistics on the stream buffering, including bytes transferred, buffers handled, buffers in flight, etc. This is useful for debugging certain classes of streaming issues and for determining if the buffer pool size is generally correct for the driver. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c24
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.c30
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.h12
4 files changed, 84 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index b0687430fdd4..b53121c78ff9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -164,6 +164,8 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
164 int ccnt; 164 int ccnt;
165 int ret; 165 int ret;
166 u32 gpio_dir,gpio_in,gpio_out; 166 u32 gpio_dir,gpio_in,gpio_out;
167 struct pvr2_stream_stats stats;
168 struct pvr2_stream *sp;
167 169
168 ret = pvr2_hdw_is_hsm(hdw); 170 ret = pvr2_hdw_is_hsm(hdw);
169 ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", 171 ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
@@ -182,6 +184,24 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
182 pvr2_hdw_get_streaming(hdw) ? "on" : "off"); 184 pvr2_hdw_get_streaming(hdw) ? "on" : "off");
183 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 185 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
184 186
187
188 sp = pvr2_hdw_get_video_stream(hdw);
189 if (sp) {
190 pvr2_stream_get_stats(sp, &stats, 0);
191 ccnt = scnprintf(
192 buf,acnt,
193 "Bytes streamed=%u"
194 " URBs: queued=%u idle=%u ready=%u"
195 " processed=%u failed=%u\n",
196 stats.bytes_processed,
197 stats.buffers_in_queue,
198 stats.buffers_in_idle,
199 stats.buffers_in_ready,
200 stats.buffers_processed,
201 stats.buffers_failed);
202 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
203 }
204
185 return bcnt; 205 return bcnt;
186} 206}
187 207
@@ -220,6 +240,10 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
220 return pvr2_hdw_cmd_decoder_reset(hdw); 240 return pvr2_hdw_cmd_decoder_reset(hdw);
221 } else if (debugifc_match_keyword(wptr,wlen,"worker")) { 241 } else if (debugifc_match_keyword(wptr,wlen,"worker")) {
222 return pvr2_hdw_untrip(hdw); 242 return pvr2_hdw_untrip(hdw);
243 } else if (debugifc_match_keyword(wptr,wlen,"usbstats")) {
244 pvr2_stream_get_stats(pvr2_hdw_get_video_stream(hdw),
245 NULL, !0);
246 return 0;
223 } 247 }
224 return -EINVAL; 248 return -EINVAL;
225 } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { 249 } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 16c7df9c093f..a26b5251ec1b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3806,6 +3806,24 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
3806 buf,acnt, 3806 buf,acnt,
3807 "state: %s", 3807 "state: %s",
3808 pvr2_get_state_name(hdw->master_state)); 3808 pvr2_get_state_name(hdw->master_state));
3809 case 4: {
3810 struct pvr2_stream_stats stats;
3811 if (!hdw->vid_stream) break;
3812 pvr2_stream_get_stats(hdw->vid_stream,
3813 &stats,
3814 0);
3815 return scnprintf(
3816 buf,acnt,
3817 "Bytes streamed=%u"
3818 " URBs: queued=%u idle=%u ready=%u"
3819 " processed=%u failed=%u",
3820 stats.bytes_processed,
3821 stats.buffers_in_queue,
3822 stats.buffers_in_idle,
3823 stats.buffers_in_ready,
3824 stats.buffers_processed,
3825 stats.buffers_failed);
3826 }
3809 default: break; 3827 default: break;
3810 } 3828 }
3811 return 0; 3829 return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c
index a9889ff96ecc..7aff8b720064 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.c
@@ -80,6 +80,10 @@ struct pvr2_stream {
80 /* Tracking state for tolerating errors */ 80 /* Tracking state for tolerating errors */
81 unsigned int fail_count; 81 unsigned int fail_count;
82 unsigned int fail_tolerance; 82 unsigned int fail_tolerance;
83
84 unsigned int buffers_processed;
85 unsigned int buffers_failed;
86 unsigned int bytes_processed;
83}; 87};
84 88
85struct pvr2_buffer { 89struct pvr2_buffer {
@@ -446,6 +450,8 @@ static void buffer_complete(struct urb *urb)
446 (urb->status == -ENOENT) || 450 (urb->status == -ENOENT) ||
447 (urb->status == -ECONNRESET) || 451 (urb->status == -ECONNRESET) ||
448 (urb->status == -ESHUTDOWN)) { 452 (urb->status == -ESHUTDOWN)) {
453 (sp->buffers_processed)++;
454 sp->bytes_processed += urb->actual_length;
449 bp->used_count = urb->actual_length; 455 bp->used_count = urb->actual_length;
450 if (sp->fail_count) { 456 if (sp->fail_count) {
451 pvr2_trace(PVR2_TRACE_TOLERANCE, 457 pvr2_trace(PVR2_TRACE_TOLERANCE,
@@ -457,11 +463,13 @@ static void buffer_complete(struct urb *urb)
457 // We can tolerate this error, because we're below the 463 // We can tolerate this error, because we're below the
458 // threshold... 464 // threshold...
459 (sp->fail_count)++; 465 (sp->fail_count)++;
466 (sp->buffers_failed)++;
460 pvr2_trace(PVR2_TRACE_TOLERANCE, 467 pvr2_trace(PVR2_TRACE_TOLERANCE,
461 "stream %p ignoring error %d" 468 "stream %p ignoring error %d"
462 " - fail count increased to %u", 469 " - fail count increased to %u",
463 sp,urb->status,sp->fail_count); 470 sp,urb->status,sp->fail_count);
464 } else { 471 } else {
472 (sp->buffers_failed)++;
465 bp->status = urb->status; 473 bp->status = urb->status;
466 } 474 }
467 spin_unlock_irqrestore(&sp->list_lock,irq_flags); 475 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
@@ -515,6 +523,28 @@ void pvr2_stream_set_callback(struct pvr2_stream *sp,
515 } while(0); mutex_unlock(&sp->mutex); 523 } while(0); mutex_unlock(&sp->mutex);
516} 524}
517 525
526void pvr2_stream_get_stats(struct pvr2_stream *sp,
527 struct pvr2_stream_stats *stats,
528 int zero_counts)
529{
530 unsigned long irq_flags;
531 spin_lock_irqsave(&sp->list_lock,irq_flags);
532 if (stats) {
533 stats->buffers_in_queue = sp->q_count;
534 stats->buffers_in_idle = sp->i_count;
535 stats->buffers_in_ready = sp->r_count;
536 stats->buffers_processed = sp->buffers_processed;
537 stats->buffers_failed = sp->buffers_failed;
538 stats->bytes_processed = sp->bytes_processed;
539 }
540 if (zero_counts) {
541 sp->buffers_processed = 0;
542 sp->buffers_failed = 0;
543 sp->bytes_processed = 0;
544 }
545 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
546}
547
518/* Query / set the nominal buffer count */ 548/* Query / set the nominal buffer count */
519int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) 549int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
520{ 550{
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h
index 93279cc2a35e..42fcf8281a87 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.h
@@ -36,6 +36,15 @@ enum pvr2_buffer_state {
36struct pvr2_stream; 36struct pvr2_stream;
37struct pvr2_buffer; 37struct pvr2_buffer;
38 38
39struct pvr2_stream_stats {
40 unsigned int buffers_in_queue;
41 unsigned int buffers_in_idle;
42 unsigned int buffers_in_ready;
43 unsigned int buffers_processed;
44 unsigned int buffers_failed;
45 unsigned int bytes_processed;
46};
47
39/* Initialize / tear down stream structure */ 48/* Initialize / tear down stream structure */
40struct pvr2_stream *pvr2_stream_create(void); 49struct pvr2_stream *pvr2_stream_create(void);
41void pvr2_stream_destroy(struct pvr2_stream *); 50void pvr2_stream_destroy(struct pvr2_stream *);
@@ -45,6 +54,9 @@ void pvr2_stream_setup(struct pvr2_stream *,
45void pvr2_stream_set_callback(struct pvr2_stream *, 54void pvr2_stream_set_callback(struct pvr2_stream *,
46 pvr2_stream_callback func, 55 pvr2_stream_callback func,
47 void *data); 56 void *data);
57void pvr2_stream_get_stats(struct pvr2_stream *,
58 struct pvr2_stream_stats *,
59 int zero_counts);
48 60
49/* Query / set the nominal buffer count */ 61/* Query / set the nominal buffer count */
50int pvr2_stream_get_buffer_count(struct pvr2_stream *); 62int pvr2_stream_get_buffer_count(struct pvr2_stream *);