On 2/17/2015 8:13 AM, Thomas Monjalon wrote:
> 2015-02-16 13:14, Tetsuya Mukawa:
>> From: Michael Qiu <michael.qiu at intel.com>
>>
>> Currently, dpdk has no ability to know which type of driver(
>> vfio-pci/igb_uio/uio_pci_generic) the device used. It only can
>> check whether vfio is enabled or not staticly.
>>
>> It really useful to have the flag, becasue different type need to
>> handle differently in runtime. For example, pci memory map,
>> pot hotplug, and so on.
>>
>> This patch add a flag field for pci device to solve above issue.
>>
>> Signed-off-by: Michael Qiu <michael.qiu at intel.com>
>> Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
>> ---
>>  lib/librte_eal/common/include/rte_pci.h |  8 +++++
>>  lib/librte_eal/linuxapp/eal/eal_pci.c   | 53 
>> +++++++++++++++++++++++++++++++--
>>  2 files changed, 59 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/librte_eal/common/include/rte_pci.h 
>> b/lib/librte_eal/common/include/rte_pci.h
>> index 66ed793..7b48b55 100644
>> --- a/lib/librte_eal/common/include/rte_pci.h
>> +++ b/lib/librte_eal/common/include/rte_pci.h
>> @@ -139,6 +139,13 @@ struct rte_pci_addr {
>>  
>>  struct rte_devargs;
>>  
>> +enum rte_pt_driver {
>> +    RTE_PT_UNKNOWN          = 0,
>> +    RTE_PT_IGB_UIO          = 1,
>> +    RTE_PT_VFIO             = 2,
>> +    RTE_PT_UIO_GENERIC      = 3,
>> +};
> What means PT?
>
>> +
>>  /**
>>   * A structure describing a PCI device.
>>   */
>> @@ -152,6 +159,7 @@ struct rte_pci_device {
>>      uint16_t max_vfs;                       /**< sriov enable if not zero */
>>      int numa_node;                          /**< NUMA node connection */
>>      struct rte_devargs *devargs;            /**< Device user arguments */
>> +    enum rte_pt_driver pt_driver;           /**< Driver of passthrough */
> I'm not sure passtrough is the right word for this kind of driver.
> What about "kernel driver"?

We only care vfio and uio driver, here pass through means pass the
devices from kernel to userspace

If use "kernel driver"or "kn_driver", there will be some issue that we
set to "UNKNOWN" when the devices use the native linux kernel driver.


>
>>  };
>>  
>>  /** Any PCI device identifier (vendor, device, ...) */
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c 
>> b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> index 15db9c4..e760452 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
>> @@ -97,6 +97,35 @@ error:
>>      return -1;
>>  }
>>  
>> +static int
>> +pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
>> +{
>> +    int count;
>> +    char path[PATH_MAX];
>> +    char *name;
>> +
>> +    if (!filename || !dri_name)
>> +            return -1;
>> +
>> +    count = readlink(filename, path, PATH_MAX);
>> +    if (count >= PATH_MAX)
>> +            return -1;
>> +
>> +    /* For device does not have a driver */
>> +    if (count < 0)
>> +            return 1;
>> +
>> +    path[count] = '\0';
>> +
>> +    name = strrchr(path, '/');
>> +    if (name) {
>> +            strncpy(dri_name, name + 1, strlen(name + 1) + 1);
>> +            return 0;
>> +    }
>> +
>> +    return -1;
>> +}
>> +
>>  void *
>>  pci_find_max_end_va(void)
>>  {
>> @@ -222,11 +251,12 @@ pci_scan_one(const char *dirname, uint16_t domain, 
>> uint8_t bus,
>>      char filename[PATH_MAX];
>>      unsigned long tmp;
>>      struct rte_pci_device *dev;
>> +    char driver[PATH_MAX];
>> +    int ret;
>>  
>>      dev = malloc(sizeof(*dev));
>> -    if (dev == NULL) {
>> +    if (dev == NULL)
>>              return -1;
>> -    }
>>  
>>      memset(dev, 0, sizeof(*dev));
>>      dev->addr.domain = domain;
>> @@ -305,6 +335,25 @@ pci_scan_one(const char *dirname, uint16_t domain, 
>> uint8_t bus,
>>              return -1;
>>      }
>>  
>> +    /* parse driver */
>> +    snprintf(filename, sizeof(filename), "%s/driver", dirname);
>> +    ret = pci_get_kernel_driver_by_path(filename, driver);
>> +    if (!ret) {
>> +            if (!strcmp(driver, "vfio-pci"))
>> +                    dev->pt_driver = RTE_PT_VFIO;
>> +            else if (!strcmp(driver, "igb_uio"))
>> +                    dev->pt_driver = RTE_PT_IGB_UIO;
>> +            else if (!strcmp(driver, "uio_pci_generic"))
>> +                    dev->pt_driver = RTE_PT_UIO_GENERIC;
>> +            else
>> +                    dev->pt_driver = RTE_PT_UNKNOWN;
>> +    } else if (ret < 0) {
>> +            RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
>> +            free(dev);
>> +            return -1;
>> +    } else
>> +            dev->pt_driver = RTE_PT_UNKNOWN;
> Why not considering a NONE value? Example: for virtio with port I/O.

Why NONE? Do you mean, leave it unset? RTE_PT_UNKNOWN equals to zero,
when code runs here means the devices does not have a driver or not bind
to any driver.

For virtio with port I/O, as I know it will use the kernel driver
virtio-pci. So it will not run here.

Thanks,
Michael
>
>> +
>>      /* device is valid, add in list (sorted) */
>>      if (TAILQ_EMPTY(&pci_device_list)) {
>>              TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
>>
>
>

Reply via email to