[kernel/f17] Rebase to Linux v3.5

Josh Boyer jwboyer at fedoraproject.org
Thu Jul 26 20:57:34 UTC 2012


commit 53ecebd5790e6dcd9f03506c320f6b73510eb9c3
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Thu Jul 26 15:12:33 2012 -0400

    Rebase to Linux v3.5

 ...don-t-mess-with-hot-plug-detect-for-eDP-o.patch |   38 -
 ...pusets-suspend-Dont-modify-cpusets-during.patch |   21 +-
 atl1c_net_next_update-3.4.patch                    | 3658 ----------
 config-arm-generic                                 |    6 +
 config-arm-imx                                     |   10 +
 config-arm-kirkwood                                |   10 +
 config-arm-omap                                    |   21 +
 config-arm-tegra                                   |    7 +
 config-generic                                     |   73 +-
 config-powerpc-generic                             |    3 +
 config-powerpc64                                   |    6 +
 config-s390x                                       |    1 +
 config-sparc64-generic                             |    3 +
 config-x86-32-generic                              |    2 +
 config-x86-generic                                 |    7 +
 ...d-Make-the-header-fixup-threshold-tunable.patch |   60 -
 drm-i915-lvds-dual-channel.patch                   |  161 -
 highbank-secure-smc.patch                          |  104 -
 kernel.spec                                        |   47 +-
 linux-2.6-input-kill-stupid-messages.patch         |   20 +-
 linux-2.6-makefile-after_link.patch                |   82 +-
 sources                                            |    3 +-
 team-update-from-net-next.patch                    | 1531 ++---
 uprobes-3.4-backport.patch                         | 6983 --------------------
 ...ork_add-generic-process-context-callbacks.patch |  249 -
 vgaarb-vga_default_device.patch                    |  474 --
 26 files changed, 647 insertions(+), 12933 deletions(-)
---
diff --git a/CPU-hotplug-cpusets-suspend-Dont-modify-cpusets-during.patch b/CPU-hotplug-cpusets-suspend-Dont-modify-cpusets-during.patch
index f57ecee..99e05f5 100644
--- a/CPU-hotplug-cpusets-suspend-Dont-modify-cpusets-during.patch
+++ b/CPU-hotplug-cpusets-suspend-Dont-modify-cpusets-during.patch
@@ -52,9 +52,11 @@ Signed-off-by: Ingo Molnar <mingo at kernel.org>
  kernel/sched/core.c |   40 ++++++++++++++++++++++++++++++++++++----
  2 files changed, 39 insertions(+), 4 deletions(-)
 
---- linux-3.4.6-3.1.fc17.noarch.orig/kernel/cpuset.c
-+++ linux-3.4.6-3.1.fc17.noarch/kernel/cpuset.c
-@@ -2065,6 +2065,9 @@ static void scan_for_empty_cpusets(struc
+diff --git a/kernel/cpuset.c b/kernel/cpuset.c
+index 47de450..77abe1a 100644
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -2054,6 +2054,9 @@ static void scan_for_empty_cpusets(struct cpuset *root)
   * (of no affect) on systems that are actively using CPU hotplug
   * but making no active use of cpusets.
   *
@@ -64,11 +66,13 @@ Signed-off-by: Ingo Molnar <mingo at kernel.org>
   * This routine ensures that top_cpuset.cpus_allowed tracks
   * cpu_active_mask on each CPU hotplug (cpuhp) event.
   *
---- linux-3.4.6-3.1.fc17.noarch.orig/kernel/sched/core.c
-+++ linux-3.4.6-3.1.fc17.noarch/kernel/sched/core.c
-@@ -6931,34 +6931,66 @@ int __init sched_create_sysfs_power_savi
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index ca07ee0..e368731 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -7014,34 +7014,66 @@ match2:
+ 	mutex_unlock(&sched_domains_mutex);
  }
- #endif /* CONFIG_SCHED_MC || CONFIG_SCHED_SMT */
  
 +static int num_cpus_frozen;	/* used to mark begin/end of suspend/resume */
 +
@@ -137,3 +141,6 @@ Signed-off-by: Ingo Molnar <mingo at kernel.org>
  }
  
  void __init sched_init_smp(void)
+-- 
+1.7.7.6
+
diff --git a/config-arm-generic b/config-arm-generic
index 80a7f2b..98a11c1 100644
--- a/config-arm-generic
+++ b/config-arm-generic
@@ -138,6 +138,12 @@ CONFIG_RTC_DRV_PL031=y
 CONFIG_ARM_UNWIND=y
 
 CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=8
+
+# CONFIG_ARM_ARCH_TIMER is not set
+# CONFIG_HW_RANDOM_ATMEL is not set
+# CONFIG_SERIAL_8250_EM is not set
+# CONFIG_SND_SIMPLE_CARD is not set
 
 # CONFIG_USB_ULPI is not set
 # CONFIG_OC_ETM is not set
diff --git a/config-arm-imx b/config-arm-imx
index 4937698..d6bea10 100644
--- a/config-arm-imx
+++ b/config-arm-imx
@@ -87,3 +87,13 @@ CONFIG_LEDS_RENESAS_TPU=y
 
 CONFIG_MFD_ANATOP=y
 
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_IMX51 is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_FB_IMX is not set
+# CONFIG_SND_SOC_IMX_SGTL5000 is not set
+# CONFIG_RTC_DRV_MXC is not set
+# CONFIG_COMMON_CLK_DEBUG is not set
+
diff --git a/config-arm-kirkwood b/config-arm-kirkwood
index 3d3466b..c3d1891 100644
--- a/config-arm-kirkwood
+++ b/config-arm-kirkwood
@@ -52,3 +52,13 @@ CONFIG_CRYPTO_DEV_MV_CESA=m
 # CONFIG_VFPv3 is not set
 # CONFIG_NEON is not set
 # CONFIG_SMP is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_MACH_ICONNECT_DT is not set
+# CONFIG_MACH_DLINK_KIRKWOOD_DT is not set
+# CONFIG_MACH_IB62X0_DT is not set
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_TCM_QLA2XXX is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_LEDS_RENESAS_TPU is not set
+# CONFIG_COMMON_CLK_DEBUG is not set
+
diff --git a/config-arm-omap b/config-arm-omap
index 283267c..ae46b5a 100644
--- a/config-arm-omap
+++ b/config-arm-omap
@@ -1085,3 +1085,24 @@ CONFIG_USB_RENESAS_USBHS_HCD=m
 # CONFIG_VIDEO_AS3645A is not set
 #
 # CONFIG_TI_CPSW is not set
+# CONFIG_SOC_TI81XX is not set
+# CONFIG_SOC_AM33XX is not set
+# CONFIG_MTD_NAND_OMAP_BCH is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_VIDEO_SMIAPP is not set
+# CONFIG_PANEL_TFP410 is not set
+# CONFIG_SND_OMAP_SOC_OMAP_HDMI is not set
+# CONFIG_USB_FUSB300 is not set
+# CONFIG_USB_OMAP is not set
+# CONFIG_USB_R8A66597 is not set
+# CONFIG_USB_RENESAS_USBHS_UDC is not set
+# CONFIG_USB_MV_UDC is not set
+# CONFIG_USB_M66592 is not set
+# CONFIG_USB_NET2272 is not set
+# CONFIG_USB_DUMMY_HCD is not set
+#
diff --git a/config-arm-tegra b/config-arm-tegra
index ef4f535..818008f 100644
--- a/config-arm-tegra
+++ b/config-arm-tegra
@@ -97,3 +97,10 @@ CONFIG_SERIAL_OF_PLATFORM=y
 
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
+
+# CONFIG_TEGRA_AHB is not set
+# CONFIG_TCM_QLA2XXX is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
+# CONFIG_GPIO_EM is not set
+# CONFIG_SND_SOC_TEGRA_WM8753 is not set
+
diff --git a/config-generic b/config-generic
index 4e79b18..778535a 100644
--- a/config-generic
+++ b/config-generic
@@ -166,6 +166,7 @@ CONFIG_MLX4_INFINIBAND=m
 CONFIG_INFINIBAND_NES=m
 # CONFIG_INFINIBAND_NES_DEBUG is not set
 CONFIG_INFINIBAND_QIB=m
+# CONFIG_INFINIBAND_OCRDMA is not set
 
 #
 # Executable file formats
@@ -186,6 +187,8 @@ CONFIG_FW_LOADER=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_EXTRA_FIRMWARE=""
 
+# CONFIG_CMA is not set
+
 # CONFIG_SPI is not set
 
 #
@@ -330,6 +333,7 @@ CONFIG_VIRTIO_BLK=m
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_MMIO=m
+# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
 CONFIG_VIRTIO_NET=m
 CONFIG_VMXNET3=m
 CONFIG_HW_RANDOM_VIRTIO=m
@@ -472,6 +476,7 @@ CONFIG_SCSI_DC395x=m
 CONFIG_SCSI_DEBUG=m
 CONFIG_SCSI_DC390T=m
 CONFIG_SCSI_QLA_FC=m
+CONFIG_TCM_QLA2XXX=m
 CONFIG_SCSI_QLA_ISCSI=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_DPT_I2O is not set
@@ -777,6 +782,7 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_CT=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
 CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
 CONFIG_NETFILTER_XT_TARGET_LED=m
 CONFIG_NETFILTER_XT_TARGET_LOG=m
@@ -1031,6 +1037,8 @@ CONFIG_NET_SCH_MQPRIO=m
 CONFIG_NET_SCH_MULTIQ=m
 CONFIG_NET_SCH_CHOKE=m
 CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
 CONFIG_NET_SCH_PLUG=m
 CONFIG_NET_CLS=y
 CONFIG_NET_CLS_ACT=y
@@ -1231,12 +1239,15 @@ CONFIG_E1000=m
 CONFIG_E1000E=m
 CONFIG_IGB=m
 CONFIG_IGB_DCA=y
+CONFIG_IGB_PTP=y
 CONFIG_IGBVF=m
 CONFIG_IXGB=m
 CONFIG_IXGBEVF=m
 CONFIG_IXGBE=m
 CONFIG_IXGBE_DCA=y
 CONFIG_IXGBE_DCB=y
+CONFIG_IXGBE_HWMON=y
+CONFIG_IXGBE_PTP=y
 
 # CONFIG_NET_VENDOR_I825XX is not set
 CONFIG_NET_VENDOR_MARVELL=y
@@ -1335,6 +1346,10 @@ CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
 CONFIG_VIA_VELOCITY=m
 
+CONFIG_NET_VENDOR_WIZNET=y
+CONFIG_WIZNET_W5100=m
+CONFIG_WIZNET_W5300=m
+
 CONFIG_NET_VENDOR_XIRCOM=y
 CONFIG_PCMCIA_XIRC2PS=m
 
@@ -1387,6 +1402,7 @@ CONFIG_JME=m
 #
 CONFIG_IP1000=m
 CONFIG_MLX4_EN=m
+CONFIG_MLX4_EN_DCB=y
 # CONFIG_MLX4_DEBUG is not set
 CONFIG_SFC=m
 CONFIG_SFC_MCDI_MON=y
@@ -1503,6 +1519,7 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
 CONFIG_BRCMSMAC=m
 CONFIG_BRCMFMAC=m
 CONFIG_BRCMFMAC_SDIO=y
+CONFIG_BRCMFMAC_SDIO_OOB=y
 CONFIG_BRCMFMAC_USB=y
 # CONFIG_BRCMDBG is not set
 CONFIG_HERMES=m
@@ -1585,6 +1602,7 @@ CONFIG_USB_NET_RNDIS_WLAN=m
 CONFIG_USB_NET_KALMIA=m
 CONFIG_USB_NET_QMI_WWAN=m
 CONFIG_USB_NET_SMSC75XX=m
+# CONFIG_WL_TI is not set
 CONFIG_ZD1211RW=m
 # CONFIG_ZD1211RW_DEBUG is not set
 
@@ -1607,6 +1625,7 @@ CONFIG_RTL8192DE=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_SDIO=m
 CONFIG_MWIFIEX_PCIE=m
+CONFIG_MWIFIEX_USB=m
 
 #
 # Token Ring devices
@@ -1866,6 +1885,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
 
 CONFIG_INPUT_TABLET=y
 CONFIG_TABLET_USB_ACECAD=m
@@ -1916,6 +1936,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_LM8333 is not set
 # CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_ADP5589 is not set
@@ -1998,6 +2019,7 @@ CONFIG_TOUCHSCREEN_TOUCHWIN=m
 CONFIG_TOUCHSCREEN_PIXCIR=m
 CONFIG_TOUCHSCREEN_UCB1400=m
 CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_WACOM_I2C=m
 CONFIG_TOUCHSCREEN_USB_E2I=y
 CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
 # CONFIG_TOUCHSCREEN_WM97XX is not set
@@ -2252,6 +2274,7 @@ CONFIG_SENSORS_WM8350=m
 CONFIG_SENSORS_WM831X=m
 CONFIG_SENSORS_LM73=m
 CONFIG_SENSORS_AMC6821=m
+CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_ADT7411=m
 CONFIG_SENSORS_ASC7621=m
 CONFIG_SENSORS_EMC1403=m
@@ -2291,6 +2314,7 @@ CONFIG_SENSORS_MAX1668=m
 
 # CONFIG_HMC6352 is not set
 # CONFIG_BMP085 is not set
+# CONFIG_BMP085_I2C is not set
 # CONFIG_PCH_PHUB is not set
 # CONFIG_SERIAL_PCH_UART is not set
 # CONFIG_USB_SWITCH_FSA9480 is not set
@@ -2430,12 +2454,15 @@ CONFIG_VGA_ARB_MAX_GPUS=16
 
 CONFIG_DRM=m
 # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
+# CONFIG_DRM_AST is not set
+# CONFIG_DRM_CIRRUS_QEMU is not set
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
 CONFIG_DRM_RADEON=m
 CONFIG_DRM_RADEON_KMS=y
 # CONFIG_DRM_I810 is not set
 # CONFIG_DRM_MGA is not set
+# CONFIG_DRM_MGAG200 is not set
 # CONFIG_DRM_SIS is not set
 # CONFIG_DRM_SAVAGE is not set
 CONFIG_DRM_I915=m
@@ -2718,6 +2745,7 @@ CONFIG_FB=y
 # CONFIG_FB_ATY_CT is not set
 # CONFIG_FB_ATY_GX is not set
 # CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_AUO_K190X is not set
 # CONFIG_FB_CARMINE is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -3038,7 +3066,8 @@ CONFIG_USB_HID=y
 
 CONFIG_HID_SUPPORT=y
 
-CONFIG_HID=m
+CONFIG_HID=y
+CONFIG_HID_BATTERY_STRENGTH=y
 # debugging default is y upstream now
 CONFIG_HIDRAW=y
 CONFIG_HID_PID=y
@@ -3103,6 +3132,8 @@ CONFIG_HID_WIIMOTE_EXT=y
 CONFIG_HID_KYE=m
 CONFIG_HID_SAITEK=m
 CONFIG_HID_TIVO=m
+CONFIG_HID_GENERIC=y
+CONFIG_HID_AUREAL=m
 
 #
 # USB Imaging devices
@@ -3214,6 +3245,7 @@ CONFIG_USB_EPSON2888=y
 CONFIG_USB_KC2190=y
 
 # CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_CHIPIDEA is not set
 
 #
 # USB port drivers
@@ -3290,6 +3322,7 @@ CONFIG_USB_SERIAL_QCAUX=m
 CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
 CONFIG_USB_SERIAL_DEBUG=m
 CONFIG_USB_SERIAL_SSU100=m
+CONFIG_USB_SERIAL_QT2=m
 
 CONFIG_USB_SERIAL_CONSOLE=y
 
@@ -3351,6 +3384,8 @@ CONFIG_USB_ZERO=m
 
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
+# CONFIG_USB_ISP1301 is not set
+
 # CONFIG_USB_OTG is not set
 
 #
@@ -3389,6 +3424,7 @@ CONFIG_MFD_WM8400=m
 # CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_88PM860X is not set
 # CONFIG_LPC_SCH is not set
+# CONFIG_LPC_ICH is not set
 # CONFIG_HTC_I2CPLD is not set
 # CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_ASIC3 is not set
@@ -3405,6 +3441,8 @@ CONFIG_MFD_WM8400=m
 # CONFIG_MFD_TC3589X is not set
 # CONFIG_MFD_WL1273_CORE is not set
 # CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
 
 #
 # File systems
@@ -3541,6 +3579,7 @@ CONFIG_CUSE=m
 #
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
+CONFIG_NFS_V2=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
@@ -3675,6 +3714,17 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_NLS_UTF8=m
 CONFIG_NLS_ASCII=y
 
@@ -3697,6 +3747,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_DRIVER is not set
 CONFIG_HEADERS_CHECK=y
 # CONFIG_LKDTM is not set
+# CONFIG_READABLE_ASM is not set
 
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_LOCKDEP is not set
@@ -3730,6 +3781,7 @@ CONFIG_LOCKUP_DETECTOR=y
 CONFIG_ATOMIC64_SELFTEST=y
 CONFIG_MEMORY_FAILURE=y
 CONFIG_HWPOISON_INJECT=m
+CONFIG_CROSS_MEMORY_ATTACH=y
 # CONFIG_DEBUG_SECTION_MISMATCH is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 CONFIG_LATENCYTOP=y
@@ -3862,6 +3914,7 @@ CONFIG_CRC_T10DIF=m
 CONFIG_CRC8=m
 # CONFIG_CRC7 is not set
 CONFIG_CORDIC=m
+# CONFIG_DDR is not set
 
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_ZLIB_INFLATE=y
@@ -3948,6 +4001,8 @@ CONFIG_PM_TRACE_RTC=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_PM_RUNTIME=y
 # CONFIG_PM_OPP is not set
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
 
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
@@ -4022,6 +4077,7 @@ CONFIG_LEDS_TRIGGER_IDE_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_LEDS_TRIGGER_BACKLIGHT=m
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
 CONFIG_LEDS_ALIX2=m
 CONFIG_LEDS_CLEVO_MAIL=m
 CONFIG_LEDS_INTEL_SS4200=m
@@ -4082,7 +4138,7 @@ CONFIG_CFAG12864B_RATE=20
 # CONFIG_PHANTOM is not set
 # CONFIG_INTEL_MID_PTI is not set
 
-CONFIG_POWER_SUPPLY=m
+CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 
 # CONFIG_TEST_POWER is not set
@@ -4197,6 +4253,8 @@ CONFIG_USB_WUSB_CBAF=m
 # CONFIG_USB_WUSB_CBAF_DEBUG is not set
 CONFIG_USB_WHCI_HCD=m
 CONFIG_USB_HWA_HCD=m
+# CONFIG_USB_HCD_BCMA is not set
+# CONFIG_USB_HCD_SSB is not set
 
 CONFIG_UWB=m
 CONFIG_UWB_HWA=m
@@ -4267,6 +4325,8 @@ CONFIG_ALTERA_STAPL=m
 # CONFIG_ZSMALLOC is not set
 # CONFIG_RAMSTER is not set
 # CONFIG_USB_WPAN_HCD is not set
+# CONFIG_WIMAX_GDM72XX is not set 
+# CONFIG_IPACK_BUS is not set
 #
 # END OF STAGING
 
@@ -4307,6 +4367,12 @@ CONFIG_IEEE802154=m
 CONFIG_IEEE802154_6LOWPAN=m
 CONFIG_IEEE802154_DRIVERS=m
 CONFIG_IEEE802154_FAKEHARD=m
+CONFIG_IEEE802154_FAKELB=m
+
+CONFIG_MAC802154=m
+
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
 
 CONFIG_PPS=m
 # CONFIG_PPS_CLIENT_KTIMER is not set
@@ -4321,6 +4387,7 @@ CONFIG_PTP_1588_CLOCK=m
 CONFIG_PTP_1588_CLOCK_PCH=m
 
 CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
 
 # CONFIG_MDIO_GPIO is not set
 # CONFIG_KEYBOARD_GPIO is not set
@@ -4362,6 +4429,7 @@ CONFIG_TEST_KSTRTOX=y
 CONFIG_TARGET_CORE=m
 CONFIG_ISCSI_TARGET=m
 CONFIG_LOOPBACK_TARGET=m
+CONFIG_SBP_TARGET=m
 CONFIG_TCM_IBLOCK=m
 CONFIG_TCM_FILEIO=m
 CONFIG_TCM_PSCSI=m
@@ -4370,6 +4438,7 @@ CONFIG_TCM_FC=m
 CONFIG_HWSPINLOCK=m
 
 CONFIG_PSTORE=y
+CONFIG_PSTORE_RAM=m
 
 # CONFIG_AVERAGE is not set
 
diff --git a/config-powerpc-generic b/config-powerpc-generic
index 8045c06..366756b 100644
--- a/config-powerpc-generic
+++ b/config-powerpc-generic
@@ -359,6 +359,9 @@ CONFIG_RFKILL_GPIO=m
 # CONFIG_INPUT_GPIO_TILT_POLLED is not set
 CONFIG_STRICT_DEVMEM=y
 
+CONFIG_RCU_FANOUT_LEAF=16
+
 # CONFIG_IRQ_DOMAIN_DEBUG is not set
 # CONFIG_MPIC_MSGR is not set
 # CONFIG_FA_DUMP is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
diff --git a/config-powerpc64 b/config-powerpc64
index 2d5a752..5be9caa 100644
--- a/config-powerpc64
+++ b/config-powerpc64
@@ -1,6 +1,8 @@
+CONFIG_WINDFARM_PM72=y
 CONFIG_WINDFARM_PM81=y
 CONFIG_WINDFARM_PM91=y
 CONFIG_WINDFARM_PM121=y
+CONFIG_WINDFARM_RM31=y
 CONFIG_PPC_PMAC64=y
 CONFIG_PPC_MAPLE=y
 # CONFIG_PPC_CELL is not set
@@ -161,6 +163,10 @@ CONFIG_PPC_ICSWX=y
 CONFIG_IO_EVENT_IRQ=y
 CONFIG_HW_RANDOM_AMD=m
 
+# CONFIG_HW_RANDOM_PSERIES is not set
+# CONFIG_CRYPTO_DEV_NX is not set
+
+
 CONFIG_BPF_JIT=y
 # CONFIG_PPC_ICSWX_PID is not set
 # CONFIG_PPC_ICSWX_USE_SIGILL is not set
diff --git a/config-s390x b/config-s390x
index 848709d..451512e 100644
--- a/config-s390x
+++ b/config-s390x
@@ -211,6 +211,7 @@ CONFIG_CHSC_SCH=m
 CONFIG_HVC_IUCV=y
 
 CONFIG_RCU_FANOUT=64
+CONFIG_RCU_FANOUT_LEAF=16
 
 CONFIG_SECCOMP=y
 
diff --git a/config-sparc64-generic b/config-sparc64-generic
index 2b29f9b..a2b72df 100644
--- a/config-sparc64-generic
+++ b/config-sparc64-generic
@@ -173,6 +173,7 @@ CONFIG_LEDS_SUNFIRE=m
 CONFIG_TADPOLE_TS102_UCTRL=m
 
 CONFIG_RCU_FANOUT=64
+CONFIG_RCU_FANOUT_LEAF=16
 
 CONFIG_LIRC_ENE0100=m
 # CONFIG_BATTERY_DS2782 is not set
@@ -196,3 +197,5 @@ CONFIG_CRYPTO_DEV_NIAGARA2=y
 # CONFIG_MTD_PHYSMAP_OF is not set
 # CONFIG_MMC_SDHCI_OF is not set
 # CONFIG_OF_SELFTEST is not set
+
+CONFIG_BPF_JIT=y
diff --git a/config-x86-32-generic b/config-x86-32-generic
index 6eb6269..1c75224 100644
--- a/config-x86-32-generic
+++ b/config-x86-32-generic
@@ -27,6 +27,7 @@ CONFIG_M686=y
 # CONFIG_MWINCHIP3D is not set
 # CONFIG_MCYRIXIII is not set
 # CONFIG_MVIAC3_2 is not set
+# CONFIG_STA2X11 is not set
 
 CONFIG_NR_CPUS=32
 CONFIG_X86_GENERIC=y
@@ -212,5 +213,6 @@ CONFIG_I2O_BUS=m
 # CONFIG_INPUT_GPIO_TILT_POLLED is not set
 # CONFIG_GEOS is not set
 # CONFIG_NET5501 is not set
+# CONFIG_MDIO_BUS_MUX_GPIO is not set
 # CONFIG_GPIO_SODAVILLE is not set
 # CONFIG_BACKLIGHT_OT200 is not set
diff --git a/config-x86-generic b/config-x86-generic
index bddec16..4fab1ce 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -222,6 +222,7 @@ CONFIG_XO15_EBOOK=m
 # CONFIG_SMSC37B787_WDT is not set
 CONFIG_W83697HF_WDT=m
 CONFIG_VIA_WDT=m
+CONFIG_IE6XX_WDT=m
 
 CONFIG_CRASH_DUMP=y
 CONFIG_PROC_VMCORE=y
@@ -354,6 +355,9 @@ CONFIG_TOSHIBA_BT_RFKILL=m
 
 CONFIG_VGA_SWITCHEROO=y
 CONFIG_LPC_SCH=m
+CONFIG_LPC_ICH=m
+
+CONFIG_GPIO_ICH=m
 
 CONFIG_PCI_CNB20LE_QUIRK=y
 
@@ -409,7 +413,10 @@ CONFIG_DRM_GMA500=m
 # CONFIG_DRM_GMA600 is not set
 CONFIG_DRM_GMA3600=y
 
+CONFIG_RCU_FANOUT_LEAF=16
+
 # Maybe enable in debug kernels?
 # CONFIG_DEBUG_NMI_SELFTEST is not set
 
 CONFIG_APPLE_GMUX=m
+CONFIG_INTEL_MEI=m
diff --git a/kernel.spec b/kernel.spec
index 42ef71f..6f38205 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -54,19 +54,19 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 4
+%global baserelease 1
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
 # on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base,
 # which yields a base_sublevel of 21.
-%define base_sublevel 4
+%define base_sublevel 5
 
 ## If this is a released kernel ##
 %if 0%{?released_kernel}
 
 # Do we have a -stable update to apply?
-%define stable_update 6
+%define stable_update 0
 # Is it a -stable RC?
 %define stable_rc 0
 # Set rpm version accordingly
@@ -677,7 +677,6 @@ Patch1555: fix_xen_guest_on_old_EC2.patch
 # DRM
 #atch1700: drm-edid-try-harder-to-fix-up-broken-headers.patch
 Patch1800: drm-vgem.patch
-Patch1810: drm-edid-Make-the-header-fixup-threshold-tunable.patch
 
 # nouveau + drm fixes
 # intel drm is all merged upstream
@@ -686,8 +685,6 @@ Patch1825: drm-i915-dp-stfu.patch
 
 Patch1900: linux-2.6-intel-iommu-igfx.patch
 
-Patch1952: drm-i915-lvds-dual-channel.patch
-
 # Quiet boot fixes
 # silence the ACPI blacklist code
 Patch2802: linux-2.6-silence-acpi-blacklist.patch
@@ -715,27 +712,23 @@ Patch14015: team-update-from-net-next.patch
 Patch19000: ips-noirq.patch
 
 # Uprobes (rhbz 832083)
-Patch20000: uprobes-3.4-backport.patch
 Patch20001: uprobes-3.4-tip.patch
-Patch20002: uprobes-task_work_add-generic-process-context-callbacks.patch
 
 # ARM
 # Flattened devicetree support
 Patch21000: arm-omap-dt-compat.patch
 Patch21001: arm-smsc-support-reading-mac-address-from-device-tree.patch
 # drm register derived from http://www.digipedia.pl/usenet/thread/19013/36923/ 
-Patch21002: arm-omap-drm-register.patch
+#atch21002: arm-omap-drm-register.patch
 
 # ARM tegra
 Patch21004: arm-tegra-nvec-kconfig.patch
 Patch21005: arm-tegra-usb-no-reset-linux33.patch
-Patch21006: arm-beagle-usb-init.patch
+#atch21006: arm-beagle-usb-init.patch
 
 # ARM highbank patches
 # Highbank clock functions need to be EXPORT for module builds
 Patch21010: highbank-export-clock-functions.patch
-# http://lists.arm.linux.org.uk/lurker/message/20120605.031140.e7d9b601.en.html
-Patch21011: highbank-secure-smc.patch
 
 Patch21094: power-x86-destdir.patch
 
@@ -749,8 +742,6 @@ Patch21306: shlib_base_randomize.patch
 
 Patch21400: unhandled-irqs-switch-to-polling.patch
 
-Patch21620: vgaarb-vga_default_device.patch
-
 Patch22000: weird-root-dentry-name-debug.patch
 
 #selinux ptrace child permissions
@@ -758,12 +749,6 @@ Patch22001: selinux-apply-different-permission-to-ptrace-child.patch
 
 Patch22014: efifb-skip-DMI-checks-if-bootloader-knows.patch
 
-#rhbz 726143
-Patch22017: 0001-drm-radeon-don-t-mess-with-hot-plug-detect-for-eDP-o.patch
-
-#rhbz 749276
-Patch22018: atl1c_net_next_update-3.4.patch
-
 #Fix FIPS for aesni hardare
 Patch22055: crypto-testmgr-allow-aesni-intel-and-ghash_clmulni-intel.patch
 Patch22056: crypto-aesni-intel-fix-wrong-kfree-pointer.patch
@@ -1339,8 +1324,8 @@ ApplyPatch taint-rss.patch
 # ApplyPatch arm-smsc-support-reading-mac-address-from-device-tree.patch
 ApplyPatch arm-tegra-nvec-kconfig.patch
 ApplyPatch arm-tegra-usb-no-reset-linux33.patch
-ApplyPatch arm-beagle-usb-init.patch
-ApplyPatch arm-omap-drm-register.patch
+#pplyPatch arm-beagle-usb-init.patch
+#pplyPatch arm-omap-drm-register.patch
 
 #
 # bugfixes to drivers and filesystems
@@ -1416,7 +1401,6 @@ ApplyPatch fix_xen_guest_on_old_EC2.patch
 # DRM core
 #ApplyPatch drm-edid-try-harder-to-fix-up-broken-headers.patch
 ApplyPatch drm-vgem.patch
-ApplyPatch drm-edid-Make-the-header-fixup-threshold-tunable.patch
 
 # Nouveau DRM
 
@@ -1426,8 +1410,6 @@ ApplyPatch drm-i915-dp-stfu.patch
 
 ApplyPatch linux-2.6-intel-iommu-igfx.patch
 
-ApplyPatch drm-i915-lvds-dual-channel.patch
-
 # silence the ACPI blacklist code
 ApplyPatch linux-2.6-silence-acpi-blacklist.patch
 ApplyPatch quite-apm.patch
@@ -1453,9 +1435,7 @@ ApplyPatch team-update-from-net-next.patch
 ApplyPatch ips-noirq.patch
 
 # Uprobes (rhbz 832083)
-ApplyPatch uprobes-3.4-backport.patch
 ApplyPatch uprobes-3.4-tip.patch
-ApplyPatch uprobes-task_work_add-generic-process-context-callbacks.patch
 
 ApplyPatch power-x86-destdir.patch
 
@@ -1468,22 +1448,12 @@ ApplyPatch weird-root-dentry-name-debug.patch
 
 #Highbank clock functions
 ApplyPatch highbank-export-clock-functions.patch 
-ApplyPatch highbank-secure-smc.patch
 
 #selinux ptrace child permissions
 ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch
 
-#vgaarb patches.  blame mjg59
-ApplyPatch vgaarb-vga_default_device.patch
-
 ApplyPatch efifb-skip-DMI-checks-if-bootloader-knows.patch
 
-#rhbz 726143
-ApplyPatch 0001-drm-radeon-don-t-mess-with-hot-plug-detect-for-eDP-o.patch
-
-#rhbz 749276
-ApplyPatch atl1c_net_next_update-3.4.patch
-
 #Fix FIPS for aesni hardare
 ApplyPatch crypto-testmgr-allow-aesni-intel-and-ghash_clmulni-intel.patch
 ApplyPatch crypto-aesni-intel-fix-wrong-kfree-pointer.patch
@@ -2362,6 +2332,9 @@ fi
 #              '-'
 %changelog
 * Thu Jul 26 2012 Josh Boyer <jwboyer at redhat.com>
+- Rebase to Linux v3.5
+
+* Thu Jul 26 2012 Josh Boyer <jwboyer at redhat.com>
 - kernel: recv{from,msg}() on an rds socket can leak kernel
   memory (rhbz 820039 843554)
 - Apply patch to fix uvcvideo crash (rhbz 836742)
diff --git a/linux-2.6-input-kill-stupid-messages.patch b/linux-2.6-input-kill-stupid-messages.patch
index cc1dd74..ff7023f 100644
--- a/linux-2.6-input-kill-stupid-messages.patch
+++ b/linux-2.6-input-kill-stupid-messages.patch
@@ -1,32 +1,20 @@
-From b2c6d55b2351152696aafb8c9bf3ec8968acf77c Mon Sep 17 00:00:00 2001
-From: Kyle McMartin <kyle at phobos.i.jkkm.org>
-Date: Mon, 29 Mar 2010 23:59:58 -0400
-Subject: linux-2.6-input-kill-stupid-messages
-
----
- drivers/input/keyboard/atkbd.c |    5 +++++
- 1 files changed, 5 insertions(+), 0 deletions(-)
-
 diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
-index d358ef8..38db098 100644
+index add5ffd..5eb2f03 100644
 --- a/drivers/input/keyboard/atkbd.c
 +++ b/drivers/input/keyboard/atkbd.c
-@@ -425,11 +426,15 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
+@@ -430,11 +430,15 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
  		goto out;
  	case ATKBD_RET_ACK:
  	case ATKBD_RET_NAK:
-+#if 0
++# if 0
 +		/* Quite a few key switchers and other tools trigger this
 +		 * and it confuses people who can do nothing about it */
  		if (printk_ratelimit())
  			dev_warn(&serio->dev,
  				 "Spurious %s on %s. "
- 				 "Some program might be trying access hardware directly.\n",
+ 				 "Some program might be trying to access hardware directly.\n",
  				 data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
 +#endif
  		goto out;
  	case ATKBD_RET_ERR:
  		atkbd->err_count++;
--- 
-1.7.0.1
-
diff --git a/linux-2.6-makefile-after_link.patch b/linux-2.6-makefile-after_link.patch
index c2541b1..b520b19 100644
--- a/linux-2.6-makefile-after_link.patch
+++ b/linux-2.6-makefile-after_link.patch
@@ -1,4 +1,4 @@
-From f072f7db2194c8255c003d985b61ad2f97ebbee0 Mon Sep 17 00:00:00 2001
+From b707aea6a4947c3806ced2c23e889943a0f36876 Mon Sep 17 00:00:00 2001
 From: Roland McGrath <roland at redhat.com>
 Date: Mon, 6 Oct 2008 23:03:03 -0700
 Subject: [PATCH] kbuild: AFTER_LINK
@@ -7,24 +7,9 @@ If the make variable AFTER_LINK is set, it is a command line to run
 after each final link.  This includes vmlinux itself and vDSO images.
 
 Signed-off-by: Roland McGrath <roland at redhat.com>
----
-diff --git a/Makefile b/Makefile
-index f908acc..960ff6f 100644
---- a/Makefile
-+++ b/Makefile
-@@ -746,6 +746,10 @@ quiet_cmd_vmlinux__ ?= LD      $@
-       --start-group $(vmlinux-main) --end-group                  \
-       $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^)
- 
-+ifdef AFTER_LINK
-+cmd_vmlinux__ += ; $(AFTER_LINK)
-+endif
-+
- # Generate new vmlinux version
- quiet_cmd_vmlinux_version = GEN     .version
-       cmd_vmlinux_version = set -e;                     \
+
 diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
-index 51ead52..ad21273 100644
+index 9a7946c..28d6765 100644
 --- a/arch/powerpc/kernel/vdso32/Makefile
 +++ b/arch/powerpc/kernel/vdso32/Makefile
 @@ -41,7 +41,8 @@ $(obj-vdso32): %.o: %.S
@@ -38,7 +23,7 @@ index 51ead52..ad21273 100644
        cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
  
 diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
-index 79da65d..f11c21b 100644
+index 8c500d8..d27737b 100644
 --- a/arch/powerpc/kernel/vdso64/Makefile
 +++ b/arch/powerpc/kernel/vdso64/Makefile
 @@ -36,7 +36,8 @@ $(obj-vdso64): %.o: %.S
@@ -51,28 +36,11 @@ index 79da65d..f11c21b 100644
  quiet_cmd_vdso64as = VDSO64A $@
        cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
  
-diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
-index 4a2afa1..12ad9f7 100644
---- a/arch/x86/vdso/Makefile
-+++ b/arch/x86/vdso/Makefile
-@@ -120,8 +120,9 @@ $(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
- quiet_cmd_vdso = VDSO    $@
-       cmd_vdso = $(CC) -nostdlib -o $@ \
- 		       $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
--		       -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
--		 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
-+		       -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) \
-+		$(if $(AFTER_LINK),; $(AFTER_LINK)) && \
-+		sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
- 
- VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
- GCOV_PROFILE := n
-
 diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
-index d13e875..28a3e1ad 100644
+index 8ad2b34..e153572 100644
 --- a/arch/s390/kernel/vdso32/Makefile
 +++ b/arch/s390/kernel/vdso32/Makefile
-@@ -40,7 +40,8 @@ $(obj-vdso32): %.o: %.S
+@@ -43,7 +43,8 @@ $(obj-vdso32): %.o: %.S
  
  # actual build commands
  quiet_cmd_vdso32ld = VDSO32L $@
@@ -83,10 +51,10 @@ index d13e875..28a3e1ad 100644
        cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $<
  
 diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
-index 449352d..e90e656 100644
+index 2a8ddfd..452ca53 100644
 --- a/arch/s390/kernel/vdso64/Makefile
 +++ b/arch/s390/kernel/vdso64/Makefile
-@@ -40,7 +40,8 @@ $(obj-vdso64): %.o: %.S
+@@ -43,7 +43,8 @@ $(obj-vdso64): %.o: %.S
  
  # actual build commands
  quiet_cmd_vdso64ld = VDSO64L $@
@@ -96,3 +64,37 @@ index 449352d..e90e656 100644
  quiet_cmd_vdso64as = VDSO64A $@
        cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
  
+diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
+index fd14be1..1f3eb19 100644
+--- a/arch/x86/vdso/Makefile
++++ b/arch/x86/vdso/Makefile
+@@ -178,8 +178,9 @@ $(obj)/vdso32-syms.lds: $(vdso32.so-y:%=$(obj)/vdso32-%-syms.lds) FORCE
+ quiet_cmd_vdso = VDSO    $@
+       cmd_vdso = $(CC) -nostdlib -o $@ \
+ 		       $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
+-		       -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
+-		 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
++		       -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) \
++		$(if $(AFTER_LINK),; $(AFTER_LINK)) && \
++		sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
+ 
+ VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+ GCOV_PROFILE := n
+diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
+index cd9c6c6..3edf048 100644
+--- a/scripts/link-vmlinux.sh
++++ b/scripts/link-vmlinux.sh
+@@ -65,6 +65,10 @@ vmlinux_link()
+ 			-lutil ${1}
+ 		rm -f linux
+ 	fi
++	if [ -n "${AFTER_LINK}" ]; then
++		/usr/lib/rpm/debugedit -b ${RPM_BUILD_DIR} -d /usr/src/debug -i ${2} \
++			> ${2}.id
++	fi
+ }
+ 
+ 
+-- 
+1.7.7.6
+
diff --git a/sources b/sources
index 6f10d0c..d239339 100644
--- a/sources
+++ b/sources
@@ -1,2 +1 @@
-967f72983655e2479f951195953e8480  linux-3.4.tar.xz
-14443e53d3ab88e6eac45d954d891e00  patch-3.4.6.xz
+24153eaaa81dedc9481ada8cd9c3b83d  linux-3.5.tar.xz
diff --git a/team-update-from-net-next.patch b/team-update-from-net-next.patch
index 58fcbe5..14794ce 100644
--- a/team-update-from-net-next.patch
+++ b/team-update-from-net-next.patch
@@ -1,28 +1,12 @@
 Update team driver to latest net-next.
 
 Split patches available here:
-http://people.redhat.com/jpirko/f17_team_update/
+http://people.redhat.com/jpirko/f18_team_update/
 
-Modification of the kernel config is needed:
- +CONFIG_NET_TEAM_MODE_LOADBALANCE=m
-
-David S. Miller (2):
-  team: Stop using NLA_PUT*().
+David S. Miller (1):
   team: Revert previous two changes.
 
-Jiri Pirko (37):
-  filter: Allow to create sk-unattached filters
-  filter: add XOR operation
-  team: add binary option type
-  team: add loadbalance mode
-  team: add support for per-port options
-  team: add bool option type
-  team: add user_linkup and user_linkup_enabled per-port option
-  team: ab: walk through port list non-rcu
-  team: add missed "statics"
-  team: lb: let userspace care about port macs
-  team: allow to enable/disable ports
-  team: add per-port option for enabling/disabling ports
+Jiri Pirko (25):
   team: make team_mode struct const
   team: for nomode use dummy struct team_mode
   team: add mode priv to port
@@ -50,51 +34,17 @@ Jiri Pirko (37):
   team: do not allow to map disabled ports
   team: remove unused rcu_head field from team_port struct
 
- drivers/net/team/Kconfig                  |   11 +
- drivers/net/team/Makefile                 |    1 +
- drivers/net/team/team.c                   |  862 ++++++++++++++++++++++-------
- drivers/net/team/team_mode_activebackup.c |   30 +-
- drivers/net/team/team_mode_loadbalance.c  |  673 ++++++++++++++++++++++
- drivers/net/team/team_mode_roundrobin.c   |    6 +-
- include/linux/filter.h                    |    7 +-
- include/linux/if_team.h                   |   90 ++-
- net/core/filter.c                         |   70 ++-
- 9 files changed, 1514 insertions(+), 236 deletions(-)
- create mode 100644 drivers/net/team/team_mode_loadbalance.c
+ drivers/net/team/team.c                   |  577 ++++++++++++++++++-----------
+ drivers/net/team/team_mode_activebackup.c |   14 +-
+ drivers/net/team/team_mode_loadbalance.c  |  543 +++++++++++++++++++++++++--
+ drivers/net/team/team_mode_roundrobin.c   |    4 +-
+ include/linux/if_team.h                   |   25 +-
+ 5 files changed, 919 insertions(+), 244 deletions(-)
 
 Signed-off-by: Jiri Pirko <jpirko at redhat.com>
 
-diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
-index 248a144..89024d5 100644
---- a/drivers/net/team/Kconfig
-+++ b/drivers/net/team/Kconfig
-@@ -40,4 +40,15 @@ config NET_TEAM_MODE_ACTIVEBACKUP
- 	  To compile this team mode as a module, choose M here: the module
- 	  will be called team_mode_activebackup.
- 
-+config NET_TEAM_MODE_LOADBALANCE
-+	tristate "Load-balance mode support"
-+	depends on NET_TEAM
-+	---help---
-+	  This mode provides load balancing functionality. Tx port selection
-+	  is done using BPF function set up from userspace (bpf_hash_func
-+	  option)
-+
-+	  To compile this team mode as a module, choose M here: the module
-+	  will be called team_mode_loadbalance.
-+
- endif # NET_TEAM
-diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile
-index 85f2028..fb9f4c1 100644
---- a/drivers/net/team/Makefile
-+++ b/drivers/net/team/Makefile
-@@ -5,3 +5,4 @@
- obj-$(CONFIG_NET_TEAM) += team.o
- obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o
- obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o
-+obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o
 diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
-index 8f81805..5350eea 100644
+index c61ae35..5350eea 100644
 --- a/drivers/net/team/team.c
 +++ b/drivers/net/team/team.c
 @@ -1,5 +1,5 @@
@@ -104,69 +54,51 @@ index 8f81805..5350eea 100644
   * Copyright (c) 2011 Jiri Pirko <jpirko at redhat.com>
   *
   * This program is free software; you can redistribute it and/or modify
-@@ -65,7 +65,7 @@ static int __set_port_mac(struct net_device *port_dev,
- 	return dev_set_mac_address(port_dev, &addr);
- }
- 
--int team_port_set_orig_mac(struct team_port *port)
-+static int team_port_set_orig_mac(struct team_port *port)
- {
- 	return __set_port_mac(port->dev, port->orig.dev_addr);
+@@ -82,14 +82,16 @@ static void team_refresh_port_linkup(struct team_port *port)
+ 						   port->state.linkup;
  }
-@@ -76,12 +76,28 @@ int team_port_set_team_mac(struct team_port *port)
- }
- EXPORT_SYMBOL(team_port_set_team_mac);
  
-+static void team_refresh_port_linkup(struct team_port *port)
-+{
-+	port->linkup = port->user.linkup_enabled ? port->user.linkup :
-+						   port->state.linkup;
-+}
 +
- 
  /*******************
   * Options handling
   *******************/
  
--struct team_option *__team_find_option(struct team *team, const char *opt_name)
-+struct team_option_inst { /* One for each option instance */
-+	struct list_head list;
+ struct team_option_inst { /* One for each option instance */
+ 	struct list_head list;
 +	struct list_head tmp_list;
-+	struct team_option *option;
-+	struct team_option_inst_info info;
-+	bool changed;
-+	bool removed;
-+};
-+
-+static struct team_option *__team_find_option(struct team *team,
-+					      const char *opt_name)
- {
  	struct team_option *option;
- 
-@@ -92,9 +108,140 @@ struct team_option *__team_find_option(struct team *team, const char *opt_name)
+-	struct team_port *port; /* != NULL if per-port */
++	struct team_option_inst_info info;
+ 	bool changed;
+ 	bool removed;
+ };
+@@ -106,22 +108,6 @@ static struct team_option *__team_find_option(struct team *team,
  	return NULL;
  }
  
--int __team_options_register(struct team *team,
--			    const struct team_option *option,
--			    size_t option_count)
-+static void __team_option_inst_del(struct team_option_inst *opt_inst)
-+{
-+	list_del(&opt_inst->list);
-+	kfree(opt_inst);
-+}
-+
-+static void __team_option_inst_del_option(struct team *team,
-+					  struct team_option *option)
-+{
-+	struct team_option_inst *opt_inst, *tmp;
-+
-+	list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
-+		if (opt_inst->option == option)
-+			__team_option_inst_del(opt_inst);
-+	}
-+}
-+
+-static int __team_option_inst_add(struct team *team, struct team_option *option,
+-				  struct team_port *port)
+-{
+-	struct team_option_inst *opt_inst;
+-
+-	opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL);
+-	if (!opt_inst)
+-		return -ENOMEM;
+-	opt_inst->option = option;
+-	opt_inst->port = port;
+-	opt_inst->changed = true;
+-	opt_inst->removed = false;
+-	list_add_tail(&opt_inst->list, &team->option_inst_list);
+-	return 0;
+-}
+-
+ static void __team_option_inst_del(struct team_option_inst *opt_inst)
+ {
+ 	list_del(&opt_inst->list);
+@@ -139,14 +125,49 @@ static void __team_option_inst_del_option(struct team *team,
+ 	}
+ }
+ 
 +static int __team_option_inst_add(struct team *team, struct team_option *option,
 +				  struct team_port *port)
 +{
@@ -199,175 +131,74 @@ index 8f81805..5350eea 100644
 +	return 0;
 +}
 +
-+static int __team_option_inst_add_option(struct team *team,
-+					 struct team_option *option)
-+{
-+	struct team_port *port;
-+	int err;
-+
+ static int __team_option_inst_add_option(struct team *team,
+ 					 struct team_option *option)
+ {
+ 	struct team_port *port;
+ 	int err;
+ 
+-	if (!option->per_port)
+-		return __team_option_inst_add(team, option, 0);
 +	if (!option->per_port) {
 +		err = __team_option_inst_add(team, option, NULL);
 +		if (err)
 +			goto inst_del_option;
 +	}
-+
-+	list_for_each_entry(port, &team->port_list, list) {
-+		err = __team_option_inst_add(team, option, port);
-+		if (err)
-+			goto inst_del_option;
-+	}
-+	return 0;
-+
-+inst_del_option:
-+	__team_option_inst_del_option(team, option);
-+	return err;
-+}
-+
-+static void __team_option_inst_mark_removed_option(struct team *team,
-+						   struct team_option *option)
-+{
-+	struct team_option_inst *opt_inst;
-+
-+	list_for_each_entry(opt_inst, &team->option_inst_list, list) {
-+		if (opt_inst->option == option) {
-+			opt_inst->changed = true;
-+			opt_inst->removed = true;
-+		}
-+	}
-+}
-+
-+static void __team_option_inst_del_port(struct team *team,
-+					struct team_port *port)
-+{
-+	struct team_option_inst *opt_inst, *tmp;
-+
-+	list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
-+		if (opt_inst->option->per_port &&
-+		    opt_inst->info.port == port)
-+			__team_option_inst_del(opt_inst);
-+	}
-+}
-+
-+static int __team_option_inst_add_port(struct team *team,
-+				       struct team_port *port)
-+{
-+	struct team_option *option;
-+	int err;
-+
-+	list_for_each_entry(option, &team->option_list, list) {
-+		if (!option->per_port)
-+			continue;
-+		err = __team_option_inst_add(team, option, port);
-+		if (err)
-+			goto inst_del_port;
-+	}
-+	return 0;
-+
-+inst_del_port:
-+	__team_option_inst_del_port(team, port);
-+	return err;
-+}
-+
-+static void __team_option_inst_mark_removed_port(struct team *team,
-+						 struct team_port *port)
-+{
-+	struct team_option_inst *opt_inst;
-+
-+	list_for_each_entry(opt_inst, &team->option_inst_list, list) {
-+		if (opt_inst->info.port == port) {
-+			opt_inst->changed = true;
-+			opt_inst->removed = true;
-+		}
-+	}
-+}
-+
-+static int __team_options_register(struct team *team,
-+				   const struct team_option *option,
-+				   size_t option_count)
- {
- 	int i;
- 	struct team_option **dst_opts;
-@@ -107,26 +254,32 @@ int __team_options_register(struct team *team,
- 	for (i = 0; i < option_count; i++, option++) {
- 		if (__team_find_option(team, option->name)) {
- 			err = -EEXIST;
--			goto rollback;
-+			goto alloc_rollback;
- 		}
- 		dst_opts[i] = kmemdup(option, sizeof(*option), GFP_KERNEL);
- 		if (!dst_opts[i]) {
- 			err = -ENOMEM;
--			goto rollback;
-+			goto alloc_rollback;
- 		}
- 	}
  
- 	for (i = 0; i < option_count; i++) {
--		dst_opts[i]->changed = true;
--		dst_opts[i]->removed = false;
-+		err = __team_option_inst_add_option(team, dst_opts[i]);
-+		if (err)
-+			goto inst_rollback;
- 		list_add_tail(&dst_opts[i]->list, &team->option_list);
- 	}
- 
- 	kfree(dst_opts);
- 	return 0;
+ 	list_for_each_entry(port, &team->port_list, list) {
+ 		err = __team_option_inst_add(team, option, port);
+@@ -180,7 +201,7 @@ static void __team_option_inst_del_port(struct team *team,
  
--rollback:
--	for (i = 0; i < option_count; i++)
-+inst_rollback:
-+	for (i--; i >= 0; i--)
-+		__team_option_inst_del_option(team, dst_opts[i]);
-+
-+	i = option_count - 1;
-+alloc_rollback:
-+	for (i--; i >= 0; i--)
- 		kfree(dst_opts[i]);
- 
- 	kfree(dst_opts);
-@@ -143,10 +296,8 @@ static void __team_options_mark_removed(struct team *team,
- 		struct team_option *del_opt;
- 
- 		del_opt = __team_find_option(team, option->name);
--		if (del_opt) {
--			del_opt->changed = true;
--			del_opt->removed = true;
--		}
-+		if (del_opt)
-+			__team_option_inst_mark_removed_option(team, del_opt);
+ 	list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
+ 		if (opt_inst->option->per_port &&
+-		    opt_inst->port == port)
++		    opt_inst->info.port == port)
+ 			__team_option_inst_del(opt_inst);
  	}
  }
+@@ -211,7 +232,7 @@ static void __team_option_inst_mark_removed_port(struct team *team,
+ 	struct team_option_inst *opt_inst;
  
-@@ -161,6 +312,7 @@ static void __team_options_unregister(struct team *team,
- 
- 		del_opt = __team_find_option(team, option->name);
- 		if (del_opt) {
-+			__team_option_inst_del_option(team, del_opt);
- 			list_del(&del_opt->list);
- 			kfree(del_opt);
+ 	list_for_each_entry(opt_inst, &team->option_inst_list, list) {
+-		if (opt_inst->port == port) {
++		if (opt_inst->info.port == port) {
+ 			opt_inst->changed = true;
+ 			opt_inst->removed = true;
  		}
-@@ -193,25 +345,39 @@ void team_options_unregister(struct team *team,
+@@ -324,28 +345,12 @@ void team_options_unregister(struct team *team,
  }
  EXPORT_SYMBOL(team_options_unregister);
  
--static int team_option_get(struct team *team, struct team_option *option,
--			   void *arg)
-+static int team_option_get(struct team *team,
-+			   struct team_option_inst *opt_inst,
-+			   struct team_gsetter_ctx *ctx)
+-static int team_option_port_add(struct team *team, struct team_port *port)
+-{
+-	int err;
+-
+-	err = __team_option_inst_add_port(team, port);
+-	if (err)
+-		return err;
+-	__team_options_change_check(team);
+-	return 0;
+-}
+-
+-static void team_option_port_del(struct team *team, struct team_port *port)
+-{
+-	__team_option_inst_mark_removed_port(team, port);
+-	__team_options_change_check(team);
+-	__team_option_inst_del_port(team, port);
+-}
+-
+ static int team_option_get(struct team *team,
+ 			   struct team_option_inst *opt_inst,
+ 			   struct team_gsetter_ctx *ctx)
  {
--	return option->getter(team, arg);
 +	if (!opt_inst->option->getter)
 +		return -EOPNOTSUPP;
-+	return opt_inst->option->getter(team, ctx);
+ 	return opt_inst->option->getter(team, ctx);
  }
  
--static int team_option_set(struct team *team, struct team_option *option,
--			   void *arg)
-+static int team_option_set(struct team *team,
-+			   struct team_option_inst *opt_inst,
-+			   struct team_gsetter_ctx *ctx)
+@@ -353,16 +358,26 @@ static int team_option_set(struct team *team,
+ 			   struct team_option_inst *opt_inst,
+ 			   struct team_gsetter_ctx *ctx)
  {
 -	int err;
 +	if (!opt_inst->option->setter)
@@ -375,19 +206,18 @@ index 8f81805..5350eea 100644
 +	return opt_inst->option->setter(team, ctx);
 +}
  
--	err = option->setter(team, arg);
+-	err = opt_inst->option->setter(team, ctx);
 -	if (err)
 -		return err;
 +void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info)
 +{
 +	struct team_option_inst *opt_inst;
-+
+ 
 +	opt_inst = container_of(opt_inst_info, struct team_option_inst, info);
-+	opt_inst->changed = true;
+ 	opt_inst->changed = true;
 +}
 +EXPORT_SYMBOL(team_option_inst_set_change);
- 
--	option->changed = true;
++
 +void team_options_change_check(struct team *team)
 +{
  	__team_options_change_check(team);
@@ -398,7 +228,7 @@ index 8f81805..5350eea 100644
  
  /****************
   * Mode handling
-@@ -220,13 +386,18 @@ static int team_option_set(struct team *team, struct team_option *option,
+@@ -371,13 +386,18 @@ static int team_option_set(struct team *team,
  static LIST_HEAD(mode_list);
  static DEFINE_SPINLOCK(mode_list_lock);
  
@@ -422,7 +252,7 @@ index 8f81805..5350eea 100644
  	}
  	return NULL;
  }
-@@ -241,49 +412,65 @@ static bool is_good_mode_name(const char *name)
+@@ -392,49 +412,65 @@ static bool is_good_mode_name(const char *name)
  	return true;
  }
  
@@ -499,7 +329,7 @@ index 8f81805..5350eea 100644
  
  	spin_unlock(&mode_list_lock);
  	return mode;
-@@ -307,26 +494,45 @@ rx_handler_result_t team_dummy_receive(struct team *team,
+@@ -458,26 +494,45 @@ rx_handler_result_t team_dummy_receive(struct team *team,
  	return RX_HANDLER_ANOTHER;
  }
  
@@ -550,7 +380,7 @@ index 8f81805..5350eea 100644
  /*
   * We can benefit from the fact that it's ensured no port is present
   * at the time of mode change. Therefore no packets are in fly so there's no
-@@ -336,7 +542,7 @@ static int __team_change_mode(struct team *team,
+@@ -487,7 +542,7 @@ static int __team_change_mode(struct team *team,
  			      const struct team_mode *new_mode)
  {
  	/* Check if mode was previously set and do cleanup if so */
@@ -559,7 +389,7 @@ index 8f81805..5350eea 100644
  		void (*exit_op)(struct team *team) = team->ops.exit;
  
  		/* Clear ops area so no callback is called any longer */
-@@ -346,7 +552,7 @@ static int __team_change_mode(struct team *team,
+@@ -497,7 +552,7 @@ static int __team_change_mode(struct team *team,
  		if (exit_op)
  			exit_op(team);
  		team_mode_put(team->mode);
@@ -568,7 +398,7 @@ index 8f81805..5350eea 100644
  		/* zero private data area */
  		memset(&team->mode_priv, 0,
  		       sizeof(struct team) - offsetof(struct team, mode_priv));
-@@ -372,7 +578,7 @@ static int __team_change_mode(struct team *team,
+@@ -523,7 +578,7 @@ static int __team_change_mode(struct team *team,
  
  static int team_change_mode(struct team *team, const char *kind)
  {
@@ -577,7 +407,7 @@ index 8f81805..5350eea 100644
  	struct net_device *dev = team->dev;
  	int err;
  
-@@ -381,7 +587,7 @@ static int team_change_mode(struct team *team, const char *kind)
+@@ -532,7 +587,7 @@ static int team_change_mode(struct team *team, const char *kind)
  		return -EBUSY;
  	}
  
@@ -586,87 +416,53 @@ index 8f81805..5350eea 100644
  		netdev_err(dev, "Unable to change to the same mode the team is in\n");
  		return -EINVAL;
  	}
-@@ -424,8 +630,12 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
+@@ -559,8 +614,6 @@ static int team_change_mode(struct team *team, const char *kind)
+  * Rx path frame handler
+  ************************/
  
- 	port = team_port_get_rcu(skb->dev);
- 	team = port->team;
+-static bool team_port_enabled(struct team_port *port);
 -
--	res = team->ops.receive(team, port, skb);
-+	if (!team_port_enabled(port)) {
-+		/* allow exact match delivery for disabled ports */
-+		res = RX_HANDLER_EXACT;
-+	} else {
-+		res = team->ops.receive(team, port, skb);
-+	}
- 	if (res == RX_HANDLER_ANOTHER) {
- 		struct team_pcpu_stats *pcpu_stats;
- 
-@@ -461,17 +671,29 @@ static bool team_port_find(const struct team *team,
+ /* note: already called with rcu_read_lock */
+ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
+ {
+@@ -618,10 +671,11 @@ static bool team_port_find(const struct team *team,
  	return false;
  }
  
+-static bool team_port_enabled(struct team_port *port)
 +bool team_port_enabled(struct team_port *port)
-+{
-+	return port->index != -1;
-+}
+ {
+ 	return port->index != -1;
+ }
 +EXPORT_SYMBOL(team_port_enabled);
-+
+ 
  /*
-- * Add/delete port to the team port list. Write guarded by rtnl_lock.
-- * Takes care of correct port->index setup (might be racy).
-+ * Enable/disable port by adding to enabled port hashlist and setting
-+ * port->index (Might be racy so reader could see incorrect ifindex when
-+ * processing a flying packet, but that is not a problem). Write guarded
-+ * by team->lock.
-  */
--static void team_port_list_add_port(struct team *team,
--				    struct team_port *port)
-+static void team_port_enable(struct team *team,
-+			     struct team_port *port)
- {
--	port->index = team->port_count++;
-+	if (team_port_enabled(port))
-+		return;
-+	port->index = team->en_port_count++;
+  * Enable/disable port by adding to enabled port hashlist and setting
+@@ -637,6 +691,9 @@ static void team_port_enable(struct team *team,
+ 	port->index = team->en_port_count++;
  	hlist_add_head_rcu(&port->hlist,
  			   team_port_index_hash(team, port->index));
--	list_add_tail_rcu(&port->list, &team->port_list);
 +	team_adjust_ops(team);
 +	if (team->ops.port_enabled)
 +		team->ops.port_enabled(team, port);
  }
  
  static void __reconstruct_port_hlist(struct team *team, int rm_index)
-@@ -479,7 +701,7 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index)
- 	int i;
- 	struct team_port *port;
- 
--	for (i = rm_index + 1; i < team->port_count; i++) {
-+	for (i = rm_index + 1; i < team->en_port_count; i++) {
- 		port = team_get_port_by_index(team, i);
- 		hlist_del_rcu(&port->hlist);
- 		port->index--;
-@@ -488,15 +710,23 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index)
- 	}
- }
- 
--static void team_port_list_del_port(struct team *team,
--				   struct team_port *port)
-+static void team_port_disable(struct team *team,
-+			      struct team_port *port)
+@@ -656,14 +713,20 @@ static void __reconstruct_port_hlist(struct team *team, int rm_index)
+ static void team_port_disable(struct team *team,
+ 			      struct team_port *port)
  {
 -	int rm_index = port->index;
 -
-+	if (!team_port_enabled(port))
-+		return;
+ 	if (!team_port_enabled(port))
+ 		return;
 +	if (team->ops.port_disabled)
 +		team->ops.port_disabled(team, port);
  	hlist_del_rcu(&port->hlist);
--	list_del_rcu(&port->list);
 -	__reconstruct_port_hlist(team, rm_index);
--	team->port_count--;
+-	team->en_port_count--;
 +	__reconstruct_port_hlist(team, port->index);
-+	port->index = -1;
+ 	port->index = -1;
 +	__team_adjust_ops(team, team->en_port_count - 1);
 +	/*
 +	 * Wait until readers see adjusted ops. This ensures that
@@ -677,7 +473,7 @@ index 8f81805..5350eea 100644
  }
  
  #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
-@@ -591,7 +821,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
+@@ -758,7 +821,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
  		return -EBUSY;
  	}
  
@@ -687,37 +483,27 @@ index 8f81805..5350eea 100644
  	if (!port)
  		return -ENOMEM;
  
-@@ -642,15 +873,27 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
+@@ -809,7 +873,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
  		goto err_handler_register;
  	}
  
--	team_port_list_add_port(team, port);
--	team_adjust_ops(team);
+-	err = team_option_port_add(team, port);
 +	err = __team_option_inst_add_port(team, port);
-+	if (err) {
-+		netdev_err(dev, "Device %s failed to add per-port options\n",
-+			   portname);
-+		goto err_option_port_add;
-+	}
-+
-+	port->index = -1;
-+	team_port_enable(team, port);
-+	list_add_tail_rcu(&port->list, &team->port_list);
+ 	if (err) {
+ 		netdev_err(dev, "Device %s failed to add per-port options\n",
+ 			   portname);
+@@ -819,9 +883,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
+ 	port->index = -1;
+ 	team_port_enable(team, port);
+ 	list_add_tail_rcu(&port->list, &team->port_list);
+-	team_adjust_ops(team);
  	__team_compute_features(team);
  	__team_port_change_check(port, !!netif_carrier_ok(port_dev));
 +	__team_options_change_check(team);
  
  	netdev_info(dev, "Port device %s added\n", portname);
  
- 	return 0;
- 
-+err_option_port_add:
-+	netdev_rx_handler_unregister(port_dev);
-+
- err_handler_register:
- 	netdev_set_master(port_dev, NULL);
- 
-@@ -686,10 +929,13 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
+@@ -865,12 +929,13 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
  		return -ENOENT;
  	}
  
@@ -726,124 +512,95 @@ index 8f81805..5350eea 100644
 +	__team_option_inst_del_port(team, port);
  	port->removed = true;
  	__team_port_change_check(port, false);
--	team_port_list_del_port(team, port);
+ 	team_port_disable(team, port);
+ 	list_del_rcu(&port->list);
 -	team_adjust_ops(team);
-+	team_port_disable(team, port);
-+	list_del_rcu(&port->list);
+-	team_option_port_del(team, port);
  	netdev_rx_handler_unregister(port_dev);
  	netdev_set_master(port_dev, NULL);
  	vlan_vids_del_by_dev(port_dev, dev);
-@@ -710,21 +956,74 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
+@@ -891,11 +956,9 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
   * Net device ops
   *****************/
  
 -static const char team_no_mode_kind[] = "*NOMODE*";
-+static int team_mode_option_get(struct team *team, struct team_gsetter_ctx *ctx)
-+{
+-
+ static int team_mode_option_get(struct team *team, struct team_gsetter_ctx *ctx)
+ {
+-	ctx->data.str_val = team->mode ? team->mode->kind : team_no_mode_kind;
 +	ctx->data.str_val = team->mode->kind;
-+	return 0;
-+}
-+
-+static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
-+{
-+	return team_change_mode(team, ctx->data.str_val);
-+}
-+
-+static int team_port_en_option_get(struct team *team,
-+				   struct team_gsetter_ctx *ctx)
-+{
+ 	return 0;
+ }
+ 
+@@ -907,39 +970,47 @@ static int team_mode_option_set(struct team *team, struct team_gsetter_ctx *ctx)
+ static int team_port_en_option_get(struct team *team,
+ 				   struct team_gsetter_ctx *ctx)
+ {
+-	ctx->data.bool_val = team_port_enabled(ctx->port);
 +	struct team_port *port = ctx->info->port;
 +
 +	ctx->data.bool_val = team_port_enabled(port);
-+	return 0;
-+}
-+
-+static int team_port_en_option_set(struct team *team,
-+				   struct team_gsetter_ctx *ctx)
-+{
+ 	return 0;
+ }
+ 
+ static int team_port_en_option_set(struct team *team,
+ 				   struct team_gsetter_ctx *ctx)
+ {
 +	struct team_port *port = ctx->info->port;
 +
-+	if (ctx->data.bool_val)
+ 	if (ctx->data.bool_val)
+-		team_port_enable(team, ctx->port);
 +		team_port_enable(team, port);
-+	else
+ 	else
+-		team_port_disable(team, ctx->port);
 +		team_port_disable(team, port);
-+	return 0;
-+}
-+
-+static int team_user_linkup_option_get(struct team *team,
-+				       struct team_gsetter_ctx *ctx)
-+{
+ 	return 0;
+ }
+ 
+ static int team_user_linkup_option_get(struct team *team,
+ 				       struct team_gsetter_ctx *ctx)
+ {
+-	ctx->data.bool_val = ctx->port->user.linkup;
 +	struct team_port *port = ctx->info->port;
 +
 +	ctx->data.bool_val = port->user.linkup;
-+	return 0;
-+}
+ 	return 0;
+ }
  
--static int team_mode_option_get(struct team *team, void *arg)
-+static int team_user_linkup_option_set(struct team *team,
-+				       struct team_gsetter_ctx *ctx)
+ static int team_user_linkup_option_set(struct team *team,
+ 				       struct team_gsetter_ctx *ctx)
  {
--	const char **str = arg;
+-	ctx->port->user.linkup = ctx->data.bool_val;
+-	team_refresh_port_linkup(ctx->port);
 +	struct team_port *port = ctx->info->port;
- 
--	*str = team->mode ? team->mode->kind : team_no_mode_kind;
++
 +	port->user.linkup = ctx->data.bool_val;
 +	team_refresh_port_linkup(port);
  	return 0;
  }
  
--static int team_mode_option_set(struct team *team, void *arg)
-+static int team_user_linkup_en_option_get(struct team *team,
-+					  struct team_gsetter_ctx *ctx)
+ static int team_user_linkup_en_option_get(struct team *team,
+ 					  struct team_gsetter_ctx *ctx)
  {
--	const char **str = arg;
+-	struct team_port *port = ctx->port;
 +	struct team_port *port = ctx->info->port;
  
--	return team_change_mode(team, *str);
-+	ctx->data.bool_val = port->user.linkup_enabled;
-+	return 0;
-+}
-+
-+static int team_user_linkup_en_option_set(struct team *team,
-+					  struct team_gsetter_ctx *ctx)
-+{
+ 	ctx->data.bool_val = port->user.linkup_enabled;
+ 	return 0;
+@@ -948,10 +1019,10 @@ static int team_user_linkup_en_option_get(struct team *team,
+ static int team_user_linkup_en_option_set(struct team *team,
+ 					  struct team_gsetter_ctx *ctx)
+ {
+-	struct team_port *port = ctx->port;
 +	struct team_port *port = ctx->info->port;
-+
-+	port->user.linkup_enabled = ctx->data.bool_val;
+ 
+ 	port->user.linkup_enabled = ctx->data.bool_val;
+-	team_refresh_port_linkup(ctx->port);
 +	team_refresh_port_linkup(port);
-+	return 0;
+ 	return 0;
  }
  
- static const struct team_option team_options[] = {
-@@ -734,6 +1033,27 @@ static const struct team_option team_options[] = {
- 		.getter = team_mode_option_get,
- 		.setter = team_mode_option_set,
- 	},
-+	{
-+		.name = "enabled",
-+		.type = TEAM_OPTION_TYPE_BOOL,
-+		.per_port = true,
-+		.getter = team_port_en_option_get,
-+		.setter = team_port_en_option_set,
-+	},
-+	{
-+		.name = "user_linkup",
-+		.type = TEAM_OPTION_TYPE_BOOL,
-+		.per_port = true,
-+		.getter = team_user_linkup_option_get,
-+		.setter = team_user_linkup_option_set,
-+	},
-+	{
-+		.name = "user_linkup_enabled",
-+		.type = TEAM_OPTION_TYPE_BOOL,
-+		.per_port = true,
-+		.getter = team_user_linkup_en_option_get,
-+		.setter = team_user_linkup_en_option_set,
-+	},
- };
- 
- static int team_init(struct net_device *dev)
-@@ -744,18 +1064,20 @@ static int team_init(struct net_device *dev)
+@@ -993,6 +1064,7 @@ static int team_init(struct net_device *dev)
  
  	team->dev = dev;
  	mutex_init(&team->lock);
@@ -851,33 +608,7 @@ index 8f81805..5350eea 100644
  
  	team->pcpu_stats = alloc_percpu(struct team_pcpu_stats);
  	if (!team->pcpu_stats)
- 		return -ENOMEM;
- 
- 	for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
--		INIT_HLIST_HEAD(&team->port_hlist[i]);
-+		INIT_HLIST_HEAD(&team->en_port_hlist[i]);
- 	INIT_LIST_HEAD(&team->port_list);
- 
- 	team_adjust_ops(team);
- 
- 	INIT_LIST_HEAD(&team->option_list);
-+	INIT_LIST_HEAD(&team->option_inst_list);
- 	err = team_options_register(team, team_options, ARRAY_SIZE(team_options));
- 	if (err)
- 		goto err_options_register;
-@@ -1145,10 +1467,7 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = {
- 	},
- 	[TEAM_ATTR_OPTION_CHANGED]		= { .type = NLA_FLAG },
- 	[TEAM_ATTR_OPTION_TYPE]			= { .type = NLA_U8 },
--	[TEAM_ATTR_OPTION_DATA] = {
--		.type = NLA_BINARY,
--		.len = TEAM_STRING_MAX_LEN,
--	},
-+	[TEAM_ATTR_OPTION_DATA]			= { .type = NLA_BINARY },
- };
- 
- static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
-@@ -1235,98 +1554,210 @@ err_fill:
+@@ -1482,16 +1554,128 @@ err_fill:
  	return err;
  }
  
@@ -991,9 +722,8 @@ index 8f81805..5350eea 100644
  	struct nlattr *option_list;
 +	struct nlmsghdr *nlh;
  	void *hdr;
--	struct team_option *option;
-+	struct team_option_inst *opt_inst;
-+	int err;
+ 	struct team_option_inst *opt_inst;
+ 	int err;
 +	struct sk_buff *skb = NULL;
 +	bool incomplete;
 +	int i;
@@ -1011,43 +741,79 @@ index 8f81805..5350eea 100644
  			  TEAM_CMD_OPTIONS_GET);
  	if (IS_ERR(hdr))
  		return PTR_ERR(hdr);
- 
--	NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
-+	if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
-+		goto nla_put_failure;
+@@ -1500,122 +1684,80 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
+ 		goto nla_put_failure;
  	option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION);
  	if (!option_list)
 -		return -EMSGSIZE;
+-
+-	list_for_each_entry(opt_inst, &team->option_inst_list, list) {
+-		struct nlattr *option_item;
+-		struct team_option *option = opt_inst->option;
+-		struct team_gsetter_ctx ctx;
 +		goto nla_put_failure;
  
--	list_for_each_entry(option, &team->option_list, list) {
--		struct nlattr *option_item;
--		long arg;
--
 -		/* Include only changed options if fill all mode is not on */
--		if (!fillall && !option->changed)
+-		if (!fillall && !opt_inst->changed)
 -			continue;
 -		option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
 -		if (!option_item)
 -			goto nla_put_failure;
--		NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name);
--		if (option->changed) {
--			NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED);
--			option->changed = false;
+-		if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name))
+-			goto nla_put_failure;
+-		if (opt_inst->changed) {
+-			if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED))
+-				goto nla_put_failure;
+-			opt_inst->changed = false;
 -		}
--		if (option->removed)
--			NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_REMOVED);
+-		if (opt_inst->removed &&
+-		    nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
+-			goto nla_put_failure;
+-		if (opt_inst->port &&
+-		    nla_put_u32(skb, TEAM_ATTR_OPTION_PORT_IFINDEX,
+-				opt_inst->port->dev->ifindex))
+-			goto nla_put_failure;
+-		ctx.port = opt_inst->port;
 -		switch (option->type) {
 -		case TEAM_OPTION_TYPE_U32:
--			NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32);
--			team_option_get(team, option, &arg);
--			NLA_PUT_U32(skb, TEAM_ATTR_OPTION_DATA, arg);
+-			if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
+-				goto nla_put_failure;
+-			err = team_option_get(team, opt_inst, &ctx);
+-			if (err)
+-				goto errout;
+-			if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA,
+-					ctx.data.u32_val))
+-				goto nla_put_failure;
 -			break;
 -		case TEAM_OPTION_TYPE_STRING:
--			NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING);
--			team_option_get(team, option, &arg);
--			NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_DATA,
--				       (char *) arg);
+-			if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING))
+-				goto nla_put_failure;
+-			err = team_option_get(team, opt_inst, &ctx);
+-			if (err)
+-				goto errout;
+-			if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA,
+-					   ctx.data.str_val))
+-				goto nla_put_failure;
+-			break;
+-		case TEAM_OPTION_TYPE_BINARY:
+-			if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY))
+-				goto nla_put_failure;
+-			err = team_option_get(team, opt_inst, &ctx);
+-			if (err)
+-				goto errout;
+-			if (nla_put(skb, TEAM_ATTR_OPTION_DATA,
+-				    ctx.data.bin_val.len, ctx.data.bin_val.ptr))
+-				goto nla_put_failure;
+-			break;
+-		case TEAM_OPTION_TYPE_BOOL:
+-			if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_FLAG))
+-				goto nla_put_failure;
+-			err = team_option_get(team, opt_inst, &ctx);
+-			if (err)
+-				goto errout;
+-			if (ctx.data.bool_val &&
+-			    nla_put_flag(skb, TEAM_ATTR_OPTION_DATA))
+-				goto nla_put_failure;
 -			break;
 -		default:
 -			BUG();
@@ -1086,12 +852,13 @@ index 8f81805..5350eea 100644
 +	return send_func(skb, team, pid);
  
  nla_put_failure:
-+	err = -EMSGSIZE;
-+errout:
+ 	err = -EMSGSIZE;
+ errout:
  	genlmsg_cancel(skb, hdr);
--	return -EMSGSIZE;
--}
--
++	nlmsg_free(skb);
+ 	return err;
+ }
+ 
 -static int team_nl_fill_options_get_all(struct sk_buff *skb,
 -					struct genl_info *info, int flags,
 -					struct team *team)
@@ -1099,10 +866,8 @@ index 8f81805..5350eea 100644
 -	return team_nl_fill_options_get(skb, info->snd_pid,
 -					info->snd_seq, NLM_F_ACK,
 -					team, true);
-+	nlmsg_free(skb);
-+	return err;
- }
- 
+-}
+-
  static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
  {
  	struct team *team;
@@ -1139,69 +904,27 @@ index 8f81805..5350eea 100644
  
  	team = team_nl_team_get(info);
  	if (!team)
-@@ -1339,9 +1770,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
- 	}
+@@ -1629,10 +1771,12 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
  
  	nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) {
--		struct nlattr *mode_attrs[TEAM_ATTR_OPTION_MAX + 1];
-+		struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1];
+ 		struct nlattr *opt_attrs[TEAM_ATTR_OPTION_MAX + 1];
+-		struct nlattr *attr_port_ifindex;
 +		struct nlattr *attr;
-+		struct nlattr *attr_data;
+ 		struct nlattr *attr_data;
  		enum team_option_type opt_type;
--		struct team_option *option;
-+		int opt_port_ifindex = 0; /* != 0 for per-port options */
+ 		int opt_port_ifindex = 0; /* != 0 for per-port options */
 +		u32 opt_array_index = 0;
 +		bool opt_is_array = false;
-+		struct team_option_inst *opt_inst;
+ 		struct team_option_inst *opt_inst;
  		char *opt_name;
  		bool opt_found = false;
- 
-@@ -1349,50 +1785,92 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
- 			err = -EINVAL;
- 			goto team_put;
- 		}
--		err = nla_parse_nested(mode_attrs, TEAM_ATTR_OPTION_MAX,
-+		err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX,
- 				       nl_option, team_nl_option_policy);
- 		if (err)
- 			goto team_put;
--		if (!mode_attrs[TEAM_ATTR_OPTION_NAME] ||
--		    !mode_attrs[TEAM_ATTR_OPTION_TYPE] ||
--		    !mode_attrs[TEAM_ATTR_OPTION_DATA]) {
-+		if (!opt_attrs[TEAM_ATTR_OPTION_NAME] ||
-+		    !opt_attrs[TEAM_ATTR_OPTION_TYPE]) {
- 			err = -EINVAL;
- 			goto team_put;
- 		}
--		switch (nla_get_u8(mode_attrs[TEAM_ATTR_OPTION_TYPE])) {
-+		switch (nla_get_u8(opt_attrs[TEAM_ATTR_OPTION_TYPE])) {
- 		case NLA_U32:
- 			opt_type = TEAM_OPTION_TYPE_U32;
- 			break;
- 		case NLA_STRING:
- 			opt_type = TEAM_OPTION_TYPE_STRING;
- 			break;
-+		case NLA_BINARY:
-+			opt_type = TEAM_OPTION_TYPE_BINARY;
-+			break;
-+		case NLA_FLAG:
-+			opt_type = TEAM_OPTION_TYPE_BOOL;
-+			break;
- 		default:
- 			goto team_put;
+@@ -1674,23 +1818,33 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
  		}
  
--		opt_name = nla_data(mode_attrs[TEAM_ATTR_OPTION_NAME]);
--		list_for_each_entry(option, &team->option_list, list) {
--			long arg;
--			struct nlattr *opt_data_attr;
-+		attr_data = opt_attrs[TEAM_ATTR_OPTION_DATA];
-+		if (opt_type != TEAM_OPTION_TYPE_BOOL && !attr_data) {
-+			err = -EINVAL;
-+			goto team_put;
-+		}
-+
-+		opt_name = nla_data(opt_attrs[TEAM_ATTR_OPTION_NAME]);
+ 		opt_name = nla_data(opt_attrs[TEAM_ATTR_OPTION_NAME]);
+-		attr_port_ifindex = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
+-		if (attr_port_ifindex)
+-			opt_port_ifindex = nla_get_u32(attr_port_ifindex);
 +		attr = opt_attrs[TEAM_ATTR_OPTION_PORT_IFINDEX];
 +		if (attr)
 +			opt_port_ifindex = nla_get_u32(attr);
@@ -1212,50 +935,32 @@ index 8f81805..5350eea 100644
 +			opt_array_index = nla_get_u32(attr);
 +		}
  
-+		list_for_each_entry(opt_inst, &team->option_inst_list, list) {
-+			struct team_option *option = opt_inst->option;
-+			struct team_gsetter_ctx ctx;
+ 		list_for_each_entry(opt_inst, &team->option_inst_list, list) {
+ 			struct team_option *option = opt_inst->option;
+ 			struct team_gsetter_ctx ctx;
 +			struct team_option_inst_info *opt_inst_info;
-+			int tmp_ifindex;
-+
+ 			int tmp_ifindex;
+ 
+-			tmp_ifindex = opt_inst->port ?
+-				      opt_inst->port->dev->ifindex : 0;
 +			opt_inst_info = &opt_inst->info;
 +			tmp_ifindex = opt_inst_info->port ?
 +				      opt_inst_info->port->dev->ifindex : 0;
  			if (option->type != opt_type ||
--			    strcmp(option->name, opt_name))
-+			    strcmp(option->name, opt_name) ||
+ 			    strcmp(option->name, opt_name) ||
+-			    tmp_ifindex != opt_port_ifindex)
 +			    tmp_ifindex != opt_port_ifindex ||
 +			    (option->array_size && !opt_is_array) ||
 +			    opt_inst_info->array_index != opt_array_index)
  				continue;
  			opt_found = true;
--			opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA];
+-			ctx.port = opt_inst->port;
 +			ctx.info = opt_inst_info;
  			switch (opt_type) {
  			case TEAM_OPTION_TYPE_U32:
--				arg = nla_get_u32(opt_data_attr);
-+				ctx.data.u32_val = nla_get_u32(attr_data);
- 				break;
- 			case TEAM_OPTION_TYPE_STRING:
--				arg = (long) nla_data(opt_data_attr);
-+				if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) {
-+					err = -EINVAL;
-+					goto team_put;
-+				}
-+				ctx.data.str_val = nla_data(attr_data);
-+				break;
-+			case TEAM_OPTION_TYPE_BINARY:
-+				ctx.data.bin_val.len = nla_len(attr_data);
-+				ctx.data.bin_val.ptr = nla_data(attr_data);
-+				break;
-+			case TEAM_OPTION_TYPE_BOOL:
-+				ctx.data.bool_val = attr_data ? true : false;
- 				break;
- 			default:
- 				BUG();
- 			}
--			err = team_option_set(team, option, &arg);
-+			err = team_option_set(team, opt_inst, &ctx);
+ 				ctx.data.u32_val = nla_get_u32(attr_data);
+@@ -1715,6 +1869,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
+ 			err = team_option_set(team, opt_inst, &ctx);
  			if (err)
  				goto team_put;
 +			opt_inst->changed = true;
@@ -1263,7 +968,7 @@ index 8f81805..5350eea 100644
  		}
  		if (!opt_found) {
  			err = -ENOENT;
-@@ -1400,6 +1878,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
+@@ -1722,6 +1878,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
  		}
  	}
  
@@ -1272,13 +977,8 @@ index 8f81805..5350eea 100644
  team_put:
  	team_nl_team_put(team);
  
-@@ -1420,10 +1900,11 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
- 	if (IS_ERR(hdr))
- 		return PTR_ERR(hdr);
- 
--	NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
-+	if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
-+		goto nla_put_failure;
+@@ -1746,7 +1904,7 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
+ 		goto nla_put_failure;
  	port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT);
  	if (!port_list)
 -		return -EMSGSIZE;
@@ -1286,36 +986,7 @@ index 8f81805..5350eea 100644
  
  	list_for_each_entry(port, &team->port_list, list) {
  		struct nlattr *port_item;
-@@ -1434,17 +1915,20 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
- 		port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT);
- 		if (!port_item)
- 			goto nla_put_failure;
--		NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex);
-+		if (nla_put_u32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex))
-+			goto nla_put_failure;
- 		if (port->changed) {
--			NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED);
-+			if (nla_put_flag(skb, TEAM_ATTR_PORT_CHANGED))
-+				goto nla_put_failure;
- 			port->changed = false;
- 		}
--		if (port->removed)
--			NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_REMOVED);
--		if (port->linkup)
--			NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP);
--		NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed);
--		NLA_PUT_U8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex);
-+		if ((port->removed &&
-+		     nla_put_flag(skb, TEAM_ATTR_PORT_REMOVED)) ||
-+		    (port->state.linkup &&
-+		     nla_put_flag(skb, TEAM_ATTR_PORT_LINKUP)) ||
-+		    nla_put_u32(skb, TEAM_ATTR_PORT_SPEED, port->state.speed) ||
-+		    nla_put_u8(skb, TEAM_ATTR_PORT_DUPLEX, port->state.duplex))
-+			goto nla_put_failure;
- 		nla_nest_end(skb, port_item);
- 	}
- 
-@@ -1512,27 +1996,18 @@ static struct genl_multicast_group team_change_event_mcgrp = {
+@@ -1838,27 +1996,18 @@ static struct genl_multicast_group team_change_event_mcgrp = {
  	.name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME,
  };
  
@@ -1353,7 +1024,7 @@ index 8f81805..5350eea 100644
  }
  
  static int team_nl_send_event_port_list_get(struct team *team)
-@@ -1592,10 +2067,17 @@ static void team_nl_fini(void)
+@@ -1918,10 +2067,17 @@ static void team_nl_fini(void)
  static void __team_options_change_check(struct team *team)
  {
  	int err;
@@ -1373,38 +1044,7 @@ index 8f81805..5350eea 100644
  }
  
  /* rtnl lock is held */
-@@ -1603,23 +2085,24 @@ static void __team_port_change_check(struct team_port *port, bool linkup)
- {
- 	int err;
- 
--	if (!port->removed && port->linkup == linkup)
-+	if (!port->removed && port->state.linkup == linkup)
- 		return;
- 
- 	port->changed = true;
--	port->linkup = linkup;
-+	port->state.linkup = linkup;
-+	team_refresh_port_linkup(port);
- 	if (linkup) {
- 		struct ethtool_cmd ecmd;
- 
- 		err = __ethtool_get_settings(port->dev, &ecmd);
- 		if (!err) {
--			port->speed = ethtool_cmd_speed(&ecmd);
--			port->duplex = ecmd.duplex;
-+			port->state.speed = ethtool_cmd_speed(&ecmd);
-+			port->state.duplex = ecmd.duplex;
- 			goto send_event;
- 		}
- 	}
--	port->speed = 0;
--	port->duplex = 0;
-+	port->state.speed = 0;
-+	port->state.duplex = 0;
- 
- send_event:
- 	err = team_nl_send_event_port_list_get(port->team);
-@@ -1638,6 +2121,7 @@ static void team_port_change_check(struct team_port *port, bool linkup)
+@@ -1965,6 +2121,7 @@ static void team_port_change_check(struct team_port *port, bool linkup)
  	mutex_unlock(&team->lock);
  }
  
@@ -1413,7 +1053,7 @@ index 8f81805..5350eea 100644
   * Net device notifier event handler
   ************************************/
 diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c
-index f4d960e..253b8a5 100644
+index fd6bd03..253b8a5 100644
 --- a/drivers/net/team/team_mode_activebackup.c
 +++ b/drivers/net/team/team_mode_activebackup.c
 @@ -1,5 +1,5 @@
@@ -1432,57 +1072,22 @@ index f4d960e..253b8a5 100644
  	if (unlikely(!active_port))
  		goto drop;
  	skb->dev = active_port->dev;
-@@ -59,23 +59,25 @@ static void ab_port_leave(struct team *team, struct team_port *port)
- 		RCU_INIT_POINTER(ab_priv(team)->active_port, NULL);
- }
+@@ -61,8 +61,12 @@ static void ab_port_leave(struct team *team, struct team_port *port)
  
--static int ab_active_port_get(struct team *team, void *arg)
-+static int ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx)
+ static int ab_active_port_get(struct team *team, struct team_gsetter_ctx *ctx)
  {
--	u32 *ifindex = arg;
-+	struct team_port *active_port;
- 
--	*ifindex = 0;
 -	if (ab_priv(team)->active_port)
--		*ifindex = ab_priv(team)->active_port->dev->ifindex;
+-		ctx->data.u32_val = ab_priv(team)->active_port->dev->ifindex;
++	struct team_port *active_port;
++
 +	active_port = rcu_dereference_protected(ab_priv(team)->active_port,
 +						lockdep_is_held(&team->lock));
 +	if (active_port)
 +		ctx->data.u32_val = active_port->dev->ifindex;
-+	else
-+		ctx->data.u32_val = 0;
+ 	else
+ 		ctx->data.u32_val = 0;
  	return 0;
- }
- 
--static int ab_active_port_set(struct team *team, void *arg)
-+static int ab_active_port_set(struct team *team, struct team_gsetter_ctx *ctx)
- {
--	u32 *ifindex = arg;
- 	struct team_port *port;
- 
--	list_for_each_entry_rcu(port, &team->port_list, list) {
--		if (port->dev->ifindex == *ifindex) {
-+	list_for_each_entry(port, &team->port_list, list) {
-+		if (port->dev->ifindex == ctx->data.u32_val) {
- 			rcu_assign_pointer(ab_priv(team)->active_port, port);
- 			return 0;
- 		}
-@@ -92,12 +94,12 @@ static const struct team_option ab_options[] = {
- 	},
- };
- 
--int ab_init(struct team *team)
-+static int ab_init(struct team *team)
- {
- 	return team_options_register(team, ab_options, ARRAY_SIZE(ab_options));
- }
- 
--void ab_exit(struct team *team)
-+static void ab_exit(struct team *team)
- {
- 	team_options_unregister(team, ab_options, ARRAY_SIZE(ab_options));
- }
-@@ -110,7 +112,7 @@ static const struct team_mode_ops ab_mode_ops = {
+@@ -108,7 +112,7 @@ static const struct team_mode_ops ab_mode_ops = {
  	.port_leave		= ab_port_leave,
  };
  
@@ -1492,30 +1097,13 @@ index f4d960e..253b8a5 100644
  	.owner		= THIS_MODULE,
  	.priv_size	= sizeof(struct ab_priv),
 diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
-new file mode 100644
-index 0000000..51a4b19
---- /dev/null
+index 86e8183..51a4b19 100644
+--- a/drivers/net/team/team_mode_loadbalance.c
 +++ b/drivers/net/team/team_mode_loadbalance.c
-@@ -0,0 +1,673 @@
-+/*
-+ * drivers/net/team/team_mode_loadbalance.c - Load-balancing mode for team
-+ * Copyright (c) 2012 Jiri Pirko <jpirko at redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/filter.h>
-+#include <linux/if_team.h>
-+
+@@ -17,34 +17,210 @@
+ #include <linux/filter.h>
+ #include <linux/if_team.h>
+ 
 +struct lb_priv;
 +
 +typedef struct team_port *lb_select_tx_port_func_t(struct team *,
@@ -1556,18 +1144,21 @@ index 0000000..51a4b19
 +	} stats;
 +};
 +
-+struct lb_priv {
-+	struct sk_filter __rcu *fp;
+ struct lb_priv {
+ 	struct sk_filter __rcu *fp;
+-	struct sock_fprog *orig_fprog;
 +	lb_select_tx_port_func_t __rcu *select_tx_port_func;
 +	struct lb_pcpu_stats __percpu *pcpu_stats;
 +	struct lb_priv_ex *ex; /* priv extension */
-+};
-+
+ };
+ 
+-static struct lb_priv *lb_priv(struct team *team)
 +static struct lb_priv *get_lb_priv(struct team *team)
-+{
-+	return (struct lb_priv *) &team->mode_priv;
-+}
-+
+ {
+ 	return (struct lb_priv *) &team->mode_priv;
+ }
+ 
+-static bool lb_transmit(struct team *team, struct sk_buff *skb)
 +struct lb_port_priv {
 +	struct lb_stats __percpu *pcpu_stats;
 +	struct lb_stats_info stats_info;
@@ -1610,10 +1201,18 @@ index 0000000..51a4b19
 +						struct lb_priv *lb_priv,
 +						struct sk_buff *skb,
 +						unsigned char hash)
-+{
-+	int port_index;
-+
-+	port_index = hash % team->en_port_count;
+ {
+-	struct sk_filter *fp;
+-	struct team_port *port;
+-	unsigned int hash;
+ 	int port_index;
+ 
+-	fp = rcu_dereference(lb_priv(team)->fp);
+-	if (unlikely(!fp))
+-		goto drop;
+-	hash = SK_RUN_FILTER(fp, skb);
+ 	port_index = hash % team->en_port_count;
+-	port = team_get_port_by_index_rcu(team, port_index);
 +	return team_get_port_by_index_rcu(team, port_index);
 +}
 +
@@ -1714,89 +1313,62 @@ index 0000000..51a4b19
 +	hash = lb_get_skb_hash(lb_priv, skb);
 +	select_tx_port_func = rcu_dereference_bh(lb_priv->select_tx_port_func);
 +	port = select_tx_port_func(team, lb_priv, skb, hash);
-+	if (unlikely(!port))
-+		goto drop;
-+	skb->dev = port->dev;
-+	if (dev_queue_xmit(skb))
-+		return false;
+ 	if (unlikely(!port))
+ 		goto drop;
+ 	skb->dev = port->dev;
+ 	if (dev_queue_xmit(skb))
+ 		return false;
 +	lb_update_tx_stats(tx_bytes, lb_priv, get_lb_port_priv(port), hash);
-+	return true;
-+
-+drop:
-+	dev_kfree_skb_any(skb);
-+	return false;
-+}
-+
-+static int lb_bpf_func_get(struct team *team, struct team_gsetter_ctx *ctx)
-+{
+ 	return true;
+ 
+ drop:
+@@ -54,14 +230,16 @@ drop:
+ 
+ static int lb_bpf_func_get(struct team *team, struct team_gsetter_ctx *ctx)
+ {
+-	if (!lb_priv(team)->orig_fprog) {
 +	struct lb_priv *lb_priv = get_lb_priv(team);
 +
 +	if (!lb_priv->ex->orig_fprog) {
-+		ctx->data.bin_val.len = 0;
-+		ctx->data.bin_val.ptr = NULL;
-+		return 0;
-+	}
+ 		ctx->data.bin_val.len = 0;
+ 		ctx->data.bin_val.ptr = NULL;
+ 		return 0;
+ 	}
+-	ctx->data.bin_val.len = lb_priv(team)->orig_fprog->len *
 +	ctx->data.bin_val.len = lb_priv->ex->orig_fprog->len *
-+				sizeof(struct sock_filter);
+ 				sizeof(struct sock_filter);
+-	ctx->data.bin_val.ptr = lb_priv(team)->orig_fprog->filter;
 +	ctx->data.bin_val.ptr = lb_priv->ex->orig_fprog->filter;
-+	return 0;
-+}
-+
-+static int __fprog_create(struct sock_fprog **pfprog, u32 data_len,
-+			  const void *data)
-+{
-+	struct sock_fprog *fprog;
-+	struct sock_filter *filter = (struct sock_filter *) data;
-+
-+	if (data_len % sizeof(struct sock_filter))
-+		return -EINVAL;
-+	fprog = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
-+	if (!fprog)
-+		return -ENOMEM;
-+	fprog->filter = kmemdup(filter, data_len, GFP_KERNEL);
-+	if (!fprog->filter) {
-+		kfree(fprog);
-+		return -ENOMEM;
-+	}
-+	fprog->len = data_len / sizeof(struct sock_filter);
-+	*pfprog = fprog;
-+	return 0;
-+}
-+
-+static void __fprog_destroy(struct sock_fprog *fprog)
-+{
-+	kfree(fprog->filter);
-+	kfree(fprog);
-+}
-+
-+static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
-+{
+ 	return 0;
+ }
+ 
+@@ -94,7 +272,9 @@ static void __fprog_destroy(struct sock_fprog *fprog)
+ 
+ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
+ {
 +	struct lb_priv *lb_priv = get_lb_priv(team);
-+	struct sk_filter *fp = NULL;
+ 	struct sk_filter *fp = NULL;
 +	struct sk_filter *orig_fp;
-+	struct sock_fprog *fprog = NULL;
-+	int err;
-+
-+	if (ctx->data.bin_val.len) {
-+		err = __fprog_create(&fprog, ctx->data.bin_val.len,
-+				     ctx->data.bin_val.ptr);
-+		if (err)
-+			return err;
-+		err = sk_unattached_filter_create(&fp, fprog);
-+		if (err) {
-+			__fprog_destroy(fprog);
-+			return err;
-+		}
-+	}
-+
+ 	struct sock_fprog *fprog = NULL;
+ 	int err;
+ 
+@@ -110,14 +290,238 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
+ 		}
+ 	}
+ 
+-	if (lb_priv(team)->orig_fprog) {
 +	if (lb_priv->ex->orig_fprog) {
-+		/* Clear old filter data */
+ 		/* Clear old filter data */
+-		__fprog_destroy(lb_priv(team)->orig_fprog);
+-		sk_unattached_filter_destroy(lb_priv(team)->fp);
 +		__fprog_destroy(lb_priv->ex->orig_fprog);
 +		orig_fp = rcu_dereference_protected(lb_priv->fp,
 +						lockdep_is_held(&team->lock));
 +		sk_unattached_filter_destroy(orig_fp);
-+	}
-+
+ 	}
+ 
+-	rcu_assign_pointer(lb_priv(team)->fp, fp);
+-	lb_priv(team)->orig_fprog = fprog;
 +	rcu_assign_pointer(lb_priv->fp, fp);
 +	lb_priv->ex->orig_fprog = fprog;
 +	return 0;
@@ -2021,16 +1593,13 @@ index 0000000..51a4b19
 +		schedule_delayed_work(&lb_priv->ex->stats.refresh_dw, 0);
 +	else
 +		cancel_delayed_work(&lb_priv->ex->stats.refresh_dw);
-+	return 0;
-+}
-+
-+static const struct team_option lb_options[] = {
-+	{
-+		.name = "bpf_hash_func",
-+		.type = TEAM_OPTION_TYPE_BINARY,
-+		.getter = lb_bpf_func_get,
-+		.setter = lb_bpf_func_set,
-+	},
+ 	return 0;
+ }
+ 
+@@ -128,30 +532,125 @@ static const struct team_option lb_options[] = {
+ 		.getter = lb_bpf_func_get,
+ 		.setter = lb_bpf_func_set,
+ 	},
 +	{
 +		.name = "lb_tx_method",
 +		.type = TEAM_OPTION_TYPE_STRING,
@@ -2065,10 +1634,12 @@ index 0000000..51a4b19
 +		.getter = lb_stats_refresh_interval_get,
 +		.setter = lb_stats_refresh_interval_set,
 +	},
-+};
-+
-+static int lb_init(struct team *team)
-+{
+ };
+ 
+ static int lb_init(struct team *team)
+ {
+-	return team_options_register(team, lb_options,
+-				     ARRAY_SIZE(lb_options));
 +	struct lb_priv *lb_priv = get_lb_priv(team);
 +	lb_select_tx_port_func_t *func;
 +	int err;
@@ -2101,14 +1672,14 @@ index 0000000..51a4b19
 +err_alloc_pcpu_stats:
 +	kfree(lb_priv->ex);
 +	return err;
-+}
-+
-+static void lb_exit(struct team *team)
-+{
+ }
+ 
+ static void lb_exit(struct team *team)
+ {
 +	struct lb_priv *lb_priv = get_lb_priv(team);
 +
-+	team_options_unregister(team, lb_options,
-+				ARRAY_SIZE(lb_options));
+ 	team_options_unregister(team, lb_options,
+ 				ARRAY_SIZE(lb_options));
 +	cancel_delayed_work_sync(&lb_priv->ex->stats.refresh_dw);
 +	free_percpu(lb_priv->pcpu_stats);
 +	kfree(lb_priv->ex);
@@ -2134,44 +1705,28 @@ index 0000000..51a4b19
 +static void lb_port_disabled(struct team *team, struct team_port *port)
 +{
 +	lb_tx_hash_to_port_mapping_null_port(team, port);
-+}
-+
-+static const struct team_mode_ops lb_mode_ops = {
-+	.init			= lb_init,
-+	.exit			= lb_exit,
+ }
+ 
+ static const struct team_mode_ops lb_mode_ops = {
+ 	.init			= lb_init,
+ 	.exit			= lb_exit,
 +	.port_enter		= lb_port_enter,
 +	.port_leave		= lb_port_leave,
 +	.port_disabled		= lb_port_disabled,
-+	.transmit		= lb_transmit,
-+};
-+
+ 	.transmit		= lb_transmit,
+ };
+ 
+-static struct team_mode lb_mode = {
 +static const struct team_mode lb_mode = {
-+	.kind		= "loadbalance",
-+	.owner		= THIS_MODULE,
-+	.priv_size	= sizeof(struct lb_priv),
+ 	.kind		= "loadbalance",
+ 	.owner		= THIS_MODULE,
+ 	.priv_size	= sizeof(struct lb_priv),
 +	.port_priv_size	= sizeof(struct lb_port_priv),
-+	.ops		= &lb_mode_ops,
-+};
-+
-+static int __init lb_init_module(void)
-+{
-+	return team_mode_register(&lb_mode);
-+}
-+
-+static void __exit lb_cleanup_module(void)
-+{
-+	team_mode_unregister(&lb_mode);
-+}
-+
-+module_init(lb_init_module);
-+module_exit(lb_cleanup_module);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Jiri Pirko <jpirko at redhat.com>");
-+MODULE_DESCRIPTION("Load-balancing mode for team");
-+MODULE_ALIAS("team-mode-loadbalance");
+ 	.ops		= &lb_mode_ops,
+ };
+ 
 diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c
-index a0e8f80..52dd0ec 100644
+index 6abfbdc..52dd0ec 100644
 --- a/drivers/net/team/team_mode_roundrobin.c
 +++ b/drivers/net/team/team_mode_roundrobin.c
 @@ -1,5 +1,5 @@
@@ -2181,15 +1736,6 @@ index a0e8f80..52dd0ec 100644
   * Copyright (c) 2011 Jiri Pirko <jpirko at redhat.com>
   *
   * This program is free software; you can redistribute it and/or modify
-@@ -50,7 +50,7 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
- 	struct team_port *port;
- 	int port_index;
- 
--	port_index = rr_priv(team)->sent_packets++ % team->port_count;
-+	port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
- 	port = team_get_port_by_index_rcu(team, port_index);
- 	port = __get_first_port_up(team, port);
- 	if (unlikely(!port))
 @@ -81,7 +81,7 @@ static const struct team_mode_ops rr_mode_ops = {
  	.port_change_mac	= rr_port_change_mac,
  };
@@ -2199,85 +1745,14 @@ index a0e8f80..52dd0ec 100644
  	.kind		= "roundrobin",
  	.owner		= THIS_MODULE,
  	.priv_size	= sizeof(struct rr_priv),
-diff --git a/include/linux/filter.h b/include/linux/filter.h
-index 8eeb205..7209099 100644
---- a/include/linux/filter.h
-+++ b/include/linux/filter.h
-@@ -126,7 +126,8 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
- #define SKF_AD_HATYPE	28
- #define SKF_AD_RXHASH	32
- #define SKF_AD_CPU	36
--#define SKF_AD_MAX	40
-+#define SKF_AD_ALU_XOR_X	40
-+#define SKF_AD_MAX	44
- #define SKF_NET_OFF   (-0x100000)
- #define SKF_LL_OFF    (-0x200000)
- 
-@@ -153,6 +154,9 @@ static inline unsigned int sk_filter_len(const struct sk_filter *fp)
- extern int sk_filter(struct sock *sk, struct sk_buff *skb);
- extern unsigned int sk_run_filter(const struct sk_buff *skb,
- 				  const struct sock_filter *filter);
-+extern int sk_unattached_filter_create(struct sk_filter **pfp,
-+				       struct sock_fprog *fprog);
-+extern void sk_unattached_filter_destroy(struct sk_filter *fp);
- extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
- extern int sk_detach_filter(struct sock *sk);
- extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
-@@ -228,6 +232,7 @@ enum {
- 	BPF_S_ANC_HATYPE,
- 	BPF_S_ANC_RXHASH,
- 	BPF_S_ANC_CPU,
-+	BPF_S_ANC_ALU_XOR_X,
- };
- 
- #endif /* __KERNEL__ */
 diff --git a/include/linux/if_team.h b/include/linux/if_team.h
-index 58404b0..99efd60 100644
+index 8185f57..99efd60 100644
 --- a/include/linux/if_team.h
 +++ b/include/linux/if_team.h
-@@ -28,10 +28,28 @@ struct team;
- 
- struct team_port {
- 	struct net_device *dev;
--	struct hlist_node hlist; /* node in hash list */
-+	struct hlist_node hlist; /* node in enabled ports hash list */
- 	struct list_head list; /* node in ordinary list */
- 	struct team *team;
--	int index;
-+	int index; /* index of enabled port. If disabled, it's set to -1 */
-+
-+	bool linkup; /* either state.linkup or user.linkup */
-+
-+	struct {
-+		bool linkup;
-+		u32 speed;
-+		u8 duplex;
-+	} state;
-+
-+	/* Values set by userspace */
-+	struct {
-+		bool linkup;
-+		bool linkup_enabled;
-+	} user;
-+
-+	/* Custom gennetlink interface related flags */
-+	bool changed;
-+	bool removed;
- 
- 	/*
- 	 * A place for storing original values of the device before it
-@@ -42,17 +60,11 @@ struct team_port {
+@@ -60,9 +60,11 @@ struct team_port {
  		unsigned int mtu;
  	} orig;
  
--	bool linkup;
--	u32 speed;
--	u8 duplex;
--
--	/* Custom gennetlink interface related flags */
--	bool changed;
--	bool removed;
--
 -	struct rcu_head rcu;
 +	long mode_priv[0];
  };
@@ -2287,7 +1762,7 @@ index 58404b0..99efd60 100644
  struct team_mode_ops {
  	int (*init)(struct team *team);
  	void (*exit)(struct team *team);
-@@ -63,30 +75,54 @@ struct team_mode_ops {
+@@ -73,6 +75,8 @@ struct team_mode_ops {
  	int (*port_enter)(struct team *team, struct team_port *port);
  	void (*port_leave)(struct team *team, struct team_port *port);
  	void (*port_change_mac)(struct team *team, struct team_port *port);
@@ -2296,45 +1771,35 @@ index 58404b0..99efd60 100644
  };
  
  enum team_option_type {
- 	TEAM_OPTION_TYPE_U32,
- 	TEAM_OPTION_TYPE_STRING,
-+	TEAM_OPTION_TYPE_BINARY,
-+	TEAM_OPTION_TYPE_BOOL,
-+};
-+
+@@ -82,6 +86,11 @@ enum team_option_type {
+ 	TEAM_OPTION_TYPE_BOOL,
+ };
+ 
 +struct team_option_inst_info {
 +	u32 array_index;
 +	struct team_port *port; /* != NULL if per-port */
 +};
 +
-+struct team_gsetter_ctx {
-+	union {
-+		u32 u32_val;
-+		const char *str_val;
-+		struct {
-+			const void *ptr;
-+			u32 len;
-+		} bin_val;
-+		bool bool_val;
-+	} data;
+ struct team_gsetter_ctx {
+ 	union {
+ 		u32 u32_val;
+@@ -92,23 +101,28 @@ struct team_gsetter_ctx {
+ 		} bin_val;
+ 		bool bool_val;
+ 	} data;
+-	struct team_port *port;
 +	struct team_option_inst_info *info;
  };
  
  struct team_option {
  	struct list_head list;
  	const char *name;
-+	bool per_port;
+ 	bool per_port;
 +	unsigned int array_size; /* != 0 means the option is array */
  	enum team_option_type type;
--	int (*getter)(struct team *team, void *arg);
--	int (*setter)(struct team *team, void *arg);
--
--	/* Custom gennetlink interface related flags */
--	bool changed;
--	bool removed;
 +	int (*init)(struct team *team, struct team_option_inst_info *info);
-+	int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
-+	int (*setter)(struct team *team, struct team_gsetter_ctx *ctx);
+ 	int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
+ 	int (*setter)(struct team *team, struct team_gsetter_ctx *ctx);
  };
  
 +extern void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info);
@@ -2349,36 +1814,7 @@ index 58404b0..99efd60 100644
  	const struct team_mode_ops *ops;
  };
  
-@@ -103,13 +139,15 @@ struct team {
- 	struct mutex lock; /* used for overall locking, e.g. port lists write */
- 
- 	/*
--	 * port lists with port count
-+	 * List of enabled ports and their count
- 	 */
--	int port_count;
--	struct hlist_head port_hlist[TEAM_PORT_HASHENTRIES];
--	struct list_head port_list;
-+	int en_port_count;
-+	struct hlist_head en_port_hlist[TEAM_PORT_HASHENTRIES];
-+
-+	struct list_head port_list; /* list of all ports */
- 
- 	struct list_head option_list;
-+	struct list_head option_inst_list; /* list of option instances */
- 
- 	const struct team_mode *mode;
- 	struct team_mode_ops ops;
-@@ -119,7 +157,7 @@ struct team {
- static inline struct hlist_head *team_port_index_hash(struct team *team,
- 						      int port_index)
- {
--	return &team->port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
-+	return &team->en_port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
- }
- 
- static inline struct team_port *team_get_port_by_index(struct team *team,
-@@ -154,8 +192,8 @@ extern int team_options_register(struct team *team,
+@@ -178,8 +192,8 @@ extern int team_options_register(struct team *team,
  extern void team_options_unregister(struct team *team,
  				    const struct team_option *option,
  				    size_t option_count);
@@ -2389,123 +1825,14 @@ index 58404b0..99efd60 100644
  
  #endif /* __KERNEL__ */
  
-@@ -216,6 +254,8 @@ enum {
- 	TEAM_ATTR_OPTION_TYPE,		/* u8 */
+@@ -241,6 +255,7 @@ enum {
  	TEAM_ATTR_OPTION_DATA,		/* dynamic */
  	TEAM_ATTR_OPTION_REMOVED,	/* flag */
-+	TEAM_ATTR_OPTION_PORT_IFINDEX,	/* u32 */ /* for per-port options */
+ 	TEAM_ATTR_OPTION_PORT_IFINDEX,	/* u32 */ /* for per-port options */
 +	TEAM_ATTR_OPTION_ARRAY_INDEX,	/* u32 */ /* for array options */
  
  	__TEAM_ATTR_OPTION_MAX,
  	TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
-diff --git a/net/core/filter.c b/net/core/filter.c
-index 6f755cc..95d05a6 100644
---- a/net/core/filter.c
-+++ b/net/core/filter.c
-@@ -317,6 +317,9 @@ load_b:
- 		case BPF_S_ANC_CPU:
- 			A = raw_smp_processor_id();
- 			continue;
-+		case BPF_S_ANC_ALU_XOR_X:
-+			A ^= X;
-+			continue;
- 		case BPF_S_ANC_NLATTR: {
- 			struct nlattr *nla;
- 
-@@ -561,6 +564,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
- 			ANCILLARY(HATYPE);
- 			ANCILLARY(RXHASH);
- 			ANCILLARY(CPU);
-+			ANCILLARY(ALU_XOR_X);
- 			}
- 		}
- 		ftest->code = code;
-@@ -589,6 +593,67 @@ void sk_filter_release_rcu(struct rcu_head *rcu)
- }
- EXPORT_SYMBOL(sk_filter_release_rcu);
- 
-+static int __sk_prepare_filter(struct sk_filter *fp)
-+{
-+	int err;
-+
-+	fp->bpf_func = sk_run_filter;
-+
-+	err = sk_chk_filter(fp->insns, fp->len);
-+	if (err)
-+		return err;
-+
-+	bpf_jit_compile(fp);
-+	return 0;
-+}
-+
-+/**
-+ *	sk_unattached_filter_create - create an unattached filter
-+ *	@fprog: the filter program
-+ *	@sk: the socket to use
-+ *
-+ * Create a filter independent ofr any socket. We first run some
-+ * sanity checks on it to make sure it does not explode on us later.
-+ * If an error occurs or there is insufficient memory for the filter
-+ * a negative errno code is returned. On success the return is zero.
-+ */
-+int sk_unattached_filter_create(struct sk_filter **pfp,
-+				struct sock_fprog *fprog)
-+{
-+	struct sk_filter *fp;
-+	unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
-+	int err;
-+
-+	/* Make sure new filter is there and in the right amounts. */
-+	if (fprog->filter == NULL)
-+		return -EINVAL;
-+
-+	fp = kmalloc(fsize + sizeof(*fp), GFP_KERNEL);
-+	if (!fp)
-+		return -ENOMEM;
-+	memcpy(fp->insns, fprog->filter, fsize);
-+
-+	atomic_set(&fp->refcnt, 1);
-+	fp->len = fprog->len;
-+
-+	err = __sk_prepare_filter(fp);
-+	if (err)
-+		goto free_mem;
-+
-+	*pfp = fp;
-+	return 0;
-+free_mem:
-+	kfree(fp);
-+	return err;
-+}
-+EXPORT_SYMBOL_GPL(sk_unattached_filter_create);
-+
-+void sk_unattached_filter_destroy(struct sk_filter *fp)
-+{
-+	sk_filter_release(fp);
-+}
-+EXPORT_SYMBOL_GPL(sk_unattached_filter_destroy);
-+
- /**
-  *	sk_attach_filter - attach a socket filter
-  *	@fprog: the filter program
-@@ -619,16 +684,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
- 
- 	atomic_set(&fp->refcnt, 1);
- 	fp->len = fprog->len;
--	fp->bpf_func = sk_run_filter;
- 
--	err = sk_chk_filter(fp->insns, fp->len);
-+	err = __sk_prepare_filter(fp);
- 	if (err) {
- 		sk_filter_uncharge(sk, fp);
- 		return err;
- 	}
- 
--	bpf_jit_compile(fp);
--
- 	old_fp = rcu_dereference_protected(sk->sk_filter,
- 					   sock_owned_by_user(sk));
- 	rcu_assign_pointer(sk->sk_filter, fp);
 _______________________________________________
 kernel mailing list
 kernel at lists.fedoraproject.org


More information about the scm-commits mailing list