[libvirt] [PATCHv2] SRIOV NIC offload feature discovery

Ján Tomko jtomko at redhat.com
Thu Mar 5 10:38:37 UTC 2015


On Mon, Feb 23, 2015 at 03:38:29PM +0000, James Chapman wrote:
> Adding functionality to libvirt that will allow it
> query the ethtool interface for the availability
> of certain NIC HW offload features
> 
> Here is an example of the feature XML definition:
> 
> <device>
> <name>net_eth4_90_e2_ba_5e_a5_45</name>
>   <path>/sys/devices/pci0000:00/0000:00:03.0/0000:08:00.1/net/eth4</path>
>   <parent>pci_0000_08_00_1</parent>
>   <capability type='net'>
>     <interface>eth4</interface>
>     <address>90:e2:ba:5e:a5:45</address>
>     <link speed='10000' state='up'/>
>     <feature name='rx'/>
>     <feature name='tx'/>
>     <feature name='sg'/>
>     <feature name='tso'/>
>     <feature name='gso'/>
>     <feature name='gro'/>
>     <feature name='rxvlan'/>
>     <feature name='txvlan'/>
>     <feature name='rxhash'/>
>     <capability type='80203'/>
>   </capability>
> </device>
> ---
>  docs/formatnode.html.in                           |  18 +++
>  docs/schemas/nodedev.rng                          |  14 +++
>  src/conf/device_conf.h                            |   6 +
>  src/conf/node_device_conf.c                       |  45 ++++++-
>  src/conf/node_device_conf.h                       |   2 +
>  src/libvirt_private.syms                          |   1 +
>  src/node_device/node_device_udev.c                |   4 +
>  src/util/virnetdev.c                              | 143 ++++++++++++++++++++++
>  src/util/virnetdev.h                              |   7 ++
>  tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml |   9 ++
>  tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml |   9 ++
>  11 files changed, 257 insertions(+), 1 deletion(-)
> 

> diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
> index 7256cdc..091f2f0 100644
> --- a/src/conf/device_conf.h
> +++ b/src/conf/device_conf.h
> @@ -62,6 +62,12 @@ struct _virInterfaceLink {
>      unsigned int speed;      /* link speed in Mbits per second */
>  };
>  
> +typedef struct _virDevFeature virDevFeature;
> +typedef virDevFeature *virDevFeaturePtr;
> +struct _virDevFeature {
> +   char *name;             /* device feature */
> +};
> +

This would be much nicer stored in a bitmap.

I added an enum type for all the features, fixed the nits below and
pushed the patch.

> +/**
> + * virNetDevGetFeatures:
> + * This function gets the nic offloads features available for ifname
> + *
> + * @ifname: name of the interface
> + * @features: network device feature structures
> + * @nfeatures: number of features available
> + *
> + * Returns 0 on success, -1 on failure.
> + */
> +int
> +virNetDevGetFeatures(const char *ifname,
> +                     virDevFeaturePtr *features,
> +                     size_t *nfeatures)
> +{
> +    int ret = -1;
> +    size_t i = -1;
> +    size_t j = -1;
> +    struct ethtool_value cmd;
> +    virDevFeaturePtr tmpfeature = NULL;
> +
> +    struct elem{
> +        const char *name;
> +        const int cmd;
> +    };
> +    /* legacy ethtool getters */
> +    struct elem cmds[] = {
> +        {"rx",     ETHTOOL_GRXCSUM},
> +        {"tx",     ETHTOOL_GTXCSUM },
> +        {"sg",     ETHTOOL_GSG},
> +        {"tso",    ETHTOOL_GTSO},
> +        {"gso",    ETHTOOL_GGSO},
> +        {"gro",    ETHTOOL_GGRO},
> +    };
> +    /* ethtool masks */
> +    struct elem flags[] = {
> +        {"lro",    ETH_FLAG_LRO},
> +        {"rxvlan", ETH_FLAG_RXVLAN},
> +        {"txvlan", ETH_FLAG_TXVLAN},
> +        {"ntuple", ETH_FLAG_NTUPLE},
> +        {"rxhash", ETH_FLAG_RXHASH},
> +    };
> +
> +    for (i = 0; i < ARRAY_CARDINALITY(cmds); i++) {
> +        cmd.cmd = cmds[i].cmd;
> +        if (virNetDevFeatureAvailable(ifname, &cmd)) {
> +            if (VIR_ALLOC(tmpfeature) < 0)
> +                goto cleanup;
> +            if ((ret = VIR_STRDUP(tmpfeature->name, cmds[i].name)) != 1)
> +                goto cleanup;
> +            if (VIR_APPEND_ELEMENT(*features, *nfeatures, *tmpfeature) < 0)
> +                goto cleanup;
> +        }
> +    }
> +
> +    cmd.cmd = ETHTOOL_GFLAGS;

> +    for (j = 0; j < ARRAY_CARDINALITY(flags); j++) {
> +        if (virNetDevFeatureAvailable(ifname, &cmd)) {

These two lines can be exchanged to reduce number of ioctl calls.

> +            if (cmd.data & (flags[j].cmd)) {
> +                if (VIR_ALLOC(tmpfeature) < 0)
> +                    goto cleanup;
> +                if ((ret = VIR_STRDUP(tmpfeature->name, flags[j].name)) != 1)
> +                    goto cleanup;
> +                if (VIR_APPEND_ELEMENT(*features, *nfeatures, *tmpfeature) < 0)
> +                    goto cleanup;
> +            }
> +        }
> +    }
> +
> +    ret = 0;

> diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
> index de8b480..22ef1a2 100644
> --- a/src/util/virnetdev.h
> +++ b/src/util/virnetdev.h
> @@ -31,6 +31,8 @@
>  # include "virpci.h"
>  # include "device_conf.h"
>  
> +# include <linux/ethtool.h>

> +typedef struct ethtool_cmd virEthCmd;

Unused type.

Jan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150305/ba6746aa/attachment-0001.sig>


More information about the libvir-list mailing list