Drivers: hv: vmbus: Add vendor and device atttributes
authorK. Y. Srinivasan <kys@microsoft.com>
Sat, 26 Dec 2015 04:00:30 +0000 (20:00 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Feb 2016 05:32:57 +0000 (21:32 -0800)
Add vendor and device attributes to VMBUS devices. These will be used
by Hyper-V tools as well user-level RDMA libraries that will use the
vendor/device tuple to discover the RDMA device.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/stable/sysfs-bus-vmbus
drivers/hv/channel_mgmt.c
drivers/hv/vmbus_drv.c
include/linux/hyperv.h

index 636e938d5e33a4e9331a328a05a6b93a0b538e60..5d0125f7bcaf145088359bed69a2ba2cce07fa97 100644 (file)
@@ -27,3 +27,17 @@ Description: The mapping of which primary/sub channels are bound to which
                Virtual Processors.
                Format: <channel's child_relid:the bound cpu's number>
 Users:         tools/hv/lsvmbus
+
+What:          /sys/bus/vmbus/devices/vmbus_*/device
+Date:          Dec. 2015
+KernelVersion: 4.5
+Contact:       K. Y. Srinivasan <kys@microsoft.com>
+Description:   The 16 bit device ID of the device
+Users:         tools/hv/lsvmbus and user level RDMA libraries
+
+What:          /sys/bus/vmbus/devices/vmbus_*/vendor
+Date:          Dec. 2015
+KernelVersion: 4.5
+Contact:       K. Y. Srinivasan <kys@microsoft.com>
+Description:   The 16 bit vendor ID of the device
+Users:         tools/hv/lsvmbus and user level RDMA libraries
index 1c1ad47042c5d7e9a90f29d8a232bab0ad6f2a8a..107d72f9834da4a8c6e35418fd73470529c356ab 100644 (file)
 
 #include "hyperv_vmbus.h"
 
-static void init_vp_index(struct vmbus_channel *channel,
-                         const uuid_le *type_guid);
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type);
+
+static const struct vmbus_device vmbus_devs[] = {
+       /* IDE */
+       { .dev_type = HV_IDE,
+         HV_IDE_GUID,
+         .perf_device = true,
+       },
+
+       /* SCSI */
+       { .dev_type = HV_SCSI,
+         HV_SCSI_GUID,
+         .perf_device = true,
+       },
+
+       /* Fibre Channel */
+       { .dev_type = HV_FC,
+         HV_SYNTHFC_GUID,
+         .perf_device = true,
+       },
+
+       /* Synthetic NIC */
+       { .dev_type = HV_NIC,
+         HV_NIC_GUID,
+         .perf_device = true,
+       },
+
+       /* Network Direct */
+       { .dev_type = HV_ND,
+         HV_ND_GUID,
+         .perf_device = true,
+       },
+
+       /* PCIE */
+       { .dev_type = HV_PCIE,
+         HV_PCIE_GUID,
+         .perf_device = true,
+       },
+
+       /* Synthetic Frame Buffer */
+       { .dev_type = HV_FB,
+         HV_SYNTHVID_GUID,
+         .perf_device = false,
+       },
+
+       /* Synthetic Keyboard */
+       { .dev_type = HV_KBD,
+         HV_KBD_GUID,
+         .perf_device = false,
+       },
+
+       /* Synthetic MOUSE */
+       { .dev_type = HV_MOUSE,
+         HV_MOUSE_GUID,
+         .perf_device = false,
+       },
+
+       /* KVP */
+       { .dev_type = HV_KVP,
+         HV_KVP_GUID,
+         .perf_device = false,
+       },
+
+       /* Time Synch */
+       { .dev_type = HV_TS,
+         HV_TS_GUID,
+         .perf_device = false,
+       },
+
+       /* Heartbeat */
+       { .dev_type = HV_HB,
+         HV_HEART_BEAT_GUID,
+         .perf_device = false,
+       },
+
+       /* Shutdown */
+       { .dev_type = HV_SHUTDOWN,
+         HV_SHUTDOWN_GUID,
+         .perf_device = false,
+       },
+
+       /* File copy */
+       { .dev_type = HV_FCOPY,
+         HV_FCOPY_GUID,
+         .perf_device = false,
+       },
+
+       /* Backup */
+       { .dev_type = HV_BACKUP,
+         HV_VSS_GUID,
+         .perf_device = false,
+       },
+
+       /* Dynamic Memory */
+       { .dev_type = HV_DM,
+         HV_DM_GUID,
+         .perf_device = false,
+       },
+
+       /* Unknown GUID */
+       { .dev_type = HV_UNKOWN,
+         .perf_device = false,
+       },
+};
+
+static u16 hv_get_dev_type(const uuid_le *guid)
+{
+       u16 i;
+
+       for (i = HV_IDE; i < HV_UNKOWN; i++) {
+               if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
+                       return i;
+       }
+       pr_info("Unknown GUID: %pUl\n", guid);
+       return i;
+}
 
 /**
  * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
@@ -251,6 +365,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
        struct vmbus_channel *channel;
        bool fnew = true;
        unsigned long flags;
+       u16 dev_type;
 
        /* Make sure this is a new offer */
        mutex_lock(&vmbus_connection.channel_mutex);
@@ -288,7 +403,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
                        goto err_free_chan;
        }
 
-       init_vp_index(newchannel, &newchannel->offermsg.offer.if_type);
+       dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type);
+
+       init_vp_index(newchannel, dev_type);
 
        if (newchannel->target_cpu != get_cpu()) {
                put_cpu();
@@ -325,6 +442,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
        if (!newchannel->device_obj)
                goto err_deq_chan;
 
+       newchannel->device_obj->device_id = dev_type;
        /*
         * Add the new device to the bus. This will kick off device-driver
         * binding which eventually invokes the device driver's AddDevice()
@@ -358,37 +476,6 @@ err_free_chan:
        free_channel(newchannel);
 }
 
-enum {
-       IDE = 0,
-       SCSI,
-       FC,
-       NIC,
-       ND_NIC,
-       PCIE,
-       MAX_PERF_CHN,
-};
-
-/*
- * This is an array of device_ids (device types) that are performance critical.
- * We attempt to distribute the interrupt load for these devices across
- * all available CPUs.
- */
-static const struct hv_vmbus_device_id hp_devs[] = {
-       /* IDE */
-       { HV_IDE_GUID, },
-       /* Storage - SCSI */
-       { HV_SCSI_GUID, },
-       /* Storage - FC */
-       { HV_SYNTHFC_GUID, },
-       /* Network */
-       { HV_NIC_GUID, },
-       /* NetworkDirect Guest RDMA */
-       { HV_ND_GUID, },
-       /* PCI Express Pass Through */
-       { HV_PCIE_GUID, },
-};
-
-
 /*
  * We use this state to statically distribute the channel interrupt load.
  */
@@ -405,22 +492,15 @@ static int next_numa_node_id;
  * For pre-win8 hosts or non-performance critical channels we assign the
  * first CPU in the first NUMA node.
  */
-static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid)
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
 {
        u32 cur_cpu;
-       int i;
-       bool perf_chn = false;
+       bool perf_chn = vmbus_devs[dev_type].perf_device;
        struct vmbus_channel *primary = channel->primary_channel;
        int next_node;
        struct cpumask available_mask;
        struct cpumask *alloced_mask;
 
-       for (i = IDE; i < MAX_PERF_CHN; i++) {
-               if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) {
-                       perf_chn = true;
-                       break;
-               }
-       }
        if ((vmbus_proto_version == VERSION_WS2008) ||
            (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
                /*
index 328e4c3808e06d146add9ade074efd2d1728e1dd..3668a95778ec213f4bd73086fd4f8b37eb0e2a7c 100644 (file)
@@ -477,6 +477,24 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(channel_vp_mapping);
 
+static ssize_t vendor_show(struct device *dev,
+                          struct device_attribute *dev_attr,
+                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       return sprintf(buf, "0x%x\n", hv_dev->vendor_id);
+}
+static DEVICE_ATTR_RO(vendor);
+
+static ssize_t device_show(struct device *dev,
+                          struct device_attribute *dev_attr,
+                          char *buf)
+{
+       struct hv_device *hv_dev = device_to_hv_device(dev);
+       return sprintf(buf, "0x%x\n", hv_dev->device_id);
+}
+static DEVICE_ATTR_RO(device);
+
 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
 static struct attribute *vmbus_attrs[] = {
        &dev_attr_id.attr,
@@ -502,6 +520,8 @@ static struct attribute *vmbus_attrs[] = {
        &dev_attr_in_read_bytes_avail.attr,
        &dev_attr_in_write_bytes_avail.attr,
        &dev_attr_channel_vp_mapping.attr,
+       &dev_attr_vendor.attr,
+       &dev_attr_device.attr,
        NULL,
 };
 ATTRIBUTE_GROUPS(vmbus);
@@ -957,6 +977,7 @@ struct hv_device *vmbus_device_create(const uuid_le *type,
        memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
        memcpy(&child_device_obj->dev_instance, instance,
               sizeof(uuid_le));
+       child_device_obj->vendor_id = 0x1414; /* MSFT vendor ID */
 
 
        return child_device_obj;
index 753dbad0bf94302c09c6807fcb47027c2f230dbb..3172521df805f5df46aef831782f8c1dd1de2976 100644 (file)
@@ -633,6 +633,32 @@ enum hv_signal_policy {
        HV_SIGNAL_POLICY_EXPLICIT,
 };
 
+enum vmbus_device_type {
+       HV_IDE = 0,
+       HV_SCSI,
+       HV_FC,
+       HV_NIC,
+       HV_ND,
+       HV_PCIE,
+       HV_FB,
+       HV_KBD,
+       HV_MOUSE,
+       HV_KVP,
+       HV_TS,
+       HV_HB,
+       HV_SHUTDOWN,
+       HV_FCOPY,
+       HV_BACKUP,
+       HV_DM,
+       HV_UNKOWN,
+};
+
+struct vmbus_device {
+       u16  dev_type;
+       uuid_le guid;
+       bool perf_device;
+};
+
 struct vmbus_channel {
        /* Unique channel id */
        int id;
@@ -959,6 +985,8 @@ struct hv_device {
 
        /* the device instance id of this device */
        uuid_le dev_instance;
+       u16 vendor_id;
+       u16 device_id;
 
        struct device device;