aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mic/host/mic_debugfs.c
diff options
context:
space:
mode:
authorAshutosh Dixit <ashutosh.dixit@intel.com>2013-09-05 19:42:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 16:50:56 -0400
commitf69bcbf3b4c4b333dcd7a48eaf868bf0c88edab5 (patch)
tree82edf895c9db652788945faafb8d4301f79cb5f8 /drivers/misc/mic/host/mic_debugfs.c
parentaa27badd8972adb731f05d49ab74ec63e0826935 (diff)
Intel MIC Host Driver Changes for Virtio Devices.
This patch introduces the host "Virtio over PCIe" interface for Intel MIC. It allows creating user space backends on the host and instantiating virtio devices for them on the Intel MIC card. It uses the existing VRINGH infrastructure in the kernel to access virtio rings from the host. A character device per MIC is exposed with IOCTL, mmap and poll callbacks. This allows the user space backend to: (a) add/remove a virtio device via a device page. (b) map (R/O) virtio rings and device page to user space. (c) poll for availability of data. (d) copy a descriptor or entire descriptor chain to/from the card. (e) modify virtio configuration. (f) handle virtio device reset. The buffers are copied over using CPU copies for this initial patch and host initiated MIC DMA support is planned for future patches. The avail and desc virtio rings are in host memory and the used ring is in card memory to maximize writes across PCIe for performance. Co-author: Sudeep Dutt <sudeep.dutt@intel.com> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Signed-off-by: Caz Yokoyama <Caz.Yokoyama@intel.com> Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com> Signed-off-by: Harshavardhan R Kharche <harshavardhan.r.kharche@intel.com> Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com> Acked-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Reviewed-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mic/host/mic_debugfs.c')
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
index 78541d42aaf9..e22fb7bbbb98 100644
--- a/drivers/misc/mic/host/mic_debugfs.c
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -26,6 +26,7 @@
26#include "../common/mic_device.h" 26#include "../common/mic_device.h"
27#include "mic_device.h" 27#include "mic_device.h"
28#include "mic_smpt.h" 28#include "mic_smpt.h"
29#include "mic_virtio.h"
29 30
30/* Debugfs parent dir */ 31/* Debugfs parent dir */
31static struct dentry *mic_dbg; 32static struct dentry *mic_dbg;
@@ -193,7 +194,13 @@ static const struct file_operations post_code_ops = {
193static int mic_dp_show(struct seq_file *s, void *pos) 194static int mic_dp_show(struct seq_file *s, void *pos)
194{ 195{
195 struct mic_device *mdev = s->private; 196 struct mic_device *mdev = s->private;
197 struct mic_device_desc *d;
198 struct mic_device_ctrl *dc;
199 struct mic_vqconfig *vqconfig;
200 __u32 *features;
201 __u8 *config;
196 struct mic_bootparam *bootparam = mdev->dp; 202 struct mic_bootparam *bootparam = mdev->dp;
203 int i, j;
197 204
198 seq_printf(s, "Bootparam: magic 0x%x\n", 205 seq_printf(s, "Bootparam: magic 0x%x\n",
199 bootparam->magic); 206 bootparam->magic);
@@ -208,6 +215,53 @@ static int mic_dp_show(struct seq_file *s, void *pos)
208 seq_printf(s, "Bootparam: shutdown_card %d\n", 215 seq_printf(s, "Bootparam: shutdown_card %d\n",
209 bootparam->shutdown_card); 216 bootparam->shutdown_card);
210 217
218 for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
219 i += mic_total_desc_size(d)) {
220 d = mdev->dp + i;
221 dc = (void *)d + mic_aligned_desc_size(d);
222
223 /* end of list */
224 if (d->type == 0)
225 break;
226
227 if (d->type == -1)
228 continue;
229
230 seq_printf(s, "Type %d ", d->type);
231 seq_printf(s, "Num VQ %d ", d->num_vq);
232 seq_printf(s, "Feature Len %d\n", d->feature_len);
233 seq_printf(s, "Config Len %d ", d->config_len);
234 seq_printf(s, "Shutdown Status %d\n", d->status);
235
236 for (j = 0; j < d->num_vq; j++) {
237 vqconfig = mic_vq_config(d) + j;
238 seq_printf(s, "vqconfig[%d]: ", j);
239 seq_printf(s, "address 0x%llx ", vqconfig->address);
240 seq_printf(s, "num %d ", vqconfig->num);
241 seq_printf(s, "used address 0x%llx\n",
242 vqconfig->used_address);
243 }
244
245 features = (__u32 *) mic_vq_features(d);
246 seq_printf(s, "Features: Host 0x%x ", features[0]);
247 seq_printf(s, "Guest 0x%x\n", features[1]);
248
249 config = mic_vq_configspace(d);
250 for (j = 0; j < d->config_len; j++)
251 seq_printf(s, "config[%d]=%d\n", j, config[j]);
252
253 seq_puts(s, "Device control:\n");
254 seq_printf(s, "Config Change %d ", dc->config_change);
255 seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
256 seq_printf(s, "Guest Ack %d ", dc->guest_ack);
257 seq_printf(s, "Host ack %d\n", dc->host_ack);
258 seq_printf(s, "Used address updated %d ",
259 dc->used_address_updated);
260 seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
261 seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
262 seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
263 }
264
211 return 0; 265 return 0;
212} 266}
213 267
@@ -229,6 +283,89 @@ static const struct file_operations dp_ops = {
229 .release = mic_dp_debug_release 283 .release = mic_dp_debug_release
230}; 284};
231 285
286static int mic_vdev_info_show(struct seq_file *s, void *unused)
287{
288 struct mic_device *mdev = s->private;
289 struct list_head *pos, *tmp;
290 struct mic_vdev *mvdev;
291 int i, j;
292
293 mutex_lock(&mdev->mic_mutex);
294 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
295 mvdev = list_entry(pos, struct mic_vdev, list);
296 seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
297 mvdev->virtio_id,
298 mic_vdevup(mvdev) ? "UP" : "DOWN",
299 mvdev->in_bytes,
300 mvdev->out_bytes);
301 for (i = 0; i < MIC_MAX_VRINGS; i++) {
302 struct vring_desc *desc;
303 struct vring_avail *avail;
304 struct vring_used *used;
305 struct mic_vringh *mvr = &mvdev->mvr[i];
306 struct vringh *vrh = &mvr->vrh;
307 int num = vrh->vring.num;
308 if (!num)
309 continue;
310 desc = vrh->vring.desc;
311 seq_printf(s, "vring i %d avail_idx %d",
312 i, mvr->vring.info->avail_idx & (num - 1));
313 seq_printf(s, " vring i %d avail_idx %d\n",
314 i, mvr->vring.info->avail_idx);
315 seq_printf(s, "vrh i %d weak_barriers %d",
316 i, vrh->weak_barriers);
317 seq_printf(s, " last_avail_idx %d last_used_idx %d",
318 vrh->last_avail_idx, vrh->last_used_idx);
319 seq_printf(s, " completed %d\n", vrh->completed);
320 for (j = 0; j < num; j++) {
321 seq_printf(s, "desc[%d] addr 0x%llx len %d",
322 j, desc->addr, desc->len);
323 seq_printf(s, " flags 0x%x next %d\n",
324 desc->flags,
325 desc->next);
326 desc++;
327 }
328 avail = vrh->vring.avail;
329 seq_printf(s, "avail flags 0x%x idx %d\n",
330 avail->flags, avail->idx & (num - 1));
331 seq_printf(s, "avail flags 0x%x idx %d\n",
332 avail->flags, avail->idx);
333 for (j = 0; j < num; j++)
334 seq_printf(s, "avail ring[%d] %d\n",
335 j, avail->ring[j]);
336 used = vrh->vring.used;
337 seq_printf(s, "used flags 0x%x idx %d\n",
338 used->flags, used->idx & (num - 1));
339 seq_printf(s, "used flags 0x%x idx %d\n",
340 used->flags, used->idx);
341 for (j = 0; j < num; j++)
342 seq_printf(s, "used ring[%d] id %d len %d\n",
343 j, used->ring[j].id, used->ring[j].len);
344 }
345 }
346 mutex_unlock(&mdev->mic_mutex);
347
348 return 0;
349}
350
351static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
352{
353 return single_open(file, mic_vdev_info_show, inode->i_private);
354}
355
356static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
357{
358 return single_release(inode, file);
359}
360
361static const struct file_operations vdev_info_ops = {
362 .owner = THIS_MODULE,
363 .open = mic_vdev_info_debug_open,
364 .read = seq_read,
365 .llseek = seq_lseek,
366 .release = mic_vdev_info_debug_release
367};
368
232static int mic_msi_irq_info_show(struct seq_file *s, void *pos) 369static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
233{ 370{
234 struct mic_device *mdev = s->private; 371 struct mic_device *mdev = s->private;
@@ -321,6 +458,9 @@ void mic_create_debug_dir(struct mic_device *mdev)
321 debugfs_create_file("dp", 0444, mdev->dbg_dir, 458 debugfs_create_file("dp", 0444, mdev->dbg_dir,
322 mdev, &dp_ops); 459 mdev, &dp_ops);
323 460
461 debugfs_create_file("vdev_info", 0444, mdev->dbg_dir,
462 mdev, &vdev_info_ops);
463
324 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, 464 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir,
325 mdev, &msi_irq_info_ops); 465 mdev, &msi_irq_info_ops);
326} 466}