aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/xenbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netback/xenbus.c')
-rw-r--r--drivers/net/xen-netback/xenbus.c181
1 files changed, 180 insertions, 1 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 3d85acd84bad..9c47b897b6d2 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -44,6 +44,177 @@ static void unregister_hotplug_status_watch(struct backend_info *be);
44static void set_backend_state(struct backend_info *be, 44static void set_backend_state(struct backend_info *be,
45 enum xenbus_state state); 45 enum xenbus_state state);
46 46
47#ifdef CONFIG_DEBUG_FS
48struct dentry *xen_netback_dbg_root = NULL;
49
50static int xenvif_read_io_ring(struct seq_file *m, void *v)
51{
52 struct xenvif_queue *queue = m->private;
53 struct xen_netif_tx_back_ring *tx_ring = &queue->tx;
54 struct xen_netif_rx_back_ring *rx_ring = &queue->rx;
55
56 if (tx_ring->sring) {
57 struct xen_netif_tx_sring *sring = tx_ring->sring;
58
59 seq_printf(m, "Queue %d\nTX: nr_ents %u\n", queue->id,
60 tx_ring->nr_ents);
61 seq_printf(m, "req prod %u (%d) cons %u (%d) event %u (%d)\n",
62 sring->req_prod,
63 sring->req_prod - sring->rsp_prod,
64 tx_ring->req_cons,
65 tx_ring->req_cons - sring->rsp_prod,
66 sring->req_event,
67 sring->req_event - sring->rsp_prod);
68 seq_printf(m, "rsp prod %u (base) pvt %u (%d) event %u (%d)\n",
69 sring->rsp_prod,
70 tx_ring->rsp_prod_pvt,
71 tx_ring->rsp_prod_pvt - sring->rsp_prod,
72 sring->rsp_event,
73 sring->rsp_event - sring->rsp_prod);
74 seq_printf(m, "pending prod %u pending cons %u nr_pending_reqs %u\n",
75 queue->pending_prod,
76 queue->pending_cons,
77 nr_pending_reqs(queue));
78 seq_printf(m, "dealloc prod %u dealloc cons %u dealloc_queue %u\n\n",
79 queue->dealloc_prod,
80 queue->dealloc_cons,
81 queue->dealloc_prod - queue->dealloc_cons);
82 }
83
84 if (rx_ring->sring) {
85 struct xen_netif_rx_sring *sring = rx_ring->sring;
86
87 seq_printf(m, "RX: nr_ents %u\n", rx_ring->nr_ents);
88 seq_printf(m, "req prod %u (%d) cons %u (%d) event %u (%d)\n",
89 sring->req_prod,
90 sring->req_prod - sring->rsp_prod,
91 rx_ring->req_cons,
92 rx_ring->req_cons - sring->rsp_prod,
93 sring->req_event,
94 sring->req_event - sring->rsp_prod);
95 seq_printf(m, "rsp prod %u (base) pvt %u (%d) event %u (%d)\n\n",
96 sring->rsp_prod,
97 rx_ring->rsp_prod_pvt,
98 rx_ring->rsp_prod_pvt - sring->rsp_prod,
99 sring->rsp_event,
100 sring->rsp_event - sring->rsp_prod);
101 }
102
103 seq_printf(m, "NAPI state: %lx NAPI weight: %d TX queue len %u\n"
104 "Credit timer_pending: %d, credit: %lu, usec: %lu\n"
105 "remaining: %lu, expires: %lu, now: %lu\n",
106 queue->napi.state, queue->napi.weight,
107 skb_queue_len(&queue->tx_queue),
108 timer_pending(&queue->credit_timeout),
109 queue->credit_bytes,
110 queue->credit_usec,
111 queue->remaining_credit,
112 queue->credit_timeout.expires,
113 jiffies);
114
115 return 0;
116}
117
118#define XENVIF_KICK_STR "kick"
119#define BUFFER_SIZE 32
120
121static ssize_t
122xenvif_write_io_ring(struct file *filp, const char __user *buf, size_t count,
123 loff_t *ppos)
124{
125 struct xenvif_queue *queue =
126 ((struct seq_file *)filp->private_data)->private;
127 int len;
128 char write[BUFFER_SIZE];
129
130 /* don't allow partial writes and check the length */
131 if (*ppos != 0)
132 return 0;
133 if (count >= sizeof(write))
134 return -ENOSPC;
135
136 len = simple_write_to_buffer(write,
137 sizeof(write) - 1,
138 ppos,
139 buf,
140 count);
141 if (len < 0)
142 return len;
143
144 write[len] = '\0';
145
146 if (!strncmp(write, XENVIF_KICK_STR, sizeof(XENVIF_KICK_STR) - 1))
147 xenvif_interrupt(0, (void *)queue);
148 else {
149 pr_warn("Unknown command to io_ring_q%d. Available: kick\n",
150 queue->id);
151 count = -EINVAL;
152 }
153 return count;
154}
155
156static int xenvif_dump_open(struct inode *inode, struct file *filp)
157{
158 int ret;
159 void *queue = NULL;
160
161 if (inode->i_private)
162 queue = inode->i_private;
163 ret = single_open(filp, xenvif_read_io_ring, queue);
164 filp->f_mode |= FMODE_PWRITE;
165 return ret;
166}
167
168static const struct file_operations xenvif_dbg_io_ring_ops_fops = {
169 .owner = THIS_MODULE,
170 .open = xenvif_dump_open,
171 .read = seq_read,
172 .llseek = seq_lseek,
173 .release = single_release,
174 .write = xenvif_write_io_ring,
175};
176
177static void xenvif_debugfs_addif(struct xenvif *vif)
178{
179 struct dentry *pfile;
180 int i;
181
182 if (IS_ERR_OR_NULL(xen_netback_dbg_root))
183 return;
184
185 vif->xenvif_dbg_root = debugfs_create_dir(vif->dev->name,
186 xen_netback_dbg_root);
187 if (!IS_ERR_OR_NULL(vif->xenvif_dbg_root)) {
188 for (i = 0; i < vif->num_queues; ++i) {
189 char filename[sizeof("io_ring_q") + 4];
190
191 snprintf(filename, sizeof(filename), "io_ring_q%d", i);
192 pfile = debugfs_create_file(filename,
193 S_IRUSR | S_IWUSR,
194 vif->xenvif_dbg_root,
195 &vif->queues[i],
196 &xenvif_dbg_io_ring_ops_fops);
197 if (IS_ERR_OR_NULL(pfile))
198 pr_warn("Creation of io_ring file returned %ld!\n",
199 PTR_ERR(pfile));
200 }
201 } else
202 netdev_warn(vif->dev,
203 "Creation of vif debugfs dir returned %ld!\n",
204 PTR_ERR(vif->xenvif_dbg_root));
205}
206
207static void xenvif_debugfs_delif(struct xenvif *vif)
208{
209 if (IS_ERR_OR_NULL(xen_netback_dbg_root))
210 return;
211
212 if (!IS_ERR_OR_NULL(vif->xenvif_dbg_root))
213 debugfs_remove_recursive(vif->xenvif_dbg_root);
214 vif->xenvif_dbg_root = NULL;
215}
216#endif /* CONFIG_DEBUG_FS */
217
47static int netback_remove(struct xenbus_device *dev) 218static int netback_remove(struct xenbus_device *dev)
48{ 219{
49 struct backend_info *be = dev_get_drvdata(&dev->dev); 220 struct backend_info *be = dev_get_drvdata(&dev->dev);
@@ -246,8 +417,12 @@ static void backend_create_xenvif(struct backend_info *be)
246 417
247static void backend_disconnect(struct backend_info *be) 418static void backend_disconnect(struct backend_info *be)
248{ 419{
249 if (be->vif) 420 if (be->vif) {
421#ifdef CONFIG_DEBUG_FS
422 xenvif_debugfs_delif(be->vif);
423#endif /* CONFIG_DEBUG_FS */
250 xenvif_disconnect(be->vif); 424 xenvif_disconnect(be->vif);
425 }
251} 426}
252 427
253static void backend_connect(struct backend_info *be) 428static void backend_connect(struct backend_info *be)
@@ -562,6 +737,10 @@ static void connect(struct backend_info *be)
562 } 737 }
563 } 738 }
564 739
740#ifdef CONFIG_DEBUG_FS
741 xenvif_debugfs_addif(be->vif);
742#endif /* CONFIG_DEBUG_FS */
743
565 /* Initialisation completed, tell core driver the number of 744 /* Initialisation completed, tell core driver the number of
566 * active queues. 745 * active queues.
567 */ 746 */