Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

misc: mic: Enable VOP debugfs and driver build

This patch moves the virtio specific debugfs hooks previously in
mic_debugfs.c in the MIC host driver into the VOP driver. The
Kconfig/Makefile is also updated to allow building the VOP driver.

Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Sudeep Dutt and committed by
Greg Kroah-Hartman
8810df37 c1becd28

+262
+20
drivers/misc/mic/Kconfig
··· 124 124 More information about the Intel MIC family as well as the Linux 125 125 OS and tools for MIC to use with this driver are available from 126 126 <http://software.intel.com/en-us/mic-developer>. 127 + 128 + comment "VOP Driver" 129 + 130 + config VOP 131 + tristate "VOP Driver" 132 + depends on 64BIT && PCI && X86 && VOP_BUS 133 + select VHOST_RING 134 + help 135 + This enables VOP (Virtio over PCIe) Driver support for the Intel 136 + Many Integrated Core (MIC) family of PCIe form factor coprocessor 137 + devices. The VOP driver allows virtio drivers, e.g. net, console 138 + and block drivers, on the card connect to user space virtio 139 + devices on the host. 140 + 141 + If you are building a host kernel with an Intel MIC device then 142 + say M (recommended) or Y, else say N. If unsure say N. 143 + 144 + More information about the Intel MIC family as well as the Linux 145 + OS and tools for MIC to use with this driver are available from 146 + <http://software.intel.com/en-us/mic-developer>.
+1
drivers/misc/mic/Makefile
··· 8 8 obj-$(CONFIG_SCIF) += scif/ 9 9 obj-$(CONFIG_MIC_COSM) += cosm/ 10 10 obj-$(CONFIG_MIC_COSM) += cosm_client/ 11 + obj-$(CONFIG_VOP) += vop/
+9
drivers/misc/mic/vop/Makefile
··· 1 + # 2 + # Makefile - Intel MIC Linux driver. 3 + # Copyright(c) 2016, Intel Corporation. 4 + # 5 + obj-m := vop.o 6 + 7 + vop-objs += vop_main.o 8 + vop-objs += vop_debugfs.o 9 + vop-objs += vop_vringh.o
+232
drivers/misc/mic/vop/vop_debugfs.c
··· 1 + /* 2 + * Intel MIC Platform Software Stack (MPSS) 3 + * 4 + * Copyright(c) 2016 Intel Corporation. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License, version 2, as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 + * General Public License for more details. 14 + * 15 + * The full GNU General Public License is included in this distribution in 16 + * the file called "COPYING". 17 + * 18 + * Intel Virtio Over PCIe (VOP) driver. 19 + * 20 + */ 21 + #include <linux/debugfs.h> 22 + #include <linux/seq_file.h> 23 + 24 + #include "vop_main.h" 25 + 26 + static int vop_dp_show(struct seq_file *s, void *pos) 27 + { 28 + struct mic_device_desc *d; 29 + struct mic_device_ctrl *dc; 30 + struct mic_vqconfig *vqconfig; 31 + __u32 *features; 32 + __u8 *config; 33 + struct vop_info *vi = s->private; 34 + struct vop_device *vpdev = vi->vpdev; 35 + struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev); 36 + int j, k; 37 + 38 + seq_printf(s, "Bootparam: magic 0x%x\n", 39 + bootparam->magic); 40 + seq_printf(s, "Bootparam: h2c_config_db %d\n", 41 + bootparam->h2c_config_db); 42 + seq_printf(s, "Bootparam: node_id %d\n", 43 + bootparam->node_id); 44 + seq_printf(s, "Bootparam: c2h_scif_db %d\n", 45 + bootparam->c2h_scif_db); 46 + seq_printf(s, "Bootparam: h2c_scif_db %d\n", 47 + bootparam->h2c_scif_db); 48 + seq_printf(s, "Bootparam: scif_host_dma_addr 0x%llx\n", 49 + bootparam->scif_host_dma_addr); 50 + seq_printf(s, "Bootparam: scif_card_dma_addr 0x%llx\n", 51 + bootparam->scif_card_dma_addr); 52 + 53 + for (j = sizeof(*bootparam); 54 + j < MIC_DP_SIZE; j += mic_total_desc_size(d)) { 55 + d = (void *)bootparam + j; 56 + dc = (void *)d + mic_aligned_desc_size(d); 57 + 58 + /* end of list */ 59 + if (d->type == 0) 60 + break; 61 + 62 + if (d->type == -1) 63 + continue; 64 + 65 + seq_printf(s, "Type %d ", d->type); 66 + seq_printf(s, "Num VQ %d ", d->num_vq); 67 + seq_printf(s, "Feature Len %d\n", d->feature_len); 68 + seq_printf(s, "Config Len %d ", d->config_len); 69 + seq_printf(s, "Shutdown Status %d\n", d->status); 70 + 71 + for (k = 0; k < d->num_vq; k++) { 72 + vqconfig = mic_vq_config(d) + k; 73 + seq_printf(s, "vqconfig[%d]: ", k); 74 + seq_printf(s, "address 0x%llx ", 75 + vqconfig->address); 76 + seq_printf(s, "num %d ", vqconfig->num); 77 + seq_printf(s, "used address 0x%llx\n", 78 + vqconfig->used_address); 79 + } 80 + 81 + features = (__u32 *)mic_vq_features(d); 82 + seq_printf(s, "Features: Host 0x%x ", features[0]); 83 + seq_printf(s, "Guest 0x%x\n", features[1]); 84 + 85 + config = mic_vq_configspace(d); 86 + for (k = 0; k < d->config_len; k++) 87 + seq_printf(s, "config[%d]=%d\n", k, config[k]); 88 + 89 + seq_puts(s, "Device control:\n"); 90 + seq_printf(s, "Config Change %d ", dc->config_change); 91 + seq_printf(s, "Vdev reset %d\n", dc->vdev_reset); 92 + seq_printf(s, "Guest Ack %d ", dc->guest_ack); 93 + seq_printf(s, "Host ack %d\n", dc->host_ack); 94 + seq_printf(s, "Used address updated %d ", 95 + dc->used_address_updated); 96 + seq_printf(s, "Vdev 0x%llx\n", dc->vdev); 97 + seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db); 98 + seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db); 99 + } 100 + schedule_work(&vi->hotplug_work); 101 + return 0; 102 + } 103 + 104 + static int vop_dp_debug_open(struct inode *inode, struct file *file) 105 + { 106 + return single_open(file, vop_dp_show, inode->i_private); 107 + } 108 + 109 + static int vop_dp_debug_release(struct inode *inode, struct file *file) 110 + { 111 + return single_release(inode, file); 112 + } 113 + 114 + static const struct file_operations dp_ops = { 115 + .owner = THIS_MODULE, 116 + .open = vop_dp_debug_open, 117 + .read = seq_read, 118 + .llseek = seq_lseek, 119 + .release = vop_dp_debug_release 120 + }; 121 + 122 + static int vop_vdev_info_show(struct seq_file *s, void *unused) 123 + { 124 + struct vop_info *vi = s->private; 125 + struct list_head *pos, *tmp; 126 + struct vop_vdev *vdev; 127 + int i, j; 128 + 129 + mutex_lock(&vi->vop_mutex); 130 + list_for_each_safe(pos, tmp, &vi->vdev_list) { 131 + vdev = list_entry(pos, struct vop_vdev, list); 132 + seq_printf(s, "VDEV type %d state %s in %ld out %ld in_dma %ld out_dma %ld\n", 133 + vdev->virtio_id, 134 + vop_vdevup(vdev) ? "UP" : "DOWN", 135 + vdev->in_bytes, 136 + vdev->out_bytes, 137 + vdev->in_bytes_dma, 138 + vdev->out_bytes_dma); 139 + for (i = 0; i < MIC_MAX_VRINGS; i++) { 140 + struct vring_desc *desc; 141 + struct vring_avail *avail; 142 + struct vring_used *used; 143 + struct vop_vringh *vvr = &vdev->vvr[i]; 144 + struct vringh *vrh = &vvr->vrh; 145 + int num = vrh->vring.num; 146 + 147 + if (!num) 148 + continue; 149 + desc = vrh->vring.desc; 150 + seq_printf(s, "vring i %d avail_idx %d", 151 + i, vvr->vring.info->avail_idx & (num - 1)); 152 + seq_printf(s, " vring i %d avail_idx %d\n", 153 + i, vvr->vring.info->avail_idx); 154 + seq_printf(s, "vrh i %d weak_barriers %d", 155 + i, vrh->weak_barriers); 156 + seq_printf(s, " last_avail_idx %d last_used_idx %d", 157 + vrh->last_avail_idx, vrh->last_used_idx); 158 + seq_printf(s, " completed %d\n", vrh->completed); 159 + for (j = 0; j < num; j++) { 160 + seq_printf(s, "desc[%d] addr 0x%llx len %d", 161 + j, desc->addr, desc->len); 162 + seq_printf(s, " flags 0x%x next %d\n", 163 + desc->flags, desc->next); 164 + desc++; 165 + } 166 + avail = vrh->vring.avail; 167 + seq_printf(s, "avail flags 0x%x idx %d\n", 168 + vringh16_to_cpu(vrh, avail->flags), 169 + vringh16_to_cpu(vrh, 170 + avail->idx) & (num - 1)); 171 + seq_printf(s, "avail flags 0x%x idx %d\n", 172 + vringh16_to_cpu(vrh, avail->flags), 173 + vringh16_to_cpu(vrh, avail->idx)); 174 + for (j = 0; j < num; j++) 175 + seq_printf(s, "avail ring[%d] %d\n", 176 + j, avail->ring[j]); 177 + used = vrh->vring.used; 178 + seq_printf(s, "used flags 0x%x idx %d\n", 179 + vringh16_to_cpu(vrh, used->flags), 180 + vringh16_to_cpu(vrh, used->idx) & (num - 1)); 181 + seq_printf(s, "used flags 0x%x idx %d\n", 182 + vringh16_to_cpu(vrh, used->flags), 183 + vringh16_to_cpu(vrh, used->idx)); 184 + for (j = 0; j < num; j++) 185 + seq_printf(s, "used ring[%d] id %d len %d\n", 186 + j, vringh32_to_cpu(vrh, 187 + used->ring[j].id), 188 + vringh32_to_cpu(vrh, 189 + used->ring[j].len)); 190 + } 191 + } 192 + mutex_unlock(&vi->vop_mutex); 193 + 194 + return 0; 195 + } 196 + 197 + static int vop_vdev_info_debug_open(struct inode *inode, struct file *file) 198 + { 199 + return single_open(file, vop_vdev_info_show, inode->i_private); 200 + } 201 + 202 + static int vop_vdev_info_debug_release(struct inode *inode, struct file *file) 203 + { 204 + return single_release(inode, file); 205 + } 206 + 207 + static const struct file_operations vdev_info_ops = { 208 + .owner = THIS_MODULE, 209 + .open = vop_vdev_info_debug_open, 210 + .read = seq_read, 211 + .llseek = seq_lseek, 212 + .release = vop_vdev_info_debug_release 213 + }; 214 + 215 + void vop_init_debugfs(struct vop_info *vi) 216 + { 217 + char name[16]; 218 + 219 + snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode); 220 + vi->dbg = debugfs_create_dir(name, NULL); 221 + if (!vi->dbg) { 222 + pr_err("can't create debugfs dir vop\n"); 223 + return; 224 + } 225 + debugfs_create_file("dp", 0444, vi->dbg, vi, &dp_ops); 226 + debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vdev_info_ops); 227 + } 228 + 229 + void vop_exit_debugfs(struct vop_info *vi) 230 + { 231 + debugfs_remove_recursive(vi->dbg); 232 + }