From 418a4f2ee3e76e54b7748a469c43ac8608602cf8 Mon Sep 17 00:00:00 2001 From: simonxiao Date: Thu, 22 Jun 2017 10:40:03 -0700 Subject: [PATCH 01/12] [SRIOV] change the name of the helper script This script should be common for Ubuntu 1604, Sles12 SP2, etc. --- .../{configure_sriov_ubuntu1604.sh => configure_hv_sriov.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/sriov/{configure_sriov_ubuntu1604.sh => configure_hv_sriov.sh} (100%) diff --git a/tools/sriov/configure_sriov_ubuntu1604.sh b/tools/sriov/configure_hv_sriov.sh similarity index 100% rename from tools/sriov/configure_sriov_ubuntu1604.sh rename to tools/sriov/configure_hv_sriov.sh From e19a98d165f60fd5c4df875f377adc0b69841ff1 Mon Sep 17 00:00:00 2001 From: simonxiao Date: Thu, 22 Jun 2017 11:28:13 -0700 Subject: [PATCH 02/12] [SRIOV] change the helper script to make it support SLES12 SP2 --- tools/sriov/configure_hv_sriov.sh | 73 +++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/tools/sriov/configure_hv_sriov.sh b/tools/sriov/configure_hv_sriov.sh index e6cf5abfb..c32d13e0f 100644 --- a/tools/sriov/configure_hv_sriov.sh +++ b/tools/sriov/configure_hv_sriov.sh @@ -39,11 +39,29 @@ udev_file="60-hyperv-sriov.rules" hv_vf_name_file="hv_vf_name" bondvf_lock_file="bondvf_lock" bondvf_sh_file="bondvf.sh" -default_net_config="/etc/network/interfaces" eth0_dhcp_config_line1="auto eth0" eth0_dhcp_config_line2="iface eth0 inet dhcp" all_files_downloaded=true +######################################## +# Detect Distro +######################################## +if [ -f /etc/redhat-release ]; +then + cfgdir="/etc/sysconfig/network-scripts" + distro=redhat +elif grep -q 'Ubuntu' /etc/issue +then + cfgdir="/etc/network" + distro=ubuntu +elif grep -q 'SUSE' /etc/issue +then + cfgdir="/etc/sysconfig/network" + distro=suse +else + echo "Unsupported Distro" + exit 1 +fi function LOG() { echo "`date`: $1" @@ -51,6 +69,7 @@ function LOG() { } LOG "---------------------------------------" +LOG "Configure SRIOV for $distro" ######################################## # Download files @@ -69,6 +88,34 @@ mv -f $hv_vf_name_file $bin_folder mv -f $bondvf_lock_file $bin_folder mv -f $bondvf_sh_file $bin_folder +######################################## +# Ubuntu 1604 only: +# Change eth0 DHCP configuration +######################################## +if [ $distro == 'ubuntu' ]; then + default_net_config=$cfgdir/interfaces + LOG "Running on Ubuntu: making change to the eth0 DHCP configuration ..." + sed -i 's/^source/#source/' $default_net_config + echo "$eth0_dhcp_config_line1" >> $default_net_config + echo "$eth0_dhcp_config_line2" >> $default_net_config + + n_line1=`cat $default_net_config | grep "$eth0_dhcp_config_line1" | wc -l` + if [ $n_line1 -ne 1 ]; then + LOG "[Failed] $n_line1 line(s) of '${eth0_dhcp_config_line1}' in $default_net_config" + exit + fi + + n_line2=`cat $default_net_config | grep "$eth0_dhcp_config_line2" | wc -l` + if [ $n_line2 -ne 1 ]; then + LOG "[Failed] $n_line2 line(s) of '${eth0_dhcp_config_line2}' in $default_net_config" + exit + fi +fi + +######################################## +# Check downloaded files +######################################## +LOG "Check downloaded files ..." if [ ! -f ${udev_folder}${udev_file} ]; then all_files_downloaded=false LOG "${udev_file} is not found in ${udev_folder}!" @@ -78,7 +125,7 @@ if [ ! -f ${bin_folder}${hv_vf_name_file} ]; then all_files_downloaded=false LOG "${hv_vf_name_file} is not found in ${bin_folder}!" fi - + if [ ! -f ${bin_folder}${bondvf_lock_file} ]; then all_files_downloaded=false LOG "${bondvf_lock_file} is not found in ${bin_folder}!" @@ -89,28 +136,6 @@ if [ ! -f ${bin_folder}${bondvf_sh_file} ]; then LOG "${bondvf_sh_file} is not found in ${bin_folder}!" fi -######################################## -# Change eth0 DHCP configuration -######################################## -LOG "Make change to the eth0 DHCP configuration ..." -sed -i 's/^source/#source/' $default_net_config -echo "$eth0_dhcp_config_line1" >> $default_net_config -echo "$eth0_dhcp_config_line2" >> $default_net_config - -LOG "Check files ..." -n_line1=`cat $default_net_config | grep "$eth0_dhcp_config_line1" | wc -l` -if [ $n_line1 -ne 1 ]; then - LOG "[Failed] $n_line1 line(s) of '${eth0_dhcp_config_line1}' in $default_net_config" - exit -fi - -n_line2=`cat $default_net_config | grep "$eth0_dhcp_config_line2" | wc -l` -if [ $n_line2 -ne 1 ]; then - LOG "[Failed] $n_line2 line(s) of '${eth0_dhcp_config_line2}' in $default_net_config" - exit -fi - - if [ $all_files_downloaded == false ]; then LOG "[Failed] Some files are missing; please download them again." exit From 759662116349c0bfff0e2be3d4a7320fe1959f9e Mon Sep 17 00:00:00 2001 From: Simon Xiao Date: Fri, 23 Jun 2017 00:31:20 -0700 Subject: [PATCH 03/12] [SRIOV] sriov helper script: change the way to configure with one reboot only The previous implementation is: -- Download udev rule file and it will trigger bondvf.sh, when vf device shows up; -- But with this way, user may need to reboot system twice: The first reboot is for vf show up, and trigger the vf name change and call bondvf.sh; The second reboot is for bond driver loads the bond config files. Now, change the way to: -- After VM provisioned, user call this helper script; -- This script will write bond0/vf1/eth0 config to the right place; -- Reboot, then bonding driver will load all the NIC config. --- tools/sriov/configure_hv_sriov.sh | 126 +++++++++++++++++++----------- 1 file changed, 81 insertions(+), 45 deletions(-) diff --git a/tools/sriov/configure_hv_sriov.sh b/tools/sriov/configure_hv_sriov.sh index c32d13e0f..084f99e4e 100644 --- a/tools/sriov/configure_hv_sriov.sh +++ b/tools/sriov/configure_hv_sriov.sh @@ -23,25 +23,16 @@ ######################################################################## # -# This is a script to configure SRIOV for Ubuntu 1604 VM on Azure. +# This is a script to configure SRIOV for Linux VMs on Azure. # # How to use this: -# $sudo ./configure_sriov_ubuntu1604.sh +# $sudo ./configure_hv_sriov.sh # Logging: -# See log: "/var/log/configure_sriov_ubuntu1604.log" +# See log: "/var/log/configure_hv_sriov.log" # ######################################################################## -log_file="/var/log/configure_sriov_ubuntu1604.log" -bin_folder="/usr/sbin/" -udev_folder="/etc/udev/rules.d/" -udev_file="60-hyperv-sriov.rules" -hv_vf_name_file="hv_vf_name" -bondvf_lock_file="bondvf_lock" -bondvf_sh_file="bondvf.sh" -eth0_dhcp_config_line1="auto eth0" -eth0_dhcp_config_line2="iface eth0 inet dhcp" -all_files_downloaded=true +log_file="/var/log/configure_hv_sriov.log" ######################################## # Detect Distro @@ -72,46 +63,96 @@ LOG "---------------------------------------" LOG "Configure SRIOV for $distro" ######################################## -# Download files -######################################## -LOG "Start downloading configuration files ..." -cd /tmp -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/60-hyperv-sriov.rules" -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/hv_vf_name" -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/bondvf_lock" -wget "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/plain/tools/hv/bondvf.sh" - -LOG "Move configuration to the destination folder ..." -mv -f $udev_file $udev_folder -chmod +x $hv_vf_name_file $bondvf_lock_file $bondvf_sh_file -mv -f $hv_vf_name_file $bin_folder -mv -f $bondvf_lock_file $bin_folder -mv -f $bondvf_sh_file $bin_folder - -######################################## -# Ubuntu 1604 only: -# Change eth0 DHCP configuration +# Write configuration for: +# vf, synthetic NIC, bond interfaces ######################################## if [ $distro == 'ubuntu' ]; then default_net_config=$cfgdir/interfaces - LOG "Running on Ubuntu: making change to the eth0 DHCP configuration ..." - sed -i 's/^source/#source/' $default_net_config - echo "$eth0_dhcp_config_line1" >> $default_net_config - echo "$eth0_dhcp_config_line2" >> $default_net_config - n_line1=`cat $default_net_config | grep "$eth0_dhcp_config_line1" | wc -l` + LOG "Running on Ubuntu: making change to ${default_net_config} ..." + sed -i 's/^source/#source/' $default_net_config + echo "allow-hotplug vf1" >> $default_net_config + echo "iface vf1 inet manual" >> $default_net_config + echo "bond-master bond0" >> $default_net_config + echo "bond-primary vf1" >> $default_net_config + echo "" >> $default_net_config + echo "auto eth0" >> $default_net_config + echo "iface eth0 inet manual" >> $default_net_config + echo "bond-master bond0" >> $default_net_config + echo "" >> $default_net_config + echo "auto bond0" >> $default_net_config + echo "iface bond0 inet dhcp" >> $default_net_config + echo "bond-mode active-backup" >> $default_net_config + echo "bond-miimon 100" >> $default_net_config + echo "bond-slaves none" >> $default_net_config + + n_line1=`cat $default_net_config | grep "allow-hotplug" | grep "vf1" | wc -l` if [ $n_line1 -ne 1 ]; then - LOG "[Failed] $n_line1 line(s) of '${eth0_dhcp_config_line1}' in $default_net_config" + LOG "[Failed] allow-hotplug vf1: was defined multiple times in ${default_net_config}" exit fi - n_line2=`cat $default_net_config | grep "$eth0_dhcp_config_line2" | wc -l` + n_line2=`cat $default_net_config | grep "auto" | grep "eth0" | wc -l` if [ $n_line2 -ne 1 ]; then - LOG "[Failed] $n_line2 line(s) of '${eth0_dhcp_config_line2}' in $default_net_config" + LOG "[Failed] auto eth0: was defined multiple times in ${default_net_config}" exit fi + + n_line3=`cat $default_net_config | grep "auto" | grep "bond0" | wc -l` + if [ $n_line3 -ne 1 ]; then + LOG "[Failed] auto bond0: was defined multiple times in ${default_net_config}" + exit + fi +elif [ $distro == 'suse' ]; then + ifcfg_bond0_cfg=$cfgdir/ifcfg-bond0 + ifcfg_eth0_cfg=$cfgdir/ifcfg-eth0 + ifcfg_eth0_old_cfg=$cfgdir/old.ifcfg-eth0.backup + ifcfg_vf1_cfg=$cfgdir/ifcfg-vf1 + + LOG "Running on Suse: making change to:" + LOG "${ifcfg_bond0_cfg} ..." + echo "BOOTPROTO=dhcp" > $ifcfg_bond0_cfg + echo "STARTMODE=auto" >> $ifcfg_bond0_cfg + echo "BONDING_MASTER=yes" >> $ifcfg_bond0_cfg + echo "BONDING_SLAVE_0=vf1" >> $ifcfg_bond0_cfg + echo "BONDING_SLAVE_1=eth0" >> $ifcfg_bond0_cfg + echo "BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=vf1'" >> $ifcfg_bond0_cfg + + LOG "${ifcfg_eth0_cfg} ..." + mv $ifcfg_eth0_cfg $ifcfg_eth0_old_cfg + echo "BOOTPROTO=none" > $ifcfg_eth0_cfg + echo "STARTMODE=auto" >> $ifcfg_eth0_cfg + + LOG "${ifcfg_vf1_cfg} ..." + echo "BOOTPROTO=none" > $ifcfg_vf1_cfg + echo "STARTMODE=hotplug" >> $ifcfg_vf1_cfg +else + echo "Unsupported distro. Exiting." + exit 1 fi +######################################## +# Download files +######################################## +bin_folder="/usr/sbin/" +udev_folder="/etc/udev/rules.d/" +udev_file="60-hyperv-vf-name.rules" +hv_vf_name_file="hv_vf_name" +bondvf_sh_file="bondvf.sh" +all_files_downloaded=true + +LOG "Start downloading udev rule and config scripts ..." +cd /tmp +wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/${udev_file}" +wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/${hv_vf_name_file}" +wget "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/plain/tools/hv/${bondvf_sh_file}" + +LOG "Move configuration to the destination folder ..." +mv -f $udev_file $udev_folder +chmod +x $hv_vf_name_file $bondvf_sh_file +mv -f $hv_vf_name_file $bin_folder +mv -f $bondvf_sh_file $bin_folder + ######################################## # Check downloaded files ######################################## @@ -126,11 +167,6 @@ if [ ! -f ${bin_folder}${hv_vf_name_file} ]; then LOG "${hv_vf_name_file} is not found in ${bin_folder}!" fi -if [ ! -f ${bin_folder}${bondvf_lock_file} ]; then - all_files_downloaded=false - LOG "${bondvf_lock_file} is not found in ${bin_folder}!" -fi - if [ ! -f ${bin_folder}${bondvf_sh_file} ]; then all_files_downloaded=false LOG "${bondvf_sh_file} is not found in ${bin_folder}!" From 0934efc75f2accb120efde5b6be3ab4ecd591138 Mon Sep 17 00:00:00 2001 From: Chris Valean Date: Fri, 23 Jun 2017 12:50:31 +0300 Subject: [PATCH 04/12] 53fa1a6f33520f01f9dbee48369074b34d77616b RH7: hv_netvsc: Fix the carrier state error when data path is off --- hv-rhel7.x/hv/hyperv_net.h | 3 +++ hv-rhel7.x/hv/netvsc.c | 2 ++ hv-rhel7.x/hv/netvsc_drv.c | 8 +++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/hv-rhel7.x/hv/hyperv_net.h b/hv-rhel7.x/hv/hyperv_net.h index 86cebe4a0..a85d57288 100644 --- a/hv-rhel7.x/hv/hyperv_net.h +++ b/hv-rhel7.x/hv/hyperv_net.h @@ -719,6 +719,9 @@ struct net_device_context { u32 vf_alloc; /* Serial number of the VF to team with */ u32 vf_serial; + + bool datapath; /* 0 - synthetic, 1 - VF nic */ + /* * Tracks the current data path; initially the data path is set * to deliver packets on the synthetic path. diff --git a/hv-rhel7.x/hv/netvsc.c b/hv-rhel7.x/hv/netvsc.c index 8f9ef8269..95c58cd99 100644 --- a/hv-rhel7.x/hv/netvsc.c +++ b/hv-rhel7.x/hv/netvsc.c @@ -56,6 +56,8 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf) sizeof(struct nvsp_message), (unsigned long)init_pkt, VM_PKT_DATA_INBAND, 0); + + net_device_ctx->datapath = vf; } static struct netvsc_device *alloc_net_device(void) diff --git a/hv-rhel7.x/hv/netvsc_drv.c b/hv-rhel7.x/hv/netvsc_drv.c index 6ee01d700..c6174d3a5 100644 --- a/hv-rhel7.x/hv/netvsc_drv.c +++ b/hv-rhel7.x/hv/netvsc_drv.c @@ -69,7 +69,8 @@ static void netvsc_set_multicast_list(struct net_device *net) static int netvsc_open(struct net_device *net) { - struct netvsc_device *nvdev = net_device_to_netvsc_device(net); + struct net_device_context *ndev_ctx = netdev_priv(net); + struct netvsc_device *nvdev = ndev_ctx->nvdev; struct rndis_device *rdev; int ret = 0; @@ -85,7 +86,7 @@ static int netvsc_open(struct net_device *net) netif_tx_wake_all_queues(net); rdev = nvdev->extension; - if (!rdev->link_state) + if (!rdev->link_state && !ndev_ctx->datapath) netif_carrier_on(net); return ret; @@ -1373,7 +1374,8 @@ static void netvsc_link_change(struct work_struct *w) case RNDIS_STATUS_MEDIA_CONNECT: if (rdev->link_state) { rdev->link_state = false; - netif_carrier_on(net); + if (!ndev_ctx->datapath) + netif_carrier_on(net); netif_tx_wake_all_queues(net); } else { notify = true; From 4785f03afcf1bf32427ddf0b2791adc71099ec9a Mon Sep 17 00:00:00 2001 From: Chris Valean Date: Fri, 23 Jun 2017 10:34:14 +0300 Subject: [PATCH 05/12] RH7: hv_netvsc: Remove unnecessary var link_state from struct netvsc_device_info dedb459e13f05824bc33d2d861e9b576bfc8d0bb We simply use rndis_device->link_state in the netdev_dbg. The variable, link_state from struct netvsc_device_info, is not used anywhere else. --- hv-rhel7.x/hv/hyperv_net.h | 4 ++-- hv-rhel7.x/hv/rndis_filter.c | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/hv-rhel7.x/hv/hyperv_net.h b/hv-rhel7.x/hv/hyperv_net.h index a85d57288..fc64b8fd7 100644 --- a/hv-rhel7.x/hv/hyperv_net.h +++ b/hv-rhel7.x/hv/hyperv_net.h @@ -149,7 +149,6 @@ struct hv_netvsc_packet { struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; - bool link_state; /* 0 - link up, 1 - link down */ int ring_size; u32 max_num_vrss_chns; u32 num_chn; @@ -168,7 +167,6 @@ struct rndis_device { struct net_device *ndev; enum rndis_device_state state; - bool link_state; atomic_t new_req_id; spinlock_t request_lock; @@ -176,6 +174,8 @@ struct rndis_device { struct work_struct mcast_work; + bool link_state; /* 0 - link up, 1 - link down */ + u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; diff --git a/hv-rhel7.x/hv/rndis_filter.c b/hv-rhel7.x/hv/rndis_filter.c index 9906e83c8..9cb6189a8 100644 --- a/hv-rhel7.x/hv/rndis_filter.c +++ b/hv-rhel7.x/hv/rndis_filter.c @@ -1197,11 +1197,9 @@ int rndis_filter_device_add(struct hv_device *dev, rndis_filter_query_device_link_status(rndis_device); - device_info->link_state = rndis_device->link_state; - netdev_dbg(net, "Device MAC %pM link state %s\n", rndis_device->hw_mac_adr, - device_info->link_state ? "down" : "up"); + rndis_device->link_state ? "down" : "up"); if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) return 0; From 29b46e01aafcf4d829f795b838a2dbf5aadc47e5 Mon Sep 17 00:00:00 2001 From: Chris Valean Date: Fri, 23 Jun 2017 12:15:37 +0300 Subject: [PATCH 06/12] RH6: hv_netvsc: Remove unnecessary var link_state from struct netvsc_device_info RH6: hv_netvsc: Remove unnecessary var link_state from struct netvsc_device_info Update rndis_filter.c --- hv-rhel6.x/hv/hyperv_net.h | 5 +++-- hv-rhel6.x/hv/rndis_filter.c | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hv-rhel6.x/hv/hyperv_net.h b/hv-rhel6.x/hv/hyperv_net.h index e2789f4b1..c45144b3d 100644 --- a/hv-rhel6.x/hv/hyperv_net.h +++ b/hv-rhel6.x/hv/hyperv_net.h @@ -147,7 +147,6 @@ struct hv_netvsc_packet { struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; - bool link_state; /* 0 - link up, 1 - link down */ int ring_size; u32 max_num_vrss_chns; u32 num_chn; @@ -169,7 +168,7 @@ struct rndis_device { struct net_device *ndev; enum rndis_device_state state; - bool link_state; + atomic_t new_req_id; spinlock_t request_lock; @@ -177,6 +176,8 @@ struct rndis_device { struct work_struct mcast_work; + bool link_state; /* 0 - link up, 1 - link down */ + u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; diff --git a/hv-rhel6.x/hv/rndis_filter.c b/hv-rhel6.x/hv/rndis_filter.c index 43acfc6fc..a83b491cf 100644 --- a/hv-rhel6.x/hv/rndis_filter.c +++ b/hv-rhel6.x/hv/rndis_filter.c @@ -1223,11 +1223,9 @@ int rndis_filter_device_add(struct hv_device *dev, rndis_filter_query_device_link_status(rndis_device); - device_info->link_state = rndis_device->link_state; - netdev_dbg(net, "Device MAC %pM link state %s\n", rndis_device->hw_mac_adr, - device_info->link_state ? "down" : "up"); + rndis_device->link_state ? "down" : "up"); if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) return 0; From d2f55fb55f2d64201c27b92666e65540241b5372 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Fri, 23 Jun 2017 10:49:12 -0700 Subject: [PATCH 07/12] Remove 4th dash from device_id and class_id GUIDs Remove the 4th dash from device_id and class_id GUIDs so the string format matches the LIS that is built-in RHEL/Cent/OS 5.x releases and matches what kudzu expects. Kudzu is doing string compares to find the class_id, and the extra dash when LIS is installed causes the compares to fail, which in turn causes the network to not be configured when rebooting after installing LIS. --- hv-rhel5.x/hv/vmbus_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hv-rhel5.x/hv/vmbus_drv.c b/hv-rhel5.x/hv/vmbus_drv.c index 775093b43..bf617804f 100644 --- a/hv-rhel5.x/hv/vmbus_drv.c +++ b/hv-rhel5.x/hv/vmbus_drv.c @@ -209,7 +209,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, if (!strcmp(dev_attr->attr.name, "class_id")) { ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x}\n", + "%02x%02x%02x%02x%02x%02x%02x%02x}\n", device_info->chn_type.b[3], device_info->chn_type.b[2], device_info->chn_type.b[1], @@ -228,7 +228,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, device_info->chn_type.b[15]); } else if (!strcmp(dev_attr->attr.name, "device_id")) { ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x}\n", + "%02x%02x%02x%02x%02x%02x%02x%02x}\n", device_info->chn_instance.b[3], device_info->chn_instance.b[2], device_info->chn_instance.b[1], From 6dc38630b903733c6fd70a1d3c920de4788e2e8f Mon Sep 17 00:00:00 2001 From: Alex Ng Date: Mon, 26 Jun 2017 10:25:50 -0700 Subject: [PATCH 08/12] RH6: Avoid scheduling rescind work on global workqueue. This fixes an issue introduced by backport commit: f3ad7fdb1e2129c23092ca7d2a9a9f1c6cfb6d83 --- hv-rhel6.x/hv/vmbus_drv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hv-rhel6.x/hv/vmbus_drv.c b/hv-rhel6.x/hv/vmbus_drv.c index 8922ffd2e..11b9d7cf4 100644 --- a/hv-rhel6.x/hv/vmbus_drv.c +++ b/hv-rhel6.x/hv/vmbus_drv.c @@ -608,11 +608,15 @@ void vmbus_on_msg_dpc(unsigned long data) switch (hdr->msgtype) { case CHANNELMSG_RESCIND_CHANNELOFFER: /* - * If we are handling the rescind message; - * schedule the work on the global work queue. + * Workaround for RHEL 6.X kernels: + * Don't schedule rescind work on global queue. + * For KVP/VSS, this may lead to global + * workqueue attempting to flush itself and a + * deadlock. */ - schedule_work_on(vmbus_connection.connect_cpu, - &ctx->work); + queue_work_on(vmbus_connection.connect_cpu, + vmbus_connection.work_queue, + &ctx->work); break; case CHANNELMSG_OFFERCHANNEL: From e8624da1a7a2e83a5fdb5792b756b96ee0cb689e Mon Sep 17 00:00:00 2001 From: Alex Ng Date: Tue, 27 Jun 2017 12:15:36 -0700 Subject: [PATCH 09/12] RH7: Revert hv_netvsc: Fix the queue index computation in forwarding case Reverts 93742a54c9616b915c2ea87468b55be1db66ad55 skb_get_hash() call uses UDP port in hash which causes UDP packet loss --- hv-rhel7.x/hv/netvsc_drv.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/hv-rhel7.x/hv/netvsc_drv.c b/hv-rhel7.x/hv/netvsc_drv.c index c6174d3a5..10e83fc7f 100644 --- a/hv-rhel7.x/hv/netvsc_drv.c +++ b/hv-rhel7.x/hv/netvsc_drv.c @@ -248,6 +248,9 @@ bool netvsc_set_hash(u32 *hash, struct sk_buff *skb) return true; } +// skb_get_hash() will include UDP port numbers into hash computation, +// which causes UDP loss problem. Comment this out for now. +#ifdef NOTYET static inline int netvsc_get_tx_queue(struct net_device *ndev, struct sk_buff *skb, int old_idx) { @@ -265,6 +268,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev, return q_idx; } +#endif /* * Select queue for transmit. @@ -283,21 +287,18 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb) #endif { - unsigned int num_tx_queues = ndev->real_num_tx_queues; - int q_idx = sk_tx_queue_get(skb->sk); + struct net_device_context *net_device_ctx = netdev_priv(ndev); + u32 hash; + u16 q_idx = 0; - if (q_idx < 0 || skb->ooo_okay) { - /* If forwarding a packet, we use the recorded queue when - * available for better cache locality. - */ - if (skb_rx_queue_recorded(skb)) - q_idx = skb_get_rx_queue(skb); - else - q_idx = netvsc_get_tx_queue(ndev, skb, q_idx); - } + if (ndev->real_num_tx_queues <= 1) + return 0; - while (unlikely(q_idx >= num_tx_queues)) - q_idx -= num_tx_queues; + if (netvsc_set_hash(&hash, skb)) { + q_idx = net_device_ctx->tx_send_table[hash % VRSS_SEND_TAB_SIZE] % + ndev->real_num_tx_queues; + skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); + } return q_idx; } From 68112d4a3841bdff6192224a4304fb71d3ef4bf1 Mon Sep 17 00:00:00 2001 From: Long Li Date: Mon, 3 Apr 2017 15:12:10 -0700 Subject: [PATCH 10/12] Add MLX4 to makefile --- hv-rhel7.x/hv/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hv-rhel7.x/hv/Makefile b/hv-rhel7.x/hv/Makefile index 287e74159..5d165e8c9 100644 --- a/hv-rhel7.x/hv/Makefile +++ b/hv-rhel7.x/hv/Makefile @@ -69,3 +69,5 @@ hyperv_keyboard-y := hyperv-keyboard.o hv_network_direct-y := provider.o vmbus_rdma.o hvnd_addr.o hv_sock-y := af_hvsock.o hv_uio_generic-y := uio_hv_generic.o + +obj-m += mlx4/ From 2d9f159b8efe3da12ca8d87be1a8613f311dd488 Mon Sep 17 00:00:00 2001 From: Long Li Date: Mon, 3 Apr 2017 15:38:15 -0700 Subject: [PATCH 11/12] Conditionally build MLX4 on RHEL 7.3 or newer --- hv-rhel7.x/hv/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hv-rhel7.x/hv/Makefile b/hv-rhel7.x/hv/Makefile index 5d165e8c9..cbfbf3922 100644 --- a/hv-rhel7.x/hv/Makefile +++ b/hv-rhel7.x/hv/Makefile @@ -70,4 +70,8 @@ hv_network_direct-y := provider.o vmbus_rdma.o hvnd_addr.o hv_sock-y := af_hvsock.o hv_uio_generic-y := uio_hv_generic.o -obj-m += mlx4/ +# Build MLX4 on RHEL 7.3 or newer +build_mlx=$(shell test $(rhel_release_code) -gt 1794; echo $$?) +ifeq ($(build_mlx),0) + obj-m += mlx4/ +endif From d8a9caa175955879e72ffed59fb7c6fcc8b2fc5e Mon Sep 17 00:00:00 2001 From: Chris Valean Date: Wed, 28 Jun 2017 15:52:38 +0300 Subject: [PATCH 12/12] Overwrite old dependency files --- hv-rhel6.x/hv/rhel6-hv-driver-install | 8 ++++---- hv-rhel7.x/hv/rhel7-hv-driver-install | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hv-rhel6.x/hv/rhel6-hv-driver-install b/hv-rhel6.x/hv/rhel6-hv-driver-install index aad0c8458..d45b992ab 100755 --- a/hv-rhel6.x/hv/rhel6-hv-driver-install +++ b/hv-rhel6.x/hv/rhel6-hv-driver-install @@ -23,18 +23,18 @@ cp -f ./hyperv_pvdrivers.conf /etc/modprobe.d/ echo "Copying scripts for IP injection" -\cp ./tools/hv_get_dns_info.sh /usr/sbin/hv_get_dns_info +\cp -f ./tools/hv_get_dns_info.sh /usr/sbin/hv_get_dns_info [ $? -eq 0 ] || exit 1 -\cp ./tools/hv_get_dhcp_info.sh /usr/sbin/hv_get_dhcp_info +\cp -f ./tools/hv_get_dhcp_info.sh /usr/sbin/hv_get_dhcp_info [ $? -eq 0 ] || exit 1 -\cp ./tools/hv_set_ifconfig.sh /usr/sbin/hv_set_ifconfig +\cp -f ./tools/hv_set_ifconfig.sh /usr/sbin/hv_set_ifconfig [ $? -eq 0 ] || exit 1 echo "Copying lsvmbus tool" -\cp ./tools/lsvmbus /usr/sbin/ +\cp -f ./tools/lsvmbus /usr/sbin/ [ $? -eq 0 ] || exit 1 echo "Generating initramfs" diff --git a/hv-rhel7.x/hv/rhel7-hv-driver-install b/hv-rhel7.x/hv/rhel7-hv-driver-install index 551d309b8..8afa760b8 100755 --- a/hv-rhel7.x/hv/rhel7-hv-driver-install +++ b/hv-rhel7.x/hv/rhel7-hv-driver-install @@ -21,21 +21,21 @@ cp -f ./hyperv_pvdrivers.conf /etc/modprobe.d/ [ $? -eq 0 ] || exit 1 echo "Copying scripts for IP injection" -\cp ./tools/hv_get_dns_info.sh /usr/sbin/hv_get_dns_info +\cp -f ./tools/hv_get_dns_info.sh /usr/sbin/hv_get_dns_info [ $? -eq 0 ] || exit 1 -\cp ./tools/hv_get_dhcp_info.sh /usr/sbin/hv_get_dhcp_info +\cp -f ./tools/hv_get_dhcp_info.sh /usr/sbin/hv_get_dhcp_info [ $? -eq 0 ] || exit 1 -\cp ./tools/hv_set_ifconfig.sh /usr/sbin/hv_set_ifconfig +\cp -f ./tools/hv_set_ifconfig.sh /usr/sbin/hv_set_ifconfig [ $? -eq 0 ] || exit 1 echo "Copying lsvmbus tool" -\cp ./tools/lsvmbus /usr/sbin/ +\cp -f ./tools/lsvmbus /usr/sbin/ [ $? -eq 0 ] || exit 1 echo "Copying bondvf.sh" -\cp ./tools/bondvf.sh /usr/sbin/ +\cp -f ./tools/bondvf.sh /usr/sbin/ [ $? -eq 0 ] || exit 1 echo "Generating initramfs"