Add new commands to manage SR-IOV device. Signed-off-by: Yu Zhao <yu.zhao@intel.com> diff -r b642e39d96cf tools/python/xen/util/pci.py --- a/tools/python/xen/util/pci.py Thu Sep 25 17:41:29 2008 +0100 +++ b/tools/python/xen/util/pci.py Sat Sep 27 01:08:05 2008 -0400 @@ -17,7 +17,7 @@ PROC_PCI_PATH = ''/proc/bus/pci/devices'' PROC_PCI_NUM_RESOURCES = 7 -SYSFS_PCI_DEVS_PATH = ''/bus/pci/devices'' +SYSFS_PCI_DEVS_PATH = ''/bus/pci/devices/'' SYSFS_PCI_DEV_RESOURCE_PATH = ''/resource'' SYSFS_PCI_DEV_CONFIG_PATH = ''/config'' SYSFS_PCI_DEV_IRQ_PATH = ''/irq'' @@ -28,6 +28,14 @@ SYSFS_PCI_DEV_SUBDEVICE_PATH = ''/subsystem_device'' SYSFS_PCI_DEV_CLASS_PATH = ''/class'' SYSFS_PCIBACK_PATH = ''/bus/pci/drivers/pciback/'' +SYSFS_PCIBACK_NEWSLOT = ''new_slot'' +SYSFS_PCIBACK_REMOVESLOT = ''remove_slot'' +SYSFS_PCI_IOV_ENTRY = ''/iov/'' +SYSFS_PCI_IOV_RID = ''rid'' +SYSFS_PCI_IOV_ENABLE = ''enable'' +SYSFS_PCI_IOV_NUMVFS = ''numvfs'' +SYSFS_PCI_IOV_TOTAL = ''totalvfs'' +SYSFS_PCI_IOV_INITIAL = ''initialvfs'' LSPCI_CMD = ''lspci'' @@ -330,6 +338,173 @@ result = result + [dev_list] return result + +def pci_dev_name(dev): + match = re.match(r"((?P<d>[0-9a-fA-F]{1,4})[:,])?" + \ + r"(?P<b>[0-9a-fA-F]{1,2})[:,]" + \ + r"(?P<s>[0-9a-fA-F]{1,2})[.,]" + \ + r"(?P<f>[0-7])$", dev) + if match == None: + print "Invalid PCI device name: %s." % dev + return None + + a = match.groupdict(''0'') + return "%04x:%02x:%02x.%01x" % (int(a[''d''], 16), \ + int(a[''b''], 16), int(a[''s''], 16), int(a[''f''], 16)) + +def pciback_add_device(dev): + sysfs_mnt = find_sysfs_mnt() + slot = sysfs_mnt + SYSFS_PCIBACK_PATH + SYSFS_PCIBACK_NEWSLOT + f = open(slot, ''w'') + f.write(dev) + f.close() + +def pciback_remove_device(dev): + sysfs_mnt = find_sysfs_mnt() + slot = sysfs_mnt + SYSFS_PCIBACK_PATH + SYSFS_PCIBACK_REMOVESLOT + f = open(slot, ''w'') + f.write(dev) + f.close() + +def has_iov(dev): + sysfs_mnt = find_sysfs_mnt() + path = sysfs_mnt + SYSFS_PCI_DEVS_PATH + dev + if not os.path.isdir(path): + print "Device %s doesn''t exist." % dev + return None + + path += SYSFS_PCI_IOV_ENTRY + if not os.path.isdir(path): + print "Device %s doesn''t have SR-IOV capability." % dev + return None + + return path + +def has_vf(dev, i): + path = has_iov(dev) + if path == None: + return None + + path += "%s/" % i + if not os.path.isdir(path): + print "Device %s doesn''t have Virtual Function #%s." % (dev, i) + return None + + return path + +def list_iov(dev): + path = has_iov(dev) + if path == None: + return False + + f = open(path + SYSFS_PCI_IOV_ENABLE, ''r'') + enable = f.readline().strip() + f.close() + f = open(path + SYSFS_PCI_IOV_NUMVFS, ''r'') + numvfs = f.readline().strip() + f.close() + f = open(path + SYSFS_PCI_IOV_TOTAL, ''r'') + total = f.readline().strip() + f.close() + f = open(path + SYSFS_PCI_IOV_INITIAL, ''r'') + initial = f.readline().strip() + f.close() + + print "Device: %s, SR-IOV Enabled: %s, TotalVFs: %s, InitialVFs: %s, " \ + "NumVFs: %s" % (dev, enable, total, initial, numvfs) + + for i in range(int(total)): + if i == 0: + ents = os.listdir(path + "%d/" % i) + ents.remove(SYSFS_PCI_IOV_RID) + f = open(path + "%d/" % i + SYSFS_PCI_IOV_RID, ''r'') + output = "VF-%d:[%s]" % (i, f.readline().strip()) + f.close() + for j in ents: + f = open(path + "%d/" % i + j, ''r'') + output += ", %s:[%s]" % (j, f.readline().strip()) + f.close() + print output + + return True + +def enable_iov(dev, numvfs): + path = has_iov(dev) + if path == None: + return False + + f1 = open(path + SYSFS_PCI_IOV_INITIAL, ''r'') + initial = f1.readline().strip() + f1.close() + + if int(numvfs) < 0 or int(numvfs) > int(initial): + print "Invalid NumVFS %s." % numvfs + return False + + f1 = open(path + SYSFS_PCI_IOV_ENABLE, ''r+'') + enable = f1.readline().strip() + if enable == "1": + print "Device %s SR-IOV is enabled." % dev + f1.close() + return False + + f2 = open(path + SYSFS_PCI_IOV_NUMVFS, ''r+'') + f2.write(numvfs) + f2.close() + + for i in range(int(numvfs)): + f2 = open(path + "%d/" % i + SYSFS_PCI_IOV_RID, ''r'') + rid = f2.readline() + f2.close() + pciback_add_device(rid) + + f1.write("1") + f1.close() + + return True + +def disable_iov(dev): + path = has_iov(dev) + if path == None: + return False + + f1 = open(path + SYSFS_PCI_IOV_ENABLE, ''r+'') + enable = f1.readline().strip() + if enable == "0": + print "Device %s SR-IOV isn''t enabled." % dev + f1.close() + return False + + f2 = open(path + SYSFS_PCI_IOV_NUMVFS, ''r'') + numvfs = f2.readline().strip() + f2.close() + + f1.write("0") + f1.close() + + for i in range(int(numvfs)): + f1 = open(path + "%d/" % i + SYSFS_PCI_IOV_RID, ''r'') + rid = f1.readline() + f1.close() + pciback_remove_device(rid) + + return True + +def set_iov_param(dev, i, ent, value): + path = has_vf(dev, i) + if path == None: + return False + + path += ent + if not os.path.isfile(path): + print "Device %s doesn''t have parameter %s." % (dev, ent) + return None + + f = open(path, ''w'') + f.write(value) + f.close() + + return True class PciDeviceNotFoundError(Exception): def __init__(self,domain,bus,slot,func): diff -r b642e39d96cf tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Thu Sep 25 17:41:29 2008 +0100 +++ b/tools/python/xen/xm/main.py Sat Sep 27 01:08:05 2008 -0400 @@ -199,6 +199,14 @@ ''Detach a specified SCSI device.''), ''scsi-list'' : (''<Domain> [--long]'', ''List all SCSI devices currently attached.''), + ''iov-list'' : (''<domain:bus:slot.func>'', + ''List SR-IOV information of a device.''), + ''iov-enable'' : (''<domain:bus:slot.func> <NumVFs>'', + ''Enable SR-IOV capability of a device with NumVFs.''), + ''iov-disable'' : (''<domain:bus:slot.func>'', + ''Disable SR-IOV capability.''), + ''iov-setparam'' : (''<domain:bus:slot.func> <VFN> <parameter name> <value>'', + ''Set device specific parameters of a VF.''), # security @@ -377,6 +385,10 @@ "scsi-attach", "scsi-detach", "scsi-list", + "iov-list", + "iov-enable", + "iov-disable", + "iov-setparam", ] vnet_commands = [ @@ -2258,6 +2270,30 @@ print "%(idx)-3d %(backend-id)-3d %(state)-5d " % ni, print "%(p-dev)-10s %(p-devname)-5s %(v-dev)-10s %(frontstate)-4s" % mi +def xm_iov_list(args): + arg_check(args, ''iov-list'', 1) + dev = pci_dev_name(args[0]) + if dev == None or list_iov(dev) == False: + raise OptionError("Operation failed.") + +def xm_iov_enable(args): + arg_check(args, ''iov-enable'', 2) + dev = pci_dev_name(args[0]) + if dev == None or enable_iov(dev, args[1]) == False: + raise OptionError("Operation failed.") + +def xm_iov_disable(args): + arg_check(args, ''iov-disable'', 1) + dev = pci_dev_name(args[0]) + if dev == None or disable_iov(dev) == False: + raise OptionError("Operation failed.") + +def xm_iov_setparam(args): + arg_check(args, ''iov-setparam'', 4) + dev = pci_dev_name(args[0]) + if dev == None or set_iov_param(dev, args[1], args[2], args[3]) == False: + raise OptionError("Operation failed.") + def parse_block_configuration(args): dom = args[0] @@ -2808,6 +2844,10 @@ "scsi-attach": xm_scsi_attach, "scsi-detach": xm_scsi_detach, "scsi-list": xm_scsi_list, + "iov-list": xm_iov_list, + "iov-enable": xm_iov_enable, + "iov-disable": xm_iov_disable, + "iov-setparam": xm_iov_setparam, } ## The commands supported by a separate argument parser in xend.xm. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel