aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2011-09-14 03:36:46 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-11-01 21:11:01 -0400
commit17e5b4f20adbe286fdf14b4d08f296564e97e545 (patch)
treec6634147e4a939213033cf8f5b622a686edd3968
parent2d24cdaa6e389f85dad51eda39f1c2684a4f15b0 (diff)
virtio: console: add port stats for bytes received, sent and discarded
This commit adds port-specific stats for the number of bytes received, sent and discarded. They're exposed via the debugfs interface. This data can be used to check for data loss bugs (or disprove such claims). It can also be used for accounting, if there's such a need. The stats remain valid throughout the lifetime of the port. Unplugging a port will reset the stats. The numbers are not reset across port opens/closes. Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/char/virtio_console.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 105181c1e6be..387fcdf019b7 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -152,6 +152,10 @@ struct ports_device {
152 int chr_major; 152 int chr_major;
153}; 153};
154 154
155struct port_stats {
156 unsigned long bytes_sent, bytes_received, bytes_discarded;
157};
158
155/* This struct holds the per-port data */ 159/* This struct holds the per-port data */
156struct port { 160struct port {
157 /* Next port in the list, head is in the ports_device */ 161 /* Next port in the list, head is in the ports_device */
@@ -180,6 +184,13 @@ struct port {
180 struct dentry *debugfs_file; 184 struct dentry *debugfs_file;
181 185
182 /* 186 /*
187 * Keep count of the bytes sent, received and discarded for
188 * this port for accounting and debugging purposes. These
189 * counts are not reset across port open / close events.
190 */
191 struct port_stats stats;
192
193 /*
183 * The entries in this struct will be valid if this port is 194 * The entries in this struct will be valid if this port is
184 * hooked up to an hvc console 195 * hooked up to an hvc console
185 */ 196 */
@@ -360,6 +371,7 @@ static struct port_buffer *get_inbuf(struct port *port)
360 if (buf) { 371 if (buf) {
361 buf->len = len; 372 buf->len = len;
362 buf->offset = 0; 373 buf->offset = 0;
374 port->stats.bytes_received += len;
363 } 375 }
364 return buf; 376 return buf;
365} 377}
@@ -396,6 +408,7 @@ static void discard_port_data(struct port *port)
396 408
397 err = 0; 409 err = 0;
398 while (buf) { 410 while (buf) {
411 port->stats.bytes_discarded += buf->len - buf->offset;
399 if (add_inbuf(port->in_vq, buf) < 0) { 412 if (add_inbuf(port->in_vq, buf) < 0) {
400 err++; 413 err++;
401 free_buf(buf); 414 free_buf(buf);
@@ -519,6 +532,8 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
519 cpu_relax(); 532 cpu_relax();
520done: 533done:
521 spin_unlock_irqrestore(&port->outvq_lock, flags); 534 spin_unlock_irqrestore(&port->outvq_lock, flags);
535
536 port->stats.bytes_sent += in_count;
522 /* 537 /*
523 * We're expected to return the amount of data we wrote -- all 538 * We're expected to return the amount of data we wrote -- all
524 * of it 539 * of it
@@ -1049,6 +1064,14 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf,
1049 out_offset += snprintf(buf + out_offset, out_count - out_offset, 1064 out_offset += snprintf(buf + out_offset, out_count - out_offset,
1050 "outvq_full: %d\n", port->outvq_full); 1065 "outvq_full: %d\n", port->outvq_full);
1051 out_offset += snprintf(buf + out_offset, out_count - out_offset, 1066 out_offset += snprintf(buf + out_offset, out_count - out_offset,
1067 "bytes_sent: %lu\n", port->stats.bytes_sent);
1068 out_offset += snprintf(buf + out_offset, out_count - out_offset,
1069 "bytes_received: %lu\n",
1070 port->stats.bytes_received);
1071 out_offset += snprintf(buf + out_offset, out_count - out_offset,
1072 "bytes_discarded: %lu\n",
1073 port->stats.bytes_discarded);
1074 out_offset += snprintf(buf + out_offset, out_count - out_offset,
1052 "is_console: %s\n", 1075 "is_console: %s\n",
1053 is_console_port(port) ? "yes" : "no"); 1076 is_console_port(port) ? "yes" : "no");
1054 out_offset += snprintf(buf + out_offset, out_count - out_offset, 1077 out_offset += snprintf(buf + out_offset, out_count - out_offset,
@@ -1133,6 +1156,7 @@ static int add_port(struct ports_device *portdev, u32 id)
1133 port->cons.ws.ws_row = port->cons.ws.ws_col = 0; 1156 port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
1134 1157
1135 port->host_connected = port->guest_connected = false; 1158 port->host_connected = port->guest_connected = false;
1159 port->stats = (struct port_stats) { 0 };
1136 1160
1137 port->outvq_full = false; 1161 port->outvq_full = false;
1138 1162