ethtool: Add command to configure IOV features
Subsystems (2)
RFC PATCH v2 1/1 ethtool: Add command to configure IOV features
New command to allow configuration of IOV features such as the number of Virtual Functions to allocate for a given Physical Function interface, the number of semi-independent net devices to allocate from partitioned I/O resources in the PF and to set the number of queues per VF.
---
ethtool.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 93 insertions(+), 1 deletions(-)
ethtool.c +93 -1
@@ -99,6 +99,8 @@ static int do_flash(int fd, struct ifreq *ifr);static int do_permaddr (int fd,struct ifreq *ifr);static int do_getfwdump (int fd,struct ifreq *ifr);static int do_setfwdump (int fd,struct ifreq *ifr); +static int do_get_iov (int fd,struct ifreq *ifr); +static int do_set_iov (int fd,struct ifreq *ifr);static int send_ioctl (int fd,struct ifreq *ifr);
@@ -133,6 +135,8 @@ static enum {MODE_PERMADDR ,MODE_SET_DUMP ,MODE_GET_DUMP , +MODE_GET_IOV , +MODE_SET_IOV , } mode = MODE_GSET; static struct option {
@@ -266,6 +270,8 @@ static struct option { {"-W" ,"--set-dump" ,MODE_SET_DUMP ,"Set dump flag of the device" , " N\n"}, + { "-v", "--get-iov", MODE_GET_IOV, "Get IOV parameters", "\n" }, + { "-V", "--set_iov", MODE_SET_IOV, "Set IOV parameters", "[ N ]\n" }, { "-h", "--help", MODE_HELP, "Show this help" }, { NULL, "--version", MODE_VERSION, "Show version number" }, {}
@@ -392,6 +398,10 @@ static char **rxfhindir_weight = NULL;static char *flash_file =NULL ;static int flash =-1 ;static int flash_region =-1 ; +static int iov_changed =0 ; +static int iov_numvfs_wanted =-1 ; +static int iov_numnetdevs_wanted =-1 ; +static int iov_numvqueues_wanted =-1 ;static int msglvl_changed;static u32 msglvl_wanted =0 ;
@@ -549,6 +559,12 @@ static struct cmdline_info cmdline_msglvl[] = { NETIF_MSG_WOL, &msglvl_mask }, }; +static struct cmdline_info cmdline_iov[] = { + {"vfs" ,CMDL_S32 , &iov_numvfs_wanted,NULL }, + {"netdevs" ,CMDL_S32 , &iov_numnetdevs_wanted,NULL }, + {"vqueues" ,CMDL_S32 , &iov_numvqueues_wanted,NULL }, +}; +static long long get_int_range (char *str,int base,long long min,long long max) {
@@ -792,7 +808,9 @@ static void parse_cmdline(int argc, char **argp) (mode == MODE_FLASHDEV) || (mode == MODE_PERMADDR) || (mode == MODE_SET_DUMP) || - (mode == MODE_GET_DUMP)) { + (mode == MODE_GET_DUMP) || + (mode == MODE_GET_IOV) || + (mode == MODE_SET_IOV)) { devname = argp[i];break ; }
@@ -1007,6 +1025,14 @@ static void parse_cmdline(int argc, char **argp) i = argc;break ; } +if (mode ==MODE_SET_IOV ) { +parse_generic_cmdline (argc, argp, i, + &iov_changed, + cmdline_iov, +ARRAY_SIZE (cmdline_iov)); + i = argc; +break ; + }if (mode !=MODE_SSET )exit_bad_args ();if (!strcmp (argp[i],"speed" )) {
@@ -1949,6 +1975,10 @@ static int doit(void)return do_getfwdump (fd, &ifr); }else if (mode ==MODE_SET_DUMP ) {return do_setfwdump (fd, &ifr); + }else if (mode ==MODE_GET_IOV ) { +return do_get_iov (fd, &ifr); + }else if (mode ==MODE_SET_IOV ) { +return do_set_iov (fd, &ifr); }return 69 ;
@@ -3338,6 +3368,68 @@ static int do_setfwdump(int fd, struct ifreq *ifr)return 0 ; } +static int do_get_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_get_cmd iov_cmd; + + iov_cmd.cmd =ETHTOOL_IOV_GET_CMD ; + ifr->ifr_data = (caddr_t)&iov_cmd; + err =send_ioctl (fd, ifr); +if (err <0 ) { +perror ("Can not get current IOV mode\n" ); +return 1 ; + } + +memcpy (&iov_cmd, ifr->ifr_data,sizeof (iov_cmd)); + +switch (iov_cmd.mode) { +case ETHTOOL_IOV_MODE_SRIOV : +printf ("Device %s is configured for SR-IOV mode\n" , devname); +break ; +case ETHTOOL_IOV_MODE_VM_QUEUES : +printf ("Device %s is configured for VM Queues mode\n" , devname); +break ; +case ETHTOOL_IOV_MODE_NONE : +default : +printf ("Device %s is not configured for IO Virtualization\n" , + devname); +break ; + } + +return 0 ; +} + +static int do_set_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_set_cmd iov_cmd; + +if (iov_changed) { + iov_cmd.cmd =ETHTOOL_IOV_SET_CMD ; +if (iov_numvfs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_SRIOV ; + iov_cmd.cmd_param = iov_numvfs_wanted; + }else if (iov_numnetdevs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS ; + iov_cmd.cmd_param = iov_numnetdevs_wanted; + }else if (iov_numvqueues_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES ; + iov_cmd.cmd_param = iov_numvqueues_wanted; + }else { +return -EINVAL ; + } + ifr->ifr_data = (caddr_t)&iov_cmd; + err =send_ioctl (fd, ifr); +if (err <0 ) { +perror ("Can not set new IOV mode\n" ); +return 1 ; + } + } + +return 0 ; +} +static int send_ioctl (int fd,struct ifreq *ifr) {return ioctl (fd,SIOCETHTOOL , ifr);
Quoted 4 lines · Greg Rose
New command to allow configuration of IOV features such as the number of Virtual Functions to allocate for a given Physical Function interface, the number of semi-independent net devices to allocate from partitioned I/O resources in the PF and to set the number of queues per VF.
[...]
ethtool.c static struct option { · line 274
Quoted 6 lines
ethtool.c +2
-0@@ -266,6 +270,8 @@ static struct option { {"-W" ,"--set-dump" ,MODE_SET_DUMP ,"Set dump flag of the device" , " N\n"}, + { "-v", "--get-iov", MODE_GET_IOV, "Get IOV parameters", "\n" }, + { "-V", "--set_iov", MODE_SET_IOV, "Set IOV parameters", "[ N ]\n" },
Doesn't match the implementation.
[...]
Quoted 4 lines
ethtool.c +4
-0+static int do_get_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_get_cmd iov_cmd;
ethtool.c static int do_setfwdump(int fd, struct ifreq *ifr) · line 3384
Quoted 10 lines
ethtool.c +10
-0+ + iov_cmd.cmd =ETHTOOL_IOV_GET_CMD ; + ifr->ifr_data = (caddr_t)&iov_cmd; + err =send_ioctl (fd, ifr); +if (err <0 ) { +perror ("Can not get current IOV mode\n" ); +return 1 ; + } + +memcpy (&iov_cmd, ifr->ifr_data,sizeof (iov_cmd));
But ifr->ifr_data == &iov_cmd. So this is both pointless and dangerous (as memcpy() doesn't handle overlapping source and destination).
[...]
Quoted 9 lines
ethtool.c +9
-0+static int do_set_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_set_cmd iov_cmd; + +if (iov_changed) { + iov_cmd.cmd =ETHTOOL_IOV_SET_CMD ; +if (iov_numvfs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_SRIOV ;
ethtool.c static int do_setfwdump(int fd, struct ifreq *ifr) · line 3421
Quoted 10 lines
ethtool.c +10
-0+ iov_cmd.cmd_param = iov_numvfs_wanted; + }else if (iov_numnetdevs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS ; + iov_cmd.cmd_param = iov_numnetdevs_wanted; + }else if (iov_numvqueues_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES ; + iov_cmd.cmd_param = iov_numvqueues_wanted; + }else { +return -EINVAL ; + }
[...]
So what if the user specifies multiple keywords?
Also missing an update to the manual page.
Ben.
Signature · 3 lines
Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.
Quoted 21 lines
-----Original Message-----
From: Ben Hutchings [mailto:[email protected]]
Sent: Friday, October 07, 2011 5:41 PM
To: Rose, Gregory V
Cc: [email protected]
Subject: Re: [RFC PATCH V2] ethtool: Add command to configure IOV featuresQuoted 4 lines · Greg Rose
New command to allow configuration of IOV features such as the number of Virtual Functions to allocate for a given Physical Function interface, the number of semi-independent net devices to allocate from partitioned I/O resources in the PF and to set the number of queues per VF.
[...]
ethtool.c static struct option { · line 274
Quoted 6 lines
ethtool.c +2
-0@@ -266,6 +270,8 @@ static struct option { {"-W" ,"--set-dump" ,MODE_SET_DUMP ,"Set dump flag of the device" , " N\n"}, + { "-v", "--get-iov", MODE_GET_IOV, "Get IOV parameters", "\n" }, + { "-V", "--set_iov", MODE_SET_IOV, "Set IOV parameters", "[ N ]\n"},
Quoted 1 line
Doesn't match the implementation.
Whoops... OK.
Quoted 11 lines
[...]
Quoted 9 lines
ethtool.c +9
-0+static int do_get_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_get_cmd iov_cmd; + + iov_cmd.cmd =ETHTOOL_IOV_GET_CMD ; + ifr->ifr_data = (caddr_t)&iov_cmd; + err =send_ioctl (fd, ifr); +if (err <0 ) {
Quoted 8 lines
ethtool.c static int do_setfwdump(int fd, struct ifreq *ifr) · line 3384
Quoted 5 lines
ethtool.c +5
-0+perror ("Can not get current IOV mode\n" ); +return 1 ; + } + +memcpy (&iov_cmd, ifr->ifr_data,sizeof (iov_cmd));But
ifr->ifr_data==&iov_cmd. So this is both pointless and dangerous (asmemcpy()doesn't handle overlapping source and destination).
Huh... what was I thinking? Yeah, I'll fix that.
Quoted 23 lines
[...]
Quoted 19 lines
ethtool.c +19
-0+static int do_set_iov (int fd,struct ifreq *ifr) +{ +int err; +struct ethtool_iov_set_cmd iov_cmd; + +if (iov_changed) { + iov_cmd.cmd =ETHTOOL_IOV_SET_CMD ; +if (iov_numvfs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_SRIOV ; + iov_cmd.cmd_param = iov_numvfs_wanted; + }else if (iov_numnetdevs_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_NETDEVS ; + iov_cmd.cmd_param = iov_numnetdevs_wanted; + }else if (iov_numvqueues_wanted >=0 ) { + iov_cmd.set_cmd =ETHTOOL_IOV_CMD_CONFIGURE_VF_QUEUES ; + iov_cmd.cmd_param = iov_numvqueues_wanted; + }else { +return -EINVAL ; + }[...]
Quoted 1 line
So what if the user specifies multiple keywords?
I hadn't contemplated that.
Quoted 2 lines
Also missing an update to the manual page.
When I get through the RFC process and we've settled on something acceptable to the community I'll update the man page.
Thanks for the review Ben.
- Greg