From d80819c17743e855ba12cf1cffd174a4a6f714c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Fri, 14 Oct 2016 21:14:19 +0300 Subject: [PATCH 01/11] works for new kernel-4.8.1 --- .../kernel/files/configs/kernel-x86_64-config | 126 ++++++++++----- .../kernel/files/patches/linux/patch-4.8.1.xz | Bin 0 -> 3136 bytes .../mageia/3rd-rtl8723bs-4.8-buildfix.patch | 19 +++ .../ahci-add-new-Intel-device-IDs.patch | 37 ----- ...Add-the-ethernet-to-the-device-trees.patch | 145 ------------------ .../patches/mageia/dm-raid-aliases.patch | 7 +- ...ntel_th-Fix-a-deadlock-in-modprobing.patch | 95 ------------ ...l_th-pci-Add-Kaby-Lake-PCH-H-support.patch | 32 ---- kernel/kernel/files/patches/mageia/series | 17 +- kernel/kernel/pspec.xml | 17 +- 10 files changed, 122 insertions(+), 373 deletions(-) create mode 100644 kernel/kernel/files/patches/linux/patch-4.8.1.xz create mode 100644 kernel/kernel/files/patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch delete mode 100644 kernel/kernel/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch delete mode 100644 kernel/kernel/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch delete mode 100644 kernel/kernel/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch delete mode 100644 kernel/kernel/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index 177bdf87..663d1a80 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.7.2 Kernel Configuration +# Linux/x86_64 4.8.1 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -39,7 +39,6 @@ CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_HAVE_INTEL_TXT=y CONFIG_X86_64_SMP=y -CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_DEBUG_RODATA=y @@ -283,11 +282,14 @@ CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_GCC_PLUGINS=y +# CONFIG_GCC_PLUGINS is not set CONFIG_HAVE_CC_STACKPROTECTOR=y # CONFIG_CC_STACKPROTECTOR is not set CONFIG_CC_STACKPROTECTOR_NONE=y # CONFIG_CC_STACKPROTECTOR_REGULAR is not set # CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y @@ -534,6 +536,7 @@ CONFIG_MEMORY_FAILURE=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +CONFIG_TRANSPARENT_HUGE_PAGECACHE=y CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y # CONFIG_CMA is not set @@ -546,6 +549,7 @@ CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set # CONFIG_IDLE_PAGE_TRACKING is not set +# CONFIG_ZONE_DEVICE is not set CONFIG_FRAME_VECTOR=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_HAS_PKEYS=y @@ -582,6 +586,8 @@ CONFIG_RELOCATABLE=y CONFIG_RANDOMIZE_BASE=y CONFIG_X86_NEED_RELOCS=y CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_RANDOMIZE_MEMORY=y +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0xa CONFIG_HOTPLUG_CPU=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set @@ -635,6 +641,7 @@ CONFIG_ACPI_VIDEO=m CONFIG_ACPI_FAN=y CONFIG_ACPI_DOCK=y CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_CSTATE=y CONFIG_ACPI_PROCESSOR_IDLE=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_IPMI=m @@ -643,6 +650,7 @@ CONFIG_ACPI_PROCESSOR_AGGREGATOR=m CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y # CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y CONFIG_ACPI_TABLE_UPGRADE=y # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_PCI_SLOT=y @@ -664,8 +672,10 @@ CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y # CONFIG_ACPI_APEI_EINJ is not set # CONFIG_ACPI_APEI_ERST_DEBUG is not set +# CONFIG_DPTF_POWER is not set CONFIG_ACPI_EXTLOG=m # CONFIG_PMIC_OPREGION is not set +# CONFIG_ACPI_CONFIGFS is not set CONFIG_SFI=y # @@ -674,8 +684,7 @@ CONFIG_SFI=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_STAT=m -CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_STAT is not set CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set @@ -871,6 +880,7 @@ CONFIG_TCP_CONG_HTCP=m CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m CONFIG_TCP_CONG_VEGAS=m +# CONFIG_TCP_CONG_NV is not set CONFIG_TCP_CONG_SCALABLE=m CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m @@ -1365,6 +1375,7 @@ CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_BPF=m # CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m @@ -1405,6 +1416,7 @@ CONFIG_OPENVSWITCH_VXLAN=m CONFIG_OPENVSWITCH_GENEVE=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m +# CONFIG_VIRTIO_VSOCKETS is not set CONFIG_NETLINK_DIAG=m CONFIG_MPLS=y CONFIG_NET_MPLS_GSO=m @@ -1413,6 +1425,7 @@ CONFIG_MPLS_IPTUNNEL=m CONFIG_HSR=m # CONFIG_NET_SWITCHDEV is not set # CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_NCSI is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y @@ -1811,6 +1824,8 @@ CONFIG_BLK_DEV_RSXX=m CONFIG_NVME_CORE=m CONFIG_BLK_DEV_NVME=m # CONFIG_BLK_DEV_NVME_SCSI is not set +# CONFIG_NVME_RDMA is not set +# CONFIG_NVME_TARGET is not set # # Misc devices @@ -1830,7 +1845,6 @@ CONFIG_APDS9802ALS=m CONFIG_ISL29003=m CONFIG_ISL29020=m CONFIG_SENSORS_TSL2550=m -# CONFIG_SENSORS_BH1780 is not set CONFIG_SENSORS_BH1770=m CONFIG_SENSORS_APDS990X=m # CONFIG_HMC6352 is not set @@ -1906,8 +1920,7 @@ CONFIG_GENWQE=m CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=1 # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set -# CONFIG_CXL_KERNEL_API is not set -# CONFIG_CXL_EEH is not set +# CONFIG_CXL_AFU_DRIVER_OPS is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -1995,7 +2008,9 @@ CONFIG_SCSI_MPT3SAS_MAX_SGE=128 CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_UFSHCD=m CONFIG_SCSI_UFSHCD_PCI=m +# CONFIG_SCSI_UFS_DWC_TC_PCI is not set CONFIG_SCSI_UFSHCD_PLATFORM=m +# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set CONFIG_SCSI_HPTIOP=m CONFIG_SCSI_BUSLOGIC=m # CONFIG_SCSI_FLASHPOINT is not set @@ -2272,11 +2287,6 @@ CONFIG_ATM_SOLOS=m # # CAIF transport drivers # -CONFIG_VHOST_NET=m -CONFIG_VHOST_SCSI=m -CONFIG_VHOST_RING=m -CONFIG_VHOST=m -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # # Distributed Switch Architecture drivers @@ -2321,8 +2331,6 @@ CONFIG_CNIC=m CONFIG_TIGON3=m CONFIG_BNX2X=m CONFIG_BNX2X_SRIOV=y -CONFIG_BNX2X_VXLAN=y -# CONFIG_BNX2X_GENEVE is not set CONFIG_BNXT=m CONFIG_BNXT_SRIOV=y CONFIG_NET_VENDOR_BROCADE=y @@ -2338,9 +2346,9 @@ CONFIG_CHELSIO_T1_1G=y CONFIG_CHELSIO_T3=m CONFIG_CHELSIO_T4=m CONFIG_CHELSIO_T4_DCB=y -# CONFIG_CHELSIO_T4_UWIRE is not set CONFIG_CHELSIO_T4_FCOE=y CONFIG_CHELSIO_T4VF=m +CONFIG_CHELSIO_LIB=m CONFIG_NET_VENDOR_CISCO=y CONFIG_ENIC=m CONFIG_CX_ECAT=m @@ -2365,7 +2373,6 @@ CONFIG_SUNDANCE=m CONFIG_NET_VENDOR_EMULEX=y CONFIG_BE2NET=m CONFIG_BE2NET_HWMON=y -CONFIG_BE2NET_VXLAN=y CONFIG_NET_VENDOR_EZCHIP=y CONFIG_NET_VENDOR_EXAR=y CONFIG_S2IO=m @@ -2384,14 +2391,11 @@ CONFIG_IGB_DCA=y CONFIG_IGBVF=m CONFIG_IXGB=m CONFIG_IXGBE=m -CONFIG_IXGBE_VXLAN=y CONFIG_IXGBE_HWMON=y CONFIG_IXGBE_DCA=y CONFIG_IXGBE_DCB=y CONFIG_IXGBEVF=m CONFIG_I40E=m -CONFIG_I40E_VXLAN=y -# CONFIG_I40E_GENEVE is not set CONFIG_I40E_DCB=y # CONFIG_I40E_FCOE is not set CONFIG_I40EVF=m @@ -2409,7 +2413,6 @@ CONFIG_SKY2=m CONFIG_NET_VENDOR_MELLANOX=y CONFIG_MLX4_EN=m CONFIG_MLX4_EN_DCB=y -CONFIG_MLX4_EN_VXLAN=y CONFIG_MLX4_CORE=m CONFIG_MLX4_DEBUG=y # CONFIG_MLX5_CORE is not set @@ -2445,15 +2448,12 @@ CONFIG_QLA3XXX=m CONFIG_QLCNIC=m CONFIG_QLCNIC_SRIOV=y CONFIG_QLCNIC_DCB=y -CONFIG_QLCNIC_VXLAN=y CONFIG_QLCNIC_HWMON=y CONFIG_QLGE=m CONFIG_NETXEN_NIC=m CONFIG_QED=m CONFIG_QED_SRIOV=y CONFIG_QEDE=m -# CONFIG_QEDE_VXLAN is not set -# CONFIG_QEDE_GENEVE is not set CONFIG_NET_VENDOR_QUALCOMM=y CONFIG_NET_VENDOR_REALTEK=y CONFIG_ATP=m @@ -2518,6 +2518,7 @@ CONFIG_PCMCIA_XIRC2PS=m # CONFIG_HIPPI is not set # CONFIG_NET_SB1000 is not set CONFIG_PHYLIB=y +CONFIG_SWPHY=y # # MII PHY device drivers @@ -2553,6 +2554,7 @@ CONFIG_MDIO_CAVIUM=m CONFIG_MDIO_OCTEON=m # CONFIG_MDIO_THUNDER is not set # CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_INTEL_XWAY_PHY is not set # CONFIG_PLIP is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -3091,6 +3093,7 @@ CONFIG_TABLET_USB_AIPTEK=m CONFIG_TABLET_USB_GTCO=m CONFIG_TABLET_USB_HANWANG=m CONFIG_TABLET_USB_KBTAB=m +# CONFIG_TABLET_USB_PEGASUS is not set CONFIG_TABLET_SERIAL_WACOM4=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y @@ -3160,6 +3163,9 @@ CONFIG_TOUCHSCREEN_TSC_SERIO=m CONFIG_TOUCHSCREEN_TSC200X_CORE=m CONFIG_TOUCHSCREEN_TSC2004=m CONFIG_TOUCHSCREEN_TSC2007=m +# CONFIG_TOUCHSCREEN_RM_TS is not set +# CONFIG_TOUCHSCREEN_SILEAD is not set +# CONFIG_TOUCHSCREEN_SIS_I2C is not set CONFIG_TOUCHSCREEN_ST1232=m CONFIG_TOUCHSCREEN_SUR40=m CONFIG_TOUCHSCREEN_SX8654=m @@ -3312,7 +3318,6 @@ CONFIG_IPMI_HANDLER=m # CONFIG_IPMI_PANIC_EVENT is not set CONFIG_IPMI_DEVICE_INTERFACE=m CONFIG_IPMI_SI=m -# CONFIG_IPMI_SI_PROBE_DEFAULTS is not set # CONFIG_IPMI_SSIF is not set CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_POWEROFF=m @@ -3341,6 +3346,7 @@ CONFIG_HPET=y # CONFIG_HPET_MMAP is not set CONFIG_HANGCHECK_TIMER=m CONFIG_TCG_TPM=m +CONFIG_TCG_TIS_CORE=m CONFIG_TCG_TIS=m CONFIG_TCG_TIS_I2C_ATMEL=m CONFIG_TCG_TIS_I2C_INFINEON=m @@ -3350,6 +3356,7 @@ CONFIG_TCG_ATMEL=m CONFIG_TCG_INFINEON=m CONFIG_TCG_XEN=m CONFIG_TCG_CRB=m +# CONFIG_TCG_VTPM_PROXY is not set CONFIG_TCG_TIS_ST33ZP24=m CONFIG_TCG_TIS_ST33ZP24_I2C=m CONFIG_TELCLOCK=m @@ -3416,6 +3423,7 @@ CONFIG_I2C_CBUS_GPIO=m CONFIG_I2C_DESIGNWARE_CORE=m CONFIG_I2C_DESIGNWARE_PLATFORM=m # CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_DESIGNWARE_BAYTRAIL is not set CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set @@ -3486,7 +3494,6 @@ CONFIG_PINCTRL_CHERRYVIEW=m CONFIG_PINCTRL_INTEL=m CONFIG_PINCTRL_BROXTON=m CONFIG_PINCTRL_SUNRISEPOINT=m -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_DEVRES=y CONFIG_GPIO_ACPI=y @@ -3535,14 +3542,12 @@ CONFIG_GPIO_UCB1400=m # PCI GPIO expanders # CONFIG_GPIO_AMD8111=m -CONFIG_GPIO_INTEL_MID=y CONFIG_GPIO_ML_IOH=m CONFIG_GPIO_RDC321X=m # # SPI or I2C GPIO expanders # -CONFIG_GPIO_MCP23S08=m # # USB GPIO expanders @@ -3643,6 +3648,7 @@ CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m CONFIG_SENSORS_FSCHMD=m +# CONFIG_SENSORS_FTSTEUTATES is not set CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m CONFIG_SENSORS_G760A=m @@ -3714,6 +3720,7 @@ CONFIG_SENSORS_UCD9200=m CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m +# CONFIG_SENSORS_SHT3x is not set CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m CONFIG_SENSORS_DME1737=m @@ -3733,6 +3740,7 @@ CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_AMC6821=m CONFIG_SENSORS_INA209=m CONFIG_SENSORS_INA2XX=m +# CONFIG_SENSORS_INA3221 is not set # CONFIG_SENSORS_TC74 is not set CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m @@ -3902,6 +3910,7 @@ CONFIG_MFD_INTEL_LPSS_PCI=m # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set # CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77693 is not set # CONFIG_MFD_MAX8907 is not set CONFIG_MFD_MT6397=m @@ -3914,7 +3923,6 @@ CONFIG_MFD_RDC321X=m CONFIG_MFD_RTSX_PCI=m # CONFIG_MFD_RT5033 is not set CONFIG_MFD_RTSX_USB=m -# CONFIG_MFD_RN5T618 is not set CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SM501=m CONFIG_MFD_SM501_GPIO=y @@ -4433,6 +4441,8 @@ CONFIG_DVB_M88DS3103=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_SI2165=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m # # DVB-S (satellite) frontends @@ -4583,7 +4593,6 @@ CONFIG_DRM_TTM=m # # I2C encoder or helper chips # -# CONFIG_DRM_I2C_ADV7511 is not set CONFIG_DRM_I2C_CH7006=m CONFIG_DRM_I2C_SIL164=m CONFIG_DRM_I2C_NXP_TDA998X=m @@ -4604,6 +4613,7 @@ CONFIG_DRM_I810=m CONFIG_DRM_I915=m CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT=y CONFIG_DRM_I915_USERPTR=y +# CONFIG_DRM_I915_GVT is not set CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m CONFIG_DRM_VIA=m @@ -4976,6 +4986,7 @@ CONFIG_HID_ICADE=m CONFIG_HID_TWINHAN=m CONFIG_HID_KENSINGTON=y CONFIG_HID_LCPOWER=m +CONFIG_HID_LED=m CONFIG_HID_LENOVO=m CONFIG_HID_LOGITECH=y CONFIG_HID_LOGITECH_DJ=m @@ -5029,6 +5040,7 @@ CONFIG_ZEROPLUS_FF=y CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m +# CONFIG_HID_ALPS is not set # # USB HID support @@ -5235,7 +5247,6 @@ CONFIG_USB_SEVSEG=m # CONFIG_USB_RIO500 is not set CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -CONFIG_USB_LED=m # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set CONFIG_USB_IDMOUSE=m @@ -5337,6 +5348,7 @@ CONFIG_LEDS_PCA9532=m CONFIG_LEDS_PCA9532_GPIO=y CONFIG_LEDS_GPIO=m CONFIG_LEDS_LP3944=m +# CONFIG_LEDS_LP3952 is not set CONFIG_LEDS_LP55XX_COMMON=m CONFIG_LEDS_LP5521=m CONFIG_LEDS_LP5523=m @@ -5365,6 +5377,7 @@ CONFIG_LEDS_BLINKM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_ONESHOT=y +# CONFIG_LEDS_TRIGGER_DISK is not set # CONFIG_LEDS_TRIGGER_MTD is not set CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_BACKLIGHT=m @@ -5409,6 +5422,7 @@ CONFIG_INFINIBAND_SRPT=m CONFIG_INFINIBAND_ISER=m CONFIG_INFINIBAND_ISERT=m CONFIG_INFINIBAND_RDMAVT=m +# CONFIG_RDMA_RXE is not set CONFIG_INFINIBAND_HFI1=m CONFIG_HFI1_DEBUG_SDMA_ORDER=y CONFIG_HFI1_VERBS_31BIT_PSN=y @@ -5434,7 +5448,9 @@ CONFIG_EDAC_I5000=m CONFIG_EDAC_I5100=m CONFIG_EDAC_I7300=m CONFIG_EDAC_SBRIDGE=m +# CONFIG_EDAC_SKX is not set CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -5658,8 +5674,8 @@ CONFIG_FB_SM750=m # CONFIG_SPEAKUP is not set CONFIG_STAGING_MEDIA=y CONFIG_I2C_BCM2048=m +# CONFIG_MEDIA_CEC is not set # CONFIG_DVB_CXD2099 is not set -# CONFIG_DVB_MN88472 is not set # CONFIG_VIDEO_TW686X_KH is not set CONFIG_LIRC_STAGING=y CONFIG_LIRC_BT829=m @@ -5676,7 +5692,6 @@ CONFIG_LIRC_ZILOG=m # # CONFIG_ASHMEM is not set # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set -CONFIG_SYNC=y # CONFIG_ION is not set CONFIG_LTE_GDM724X=m CONFIG_FIREWIRE_SERIAL=m @@ -5702,6 +5717,7 @@ CONFIG_HDM_USB=m # # Old ISDN4Linux (deprecated) # +# CONFIG_KS7010 is not set CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACER_WMI=m CONFIG_ACERHDF=m @@ -5741,12 +5757,12 @@ CONFIG_EEEPC_WMI=m CONFIG_ACPI_WMI=m CONFIG_MSI_WMI=m CONFIG_TOPSTAR_LAPTOP=m -CONFIG_ACPI_TOSHIBA=m CONFIG_TOSHIBA_BT_RFKILL=m CONFIG_TOSHIBA_HAPS=m CONFIG_TOSHIBA_WMI=m CONFIG_ACPI_CMPC=m # CONFIG_INTEL_HID_EVENT is not set +# CONFIG_INTEL_VBTN is not set CONFIG_INTEL_IPS=m # CONFIG_INTEL_PMC_CORE is not set # CONFIG_IBM_RTL is not set @@ -5783,7 +5799,7 @@ CONFIG_COMMON_CLK_CDCE706=m CONFIG_COMMON_CLK_PWM=m # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_PIC32 is not set -# CONFIG_COMMON_CLK_OXNAS is not set +# CONFIG_SUNXI_CCU is not set # # Hardware Spinlock drivers @@ -5832,6 +5848,10 @@ CONFIG_STE_MODEM_RPROC=m # # SOC (System On Chip) specific Drivers # + +# +# Broadcom SoC drivers +# # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set CONFIG_PM_DEVFREQ=y @@ -5862,6 +5882,7 @@ CONFIG_NTB=m # CONFIG_VME_BUS is not set CONFIG_PWM=y CONFIG_PWM_SYSFS=y +# CONFIG_PWM_CROS_EC is not set CONFIG_PWM_LP3943=m # CONFIG_PWM_LPSS_PCI is not set # CONFIG_PWM_LPSS_PLATFORM is not set @@ -5869,6 +5890,7 @@ CONFIG_PWM_PCA9685=m CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_IPACK_BUS is not set CONFIG_RESET_CONTROLLER=y +# CONFIG_TI_SYSCON_RESET is not set # CONFIG_FMC is not set # @@ -5922,6 +5944,7 @@ CONFIG_FPGA_MGR_ZYNQ_FPGA=m # # Firmware Drivers # +# CONFIG_ARM_SCPI_PROTOCOL is not set CONFIG_EDD=m # CONFIG_EDD_OFF is not set CONFIG_FIRMWARE_MEMMAP=y @@ -5959,6 +5982,7 @@ CONFIG_UEFI_CPER=y # File systems # CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_FS_IOMAP=y CONFIG_EXT2_FS=m CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set @@ -5969,8 +5993,7 @@ CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_ENCRYPTION=m -CONFIG_EXT4_FS_ENCRYPTION=y +# CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -6019,6 +6042,7 @@ CONFIG_F2FS_IO_TRACE=y CONFIG_FS_DAX=y CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y # CONFIG_FS_ENCRYPTION is not set @@ -6138,6 +6162,9 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y # CONFIG_ROMFS_BACKED_BY_BOTH is not set CONFIG_ROMFS_ON_BLOCK=y CONFIG_PSTORE=y +CONFIG_PSTORE_ZLIB_COMPRESS=y +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_FTRACE=y @@ -6195,6 +6222,7 @@ CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y # CONFIG_NFSD_BLOCKLAYOUT is not set # CONFIG_NFSD_SCSILAYOUT is not set +# CONFIG_NFSD_FLEXFILELAYOUT is not set # CONFIG_NFSD_V4_SECURITY_LABEL is not set CONFIG_GRACE_PERIOD=m CONFIG_LOCKD=m @@ -6359,7 +6387,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 -CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -6480,6 +6507,9 @@ CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y CONFIG_INTEL_TXT=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY is not set # CONFIG_SECURITY_SELINUX is not set # CONFIG_SECURITY_SMACK is not set CONFIG_SECURITY_TOMOYO=y @@ -6491,6 +6521,7 @@ CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" CONFIG_SECURITY_APPARMOR=y CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 CONFIG_SECURITY_APPARMOR_HASH=y +CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y # CONFIG_SECURITY_LOADPIN is not set # CONFIG_SECURITY_YAMA is not set CONFIG_INTEGRITY=y @@ -6526,7 +6557,11 @@ CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=m -# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_RSA=m +CONFIG_CRYPTO_DH=m +# CONFIG_CRYPTO_ECDH is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=m @@ -6596,8 +6631,11 @@ CONFIG_CRYPTO_SHA1_SSSE3=m CONFIG_CRYPTO_SHA256_SSSE3=m CONFIG_CRYPTO_SHA512_SSSE3=m # CONFIG_CRYPTO_SHA1_MB is not set +# CONFIG_CRYPTO_SHA256_MB is not set +# CONFIG_CRYPTO_SHA512_MB is not set CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=m +# CONFIG_CRYPTO_SHA3 is not set CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m @@ -6691,7 +6729,6 @@ CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_IRQFD=y CONFIG_HAVE_KVM_IRQ_ROUTING=y CONFIG_HAVE_KVM_EVENTFD=y -CONFIG_KVM_APIC_ARCHITECTURE=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y CONFIG_HAVE_KVM_MSI=y @@ -6706,6 +6743,11 @@ CONFIG_KVM_INTEL=m CONFIG_KVM_AMD=m CONFIG_KVM_MMU_AUDIT=y CONFIG_KVM_DEVICE_ASSIGNMENT=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +# CONFIG_VHOST_VSOCK is not set +CONFIG_VHOST=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set CONFIG_BINARY_PRINTF=y # @@ -6724,7 +6766,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IO=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -CONFIG_CRC_CCITT=m +CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=m @@ -6784,9 +6826,11 @@ CONFIG_GLOB=y CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y CONFIG_LRU_CACHE=m +CONFIG_CLZ_TAB=y CONFIG_CORDIC=m # CONFIG_DDR is not set CONFIG_IRQ_POLL=y +CONFIG_MPILIB=m CONFIG_OID_REGISTRY=m CONFIG_UCS2_STRING=y CONFIG_FONT_SUPPORT=y @@ -6802,7 +6846,7 @@ CONFIG_ARCH_HAS_MMIO_FLUSH=y # # Unofficial 3rd party kernel additions # +CONFIG_NDISWRAPPER=m CONFIG_RTL8723BS=m CONFIG_WLAN_SDIO=y -CONFIG_NDISWRAPPER=m CONFIG_VIAHSS=m diff --git a/kernel/kernel/files/patches/linux/patch-4.8.1.xz b/kernel/kernel/files/patches/linux/patch-4.8.1.xz new file mode 100644 index 0000000000000000000000000000000000000000..9c2caaba14122a4bc82e28a7a00bae4f1cc7b211 GIT binary patch literal 3136 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 + +--- linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c.orig ++++ linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c +@@ -1413,7 +1413,10 @@ void rtw_cfg80211_indicate_scan_done(str + } + else + { +- cfg80211_scan_done(pwdev_priv->scan_request, aborted); ++ struct cfg80211_scan_info info = { ++ .aborted = aborted, ++ }; ++ cfg80211_scan_done(pwdev_priv->scan_request, &info); + } + + pwdev_priv->scan_request = NULL; diff --git a/kernel/kernel/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch b/kernel/kernel/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch deleted file mode 100644 index 27ba34e7..00000000 --- a/kernel/kernel/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 56e74338a535cbcc2f2da08b1ea1a92920194364 Mon Sep 17 00:00:00 2001 -From: Alexandra Yates -Date: Tue, 3 Nov 2015 14:14:18 -0800 -Subject: [PATCH] ahci: add new Intel device IDs - -Adding Intel codename Lewisburg platform device IDs for SATA. - -Signed-off-by: Alexandra Yates -Signed-off-by: Tejun Heo ---- - drivers/ata/ahci.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index ff343c4..ff02bb4 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -314,6 +314,16 @@ static const struct pci_device_id ahci_pci_tbl[] = { - { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ -+ { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ -+ { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ -+ { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ - { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ - { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ - { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ --- -2.3.10 - diff --git a/kernel/kernel/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch b/kernel/kernel/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch deleted file mode 100644 index 0c141707..00000000 --- a/kernel/kernel/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch +++ /dev/null @@ -1,145 +0,0 @@ -From f7c8d3a509e51f4a555371ded4957b225f1818ad Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Mon, 2 May 2016 09:06:51 +0200 -Subject: [PATCH] ARM: bcm2835: dt: Add the ethernet to the device trees - -The hub and the ethernet in its port 1 are hardwired on the board. - -Compared to the adapters that can be plugged into the USB ports, this -one has no serial EEPROM to store its MAC. Nevertheless, the Raspberry Pi -has the MAC address for this adapter in its ROM, accessible from its -firmware. - -U-Boot can read out the address and set the local-mac-address property of the -node with "ethernet" alias. Let's add the node so that U-Boot can do its -business. - -Model B rev2 and Model B+ entries were verified by me, the hierarchy and -pid/vid pair for the Version 2 was provided by Peter Chen. Original -Model B is a blind shot, though very likely correct. - -Signed-off-by: Lubomir Rintel -Acked-by: Stephen Warren ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 1 + - arch/arm/boot/dts/bcm2835-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 1 + - arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm283x.dtsi | 2 ++ - 7 files changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi - create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index ef54050..c3e01ce 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9514.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -index 86f1f2f..364086a 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9512.dtsi" - - / { - compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index 4859e9d..4420b09 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9512.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -index ff94666..b975f29 100644 ---- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2836.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9514.dtsi" - - / { - compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi -new file mode 100644 -index 0000000..12c981e ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi -@@ -0,0 +1,19 @@ -+/ { -+ aliases { -+ ethernet = ðernet; -+ }; -+}; -+ -+&usb { -+ usb1@1 { -+ compatible = "usb424,9512"; -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet: usbether@1 { -+ compatible = "usb424,ec00"; -+ reg = <1>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi -new file mode 100644 -index 0000000..3f0a56e ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi -@@ -0,0 +1,19 @@ -+/ { -+ aliases { -+ ethernet = ðernet; -+ }; -+}; -+ -+&usb { -+ usb1@1 { -+ compatible = "usb424,9514"; -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet: usbether@1 { -+ compatible = "usb424,ec00"; -+ reg = <1>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi -index 8aaf193..04504b7 100644 ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -287,6 +287,8 @@ - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - v3d: v3d@7ec00000 { diff --git a/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch b/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch index febdb720..4bb20cf1 100644 --- a/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch +++ b/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch @@ -8,13 +8,14 @@ Signed-off-by: Thomas Backlund drivers/md/dm-raid.c | 2 ++ 1 file changed, 2 insertions(+) ---- linux-2.6.38.2-mga2/drivers/md/dm-raid.c.orig 2011-03-15 03:20:32.000000000 +0200 -+++ linux-2.6.38.2-mga2/drivers/md/dm-raid.c 2011-04-02 21:52:21.331302590 +0300 -@@ -693,5 +693,7 @@ MODULE_DESCRIPTION(DM_NAME " raid4/5/6 t +--- linux/drivers/md/dm-raid.c.orig ++++ linux/drivers/md/dm-raid.c +@@ -3689,6 +3689,8 @@ MODULE_ALIAS("dm-raid10"); MODULE_ALIAS("dm-raid4"); MODULE_ALIAS("dm-raid5"); MODULE_ALIAS("dm-raid6"); +MODULE_ALIAS("dm-raid45"); +MODULE_ALIAS("dm-raid4-5"); MODULE_AUTHOR("Neil Brown "); + MODULE_AUTHOR("Heinz Mauelshagen "); MODULE_LICENSE("GPL"); diff --git a/kernel/kernel/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch b/kernel/kernel/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch deleted file mode 100644 index 45b63cdd..00000000 --- a/kernel/kernel/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch +++ /dev/null @@ -1,95 +0,0 @@ -From a36aa80f3cb2540fb1dbad6240852de4365a2e82 Mon Sep 17 00:00:00 2001 -From: Alexander Shishkin -Date: Thu, 30 Jun 2016 11:51:44 +0300 -Subject: [PATCH] intel_th: Fix a deadlock in modprobing - -Driver initialization tries to request a hub (GTH) driver module from -its probe callback, resulting in a deadlock. - -This patch solves the problem by adding a deferred work for requesting -the hub module. - -Signed-off-by: Alexander Shishkin -Cc: # 4.4.x- ---- - drivers/hwtracing/intel_th/core.c | 35 ++++++++++++++++++++++++++++++++++- - drivers/hwtracing/intel_th/intel_th.h | 3 +++ - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c -index 1be543e..0b112ae 100644 ---- a/drivers/hwtracing/intel_th/core.c -+++ b/drivers/hwtracing/intel_th/core.c -@@ -465,6 +465,38 @@ static struct intel_th_subdevice { - }, - }; - -+#ifdef CONFIG_MODULES -+static void __intel_th_request_hub_module(struct work_struct *work) -+{ -+ struct intel_th *th = container_of(work, struct intel_th, -+ request_module_work); -+ -+ request_module("intel_th_%s", th->hub->name); -+} -+ -+static int intel_th_request_hub_module(struct intel_th *th) -+{ -+ INIT_WORK(&th->request_module_work, __intel_th_request_hub_module); -+ schedule_work(&th->request_module_work); -+ -+ return 0; -+} -+ -+static void intel_th_request_hub_module_flush(struct intel_th *th) -+{ -+ flush_work(&th->request_module_work); -+} -+#else -+static inline int intel_th_request_hub_module(struct intel_th *th) -+{ -+ return -EINVAL; -+} -+ -+static inline void intel_th_request_hub_module_flush(struct intel_th *th) -+{ -+} -+#endif /* CONFIG_MODULES */ -+ - static int intel_th_populate(struct intel_th *th, struct resource *devres, - unsigned int ndevres, int irq) - { -@@ -535,7 +567,7 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres, - /* need switch driver to be loaded to enumerate the rest */ - if (subdev->type == INTEL_TH_SWITCH && !req) { - th->hub = thdev; -- err = request_module("intel_th_%s", subdev->name); -+ err = intel_th_request_hub_module(th); - if (!err) - req++; - } -@@ -652,6 +684,7 @@ void intel_th_free(struct intel_th *th) - { - int i; - -+ intel_th_request_hub_module_flush(th); - for (i = 0; i < TH_SUBDEVICE_MAX; i++) - if (th->thdev[i] != th->hub) - intel_th_device_remove(th->thdev[i]); -diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h -index 0df22e3..0482848 100644 ---- a/drivers/hwtracing/intel_th/intel_th.h -+++ b/drivers/hwtracing/intel_th/intel_th.h -@@ -205,6 +205,9 @@ struct intel_th { - - int id; - int major; -+#ifdef CONFIG_MODULES -+ struct work_struct request_module_work; -+#endif /* CONFIG_MODULES */ - #ifdef CONFIG_INTEL_TH_DEBUG - struct dentry *dbg; - #endif --- -2.9.2 - diff --git a/kernel/kernel/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch b/kernel/kernel/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch deleted file mode 100644 index f6d4f341..00000000 --- a/kernel/kernel/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7a1a47ce35821b40f5b2ce46379ba14393bc3873 Mon Sep 17 00:00:00 2001 -From: Alexander Shishkin -Date: Tue, 28 Jun 2016 18:55:23 +0300 -Subject: [PATCH] intel_th: pci: Add Kaby Lake PCH-H support - -This adds Intel(R) Trace Hub PCI ID for Kaby Lake PCH-H. - -Signed-off-by: Alexander Shishkin -Cc: ---- - drivers/hwtracing/intel_th/pci.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c -index 5e25c7e..0bba384 100644 ---- a/drivers/hwtracing/intel_th/pci.c -+++ b/drivers/hwtracing/intel_th/pci.c -@@ -80,6 +80,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), - .driver_data = (kernel_ulong_t)0, - }, -+ { -+ /* Kaby Lake PCH-H */ -+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), -+ .driver_data = (kernel_ulong_t)0, -+ }, - { 0 }, - }; - --- -2.9.2 - diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 6452397c..2f8c8bf4 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -119,8 +119,12 @@ ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch # Nice SSD speedup block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch -# ahci ids -ahci-add-new-Intel-device-IDs.patch +# Include new BFQ I/O scheduler +# (See http://algo.ing.unimo.it/people/paolo/disk_sched) +# DISABLED: 0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch +# DISABLED: 0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch +# DISABLED: 0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch +# DISABLED: 0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch ### ### Char @@ -232,10 +236,6 @@ platform-x86-add-shuttle-wmi-driver.patch platform-x86-shuttle-wmi-drop-devinit-exit.patch platform-x86-shuttle-wmi-4.2-buildfix.patch -# -intel_th-Fix-a-deadlock-in-modprobing.patch -intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch - ### ### RTC ### @@ -331,6 +331,7 @@ video-mageia-logo.patch # add rtl8723bs support (mga#15874) 3rd-rtl8723bs.patch 3rd-rtl8723bs-4.7-buildfix.patch +3rd-rtl8723bs-4.8-buildfix.patch ### ### Security @@ -348,10 +349,6 @@ video-mageia-logo.patch ### ARM ### -# RPi2 support -# Read MAC address from DT -arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch - ### ### IA64 ### diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 694e8c67..60385434 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -12,7 +12,7 @@ kernel The Linux kernel (the core of the Linux operating system) for Pisi Linux kernel contains the Linux kernel, the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc. - https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.7.tar.gz + https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.tar.gz configs/kernel-i686-config configs/kernel-x86_64-config @@ -28,8 +28,8 @@ - patches/linux/patch-4.7.2.xz - + patches/linux/patch-4.8.1.xz + patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch @@ -37,7 +37,7 @@ patches/mageia/x86-boot-video-80x25-if-break.patch patches/mageia/x86-default_poweroff_up_machines.patch patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch - patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch + patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch @@ -96,8 +96,6 @@ patches/mageia/platform-x86-add-shuttle-wmi-driver.patch patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch - patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch - patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch patches/mageia/include-kbuild-export-pci_ids.patch patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch patches/mageia/usb-storage-unusual_devs-add-id.patch @@ -130,8 +128,7 @@ patches/mageia/3rd-viahss-3.0-buildfix.patch patches/mageia/3rd-rtl8723bs.patch patches/mageia/3rd-rtl8723bs-4.7-buildfix.patch - patches/mageia/ahci-add-new-Intel-device-IDs.patch - patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch + patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch @@ -188,8 +185,8 @@ - 2016-08-24 - 4.7.2 + 2016-10-14 + 4.8.1 Version Bump. security From 887f25965b0cc5558ce49b6baaa8fba0e83a81a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Fri, 14 Oct 2016 22:20:55 +0300 Subject: [PATCH 02/11] add new version. opps --- kernel/kernel/pspec.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 60385434..adecba86 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -184,7 +184,7 @@ - + 2016-10-14 4.8.1 Version Bump. @@ -195,6 +195,17 @@ Ertuğrul Erata ertugrulerata@gmail.com + + 2016-08-24 + 4.7.2 + Version Bump. + security + + systemRestart + + Ertuğrul Erata + ertugrulerata@gmail.com + 2016-08-06 4.7.0 From 19402286a490795ff923c0347b4da22989c65e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Tue, 18 Oct 2016 22:46:08 +0300 Subject: [PATCH 03/11] 4.8.2 --- .../kernel/files/patches/linux/patch-4.8.2.xz | Bin 0 -> 18772 bytes ...api-linux-atm_zatm.h-include-linux-t.patch | 37 ++++++++++++++++++ kernel/kernel/files/patches/mageia/series | 5 +++ ...st-Makefile-remove-powerpc-reference.patch | 10 +++++ kernel/kernel/pspec.xml | 10 +++-- 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 kernel/kernel/files/patches/linux/patch-4.8.2.xz create mode 100644 kernel/kernel/files/patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch create mode 100644 kernel/kernel/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch diff --git a/kernel/kernel/files/patches/linux/patch-4.8.2.xz b/kernel/kernel/files/patches/linux/patch-4.8.2.xz new file mode 100644 index 0000000000000000000000000000000000000000..b2d91ab16861273f4ecbd1e5d4847d8b41a43dab GIT binary patch literal 18772 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 +Date: Sun, 16 Oct 2016 20:09:27 +0300 +Subject: [PATCH] Revert "include/uapi/linux/atm_zatm.h: include linux/time.h" + +This reverts commit cf00713a655d3019be7faa184402f16c43a0fed3. + +It causes linux-atm build breakage between glibc headers and kernel headers... + +Fixws are in progress upstream as of: +https://patchwork.kernel.org/patch/9294305/ + +But it's not accepted yet so it might still change, and since its uapi +we dont want to expose changes that might never land upstream. + +Reported by: Pascal Terjam +Signed-off-by: Thomas Backlund + +--- + include/uapi/linux/atm_zatm.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/include/uapi/linux/atm_zatm.h b/include/uapi/linux/atm_zatm.h +index 5cd4d4d..9c9c6ad 100644 +--- a/include/uapi/linux/atm_zatm.h ++++ b/include/uapi/linux/atm_zatm.h +@@ -14,7 +14,6 @@ + + #include + #include +-#include + + #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) + /* get pool statistics */ +-- +2.10.1 + diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 2f8c8bf4..1eff6fc4 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -357,6 +357,11 @@ video-mageia-logo.patch ### Tools ### +# wipe powerpc refrence so we can nuke dangling symlinks (mga#17676) +tools-testing-selftest-Makefile-remove-powerpc-reference.patch + ### ### UAPI ### +# breaks linux-arm build +Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch diff --git a/kernel/kernel/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch b/kernel/kernel/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch new file mode 100644 index 00000000..677e97df --- /dev/null +++ b/kernel/kernel/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch @@ -0,0 +1,10 @@ +--- linux/tools/testing/selftests/Makefile.orig ++++ linux/tools/testing/selftests/Makefile +@@ -15,7 +15,6 @@ TARGETS += memory-hotplug + TARGETS += mount + TARGETS += mqueue + TARGETS += net +-TARGETS += powerpc + TARGETS += pstore + TARGETS += ptrace + TARGETS += seccomp diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index adecba86..c1c1040a 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,8 +28,8 @@ - patches/linux/patch-4.8.1.xz - + patches/linux/patch-4.8.2.xz + patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch @@ -129,6 +129,8 @@ patches/mageia/3rd-rtl8723bs.patch patches/mageia/3rd-rtl8723bs-4.7-buildfix.patch patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch + patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch + patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch @@ -185,8 +187,8 @@ - 2016-10-14 - 4.8.1 + 2016-10-18 + 4.8.2 Version Bump. security From cee7fa722785767430c4b3376d8f7b0c072e7683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Wed, 19 Oct 2016 19:54:48 +0300 Subject: [PATCH 04/11] new config --- .../kernel/files/configs/kernel-x86_64-config | 96 +++++++++++-------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index 663d1a80..32e72208 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.8.1 Kernel Configuration +# Linux/x86_64 4.8.2 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -549,7 +549,7 @@ CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set # CONFIG_IDLE_PAGE_TRACKING is not set -# CONFIG_ZONE_DEVICE is not set +CONFIG_ZONE_DEVICE=y CONFIG_FRAME_VECTOR=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_HAS_PKEYS=y @@ -624,7 +624,9 @@ CONFIG_PM_SLEEP_DEBUG=y CONFIG_PM_TRACE=y CONFIG_PM_TRACE_RTC=y CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y # CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y @@ -672,10 +674,10 @@ CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y # CONFIG_ACPI_APEI_EINJ is not set # CONFIG_ACPI_APEI_ERST_DEBUG is not set -# CONFIG_DPTF_POWER is not set +CONFIG_DPTF_POWER=m CONFIG_ACPI_EXTLOG=m # CONFIG_PMIC_OPREGION is not set -# CONFIG_ACPI_CONFIGFS is not set +CONFIG_ACPI_CONFIGFS=m CONFIG_SFI=y # @@ -684,7 +686,8 @@ CONFIG_SFI=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_STAT is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set @@ -880,7 +883,7 @@ CONFIG_TCP_CONG_HTCP=m CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m CONFIG_TCP_CONG_VEGAS=m -# CONFIG_TCP_CONG_NV is not set +CONFIG_TCP_CONG_NV=m CONFIG_TCP_CONG_SCALABLE=m CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m @@ -1375,7 +1378,7 @@ CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_BPF=m # CONFIG_NET_CLS_FLOWER is not set -# CONFIG_NET_CLS_MATCHALL is not set +CONFIG_NET_CLS_MATCHALL=m CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m @@ -1416,7 +1419,8 @@ CONFIG_OPENVSWITCH_VXLAN=m CONFIG_OPENVSWITCH_GENEVE=m CONFIG_VSOCKETS=m CONFIG_VMWARE_VMCI_VSOCKETS=m -# CONFIG_VIRTIO_VSOCKETS is not set +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m CONFIG_NETLINK_DIAG=m CONFIG_MPLS=y CONFIG_NET_MPLS_GSO=m @@ -1824,8 +1828,11 @@ CONFIG_BLK_DEV_RSXX=m CONFIG_NVME_CORE=m CONFIG_BLK_DEV_NVME=m # CONFIG_BLK_DEV_NVME_SCSI is not set -# CONFIG_NVME_RDMA is not set -# CONFIG_NVME_TARGET is not set +CONFIG_NVME_FABRICS=m +CONFIG_NVME_RDMA=m +CONFIG_NVME_TARGET=m +CONFIG_NVME_TARGET_LOOP=m +CONFIG_NVME_TARGET_RDMA=m # # Misc devices @@ -2008,9 +2015,9 @@ CONFIG_SCSI_MPT3SAS_MAX_SGE=128 CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_UFSHCD=m CONFIG_SCSI_UFSHCD_PCI=m -# CONFIG_SCSI_UFS_DWC_TC_PCI is not set +CONFIG_SCSI_UFS_DWC_TC_PCI=m CONFIG_SCSI_UFSHCD_PLATFORM=m -# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set +CONFIG_SCSI_UFS_DWC_TC_PLATFORM=m CONFIG_SCSI_HPTIOP=m CONFIG_SCSI_BUSLOGIC=m # CONFIG_SCSI_FLASHPOINT is not set @@ -2554,7 +2561,7 @@ CONFIG_MDIO_CAVIUM=m CONFIG_MDIO_OCTEON=m # CONFIG_MDIO_THUNDER is not set # CONFIG_MDIO_BCM_UNIMAC is not set -# CONFIG_INTEL_XWAY_PHY is not set +CONFIG_INTEL_XWAY_PHY=m # CONFIG_PLIP is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -3093,7 +3100,7 @@ CONFIG_TABLET_USB_AIPTEK=m CONFIG_TABLET_USB_GTCO=m CONFIG_TABLET_USB_HANWANG=m CONFIG_TABLET_USB_KBTAB=m -# CONFIG_TABLET_USB_PEGASUS is not set +CONFIG_TABLET_USB_PEGASUS=m CONFIG_TABLET_SERIAL_WACOM4=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y @@ -3163,9 +3170,9 @@ CONFIG_TOUCHSCREEN_TSC_SERIO=m CONFIG_TOUCHSCREEN_TSC200X_CORE=m CONFIG_TOUCHSCREEN_TSC2004=m CONFIG_TOUCHSCREEN_TSC2007=m -# CONFIG_TOUCHSCREEN_RM_TS is not set -# CONFIG_TOUCHSCREEN_SILEAD is not set -# CONFIG_TOUCHSCREEN_SIS_I2C is not set +CONFIG_TOUCHSCREEN_RM_TS=m +CONFIG_TOUCHSCREEN_SILEAD=m +CONFIG_TOUCHSCREEN_SIS_I2C=m CONFIG_TOUCHSCREEN_ST1232=m CONFIG_TOUCHSCREEN_SUR40=m CONFIG_TOUCHSCREEN_SX8654=m @@ -3356,7 +3363,7 @@ CONFIG_TCG_ATMEL=m CONFIG_TCG_INFINEON=m CONFIG_TCG_XEN=m CONFIG_TCG_CRB=m -# CONFIG_TCG_VTPM_PROXY is not set +CONFIG_TCG_VTPM_PROXY=m CONFIG_TCG_TIS_ST33ZP24=m CONFIG_TCG_TIS_ST33ZP24_I2C=m CONFIG_TELCLOCK=m @@ -3600,6 +3607,7 @@ CONFIG_BATTERY_BQ27XXX_I2C=m # CONFIG_CHARGER_MAX8903 is not set # CONFIG_CHARGER_LP8727 is not set CONFIG_CHARGER_GPIO=m +CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_BQ2415X=m CONFIG_CHARGER_BQ24190=m # CONFIG_CHARGER_BQ24257 is not set @@ -3638,6 +3646,7 @@ CONFIG_SENSORS_K8TEMP=m CONFIG_SENSORS_K10TEMP=m CONFIG_SENSORS_FAM15H_POWER=m CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ARM_SCPI=m CONFIG_SENSORS_ASB100=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS620=m @@ -3648,7 +3657,7 @@ CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m CONFIG_SENSORS_FSCHMD=m -# CONFIG_SENSORS_FTSTEUTATES is not set +CONFIG_SENSORS_FTSTEUTATES=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m CONFIG_SENSORS_G760A=m @@ -3720,7 +3729,7 @@ CONFIG_SENSORS_UCD9200=m CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m -# CONFIG_SENSORS_SHT3x is not set +CONFIG_SENSORS_SHT3x=m CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m CONFIG_SENSORS_DME1737=m @@ -3740,7 +3749,7 @@ CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_AMC6821=m CONFIG_SENSORS_INA209=m CONFIG_SENSORS_INA2XX=m -# CONFIG_SENSORS_INA3221 is not set +CONFIG_SENSORS_INA3221=m # CONFIG_SENSORS_TC74 is not set CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m @@ -3910,7 +3919,7 @@ CONFIG_MFD_INTEL_LPSS_PCI=m # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set # CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_MAX14577 is not set +CONFIG_MFD_MAX14577=m # CONFIG_MFD_MAX77693 is not set # CONFIG_MFD_MAX8907 is not set CONFIG_MFD_MT6397=m @@ -4613,7 +4622,7 @@ CONFIG_DRM_I810=m CONFIG_DRM_I915=m CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT=y CONFIG_DRM_I915_USERPTR=y -# CONFIG_DRM_I915_GVT is not set +CONFIG_DRM_I915_GVT=y CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m CONFIG_DRM_VIA=m @@ -5040,7 +5049,7 @@ CONFIG_ZEROPLUS_FF=y CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m -# CONFIG_HID_ALPS is not set +CONFIG_HID_ALPS=m # # USB HID support @@ -5348,7 +5357,7 @@ CONFIG_LEDS_PCA9532=m CONFIG_LEDS_PCA9532_GPIO=y CONFIG_LEDS_GPIO=m CONFIG_LEDS_LP3944=m -# CONFIG_LEDS_LP3952 is not set +CONFIG_LEDS_LP3952=m CONFIG_LEDS_LP55XX_COMMON=m CONFIG_LEDS_LP5521=m CONFIG_LEDS_LP5523=m @@ -5422,7 +5431,7 @@ CONFIG_INFINIBAND_SRPT=m CONFIG_INFINIBAND_ISER=m CONFIG_INFINIBAND_ISERT=m CONFIG_INFINIBAND_RDMAVT=m -# CONFIG_RDMA_RXE is not set +CONFIG_RDMA_RXE=m CONFIG_INFINIBAND_HFI1=m CONFIG_HFI1_DEBUG_SDMA_ORDER=y CONFIG_HFI1_VERBS_31BIT_PSN=y @@ -5448,7 +5457,7 @@ CONFIG_EDAC_I5000=m CONFIG_EDAC_I5100=m CONFIG_EDAC_I7300=m CONFIG_EDAC_SBRIDGE=m -# CONFIG_EDAC_SKX is not set +CONFIG_EDAC_SKX=m CONFIG_RTC_LIB=y CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y @@ -5717,7 +5726,7 @@ CONFIG_HDM_USB=m # # Old ISDN4Linux (deprecated) # -# CONFIG_KS7010 is not set +CONFIG_KS7010=m CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACER_WMI=m CONFIG_ACERHDF=m @@ -5762,7 +5771,7 @@ CONFIG_TOSHIBA_HAPS=m CONFIG_TOSHIBA_WMI=m CONFIG_ACPI_CMPC=m # CONFIG_INTEL_HID_EVENT is not set -# CONFIG_INTEL_VBTN is not set +CONFIG_INTEL_VBTN=m CONFIG_INTEL_IPS=m # CONFIG_INTEL_PMC_CORE is not set # CONFIG_IBM_RTL is not set @@ -5792,6 +5801,7 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # +CONFIG_COMMON_CLK_SCPI=m CONFIG_COMMON_CLK_SI5351=m CONFIG_COMMON_CLK_CDCE706=m # CONFIG_COMMON_CLK_CS2000_CP is not set @@ -5882,7 +5892,7 @@ CONFIG_NTB=m # CONFIG_VME_BUS is not set CONFIG_PWM=y CONFIG_PWM_SYSFS=y -# CONFIG_PWM_CROS_EC is not set +CONFIG_PWM_CROS_EC=m CONFIG_PWM_LP3943=m # CONFIG_PWM_LPSS_PCI is not set # CONFIG_PWM_LPSS_PLATFORM is not set @@ -5890,7 +5900,7 @@ CONFIG_PWM_PCA9685=m CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_IPACK_BUS is not set CONFIG_RESET_CONTROLLER=y -# CONFIG_TI_SYSCON_RESET is not set +CONFIG_TI_SYSCON_RESET=m # CONFIG_FMC is not set # @@ -5944,7 +5954,8 @@ CONFIG_FPGA_MGR_ZYNQ_FPGA=m # # Firmware Drivers # -# CONFIG_ARM_SCPI_PROTOCOL is not set +CONFIG_ARM_SCPI_PROTOCOL=m +CONFIG_ARM_SCPI_POWER_DOMAIN=m CONFIG_EDD=m # CONFIG_EDD_OFF is not set CONFIG_FIRMWARE_MEMMAP=y @@ -5993,7 +6004,8 @@ CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_ENCRYPTION is not set +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -6045,7 +6057,7 @@ CONFIG_EXPORTFS=y # CONFIG_EXPORTFS_BLOCK_OPS is not set CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y -# CONFIG_FS_ENCRYPTION is not set +CONFIG_FS_ENCRYPTION=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y @@ -6498,7 +6510,7 @@ CONFIG_KEYS=y # CONFIG_PERSISTENT_KEYRINGS is not set # CONFIG_BIG_KEYS is not set CONFIG_TRUSTED_KEYS=m -CONFIG_ENCRYPTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=y # CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y @@ -6561,7 +6573,7 @@ CONFIG_CRYPTO_KPP2=y CONFIG_CRYPTO_KPP=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m -# CONFIG_CRYPTO_ECDH is not set +CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=m @@ -6572,7 +6584,7 @@ CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=y -# CONFIG_CRYPTO_MCRYPTD is not set +CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_ABLK_HELPER=m @@ -6592,7 +6604,7 @@ CONFIG_CRYPTO_ECHAINIV=m # CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=m @@ -6631,11 +6643,11 @@ CONFIG_CRYPTO_SHA1_SSSE3=m CONFIG_CRYPTO_SHA256_SSSE3=m CONFIG_CRYPTO_SHA512_SSSE3=m # CONFIG_CRYPTO_SHA1_MB is not set -# CONFIG_CRYPTO_SHA256_MB is not set -# CONFIG_CRYPTO_SHA512_MB is not set +CONFIG_CRYPTO_SHA256_MB=m +CONFIG_CRYPTO_SHA512_MB=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_SHA3 is not set +CONFIG_CRYPTO_SHA3=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m @@ -6745,7 +6757,7 @@ CONFIG_KVM_MMU_AUDIT=y CONFIG_KVM_DEVICE_ASSIGNMENT=y CONFIG_VHOST_NET=m CONFIG_VHOST_SCSI=m -# CONFIG_VHOST_VSOCK is not set +CONFIG_VHOST_VSOCK=m CONFIG_VHOST=m # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set CONFIG_BINARY_PRINTF=y From 37c53b3f40d7fdf2dbbf4b9062543a655449fb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Fri, 28 Oct 2016 23:09:40 +0300 Subject: [PATCH 05/11] kernel-4.8.4 work 1 --- .../kernel/files/patches/linux/patch-4.8.4.xz | Bin 0 -> 39264 bytes ...-partitioning-for-multi-screen-cases.patch | 35 + ...ir-Fix-incorrect-task-group-load_avg.patch | 73 + .../files/patches/mageia/linux-BFQ-v8r4.patch | 9004 +++++++++++++++++ .../net-add-recursion-limit-to-GRO.patch | 213 + ...ession-caused-by-commit-d86e64768859.patch | 426 + .../files/patches/mageia/nvmepatch1-V4.patch | 111 + .../files/patches/mageia/nvmepatch2-V4.patch | 107 + .../files/patches/mageia/nvmepatch3-V4.patch | 264 + ...d_mode_in_SAGV_check_on_a7fac751ddba.patch | 110 + 10 files changed, 10343 insertions(+) create mode 100644 kernel/kernel/files/patches/linux/patch-4.8.4.xz create mode 100644 kernel/kernel/files/patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch create mode 100644 kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch create mode 100644 kernel/kernel/files/patches/mageia/linux-BFQ-v8r4.patch create mode 100644 kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch create mode 100644 kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch create mode 100644 kernel/kernel/files/patches/mageia/nvmepatch1-V4.patch create mode 100644 kernel/kernel/files/patches/mageia/nvmepatch2-V4.patch create mode 100644 kernel/kernel/files/patches/mageia/nvmepatch3-V4.patch create mode 100644 kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch diff --git a/kernel/kernel/files/patches/linux/patch-4.8.4.xz b/kernel/kernel/files/patches/linux/patch-4.8.4.xz new file mode 100644 index 0000000000000000000000000000000000000000..6d7f4fa56a567e6f527265dc03a5d2f2fef432c5 GIT binary patch literal 39264 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[pipe], 0, sizeof(ddb->plane[pipe])); ++ memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); ++ + if (WARN_ON(!state)) + return 0; + + if (!cstate->base.active) { + ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0; +- memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); +- memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); + return 0; + } + +@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state) + intel_state->wm_results.dirty_pipes = ~0; + } + ++ /* ++ * We're not recomputing for the pipes not included in the commit, so ++ * make sure we start with the current state. ++ */ ++ memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); ++ + for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { + struct intel_crtc_state *cstate; + diff --git a/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch b/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch new file mode 100644 index 00000000..3c7c7279 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch @@ -0,0 +1,73 @@ +From b5a9b340789b2b24c6896bcf7a065c31a4db671c Mon Sep 17 00:00:00 2001 +From: Vincent Guittot +Date: Wed, 19 Oct 2016 14:45:23 +0200 +Subject: [PATCH] sched/fair: Fix incorrect task group ->load_avg + +A scheduler performance regression has been reported by Joseph Salisbury, +which he bisected back to: + + 3d30544f0212 ("sched/fair: Apply more PELT fixes) + +The regression triggers when several levels of task groups are involved +(read: SystemD) and cpu_possible_mask != cpu_present_mask. + +The root cause is that group entity's load (tg_child->se[i]->avg.load_avg) +is initialized to scale_load_down(se->load.weight). During the creation of +a child task group, its group entities on possible CPUs are attached to +parent's cfs_rq (tg_parent) and their loads are added to the parent's load +(tg_parent->load_avg) with update_tg_load_avg(). + +But only the load on online CPUs will then be updated to reflect real load, +whereas load on other CPUs will stay at the initial value. + +The result is a tg_parent->load_avg that is higher than the real load, the +weight of group entities (tg_parent->se[i]->load.weight) on online CPUs is +smaller than it should be, and the task group gets a less running time than +what it could expect. + +( This situation can be detected with /proc/sched_debug. The ".tg_load_avg" + of the task group will be much higher than sum of ".tg_load_avg_contrib" + of online cfs_rqs of the task group. ) + +The load of group entities don't have to be intialized to something else +than 0 because their load will increase when an entity is attached. + +Reported-by: Joseph Salisbury +Tested-by: Dietmar Eggemann +Signed-off-by: Vincent Guittot +Acked-by: Peter Zijlstra +Cc: # 4.8.x +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: joonwoop@codeaurora.org +Fixes: 3d30544f0212 ("sched/fair: Apply more PELT fixes) +Link: http://lkml.kernel.org/r/1476881123-10159-1-git-send-email-vincent.guittot@linaro.org +Signed-off-by: Ingo Molnar +--- + kernel/sched/fair.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 76ee7de..d941c97 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -690,7 +690,14 @@ void init_entity_runnable_average(struct sched_entity *se) + * will definitely be update (after enqueue). + */ + sa->period_contrib = 1023; +- sa->load_avg = scale_load_down(se->load.weight); ++ /* ++ * Tasks are intialized with full load to be seen as heavy tasks until ++ * they get a chance to stabilize to their real load level. ++ * Group entities are intialized with zero load to reflect the fact that ++ * nothing has been attached to the task group yet. ++ */ ++ if (entity_is_task(se)) ++ sa->load_avg = scale_load_down(se->load.weight); + sa->load_sum = sa->load_avg * LOAD_AVG_MAX; + /* + * At this point, util_avg won't be used in select_task_rq_fair anyway +-- +2.10.1 + diff --git a/kernel/kernel/files/patches/mageia/linux-BFQ-v8r4.patch b/kernel/kernel/files/patches/mageia/linux-BFQ-v8r4.patch new file mode 100644 index 00000000..abb33847 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/linux-BFQ-v8r4.patch @@ -0,0 +1,9004 @@ +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-cgroup.c linux-4.8-bfq/block/bfq-cgroup.c +--- linux-4.8/block/bfq-cgroup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-cgroup.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,1196 @@ ++/* ++ * BFQ: CGROUPS support. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ */ ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ++/* bfqg stats flags */ ++enum bfqg_stats_flags { ++ BFQG_stats_waiting = 0, ++ BFQG_stats_idling, ++ BFQG_stats_empty, ++}; ++ ++#define BFQG_FLAG_FNS(name) \ ++static void bfqg_stats_mark_##name(struct bfqg_stats *stats) \ ++{ \ ++ stats->flags |= (1 << BFQG_stats_##name); \ ++} \ ++static void bfqg_stats_clear_##name(struct bfqg_stats *stats) \ ++{ \ ++ stats->flags &= ~(1 << BFQG_stats_##name); \ ++} \ ++static int bfqg_stats_##name(struct bfqg_stats *stats) \ ++{ \ ++ return (stats->flags & (1 << BFQG_stats_##name)) != 0; \ ++} \ ++ ++BFQG_FLAG_FNS(waiting) ++BFQG_FLAG_FNS(idling) ++BFQG_FLAG_FNS(empty) ++#undef BFQG_FLAG_FNS ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_update_group_wait_time(struct bfqg_stats *stats) ++{ ++ unsigned long long now; ++ ++ if (!bfqg_stats_waiting(stats)) ++ return; ++ ++ now = sched_clock(); ++ if (time_after64(now, stats->start_group_wait_time)) ++ blkg_stat_add(&stats->group_wait_time, ++ now - stats->start_group_wait_time); ++ bfqg_stats_clear_waiting(stats); ++} ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg, ++ struct bfq_group *curr_bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (bfqg_stats_waiting(stats)) ++ return; ++ if (bfqg == curr_bfqg) ++ return; ++ stats->start_group_wait_time = sched_clock(); ++ bfqg_stats_mark_waiting(stats); ++} ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_end_empty_time(struct bfqg_stats *stats) ++{ ++ unsigned long long now; ++ ++ if (!bfqg_stats_empty(stats)) ++ return; ++ ++ now = sched_clock(); ++ if (time_after64(now, stats->start_empty_time)) ++ blkg_stat_add(&stats->empty_time, ++ now - stats->start_empty_time); ++ bfqg_stats_clear_empty(stats); ++} ++ ++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg) ++{ ++ blkg_stat_add(&bfqg->stats.dequeue, 1); ++} ++ ++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (blkg_rwstat_total(&stats->queued)) ++ return; ++ ++ /* ++ * group is already marked empty. This can happen if bfqq got new ++ * request in parent group and moved to this group while being added ++ * to service tree. Just ignore the event and move on. ++ */ ++ if (bfqg_stats_empty(stats)) ++ return; ++ ++ stats->start_empty_time = sched_clock(); ++ bfqg_stats_mark_empty(stats); ++} ++ ++static void bfqg_stats_update_idle_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (bfqg_stats_idling(stats)) { ++ unsigned long long now = sched_clock(); ++ ++ if (time_after64(now, stats->start_idle_time)) ++ blkg_stat_add(&stats->idle_time, ++ now - stats->start_idle_time); ++ bfqg_stats_clear_idling(stats); ++ } ++} ++ ++static void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ stats->start_idle_time = sched_clock(); ++ bfqg_stats_mark_idling(stats); ++} ++ ++static void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ blkg_stat_add(&stats->avg_queue_size_sum, ++ blkg_rwstat_total(&stats->queued)); ++ blkg_stat_add(&stats->avg_queue_size_samples, 1); ++ bfqg_stats_update_group_wait_time(stats); ++} ++ ++static struct blkcg_policy blkcg_policy_bfq; ++ ++/* ++ * blk-cgroup policy-related handlers ++ * The following functions help in converting between blk-cgroup ++ * internal structures and BFQ-specific structures. ++ */ ++ ++static struct bfq_group *pd_to_bfqg(struct blkg_policy_data *pd) ++{ ++ return pd ? container_of(pd, struct bfq_group, pd) : NULL; ++} ++ ++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg) ++{ ++ return pd_to_blkg(&bfqg->pd); ++} ++ ++static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg) ++{ ++ struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq); ++ ++ return pd_to_bfqg(pd); ++} ++ ++/* ++ * bfq_group handlers ++ * The following functions help in navigating the bfq_group hierarchy ++ * by allowing to find the parent of a bfq_group or the bfq_group ++ * associated to a bfq_queue. ++ */ ++ ++static struct bfq_group *bfqg_parent(struct bfq_group *bfqg) ++{ ++ struct blkcg_gq *pblkg = bfqg_to_blkg(bfqg)->parent; ++ ++ return pblkg ? blkg_to_bfqg(pblkg) : NULL; ++} ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *group_entity = bfqq->entity.parent; ++ ++ return group_entity ? container_of(group_entity, struct bfq_group, ++ entity) : ++ bfqq->bfqd->root_group; ++} ++ ++/* ++ * The following two functions handle get and put of a bfq_group by ++ * wrapping the related blk-cgroup hooks. ++ */ ++ ++static void bfqg_get(struct bfq_group *bfqg) ++{ ++ return blkg_get(bfqg_to_blkg(bfqg)); ++} ++ ++static void bfqg_put(struct bfq_group *bfqg) ++{ ++ return blkg_put(bfqg_to_blkg(bfqg)); ++} ++ ++static void bfqg_stats_update_io_add(struct bfq_group *bfqg, ++ struct bfq_queue *bfqq, ++ int op, int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, 1); ++ bfqg_stats_end_empty_time(&bfqg->stats); ++ if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue)) ++ bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq)); ++} ++ ++static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, ++ int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, -1); ++} ++ ++static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, ++ int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.merged, op, op_flags, 1); ++} ++ ++static void bfqg_stats_update_completion(struct bfq_group *bfqg, ++ uint64_t start_time, uint64_t io_start_time, int op, ++ int op_flags) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ unsigned long long now = sched_clock(); ++ ++ if (time_after64(now, io_start_time)) ++ blkg_rwstat_add(&stats->service_time, op, op_flags, ++ now - io_start_time); ++ if (time_after64(io_start_time, start_time)) ++ blkg_rwstat_add(&stats->wait_time, op, op_flags, ++ io_start_time - start_time); ++} ++ ++/* @stats = 0 */ ++static void bfqg_stats_reset(struct bfqg_stats *stats) ++{ ++ /* queued stats shouldn't be cleared */ ++ blkg_rwstat_reset(&stats->merged); ++ blkg_rwstat_reset(&stats->service_time); ++ blkg_rwstat_reset(&stats->wait_time); ++ blkg_stat_reset(&stats->time); ++ blkg_stat_reset(&stats->avg_queue_size_sum); ++ blkg_stat_reset(&stats->avg_queue_size_samples); ++ blkg_stat_reset(&stats->dequeue); ++ blkg_stat_reset(&stats->group_wait_time); ++ blkg_stat_reset(&stats->idle_time); ++ blkg_stat_reset(&stats->empty_time); ++} ++ ++/* @to += @from */ ++static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from) ++{ ++ if (!to || !from) ++ return; ++ ++ /* queued stats shouldn't be cleared */ ++ blkg_rwstat_add_aux(&to->merged, &from->merged); ++ blkg_rwstat_add_aux(&to->service_time, &from->service_time); ++ blkg_rwstat_add_aux(&to->wait_time, &from->wait_time); ++ blkg_stat_add_aux(&from->time, &from->time); ++ blkg_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum); ++ blkg_stat_add_aux(&to->avg_queue_size_samples, ++ &from->avg_queue_size_samples); ++ blkg_stat_add_aux(&to->dequeue, &from->dequeue); ++ blkg_stat_add_aux(&to->group_wait_time, &from->group_wait_time); ++ blkg_stat_add_aux(&to->idle_time, &from->idle_time); ++ blkg_stat_add_aux(&to->empty_time, &from->empty_time); ++} ++ ++/* ++ * Transfer @bfqg's stats to its parent's dead_stats so that the ancestors' ++ * recursive stats can still account for the amount used by this bfqg after ++ * it's gone. ++ */ ++static void bfqg_stats_xfer_dead(struct bfq_group *bfqg) ++{ ++ struct bfq_group *parent; ++ ++ if (!bfqg) /* root_group */ ++ return; ++ ++ parent = bfqg_parent(bfqg); ++ ++ lockdep_assert_held(bfqg_to_blkg(bfqg)->q->queue_lock); ++ ++ if (unlikely(!parent)) ++ return; ++ ++ bfqg_stats_add_aux(&parent->stats, &bfqg->stats); ++ bfqg_stats_reset(&bfqg->stats); ++} ++ ++static void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) { ++ bfqq->ioprio = bfqq->new_ioprio; ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ bfqg_get(bfqg); ++ } ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static void bfqg_stats_exit(struct bfqg_stats *stats) ++{ ++ blkg_rwstat_exit(&stats->merged); ++ blkg_rwstat_exit(&stats->service_time); ++ blkg_rwstat_exit(&stats->wait_time); ++ blkg_rwstat_exit(&stats->queued); ++ blkg_stat_exit(&stats->time); ++ blkg_stat_exit(&stats->avg_queue_size_sum); ++ blkg_stat_exit(&stats->avg_queue_size_samples); ++ blkg_stat_exit(&stats->dequeue); ++ blkg_stat_exit(&stats->group_wait_time); ++ blkg_stat_exit(&stats->idle_time); ++ blkg_stat_exit(&stats->empty_time); ++} ++ ++static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp) ++{ ++ if (blkg_rwstat_init(&stats->merged, gfp) || ++ blkg_rwstat_init(&stats->service_time, gfp) || ++ blkg_rwstat_init(&stats->wait_time, gfp) || ++ blkg_rwstat_init(&stats->queued, gfp) || ++ blkg_stat_init(&stats->time, gfp) || ++ blkg_stat_init(&stats->avg_queue_size_sum, gfp) || ++ blkg_stat_init(&stats->avg_queue_size_samples, gfp) || ++ blkg_stat_init(&stats->dequeue, gfp) || ++ blkg_stat_init(&stats->group_wait_time, gfp) || ++ blkg_stat_init(&stats->idle_time, gfp) || ++ blkg_stat_init(&stats->empty_time, gfp)) { ++ bfqg_stats_exit(stats); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static struct bfq_group_data *cpd_to_bfqgd(struct blkcg_policy_data *cpd) ++{ ++ return cpd ? container_of(cpd, struct bfq_group_data, pd) : NULL; ++} ++ ++static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg) ++{ ++ return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq)); ++} ++ ++static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp) ++{ ++ struct bfq_group_data *bgd; ++ ++ bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); ++ if (!bgd) ++ return NULL; ++ return &bgd->pd; ++} ++ ++static void bfq_cpd_init(struct blkcg_policy_data *cpd) ++{ ++ struct bfq_group_data *d = cpd_to_bfqgd(cpd); ++ ++ d->weight = cgroup_subsys_on_dfl(io_cgrp_subsys) ? ++ CGROUP_WEIGHT_DFL : BFQ_WEIGHT_LEGACY_DFL; ++} ++ ++static void bfq_cpd_free(struct blkcg_policy_data *cpd) ++{ ++ kfree(cpd_to_bfqgd(cpd)); ++} ++ ++static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) ++{ ++ struct bfq_group *bfqg; ++ ++ bfqg = kzalloc_node(sizeof(*bfqg), gfp, node); ++ if (!bfqg) ++ return NULL; ++ ++ if (bfqg_stats_init(&bfqg->stats, gfp)) { ++ kfree(bfqg); ++ return NULL; ++ } ++ ++ return &bfqg->pd; ++} ++ ++static void bfq_pd_init(struct blkg_policy_data *pd) ++{ ++ struct blkcg_gq *blkg; ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct bfq_entity *entity; ++ struct bfq_group_data *d; ++ ++ blkg = pd_to_blkg(pd); ++ BUG_ON(!blkg); ++ bfqg = blkg_to_bfqg(blkg); ++ bfqd = blkg->q->elevator->elevator_data; ++ entity = &bfqg->entity; ++ d = blkcg_to_bfqgd(blkg->blkcg); ++ ++ entity->orig_weight = entity->weight = entity->new_weight = d->weight; ++ entity->my_sched_data = &bfqg->sched_data; ++ bfqg->my_entity = entity; /* ++ * the root_group's will be set to NULL ++ * in bfq_init_queue() ++ */ ++ bfqg->bfqd = bfqd; ++ bfqg->active_entities = 0; ++ bfqg->rq_pos_tree = RB_ROOT; ++} ++ ++static void bfq_pd_free(struct blkg_policy_data *pd) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ ++ bfqg_stats_exit(&bfqg->stats); ++ return kfree(bfqg); ++} ++ ++static void bfq_pd_reset_stats(struct blkg_policy_data *pd) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ ++ bfqg_stats_reset(&bfqg->stats); ++} ++ ++static void bfq_group_set_parent(struct bfq_group *bfqg, ++ struct bfq_group *parent) ++{ ++ struct bfq_entity *entity; ++ ++ BUG_ON(!parent); ++ BUG_ON(!bfqg); ++ BUG_ON(bfqg == parent); ++ ++ entity = &bfqg->entity; ++ entity->parent = parent->my_entity; ++ entity->sched_data = &parent->sched_data; ++} ++ ++static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ struct blkcg_gq *blkg; ++ ++ blkg = blkg_lookup(blkcg, bfqd->queue); ++ if (likely(blkg)) ++ return blkg_to_bfqg(blkg); ++ return NULL; ++} ++ ++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ struct bfq_group *bfqg, *parent; ++ struct bfq_entity *entity; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ bfqg = bfq_lookup_bfqg(bfqd, blkcg); ++ ++ if (unlikely(!bfqg)) ++ return NULL; ++ ++ /* ++ * Update chain of bfq_groups as we might be handling a leaf group ++ * which, along with some of its relatives, has not been hooked yet ++ * to the private hierarchy of BFQ. ++ */ ++ entity = &bfqg->entity; ++ for_each_entity(entity) { ++ bfqg = container_of(entity, struct bfq_group, entity); ++ BUG_ON(!bfqg); ++ if (bfqg != bfqd->root_group) { ++ parent = bfqg_parent(bfqg); ++ if (!parent) ++ parent = bfqd->root_group; ++ BUG_ON(!parent); ++ bfq_group_set_parent(bfqg, parent); ++ } ++ } ++ ++ return bfqg; ++} ++ ++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq); ++ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason); ++ ++/** ++ * bfq_bfqq_move - migrate @bfqq to @bfqg. ++ * @bfqd: queue descriptor. ++ * @bfqq: the queue to move. ++ * @bfqg: the group to move to. ++ * ++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating ++ * it on the new one. Avoid putting the entity on the old group idle tree. ++ * ++ * Must be called under the queue lock; the cgroup owning @bfqg must ++ * not disappear (by now this just means that we are called under ++ * rcu_read_lock()). ++ */ ++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(!bfq_bfqq_busy(bfqq) && !RB_EMPTY_ROOT(&bfqq->sort_list)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list) && !entity->on_st); ++ BUG_ON(bfq_bfqq_busy(bfqq) && RB_EMPTY_ROOT(&bfqq->sort_list) ++ && entity->on_st && ++ bfqq != bfqd->in_service_queue); ++ BUG_ON(!bfq_bfqq_busy(bfqq) && bfqq == bfqd->in_service_queue); ++ ++ /* If bfqq is empty, then bfq_bfqq_expire also invokes ++ * bfq_del_bfqq_busy, thereby removing bfqq and its entity ++ * from data structures related to current group. Otherwise we ++ * need to remove bfqq explicitly with bfq_deactivate_bfqq, as ++ * we do below. ++ */ ++ if (bfqq == bfqd->in_service_queue) ++ bfq_bfqq_expire(bfqd, bfqd->in_service_queue, ++ false, BFQ_BFQQ_PREEMPTED); ++ ++ BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq) ++ && &bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); ++ ++ if (bfq_bfqq_busy(bfqq)) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ else if (entity->on_st) { ++ BUG_ON(&bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); ++ } ++ bfqg_put(bfqq_group(bfqq)); ++ ++ /* ++ * Here we use a reference to bfqg. We don't need a refcounter ++ * as the cgroup reference will not be dropped, so that its ++ * destroy() callback will not be invoked. ++ */ ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++ bfqg_get(bfqg); ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); ++ if (bfq_bfqq_busy(bfqq)) { ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++ ++ if (!bfqd->in_service_queue && !bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq) ++ && &bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++} ++ ++/** ++ * __bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bfqd: the queue descriptor. ++ * @bic: the bic to move. ++ * @blkcg: the blk-cgroup to move to. ++ * ++ * Move bic to blkcg, assuming that bfqd->queue is locked; the caller ++ * has to make sure that the reference to cgroup is valid across the call. ++ * ++ * NOTE: an alternative approach might have been to store the current ++ * cgroup in bfqq and getting a reference to it, reducing the lookup ++ * time here, at the price of slightly more complex code. ++ */ ++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic, ++ struct blkcg *blkcg) ++{ ++ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); ++ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); ++ struct bfq_group *bfqg; ++ struct bfq_entity *entity; ++ ++ lockdep_assert_held(bfqd->queue->queue_lock); ++ ++ bfqg = bfq_find_set_group(bfqd, blkcg); ++ ++ if (unlikely(!bfqg)) ++ bfqg = bfqd->root_group; ++ ++ if (async_bfqq) { ++ entity = &async_bfqq->entity; ++ ++ if (entity->sched_data != &bfqg->sched_data) { ++ bic_set_bfqq(bic, NULL, 0); ++ bfq_log_bfqq(bfqd, async_bfqq, ++ "bic_change_group: %p %d", ++ async_bfqq, ++ async_bfqq->ref); ++ bfq_put_queue(async_bfqq); ++ } ++ } ++ ++ if (sync_bfqq) { ++ entity = &sync_bfqq->entity; ++ if (entity->sched_data != &bfqg->sched_data) ++ bfq_bfqq_move(bfqd, sync_bfqq, bfqg); ++ } ++ ++ return bfqg; ++} ++ ++static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_group *bfqg = NULL; ++ uint64_t serial_nr; ++ ++ rcu_read_lock(); ++ serial_nr = bio_blkcg(bio)->css.serial_nr; ++ ++ /* ++ * Check whether blkcg has changed. The condition may trigger ++ * spuriously on a newly created cic but there's no harm. ++ */ ++ if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr)) ++ goto out; ++ ++ bfqg = __bfq_bic_change_cgroup(bfqd, bic, bio_blkcg(bio)); ++ bic->blkcg_serial_nr = serial_nr; ++out: ++ rcu_read_unlock(); ++} ++ ++/** ++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. ++ * @st: the service tree being flushed. ++ */ ++static void bfq_flush_idle_tree(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entity = st->first_idle; ++ ++ for (; entity ; entity = st->first_idle) ++ __bfq_deactivate_entity(entity, 0); ++} ++ ++/** ++ * bfq_reparent_leaf_entity - move leaf entity to the root_group. ++ * @bfqd: the device data structure with the root group. ++ * @entity: the entity to move. ++ */ ++static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(!bfqq); ++ bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); ++} ++ ++/** ++ * bfq_reparent_active_entities - move to the root group all active ++ * entities. ++ * @bfqd: the device data structure with the root group. ++ * @bfqg: the group to move from. ++ * @st: the service tree with the entities. ++ * ++ * Needs queue_lock to be taken and reference to be valid over the call. ++ */ ++static void bfq_reparent_active_entities(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st) ++{ ++ struct rb_root *active = &st->active; ++ struct bfq_entity *entity = NULL; ++ ++ if (!RB_EMPTY_ROOT(&st->active)) ++ entity = bfq_entity_of(rb_first(active)); ++ ++ for (; entity ; entity = bfq_entity_of(rb_first(active))) ++ bfq_reparent_leaf_entity(bfqd, entity); ++ ++ if (bfqg->sched_data.in_service_entity) ++ bfq_reparent_leaf_entity(bfqd, ++ bfqg->sched_data.in_service_entity); ++} ++ ++/** ++ * bfq_pd_offline - deactivate the entity associated with @pd, ++ * and reparent its children entities. ++ * @pd: descriptor of the policy going offline. ++ * ++ * blkio already grabs the queue_lock for us, so no need to use ++ * RCU-based magic ++ */ ++static void bfq_pd_offline(struct blkg_policy_data *pd) ++{ ++ struct bfq_service_tree *st; ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct bfq_entity *entity; ++ int i; ++ ++ BUG_ON(!pd); ++ bfqg = pd_to_bfqg(pd); ++ BUG_ON(!bfqg); ++ bfqd = bfqg->bfqd; ++ BUG_ON(bfqd && !bfqd->root_group); ++ ++ entity = bfqg->my_entity; ++ ++ if (!entity) /* root group */ ++ return; ++ ++ /* ++ * Empty all service_trees belonging to this group before ++ * deactivating the group itself. ++ */ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { ++ BUG_ON(!bfqg->sched_data.service_tree); ++ st = bfqg->sched_data.service_tree + i; ++ /* ++ * The idle tree may still contain bfq_queues belonging ++ * to exited task because they never migrated to a different ++ * cgroup from the one being destroyed now. No one else ++ * can access them so it's safe to act without any lock. ++ */ ++ bfq_flush_idle_tree(st); ++ ++ /* ++ * It may happen that some queues are still active ++ * (busy) upon group destruction (if the corresponding ++ * processes have been forced to terminate). We move ++ * all the leaf entities corresponding to these queues ++ * to the root_group. ++ * Also, it may happen that the group has an entity ++ * in service, which is disconnected from the active ++ * tree: it must be moved, too. ++ * There is no need to put the sync queues, as the ++ * scheduler has taken no reference. ++ */ ++ bfq_reparent_active_entities(bfqd, bfqg, st); ++ BUG_ON(!RB_EMPTY_ROOT(&st->active)); ++ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); ++ } ++ BUG_ON(bfqg->sched_data.next_in_service); ++ BUG_ON(bfqg->sched_data.in_service_entity); ++ ++ __bfq_deactivate_entity(entity, 0); ++ bfq_put_async_queues(bfqd, bfqg); ++ BUG_ON(entity->tree); ++ ++ /* ++ * @blkg is going offline and will be ignored by ++ * blkg_[rw]stat_recursive_sum(). Transfer stats to the parent so ++ * that they don't get lost. If IOs complete after this point, the ++ * stats for them will be lost. Oh well... ++ */ ++ bfqg_stats_xfer_dead(bfqg); ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ struct blkcg_gq *blkg; ++ ++ list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) { ++ struct bfq_group *bfqg = blkg_to_bfqg(blkg); ++ BUG_ON(!bfqg); ++ ++ bfq_end_wr_async_queues(bfqd, bfqg); ++ } ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static int bfq_io_show_weight(struct seq_file *sf, void *v) ++{ ++ struct blkcg *blkcg = css_to_blkcg(seq_css(sf)); ++ struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg); ++ unsigned int val = 0; ++ ++ if (bfqgd) ++ val = bfqgd->weight; ++ ++ seq_printf(sf, "%u\n", val); ++ ++ return 0; ++} ++ ++static int bfq_io_set_weight_legacy(struct cgroup_subsys_state *css, ++ struct cftype *cftype, ++ u64 val) ++{ ++ struct blkcg *blkcg = css_to_blkcg(css); ++ struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg); ++ struct blkcg_gq *blkg; ++ int ret = -ERANGE; ++ ++ if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT) ++ return ret; ++ ++ ret = 0; ++ spin_lock_irq(&blkcg->lock); ++ bfqgd->weight = (unsigned short)val; ++ hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) { ++ struct bfq_group *bfqg = blkg_to_bfqg(blkg); ++ ++ if (!bfqg) ++ continue; ++ /* ++ * Setting the prio_changed flag of the entity ++ * to 1 with new_weight == weight would re-set ++ * the value of the weight to its ioprio mapping. ++ * Set the flag only if necessary. ++ */ ++ if ((unsigned short)val != bfqg->entity.new_weight) { ++ bfqg->entity.new_weight = (unsigned short)val; ++ /* ++ * Make sure that the above new value has been ++ * stored in bfqg->entity.new_weight before ++ * setting the prio_changed flag. In fact, ++ * this flag may be read asynchronously (in ++ * critical sections protected by a different ++ * lock than that held here), and finding this ++ * flag set may cause the execution of the code ++ * for updating parameters whose value may ++ * depend also on bfqg->entity.new_weight (in ++ * __bfq_entity_update_weight_prio). ++ * This barrier makes sure that the new value ++ * of bfqg->entity.new_weight is correctly ++ * seen in that code. ++ */ ++ smp_wmb(); ++ bfqg->entity.prio_changed = 1; ++ } ++ } ++ spin_unlock_irq(&blkcg->lock); ++ ++ return ret; ++} ++ ++static ssize_t bfq_io_set_weight(struct kernfs_open_file *of, ++ char *buf, size_t nbytes, ++ loff_t off) ++{ ++ u64 weight; ++ /* First unsigned long found in the file is used */ ++ int ret = kstrtoull(strim(buf), 0, &weight); ++ ++ if (ret) ++ return ret; ++ ++ return bfq_io_set_weight_legacy(of_css(of), NULL, weight); ++} ++ ++static int bfqg_print_stat(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat, ++ &blkcg_policy_bfq, seq_cft(sf)->private, false); ++ return 0; ++} ++ ++static int bfqg_print_rwstat(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_rwstat, ++ &blkcg_policy_bfq, seq_cft(sf)->private, true); ++ return 0; ++} ++ ++static u64 bfqg_prfill_stat_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ u64 sum = blkg_stat_recursive_sum(pd_to_blkg(pd), ++ &blkcg_policy_bfq, off); ++ return __blkg_prfill_u64(sf, pd, sum); ++} ++ ++static u64 bfqg_prfill_rwstat_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct blkg_rwstat sum = blkg_rwstat_recursive_sum(pd_to_blkg(pd), ++ &blkcg_policy_bfq, ++ off); ++ return __blkg_prfill_rwstat(sf, pd, &sum); ++} ++ ++static int bfqg_print_stat_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_stat_recursive, &blkcg_policy_bfq, ++ seq_cft(sf)->private, false); ++ return 0; ++} ++ ++static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_rwstat_recursive, &blkcg_policy_bfq, ++ seq_cft(sf)->private, true); ++ return 0; ++} ++ ++static u64 bfqg_prfill_sectors(struct seq_file *sf, struct blkg_policy_data *pd, ++ int off) ++{ ++ u64 sum = blkg_rwstat_total(&pd->blkg->stat_bytes); ++ ++ return __blkg_prfill_u64(sf, pd, sum >> 9); ++} ++ ++static int bfqg_print_stat_sectors(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_sectors, &blkcg_policy_bfq, 0, false); ++ return 0; ++} ++ ++static u64 bfqg_prfill_sectors_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct blkg_rwstat tmp = blkg_rwstat_recursive_sum(pd->blkg, NULL, ++ offsetof(struct blkcg_gq, stat_bytes)); ++ u64 sum = atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_READ]) + ++ atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_WRITE]); ++ ++ return __blkg_prfill_u64(sf, pd, sum >> 9); ++} ++ ++static int bfqg_print_stat_sectors_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_sectors_recursive, &blkcg_policy_bfq, 0, ++ false); ++ return 0; ++} ++ ++ ++static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ u64 samples = blkg_stat_read(&bfqg->stats.avg_queue_size_samples); ++ u64 v = 0; ++ ++ if (samples) { ++ v = blkg_stat_read(&bfqg->stats.avg_queue_size_sum); ++ v = div64_u64(v, samples); ++ } ++ __blkg_prfill_u64(sf, pd, v); ++ return 0; ++} ++ ++/* print avg_queue_size */ ++static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_avg_queue_size, &blkcg_policy_bfq, ++ 0, false); ++ return 0; ++} ++ ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++{ ++ int ret; ++ ++ ret = blkcg_activate_policy(bfqd->queue, &blkcg_policy_bfq); ++ if (ret) ++ return NULL; ++ ++ return blkg_to_bfqg(bfqd->queue->root_blkg); ++} ++ ++static struct cftype bfq_blkcg_legacy_files[] = { ++ { ++ .name = "bfq.weight", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .seq_show = bfq_io_show_weight, ++ .write_u64 = bfq_io_set_weight_legacy, ++ }, ++ ++ /* statistics, covers only the tasks in the bfqg */ ++ { ++ .name = "bfq.time", ++ .private = offsetof(struct bfq_group, stats.time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.sectors", ++ .seq_show = bfqg_print_stat_sectors, ++ }, ++ { ++ .name = "bfq.io_service_bytes", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_bytes, ++ }, ++ { ++ .name = "bfq.io_serviced", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_ios, ++ }, ++ { ++ .name = "bfq.io_service_time", ++ .private = offsetof(struct bfq_group, stats.service_time), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_wait_time", ++ .private = offsetof(struct bfq_group, stats.wait_time), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_merged", ++ .private = offsetof(struct bfq_group, stats.merged), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_queued", ++ .private = offsetof(struct bfq_group, stats.queued), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ ++ /* the same statictics which cover the bfqg and its descendants */ ++ { ++ .name = "bfq.time_recursive", ++ .private = offsetof(struct bfq_group, stats.time), ++ .seq_show = bfqg_print_stat_recursive, ++ }, ++ { ++ .name = "bfq.sectors_recursive", ++ .seq_show = bfqg_print_stat_sectors_recursive, ++ }, ++ { ++ .name = "bfq.io_service_bytes_recursive", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_bytes_recursive, ++ }, ++ { ++ .name = "bfq.io_serviced_recursive", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_ios_recursive, ++ }, ++ { ++ .name = "bfq.io_service_time_recursive", ++ .private = offsetof(struct bfq_group, stats.service_time), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_wait_time_recursive", ++ .private = offsetof(struct bfq_group, stats.wait_time), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_merged_recursive", ++ .private = offsetof(struct bfq_group, stats.merged), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_queued_recursive", ++ .private = offsetof(struct bfq_group, stats.queued), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.avg_queue_size", ++ .seq_show = bfqg_print_avg_queue_size, ++ }, ++ { ++ .name = "bfq.group_wait_time", ++ .private = offsetof(struct bfq_group, stats.group_wait_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.idle_time", ++ .private = offsetof(struct bfq_group, stats.idle_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.empty_time", ++ .private = offsetof(struct bfq_group, stats.empty_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.dequeue", ++ .private = offsetof(struct bfq_group, stats.dequeue), ++ .seq_show = bfqg_print_stat, ++ }, ++ { } /* terminate */ ++}; ++ ++static struct cftype bfq_blkg_files[] = { ++ { ++ .name = "bfq.weight", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .seq_show = bfq_io_show_weight, ++ .write = bfq_io_set_weight, ++ }, ++ {} /* terminate */ ++}; ++ ++#else /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++static inline void bfqg_stats_update_io_add(struct bfq_group *bfqg, ++ struct bfq_queue *bfqq, int op, int op_flags) { } ++static inline void ++bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, int op_flags) { } ++static inline void ++bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, int op_flags) { } ++static inline void bfqg_stats_update_completion(struct bfq_group *bfqg, ++ uint64_t start_time, uint64_t io_start_time, int op, ++ int op_flags) { } ++static inline void ++bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg, ++ struct bfq_group *curr_bfqg) { } ++static inline void bfqg_stats_end_empty_time(struct bfqg_stats *stats) { } ++static inline void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { } ++ ++static void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) { ++ bfqq->ioprio = bfqq->new_ioprio; ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ } ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static struct bfq_group * ++bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ return bfqd->root_group; ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ return bfqd->root_group; ++} ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq) ++{ ++ return bfqq->bfqd->root_group; ++} ++ ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ int i; ++ ++ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); ++ if (!bfqg) ++ return NULL; ++ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ return bfqg; ++} ++#endif +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq.h linux-4.8-bfq/block/bfq.h +--- linux-4.8/block/bfq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq.h 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,886 @@ ++/* ++ * BFQ-v8r4 for 4.8.0: data structures and common functions prototypes. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ */ ++ ++#ifndef _BFQ_H ++#define _BFQ_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BFQ_IOPRIO_CLASSES 3 ++#define BFQ_CL_IDLE_TIMEOUT (HZ/5) ++ ++#define BFQ_MIN_WEIGHT 1 ++#define BFQ_MAX_WEIGHT 1000 ++#define BFQ_WEIGHT_CONVERSION_COEFF 10 ++ ++#define BFQ_DEFAULT_QUEUE_IOPRIO 4 ++ ++#define BFQ_WEIGHT_LEGACY_DFL 100 ++#define BFQ_DEFAULT_GRP_IOPRIO 0 ++#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE ++ ++/* ++ * Soft real-time applications are extremely more latency sensitive ++ * than interactive ones. Over-raise the weight of the former to ++ * privilege them against the latter. ++ */ ++#define BFQ_SOFTRT_WEIGHT_FACTOR 100 ++ ++struct bfq_entity; ++ ++/** ++ * struct bfq_service_tree - per ioprio_class service tree. ++ * ++ * Each service tree represents a B-WF2Q+ scheduler on its own. Each ++ * ioprio_class has its own independent scheduler, and so its own ++ * bfq_service_tree. All the fields are protected by the queue lock ++ * of the containing bfqd. ++ */ ++struct bfq_service_tree { ++ /* tree for active entities (i.e., those backlogged) */ ++ struct rb_root active; ++ /* tree for idle entities (i.e., not backlogged, with V <= F_i)*/ ++ struct rb_root idle; ++ ++ struct bfq_entity *first_idle; /* idle entity with minimum F_i */ ++ struct bfq_entity *last_idle; /* idle entity with maximum F_i */ ++ ++ u64 vtime; /* scheduler virtual time */ ++ /* scheduler weight sum; active and idle entities contribute to it */ ++ unsigned long wsum; ++}; ++ ++/** ++ * struct bfq_sched_data - multi-class scheduler. ++ * ++ * bfq_sched_data is the basic scheduler queue. It supports three ++ * ioprio_classes, and can be used either as a toplevel queue or as an ++ * intermediate queue on a hierarchical setup. @next_in_service ++ * points to the active entity of the sched_data service trees that ++ * will be scheduled next. It is used to reduce the number of steps ++ * needed for each hierarchical-schedule update. ++ * ++ * The supported ioprio_classes are the same as in CFQ, in descending ++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. ++ * Requests from higher priority queues are served before all the ++ * requests from lower priority queues; among requests of the same ++ * queue requests are served according to B-WF2Q+. ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_sched_data { ++ struct bfq_entity *in_service_entity; /* entity in service */ ++ /* head-of-the-line entity in the scheduler (see comments above) */ ++ struct bfq_entity *next_in_service; ++ /* array of service trees, one per ioprio_class */ ++ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; ++}; ++ ++/** ++ * struct bfq_weight_counter - counter of the number of all active entities ++ * with a given weight. ++ */ ++struct bfq_weight_counter { ++ unsigned int weight; /* weight of the entities this counter refers to */ ++ unsigned int num_active; /* nr of active entities with this weight */ ++ /* ++ * Weights tree member (see bfq_data's @queue_weights_tree and ++ * @group_weights_tree) ++ */ ++ struct rb_node weights_node; ++}; ++ ++/** ++ * struct bfq_entity - schedulable entity. ++ * ++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the ++ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each ++ * entity belongs to the sched_data of the parent group in the cgroup ++ * hierarchy. Non-leaf entities have also their own sched_data, stored ++ * in @my_sched_data. ++ * ++ * Each entity stores independently its priority values; this would ++ * allow different weights on different devices, but this ++ * functionality is not exported to userspace by now. Priorities and ++ * weights are updated lazily, first storing the new values into the ++ * new_* fields, then setting the @prio_changed flag. As soon as ++ * there is a transition in the entity state that allows the priority ++ * update to take place the effective and the requested priority ++ * values are synchronized. ++ * ++ * Unless cgroups are used, the weight value is calculated from the ++ * ioprio to export the same interface as CFQ. When dealing with ++ * ``well-behaved'' queues (i.e., queues that do not spend too much ++ * time to consume their budget and have true sequential behavior, and ++ * when there are no external factors breaking anticipation) the ++ * relative weights at each level of the cgroups hierarchy should be ++ * guaranteed. All the fields are protected by the queue lock of the ++ * containing bfqd. ++ */ ++struct bfq_entity { ++ struct rb_node rb_node; /* service_tree member */ ++ /* pointer to the weight counter associated with this entity */ ++ struct bfq_weight_counter *weight_counter; ++ ++ /* ++ * flag, true if the entity is on a tree (either the active or ++ * the idle one of its service_tree). ++ */ ++ int on_st; ++ ++ u64 finish; /* B-WF2Q+ finish timestamp (aka F_i) */ ++ u64 start; /* B-WF2Q+ start timestamp (aka S_i) */ ++ ++ /* tree the entity is enqueued into; %NULL if not on a tree */ ++ struct rb_root *tree; ++ ++ /* ++ * minimum start time of the (active) subtree rooted at this ++ * entity; used for O(log N) lookups into active trees ++ */ ++ u64 min_start; ++ ++ /* amount of service received during the last service slot */ ++ int service; ++ ++ /* budget, used also to calculate F_i: F_i = S_i + @budget / @weight */ ++ int budget; ++ ++ unsigned int weight; /* weight of the queue */ ++ unsigned int new_weight; /* next weight if a change is in progress */ ++ ++ /* original weight, used to implement weight boosting */ ++ unsigned int orig_weight; ++ ++ /* parent entity, for hierarchical scheduling */ ++ struct bfq_entity *parent; ++ ++ /* ++ * For non-leaf nodes in the hierarchy, the associated ++ * scheduler queue, %NULL on leaf nodes. ++ */ ++ struct bfq_sched_data *my_sched_data; ++ /* the scheduler queue this entity belongs to */ ++ struct bfq_sched_data *sched_data; ++ ++ /* flag, set to request a weight, ioprio or ioprio_class change */ ++ int prio_changed; ++}; ++ ++struct bfq_group; ++ ++/** ++ * struct bfq_queue - leaf schedulable entity. ++ * ++ * A bfq_queue is a leaf request queue; it can be associated with an ++ * io_context or more, if it is async or shared between cooperating ++ * processes. @cgroup holds a reference to the cgroup, to be sure that it ++ * does not disappear while a bfqq still references it (mostly to avoid ++ * races between request issuing and task migration followed by cgroup ++ * destruction). ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_queue { ++ /* reference counter */ ++ int ref; ++ /* parent bfq_data */ ++ struct bfq_data *bfqd; ++ ++ /* current ioprio and ioprio class */ ++ unsigned short ioprio, ioprio_class; ++ /* next ioprio and ioprio class if a change is in progress */ ++ unsigned short new_ioprio, new_ioprio_class; ++ ++ /* ++ * Shared bfq_queue if queue is cooperating with one or more ++ * other queues. ++ */ ++ struct bfq_queue *new_bfqq; ++ /* request-position tree member (see bfq_group's @rq_pos_tree) */ ++ struct rb_node pos_node; ++ /* request-position tree root (see bfq_group's @rq_pos_tree) */ ++ struct rb_root *pos_root; ++ ++ /* sorted list of pending requests */ ++ struct rb_root sort_list; ++ /* if fifo isn't expired, next request to serve */ ++ struct request *next_rq; ++ /* number of sync and async requests queued */ ++ int queued[2]; ++ /* number of sync and async requests currently allocated */ ++ int allocated[2]; ++ /* number of pending metadata requests */ ++ int meta_pending; ++ /* fifo list of requests in sort_list */ ++ struct list_head fifo; ++ ++ /* entity representing this queue in the scheduler */ ++ struct bfq_entity entity; ++ ++ /* maximum budget allowed from the feedback mechanism */ ++ int max_budget; ++ /* budget expiration (in jiffies) */ ++ unsigned long budget_timeout; ++ ++ /* number of requests on the dispatch list or inside driver */ ++ int dispatched; ++ ++ unsigned int flags; /* status flags.*/ ++ ++ /* node for active/idle bfqq list inside parent bfqd */ ++ struct list_head bfqq_list; ++ ++ /* bit vector: a 1 for each seeky requests in history */ ++ u32 seek_history; ++ ++ /* node for the device's burst list */ ++ struct hlist_node burst_list_node; ++ ++ /* position of the last request enqueued */ ++ sector_t last_request_pos; ++ ++ /* Number of consecutive pairs of request completion and ++ * arrival, such that the queue becomes idle after the ++ * completion, but the next request arrives within an idle ++ * time slice; used only if the queue's IO_bound flag has been ++ * cleared. ++ */ ++ unsigned int requests_within_timer; ++ ++ /* pid of the process owning the queue, used for logging purposes */ ++ pid_t pid; ++ ++ /* ++ * Pointer to the bfq_io_cq owning the bfq_queue, set to %NULL ++ * if the queue is shared. ++ */ ++ struct bfq_io_cq *bic; ++ ++ /* current maximum weight-raising time for this queue */ ++ unsigned long wr_cur_max_time; ++ /* ++ * Minimum time instant such that, only if a new request is ++ * enqueued after this time instant in an idle @bfq_queue with ++ * no outstanding requests, then the task associated with the ++ * queue it is deemed as soft real-time (see the comments on ++ * the function bfq_bfqq_softrt_next_start()) ++ */ ++ unsigned long soft_rt_next_start; ++ /* ++ * Start time of the current weight-raising period if ++ * the @bfq-queue is being weight-raised, otherwise ++ * finish time of the last weight-raising period. ++ */ ++ unsigned long last_wr_start_finish; ++ /* factor by which the weight of this queue is multiplied */ ++ unsigned int wr_coeff; ++ /* ++ * Time of the last transition of the @bfq_queue from idle to ++ * backlogged. ++ */ ++ unsigned long last_idle_bklogged; ++ /* ++ * Cumulative service received from the @bfq_queue since the ++ * last transition from idle to backlogged. ++ */ ++ unsigned long service_from_backlogged; ++ /* ++ * Value of wr start time when switching to soft rt ++ */ ++ unsigned long wr_start_at_switch_to_srt; ++ ++ unsigned long split_time; /* time of last split */ ++}; ++ ++/** ++ * struct bfq_ttime - per process thinktime stats. ++ */ ++struct bfq_ttime { ++ u64 last_end_request; /* completion time of last request */ ++ ++ u64 ttime_total; /* total process thinktime */ ++ unsigned long ttime_samples; /* number of thinktime samples */ ++ u64 ttime_mean; /* average process thinktime */ ++ ++}; ++ ++/** ++ * struct bfq_io_cq - per (request_queue, io_context) structure. ++ */ ++struct bfq_io_cq { ++ /* associated io_cq structure */ ++ struct io_cq icq; /* must be the first member */ ++ /* array of two process queues, the sync and the async */ ++ struct bfq_queue *bfqq[2]; ++ /* associated @bfq_ttime struct */ ++ struct bfq_ttime ttime; ++ /* per (request_queue, blkcg) ioprio */ ++ int ioprio; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ uint64_t blkcg_serial_nr; /* the current blkcg serial */ ++#endif ++ ++ /* ++ * Snapshot of the idle window before merging; taken to ++ * remember this value while the queue is merged, so as to be ++ * able to restore it in case of split. ++ */ ++ bool saved_idle_window; ++ /* ++ * Same purpose as the previous two fields for the I/O bound ++ * classification of a queue. ++ */ ++ bool saved_IO_bound; ++ ++ /* ++ * Same purpose as the previous fields for the value of the ++ * field keeping the queue's belonging to a large burst ++ */ ++ bool saved_in_large_burst; ++ /* ++ * True if the queue belonged to a burst list before its merge ++ * with another cooperating queue. ++ */ ++ bool was_in_burst_list; ++ ++ /* ++ * Similar to previous fields: save wr information. ++ */ ++ unsigned long saved_wr_coeff; ++ unsigned long saved_last_wr_start_finish; ++ unsigned long saved_wr_start_at_switch_to_srt; ++}; ++ ++enum bfq_device_speed { ++ BFQ_BFQD_FAST, ++ BFQ_BFQD_SLOW, ++}; ++ ++/** ++ * struct bfq_data - per-device data structure. ++ * ++ * All the fields are protected by the @queue lock. ++ */ ++struct bfq_data { ++ /* request queue for the device */ ++ struct request_queue *queue; ++ ++ /* root bfq_group for the device */ ++ struct bfq_group *root_group; ++ ++ /* ++ * rbtree of weight counters of @bfq_queues, sorted by ++ * weight. Used to keep track of whether all @bfq_queues have ++ * the same weight. The tree contains one counter for each ++ * distinct weight associated to some active and not ++ * weight-raised @bfq_queue (see the comments to the functions ++ * bfq_weights_tree_[add|remove] for further details). ++ */ ++ struct rb_root queue_weights_tree; ++ /* ++ * rbtree of non-queue @bfq_entity weight counters, sorted by ++ * weight. Used to keep track of whether all @bfq_groups have ++ * the same weight. The tree contains one counter for each ++ * distinct weight associated to some active @bfq_group (see ++ * the comments to the functions bfq_weights_tree_[add|remove] ++ * for further details). ++ */ ++ struct rb_root group_weights_tree; ++ ++ /* ++ * Number of bfq_queues containing requests (including the ++ * queue in service, even if it is idling). ++ */ ++ int busy_queues; ++ /* number of weight-raised busy @bfq_queues */ ++ int wr_busy_queues; ++ /* number of queued requests */ ++ int queued; ++ /* number of requests dispatched and waiting for completion */ ++ int rq_in_driver; ++ ++ /* ++ * Maximum number of requests in driver in the last ++ * @hw_tag_samples completed requests. ++ */ ++ int max_rq_in_driver; ++ /* number of samples used to calculate hw_tag */ ++ int hw_tag_samples; ++ /* flag set to one if the driver is showing a queueing behavior */ ++ int hw_tag; ++ ++ /* number of budgets assigned */ ++ int budgets_assigned; ++ ++ /* ++ * Timer set when idling (waiting) for the next request from ++ * the queue in service. ++ */ ++ struct hrtimer idle_slice_timer; ++ /* delayed work to restart dispatching on the request queue */ ++ struct work_struct unplug_work; ++ ++ /* bfq_queue in service */ ++ struct bfq_queue *in_service_queue; ++ /* bfq_io_cq (bic) associated with the @in_service_queue */ ++ struct bfq_io_cq *in_service_bic; ++ ++ /* on-disk position of the last served request */ ++ sector_t last_position; ++ ++ /* time of last request completion (ns) */ ++ u64 last_completion; ++ ++ /* time of first rq dispatch in current observation interval (ns) */ ++ u64 first_dispatch; ++ /* time of last rq dispatch in current observation interval (ns) */ ++ u64 last_dispatch; ++ ++ /* beginning of the last budget */ ++ ktime_t last_budget_start; ++ /* beginning of the last idle slice */ ++ ktime_t last_idling_start; ++ ++ /* number of samples in current observation interval */ ++ int peak_rate_samples; ++ /* num of samples of seq dispatches in current observation interval */ ++ u32 sequential_samples; ++ /* total num of sectors transferred in current observation interval */ ++ u64 tot_sectors_dispatched; ++ /* max rq size seen during current observation interval (sectors) */ ++ u32 last_rq_max_size; ++ /* time elapsed from first dispatch in current observ. interval (us) */ ++ u64 delta_from_first; ++ /* current estimate of device peak rate */ ++ u32 peak_rate; ++ ++ /* maximum budget allotted to a bfq_queue before rescheduling */ ++ int bfq_max_budget; ++ ++ /* list of all the bfq_queues active on the device */ ++ struct list_head active_list; ++ /* list of all the bfq_queues idle on the device */ ++ struct list_head idle_list; ++ ++ /* ++ * Timeout for async/sync requests; when it fires, requests ++ * are served in fifo order. ++ */ ++ u64 bfq_fifo_expire[2]; ++ /* weight of backward seeks wrt forward ones */ ++ unsigned int bfq_back_penalty; ++ /* maximum allowed backward seek */ ++ unsigned int bfq_back_max; ++ /* maximum idling time */ ++ u32 bfq_slice_idle; ++ /* last time CLASS_IDLE was served */ ++ u64 bfq_class_idle_last_service; ++ ++ /* user-configured max budget value (0 for auto-tuning) */ ++ int bfq_user_max_budget; ++ /* ++ * Timeout for bfq_queues to consume their budget; used to ++ * prevent seeky queues from imposing long latencies to ++ * sequential or quasi-sequential ones (this also implies that ++ * seeky queues cannot receive guarantees in the service ++ * domain; after a timeout they are charged for the time they ++ * have been in service, to preserve fairness among them, but ++ * without service-domain guarantees). ++ */ ++ unsigned int bfq_timeout; ++ ++ /* ++ * Number of consecutive requests that must be issued within ++ * the idle time slice to set again idling to a queue which ++ * was marked as non-I/O-bound (see the definition of the ++ * IO_bound flag for further details). ++ */ ++ unsigned int bfq_requests_within_timer; ++ ++ /* ++ * Force device idling whenever needed to provide accurate ++ * service guarantees, without caring about throughput ++ * issues. CAVEAT: this may even increase latencies, in case ++ * of useless idling for processes that did stop doing I/O. ++ */ ++ bool strict_guarantees; ++ ++ /* ++ * Last time at which a queue entered the current burst of ++ * queues being activated shortly after each other; for more ++ * details about this and the following parameters related to ++ * a burst of activations, see the comments on the function ++ * bfq_handle_burst. ++ */ ++ unsigned long last_ins_in_burst; ++ /* ++ * Reference time interval used to decide whether a queue has ++ * been activated shortly after @last_ins_in_burst. ++ */ ++ unsigned long bfq_burst_interval; ++ /* number of queues in the current burst of queue activations */ ++ int burst_size; ++ ++ /* common parent entity for the queues in the burst */ ++ struct bfq_entity *burst_parent_entity; ++ /* Maximum burst size above which the current queue-activation ++ * burst is deemed as 'large'. ++ */ ++ unsigned long bfq_large_burst_thresh; ++ /* true if a large queue-activation burst is in progress */ ++ bool large_burst; ++ /* ++ * Head of the burst list (as for the above fields, more ++ * details in the comments on the function bfq_handle_burst). ++ */ ++ struct hlist_head burst_list; ++ ++ /* if set to true, low-latency heuristics are enabled */ ++ bool low_latency; ++ /* ++ * Maximum factor by which the weight of a weight-raised queue ++ * is multiplied. ++ */ ++ unsigned int bfq_wr_coeff; ++ /* maximum duration of a weight-raising period (jiffies) */ ++ unsigned int bfq_wr_max_time; ++ ++ /* Maximum weight-raising duration for soft real-time processes */ ++ unsigned int bfq_wr_rt_max_time; ++ /* ++ * Minimum idle period after which weight-raising may be ++ * reactivated for a queue (in jiffies). ++ */ ++ unsigned int bfq_wr_min_idle_time; ++ /* ++ * Minimum period between request arrivals after which ++ * weight-raising may be reactivated for an already busy async ++ * queue (in jiffies). ++ */ ++ unsigned long bfq_wr_min_inter_arr_async; ++ ++ /* Max service-rate for a soft real-time queue, in sectors/sec */ ++ unsigned int bfq_wr_max_softrt_rate; ++ /* ++ * Cached value of the product R*T, used for computing the ++ * maximum duration of weight raising automatically. ++ */ ++ u64 RT_prod; ++ /* device-speed class for the low-latency heuristic */ ++ enum bfq_device_speed device_speed; ++ ++ /* fallback dummy bfqq for extreme OOM conditions */ ++ struct bfq_queue oom_bfqq; ++}; ++ ++enum bfqq_state_flags { ++ BFQ_BFQQ_FLAG_just_created = 0, /* queue just allocated */ ++ BFQ_BFQQ_FLAG_busy, /* has requests or is in service */ ++ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ ++ BFQ_BFQQ_FLAG_non_blocking_wait_rq, /* ++ * waiting for a request ++ * without idling the device ++ */ ++ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ ++ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ ++ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ ++ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ ++ BFQ_BFQQ_FLAG_IO_bound, /* ++ * bfqq has timed-out at least once ++ * having consumed at most 2/10 of ++ * its budget ++ */ ++ BFQ_BFQQ_FLAG_in_large_burst, /* ++ * bfqq activated in a large burst, ++ * see comments to bfq_handle_burst. ++ */ ++ BFQ_BFQQ_FLAG_softrt_update, /* ++ * may need softrt-next-start ++ * update ++ */ ++ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ ++ BFQ_BFQQ_FLAG_split_coop /* shared bfqq will be split */ ++}; ++ ++#define BFQ_BFQQ_FNS(name) \ ++static void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ ++{ \ ++ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ ++} ++ ++BFQ_BFQQ_FNS(just_created); ++BFQ_BFQQ_FNS(busy); ++BFQ_BFQQ_FNS(wait_request); ++BFQ_BFQQ_FNS(non_blocking_wait_rq); ++BFQ_BFQQ_FNS(must_alloc); ++BFQ_BFQQ_FNS(fifo_expire); ++BFQ_BFQQ_FNS(idle_window); ++BFQ_BFQQ_FNS(sync); ++BFQ_BFQQ_FNS(IO_bound); ++BFQ_BFQQ_FNS(in_large_burst); ++BFQ_BFQQ_FNS(coop); ++BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(softrt_update); ++#undef BFQ_BFQQ_FNS ++ ++/* Logging facilities. */ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); ++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); ++ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \ ++ char __pbuf[128]; \ ++ \ ++ assert_spin_locked((bfqd)->queue->queue_lock); \ ++ blkg_path(bfqg_to_blkg(bfqq_group(bfqq)), __pbuf, sizeof(__pbuf)); \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, \ ++ (bfqq)->pid, \ ++ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ ++ __pbuf, ##args); \ ++} while (0) ++ ++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \ ++ char __pbuf[128]; \ ++ \ ++ blkg_path(bfqg_to_blkg(bfqg), __pbuf, sizeof(__pbuf)); \ ++ blk_add_trace_msg((bfqd)->queue, "%s " fmt, __pbuf, ##args); \ ++} while (0) ++ ++#else /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d%c " fmt, (bfqq)->pid, \ ++ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ ++ ##args) ++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do {} while (0) ++ ++#endif /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++#define bfq_log(bfqd, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) ++ ++/* Expiration reasons. */ ++enum bfqq_expiration { ++ BFQ_BFQQ_TOO_IDLE = 0, /* ++ * queue has been idling for ++ * too long ++ */ ++ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ ++ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ ++ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ ++ BFQ_BFQQ_PREEMPTED /* preemption in progress */ ++}; ++ ++ ++struct bfqg_stats { ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ /* number of ios merged */ ++ struct blkg_rwstat merged; ++ /* total time spent on device in ns, may not be accurate w/ queueing */ ++ struct blkg_rwstat service_time; ++ /* total time spent waiting in scheduler queue in ns */ ++ struct blkg_rwstat wait_time; ++ /* number of IOs queued up */ ++ struct blkg_rwstat queued; ++ /* total disk time and nr sectors dispatched by this group */ ++ struct blkg_stat time; ++ /* sum of number of ios queued across all samples */ ++ struct blkg_stat avg_queue_size_sum; ++ /* count of samples taken for average */ ++ struct blkg_stat avg_queue_size_samples; ++ /* how many times this group has been removed from service tree */ ++ struct blkg_stat dequeue; ++ /* total time spent waiting for it to be assigned a timeslice. */ ++ struct blkg_stat group_wait_time; ++ /* time spent idling for this blkcg_gq */ ++ struct blkg_stat idle_time; ++ /* total time with empty current active q with other requests queued */ ++ struct blkg_stat empty_time; ++ /* fields after this shouldn't be cleared on stat reset */ ++ uint64_t start_group_wait_time; ++ uint64_t start_idle_time; ++ uint64_t start_empty_time; ++ uint16_t flags; ++#endif ++}; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++/* ++ * struct bfq_group_data - per-blkcg storage for the blkio subsystem. ++ * ++ * @ps: @blkcg_policy_storage that this structure inherits ++ * @weight: weight of the bfq_group ++ */ ++struct bfq_group_data { ++ /* must be the first member */ ++ struct blkcg_policy_data pd; ++ ++ unsigned int weight; ++}; ++ ++/** ++ * struct bfq_group - per (device, cgroup) data structure. ++ * @entity: schedulable entity to insert into the parent group sched_data. ++ * @sched_data: own sched_data, to contain child entities (they may be ++ * both bfq_queues and bfq_groups). ++ * @bfqd: the bfq_data for the device this group acts upon. ++ * @async_bfqq: array of async queues for all the tasks belonging to ++ * the group, one queue per ioprio value per ioprio_class, ++ * except for the idle class that has only one queue. ++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). ++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used ++ * to avoid too many special cases during group creation/ ++ * migration. ++ * @active_entities: number of active entities belonging to the group; ++ * unused for the root group. Used to know whether there ++ * are groups with more than one active @bfq_entity ++ * (see the comments to the function ++ * bfq_bfqq_may_idle()). ++ * @rq_pos_tree: rbtree sorted by next_request position, used when ++ * determining if two or more queues have interleaving ++ * requests (see bfq_find_close_cooperator()). ++ * ++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup ++ * there is a set of bfq_groups, each one collecting the lower-level ++ * entities belonging to the group that are acting on the same device. ++ * ++ * Locking works as follows: ++ * o @bfqd is protected by the queue lock, RCU is used to access it ++ * from the readers. ++ * o All the other fields are protected by the @bfqd queue lock. ++ */ ++struct bfq_group { ++ /* must be the first member */ ++ struct blkg_policy_data pd; ++ ++ struct bfq_entity entity; ++ struct bfq_sched_data sched_data; ++ ++ void *bfqd; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct bfq_entity *my_entity; ++ ++ int active_entities; ++ ++ struct rb_root rq_pos_tree; ++ ++ struct bfqg_stats stats; ++}; ++ ++#else ++struct bfq_group { ++ struct bfq_sched_data sched_data; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct rb_root rq_pos_tree; ++}; ++#endif ++ ++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity); ++ ++static struct bfq_service_tree * ++bfq_entity_service_tree(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sched_data = entity->sched_data; ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned int idx = bfqq ? bfqq->ioprio_class - 1 : ++ BFQ_DEFAULT_GRP_CLASS - 1; ++ ++ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); ++ BUG_ON(sched_data == NULL); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "entity_service_tree %p %d", ++ sched_data->service_tree + idx, idx); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "entity_service_tree %p %d", ++ sched_data->service_tree + idx, idx); ++ } ++#endif ++ return sched_data->service_tree + idx; ++} ++ ++static struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, bool is_sync) ++{ ++ return bic->bfqq[is_sync]; ++} ++ ++static void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, ++ bool is_sync) ++{ ++ bic->bfqq[is_sync] = bfqq; ++} ++ ++static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) ++{ ++ return bic->icq.q->elevator->elevator_data; ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *group_entity = bfqq->entity.parent; ++ ++ if (!group_entity) ++ group_entity = &bfqq->bfqd->root_group->entity; ++ ++ return container_of(group_entity, struct bfq_group, entity); ++} ++ ++#else ++ ++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq) ++{ ++ return bfqq->bfqd->root_group; ++} ++ ++#endif ++ ++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio); ++static void bfq_put_queue(struct bfq_queue *bfqq); ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bio *bio, bool is_sync, ++ struct bfq_io_cq *bic); ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++#endif ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++ ++#endif /* _BFQ_H */ +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-ioc.c linux-4.8-bfq/block/bfq-ioc.c +--- linux-4.8/block/bfq-ioc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-ioc.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * BFQ: I/O context handling. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++/** ++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. ++ * @icq: the iocontext queue. ++ */ ++static struct bfq_io_cq *icq_to_bic(struct io_cq *icq) ++{ ++ /* bic->icq is the first member, %NULL will convert to %NULL */ ++ return container_of(icq, struct bfq_io_cq, icq); ++} ++ ++/** ++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. ++ * @bfqd: the lookup key. ++ * @ioc: the io_context of the process doing I/O. ++ * ++ * Queue lock must be held. ++ */ ++static struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, ++ struct io_context *ioc) ++{ ++ if (ioc) ++ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); ++ return NULL; ++} +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-iosched.c linux-4.8-bfq/block/bfq-iosched.c +--- linux-4.8/block/bfq-iosched.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-iosched.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,5288 @@ ++/* ++ * Budget Fair Queueing (BFQ) disk scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ * ++ * BFQ is a proportional-share storage-I/O scheduling algorithm based ++ * on the slice-by-slice service scheme of CFQ. But BFQ assigns ++ * budgets, measured in number of sectors, to processes instead of ++ * time slices. The device is not granted to the in-service process ++ * for a given time slice, but until it has exhausted its assigned ++ * budget. This change from the time to the service domain enables BFQ ++ * to distribute the device throughput among processes as desired, ++ * without any distortion due to throughput fluctuations, or to device ++ * internal queueing. BFQ uses an ad hoc internal scheduler, called ++ * B-WF2Q+, to schedule processes according to their budgets. More ++ * precisely, BFQ schedules queues associated with processes. Thanks to ++ * the accurate policy of B-WF2Q+, BFQ can afford to assign high ++ * budgets to I/O-bound processes issuing sequential requests (to ++ * boost the throughput), and yet guarantee a low latency to ++ * interactive and soft real-time applications. ++ * ++ * BFQ is described in [1], where also a reference to the initial, more ++ * theoretical paper on BFQ can be found. The interested reader can find ++ * in the latter paper full details on the main algorithm, as well as ++ * formulas of the guarantees and formal proofs of all the properties. ++ * With respect to the version of BFQ presented in these papers, this ++ * implementation adds a few more heuristics, such as the one that ++ * guarantees a low latency to soft real-time applications, and a ++ * hierarchical extension based on H-WF2Q+. ++ * ++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with ++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) ++ * complexity derives from the one introduced with EEVDF in [3]. ++ * ++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness ++ * with the BFQ Disk I/O Scheduler'', ++ * Proceedings of the 5th Annual International Systems and Storage ++ * Conference (SYSTOR '12), June 2012. ++ * ++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf ++ * ++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing ++ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, ++ * Oct 1997. ++ * ++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz ++ * ++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline ++ * First: A Flexible and Accurate Mechanism for Proportional Share ++ * Resource Allocation,'' technical report. ++ * ++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfq.h" ++#include "blk.h" ++ ++/* Expiration time of sync (0) and async (1) requests, in ns. */ ++static const u64 bfq_fifo_expire[2] = { NSEC_PER_SEC / 4, NSEC_PER_SEC / 8 }; ++ ++/* Maximum backwards seek, in KiB. */ ++static const int bfq_back_max = 16 * 1024; ++ ++/* Penalty of a backwards seek, in number of sectors. */ ++static const int bfq_back_penalty = 2; ++ ++/* Idling period duration, in ns. */ ++static u32 bfq_slice_idle = NSEC_PER_SEC / 125; ++ ++/* Minimum number of assigned budgets for which stats are safe to compute. */ ++static const int bfq_stats_min_budgets = 194; ++ ++/* Default maximum budget values, in sectors and number of requests. */ ++static const int bfq_default_max_budget = 16 * 1024; ++ ++/* ++ * Async to sync throughput distribution is controlled as follows: ++ * when an async request is served, the entity is charged the number ++ * of sectors of the request, multiplied by the factor below ++ */ ++static const int bfq_async_charge_factor = 10; ++ ++/* Default timeout values, in jiffies, approximating CFQ defaults. */ ++static const int bfq_timeout = HZ / 8; ++ ++struct kmem_cache *bfq_pool; ++ ++/* Below this threshold (in ns), we consider thinktime immediate. */ ++#define BFQ_MIN_TT (2 * NSEC_PER_MSEC) ++ ++/* hw_tag detection: parallel requests threshold and min samples needed. */ ++#define BFQ_HW_QUEUE_THRESHOLD 4 ++#define BFQ_HW_QUEUE_SAMPLES 32 ++ ++#define BFQQ_SEEK_THR (sector_t)(8 * 100) ++#define BFQQ_CLOSE_THR (sector_t)(8 * 1024) ++#define BFQQ_SEEKY(bfqq) (hweight32(bfqq->seek_history) > 32/8) ++ ++/* Min number of samples required to perform peak-rate update */ ++#define BFQ_RATE_MIN_SAMPLES 32 ++/* Min observation time interval required to perform a peak-rate update (ns) */ ++#define BFQ_RATE_MIN_INTERVAL 300*NSEC_PER_MSEC ++/* Target observation time interval for a peak-rate update (ns) */ ++#define BFQ_RATE_REF_INTERVAL NSEC_PER_SEC ++ ++/* Shift used for peak rate fixed precision calculations. */ ++#define BFQ_RATE_SHIFT 16 ++ ++/* ++ * By default, BFQ computes the duration of the weight raising for ++ * interactive applications automatically, using the following formula: ++ * duration = (R / r) * T, where r is the peak rate of the device, and ++ * R and T are two reference parameters. ++ * In particular, R is the peak rate of the reference device (see below), ++ * and T is a reference time: given the systems that are likely to be ++ * installed on the reference device according to its speed class, T is ++ * about the maximum time needed, under BFQ and while reading two files in ++ * parallel, to load typical large applications on these systems. ++ * In practice, the slower/faster the device at hand is, the more/less it ++ * takes to load applications with respect to the reference device. ++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive ++ * applications. ++ * ++ * BFQ uses four different reference pairs (R, T), depending on: ++ * . whether the device is rotational or non-rotational; ++ * . whether the device is slow, such as old or portable HDDs, as well as ++ * SD cards, or fast, such as newer HDDs and SSDs. ++ * ++ * The device's speed class is dynamically (re)detected in ++ * bfq_update_peak_rate() every time the estimated peak rate is updated. ++ * ++ * In the following definitions, R_slow[0]/R_fast[0] and ++ * T_slow[0]/T_fast[0] are the reference values for a slow/fast ++ * rotational device, whereas R_slow[1]/R_fast[1] and ++ * T_slow[1]/T_fast[1] are the reference values for a slow/fast ++ * non-rotational device. Finally, device_speed_thresh are the ++ * thresholds used to switch between speed classes. The reference ++ * rates are not the actual peak rates of the devices used as a ++ * reference, but slightly lower values. The reason for using these ++ * slightly lower values is that the peak-rate estimator tends to ++ * yield slightly lower values than the actual peak rate (it can yield ++ * the actual peak rate only if there is only one process doing I/O, ++ * and the process does sequential I/O). ++ * ++ * Both the reference peak rates and the thresholds are measured in ++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. ++ */ ++static int R_slow[2] = {1000, 10700}; ++static int R_fast[2] = {14000, 33000}; ++/* ++ * To improve readability, a conversion function is used to initialize the ++ * following arrays, which entails that they can be initialized only in a ++ * function. ++ */ ++static int T_slow[2]; ++static int T_fast[2]; ++static int device_speed_thresh[2]; ++ ++#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ ++ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) ++ ++#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) ++#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) ++ ++static void bfq_schedule_dispatch(struct bfq_data *bfqd); ++ ++#include "bfq-ioc.c" ++#include "bfq-sched.c" ++#include "bfq-cgroup.c" ++ ++#define bfq_class_idle(bfqq) ((bfqq)->ioprio_class == IOPRIO_CLASS_IDLE) ++#define bfq_class_rt(bfqq) ((bfqq)->ioprio_class == IOPRIO_CLASS_RT) ++ ++#define bfq_sample_valid(samples) ((samples) > 80) ++ ++/* ++ * We regard a request as SYNC, if either it's a read or has the SYNC bit ++ * set (in which case it could also be a direct WRITE). ++ */ ++static int bfq_bio_sync(struct bio *bio) ++{ ++ return bio_data_dir(bio) == READ || (bio->bi_opf & REQ_SYNC); ++} ++ ++/* ++ * Scheduler run of queue, if there are requests pending and no one in the ++ * driver that will restart queueing. ++ */ ++static void bfq_schedule_dispatch(struct bfq_data *bfqd) ++{ ++ if (bfqd->queued != 0) { ++ bfq_log(bfqd, "schedule dispatch"); ++ kblockd_schedule_work(&bfqd->unplug_work); ++ } ++} ++ ++/* ++ * Lifted from AS - choose which of rq1 and rq2 that is best served now. ++ * We choose the request that is closesr to the head right now. Distance ++ * behind the head is penalized and only allowed to a certain extent. ++ */ ++static struct request *bfq_choose_req(struct bfq_data *bfqd, ++ struct request *rq1, ++ struct request *rq2, ++ sector_t last) ++{ ++ sector_t s1, s2, d1 = 0, d2 = 0; ++ unsigned long back_max; ++#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ ++#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ ++ unsigned int wrap = 0; /* bit mask: requests behind the disk head? */ ++ ++ if (!rq1 || rq1 == rq2) ++ return rq2; ++ if (!rq2) ++ return rq1; ++ ++ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) ++ return rq1; ++ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) ++ return rq2; ++ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) ++ return rq1; ++ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) ++ return rq2; ++ ++ s1 = blk_rq_pos(rq1); ++ s2 = blk_rq_pos(rq2); ++ ++ /* ++ * By definition, 1KiB is 2 sectors. ++ */ ++ back_max = bfqd->bfq_back_max * 2; ++ ++ /* ++ * Strict one way elevator _except_ in the case where we allow ++ * short backward seeks which are biased as twice the cost of a ++ * similar forward seek. ++ */ ++ if (s1 >= last) ++ d1 = s1 - last; ++ else if (s1 + back_max >= last) ++ d1 = (last - s1) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ1_WRAP; ++ ++ if (s2 >= last) ++ d2 = s2 - last; ++ else if (s2 + back_max >= last) ++ d2 = (last - s2) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ2_WRAP; ++ ++ /* Found required data */ ++ ++ /* ++ * By doing switch() on the bit mask "wrap" we avoid having to ++ * check two variables for all permutations: --> faster! ++ */ ++ switch (wrap) { ++ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ ++ if (d1 < d2) ++ return rq1; ++ else if (d2 < d1) ++ return rq2; ++ ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; ++ ++ case BFQ_RQ2_WRAP: ++ return rq1; ++ case BFQ_RQ1_WRAP: ++ return rq2; ++ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ ++ default: ++ /* ++ * Since both rqs are wrapped, ++ * start with the one that's further behind head ++ * (--> only *one* back seek required), ++ * since back seek takes more time than forward. ++ */ ++ if (s1 <= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++} ++ ++static struct bfq_queue * ++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, ++ sector_t sector, struct rb_node **ret_parent, ++ struct rb_node ***rb_link) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *bfqq = NULL; ++ ++ parent = NULL; ++ p = &root->rb_node; ++ while (*p) { ++ struct rb_node **n; ++ ++ parent = *p; ++ bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ ++ /* ++ * Sort strictly based on sector. Smallest to the left, ++ * largest to the right. ++ */ ++ if (sector > blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_right; ++ else if (sector < blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_left; ++ else ++ break; ++ p = n; ++ bfqq = NULL; ++ } ++ ++ *ret_parent = parent; ++ if (rb_link) ++ *rb_link = p; ++ ++ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", ++ (unsigned long long) sector, ++ bfqq ? bfqq->pid : 0); ++ ++ return bfqq; ++} ++ ++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *__bfqq; ++ ++ if (bfqq->pos_root) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ ++ if (bfq_class_idle(bfqq)) ++ return; ++ if (!bfqq->next_rq) ++ return; ++ ++ bfqq->pos_root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree; ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, ++ blk_rq_pos(bfqq->next_rq), &parent, &p); ++ if (!__bfqq) { ++ rb_link_node(&bfqq->pos_node, parent, p); ++ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); ++ } else ++ bfqq->pos_root = NULL; ++} ++ ++/* ++ * Tell whether there are active queues or groups with differentiated weights. ++ */ ++static bool bfq_differentiated_weights(struct bfq_data *bfqd) ++{ ++ /* ++ * For weights to differ, at least one of the trees must contain ++ * at least two nodes. ++ */ ++ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && ++ (bfqd->queue_weights_tree.rb_node->rb_left || ++ bfqd->queue_weights_tree.rb_node->rb_right) ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ) || ++ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && ++ (bfqd->group_weights_tree.rb_node->rb_left || ++ bfqd->group_weights_tree.rb_node->rb_right) ++#endif ++ ); ++} ++ ++/* ++ * The following function returns true if every queue must receive the ++ * same share of the throughput (this condition is used when deciding ++ * whether idling may be disabled, see the comments in the function ++ * bfq_bfqq_may_idle()). ++ * ++ * Such a scenario occurs when: ++ * 1) all active queues have the same weight, ++ * 2) all active groups at the same level in the groups tree have the same ++ * weight, ++ * 3) all active groups at the same level in the groups tree have the same ++ * number of children. ++ * ++ * Unfortunately, keeping the necessary state for evaluating exactly the ++ * above symmetry conditions would be quite complex and time-consuming. ++ * Therefore this function evaluates, instead, the following stronger ++ * sub-conditions, for which it is much easier to maintain the needed ++ * state: ++ * 1) all active queues have the same weight, ++ * 2) all active groups have the same weight, ++ * 3) all active groups have at most one active child each. ++ * In particular, the last two conditions are always true if hierarchical ++ * support and the cgroups interface are not enabled, thus no state needs ++ * to be maintained in this case. ++ */ ++static bool bfq_symmetric_scenario(struct bfq_data *bfqd) ++{ ++ return !bfq_differentiated_weights(bfqd); ++} ++ ++/* ++ * If the weight-counter tree passed as input contains no counter for ++ * the weight of the input entity, then add that counter; otherwise just ++ * increment the existing counter. ++ * ++ * Note that weight-counter trees contain few nodes in mostly symmetric ++ * scenarios. For example, if all queues have the same weight, then the ++ * weight-counter tree for the queues may contain at most one node. ++ * This holds even if low_latency is on, because weight-raised queues ++ * are not inserted in the tree. ++ * In most scenarios, the rate at which nodes are created/destroyed ++ * should be low too. ++ */ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ struct rb_node **new = &(root->rb_node), *parent = NULL; ++ ++ /* ++ * Do not insert if the entity is already associated with a ++ * counter, which happens if: ++ * 1) the entity is associated with a queue, ++ * 2) a request arrival has caused the queue to become both ++ * non-weight-raised, and hence change its weight, and ++ * backlogged; in this respect, each of the two events ++ * causes an invocation of this function, ++ * 3) this is the invocation of this function caused by the ++ * second event. This second invocation is actually useless, ++ * and we handle this fact by exiting immediately. More ++ * efficient or clearer solutions might possibly be adopted. ++ */ ++ if (entity->weight_counter) ++ return; ++ ++ while (*new) { ++ struct bfq_weight_counter *__counter = container_of(*new, ++ struct bfq_weight_counter, ++ weights_node); ++ parent = *new; ++ ++ if (entity->weight == __counter->weight) { ++ entity->weight_counter = __counter; ++ goto inc_counter; ++ } ++ if (entity->weight < __counter->weight) ++ new = &((*new)->rb_left); ++ else ++ new = &((*new)->rb_right); ++ } ++ ++ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), ++ GFP_ATOMIC); ++ entity->weight_counter->weight = entity->weight; ++ rb_link_node(&entity->weight_counter->weights_node, parent, new); ++ rb_insert_color(&entity->weight_counter->weights_node, root); ++ ++inc_counter: ++ entity->weight_counter->num_active++; ++} ++ ++/* ++ * Decrement the weight counter associated with the entity, and, if the ++ * counter reaches 0, remove the counter from the tree. ++ * See the comments to the function bfq_weights_tree_add() for considerations ++ * about overhead. ++ */ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ if (!entity->weight_counter) ++ return; ++ ++ BUG_ON(RB_EMPTY_ROOT(root)); ++ BUG_ON(entity->weight_counter->weight != entity->weight); ++ ++ BUG_ON(!entity->weight_counter->num_active); ++ entity->weight_counter->num_active--; ++ if (entity->weight_counter->num_active > 0) ++ goto reset_entity_pointer; ++ ++ rb_erase(&entity->weight_counter->weights_node, root); ++ kfree(entity->weight_counter); ++ ++reset_entity_pointer: ++ entity->weight_counter = NULL; ++} ++ ++static struct request *bfq_find_next_rq(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *last) ++{ ++ struct rb_node *rbnext = rb_next(&last->rb_node); ++ struct rb_node *rbprev = rb_prev(&last->rb_node); ++ struct request *next = NULL, *prev = NULL; ++ ++ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); ++ ++ if (rbprev) ++ prev = rb_entry_rq(rbprev); ++ ++ if (rbnext) ++ next = rb_entry_rq(rbnext); ++ else { ++ rbnext = rb_first(&bfqq->sort_list); ++ if (rbnext && rbnext != &last->rb_node) ++ next = rb_entry_rq(rbnext); ++ } ++ ++ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); ++} ++ ++/* see the definition of bfq_async_charge_factor for details */ ++static unsigned long bfq_serv_to_charge(struct request *rq, ++ struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_sync(bfqq) || bfqq->wr_coeff > 1) ++ return blk_rq_sectors(rq); ++ ++ /* ++ * If there are no weight-raised queues, then amplify service ++ * by just the async charge factor; otherwise amplify service ++ * by twice the async charge factor, to further reduce latency ++ * for weight-raised queues. ++ */ ++ if (bfqq->bfqd->wr_busy_queues == 0) ++ return blk_rq_sectors(rq) * bfq_async_charge_factor; ++ ++ return blk_rq_sectors(rq) * 2 * bfq_async_charge_factor; ++} ++ ++/** ++ * bfq_updated_next_req - update the queue after a new next_rq selection. ++ * @bfqd: the device data the queue belongs to. ++ * @bfqq: the queue to update. ++ * ++ * If the first request of a queue changes we make sure that the queue ++ * has enough budget to serve at least its first request (if the ++ * request has grown). We do this because if the queue has not enough ++ * budget for its first request, it has to go through two dispatch ++ * rounds to actually get it dispatched. ++ */ ++static void bfq_updated_next_req(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct request *next_rq = bfqq->next_rq; ++ unsigned long new_budget; ++ ++ if (!next_rq) ++ return; ++ ++ if (bfqq == bfqd->in_service_queue) ++ /* ++ * In order not to break guarantees, budgets cannot be ++ * changed after an entity has been selected. ++ */ ++ return; ++ ++ BUG_ON(entity->tree != &st->active); ++ BUG_ON(entity == entity->sched_data->in_service_entity); ++ ++ new_budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ if (entity->budget != new_budget) { ++ entity->budget = new_budget; ++ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", ++ new_budget); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++} ++ ++static unsigned int bfq_wr_duration(struct bfq_data *bfqd) ++{ ++ u64 dur; ++ ++ if (bfqd->bfq_wr_max_time > 0) ++ return bfqd->bfq_wr_max_time; ++ ++ dur = bfqd->RT_prod; ++ do_div(dur, bfqd->peak_rate); ++ ++ /* ++ * Limit duration between 3 and 13 seconds. Tests show that ++ * higher values than 13 seconds often yield the opposite of ++ * the desired result, i.e., worsen responsiveness by letting ++ * non-interactive and non-soft-real-time applications ++ * preserve weight raising for a too long time interval. ++ * ++ * On the other end, lower values than 3 seconds make it ++ * difficult for most interactive tasks to complete their jobs ++ * before weight-raising finishes. ++ */ ++ if (dur > msecs_to_jiffies(13000)) ++ dur = msecs_to_jiffies(13000); ++ else if (dur < msecs_to_jiffies(3000)) ++ dur = msecs_to_jiffies(3000); ++ ++ return dur; ++} ++ ++static void ++bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ if (bic->saved_idle_window) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++ ++ if (bic->saved_IO_bound) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ else ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ bfqq->wr_coeff = bic->saved_wr_coeff; ++ bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt; ++ BUG_ON(time_is_after_jiffies(bfqq->wr_start_at_switch_to_srt)); ++ bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) || ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time))) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "resume state: switching off wr"); ++ ++ bfqq->wr_coeff = 1; ++ } ++ /* make sure weight will be updated, however we got here */ ++ bfqq->entity.prio_changed = 1; ++} ++ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ lockdep_assert_held(bfqq->bfqd->queue->queue_lock); ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = bfqq->ref - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ ++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ ++static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *item; ++ struct hlist_node *n; ++ ++ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) ++ hlist_del_init(&item->burst_list_node); ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++ bfqd->burst_size = 1; ++ bfqd->burst_parent_entity = bfqq->entity.parent; ++} ++ ++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ ++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* Increment burst size to take into account also bfqq */ ++ bfqd->burst_size++; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_to_burst %d", bfqd->burst_size); ++ ++ BUG_ON(bfqd->burst_size > bfqd->bfq_large_burst_thresh); ++ ++ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { ++ struct bfq_queue *pos, *bfqq_item; ++ struct hlist_node *n; ++ ++ /* ++ * Enough queues have been activated shortly after each ++ * other to consider this burst as large. ++ */ ++ bfqd->large_burst = true; ++ bfq_log_bfqq(bfqd, bfqq, "add_to_burst: large burst started"); ++ ++ /* ++ * We can now mark all queues in the burst list as ++ * belonging to a large burst. ++ */ ++ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, ++ burst_list_node) { ++ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_log_bfqq(bfqd, bfqq_item, "marked in large burst"); ++ } ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ bfq_log_bfqq(bfqd, bfqq, "marked in large burst"); ++ ++ /* ++ * From now on, and until the current burst finishes, any ++ * new queue being activated shortly after the last queue ++ * was inserted in the burst can be immediately marked as ++ * belonging to a large burst. So the burst list is not ++ * needed any more. Remove it. ++ */ ++ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, ++ burst_list_node) ++ hlist_del_init(&pos->burst_list_node); ++ } else /* ++ * Burst not yet large: add bfqq to the burst list. Do ++ * not increment the ref counter for bfqq, because bfqq ++ * is removed from the burst list before freeing bfqq ++ * in put_queue. ++ */ ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++} ++ ++/* ++ * If many queues belonging to the same group happen to be created ++ * shortly after each other, then the processes associated with these ++ * queues have typically a common goal. In particular, bursts of queue ++ * creations are usually caused by services or applications that spawn ++ * many parallel threads/processes. Examples are systemd during boot, ++ * or git grep. To help these processes get their job done as soon as ++ * possible, it is usually better to not grant either weight-raising ++ * or device idling to their queues. ++ * ++ * In this comment we describe, firstly, the reasons why this fact ++ * holds, and, secondly, the next function, which implements the main ++ * steps needed to properly mark these queues so that they can then be ++ * treated in a different way. ++ * ++ * The above services or applications benefit mostly from a high ++ * throughput: the quicker the requests of the activated queues are ++ * cumulatively served, the sooner the target job of these queues gets ++ * completed. As a consequence, weight-raising any of these queues, ++ * which also implies idling the device for it, is almost always ++ * counterproductive. In most cases it just lowers throughput. ++ * ++ * On the other hand, a burst of queue creations may be caused also by ++ * the start of an application that does not consist of a lot of ++ * parallel I/O-bound threads. In fact, with a complex application, ++ * several short processes may need to be executed to start-up the ++ * application. In this respect, to start an application as quickly as ++ * possible, the best thing to do is in any case to privilege the I/O ++ * related to the application with respect to all other ++ * I/O. Therefore, the best strategy to start as quickly as possible ++ * an application that causes a burst of queue creations is to ++ * weight-raise all the queues created during the burst. This is the ++ * exact opposite of the best strategy for the other type of bursts. ++ * ++ * In the end, to take the best action for each of the two cases, the ++ * two types of bursts need to be distinguished. Fortunately, this ++ * seems relatively easy, by looking at the sizes of the bursts. In ++ * particular, we found a threshold such that only bursts with a ++ * larger size than that threshold are apparently caused by ++ * services or commands such as systemd or git grep. For brevity, ++ * hereafter we call just 'large' these bursts. BFQ *does not* ++ * weight-raise queues whose creation occurs in a large burst. In ++ * addition, for each of these queues BFQ performs or does not perform ++ * idling depending on which choice boosts the throughput more. The ++ * exact choice depends on the device and request pattern at ++ * hand. ++ * ++ * Unfortunately, false positives may occur while an interactive task ++ * is starting (e.g., an application is being started). The ++ * consequence is that the queues associated with the task do not ++ * enjoy weight raising as expected. Fortunately these false positives ++ * are very rare. They typically occur if some service happens to ++ * start doing I/O exactly when the interactive task starts. ++ * ++ * Turning back to the next function, it implements all the steps ++ * needed to detect the occurrence of a large burst and to properly ++ * mark all the queues belonging to it (so that they can then be ++ * treated in a different way). This goal is achieved by maintaining a ++ * "burst list" that holds, temporarily, the queues that belong to the ++ * burst in progress. The list is then used to mark these queues as ++ * belonging to a large burst if the burst does become large. The main ++ * steps are the following. ++ * ++ * . when the very first queue is created, the queue is inserted into the ++ * list (as it could be the first queue in a possible burst) ++ * ++ * . if the current burst has not yet become large, and a queue Q that does ++ * not yet belong to the burst is activated shortly after the last time ++ * at which a new queue entered the burst list, then the function appends ++ * Q to the burst list ++ * ++ * . if, as a consequence of the previous step, the burst size reaches ++ * the large-burst threshold, then ++ * ++ * . all the queues in the burst list are marked as belonging to a ++ * large burst ++ * ++ * . the burst list is deleted; in fact, the burst list already served ++ * its purpose (keeping temporarily track of the queues in a burst, ++ * so as to be able to mark them as belonging to a large burst in the ++ * previous sub-step), and now is not needed any more ++ * ++ * . the device enters a large-burst mode ++ * ++ * . if a queue Q that does not belong to the burst is created while ++ * the device is in large-burst mode and shortly after the last time ++ * at which a queue either entered the burst list or was marked as ++ * belonging to the current large burst, then Q is immediately marked ++ * as belonging to a large burst. ++ * ++ * . if a queue Q that does not belong to the burst is created a while ++ * later, i.e., not shortly after, than the last time at which a queue ++ * either entered the burst list or was marked as belonging to the ++ * current large burst, then the current burst is deemed as finished and: ++ * ++ * . the large-burst mode is reset if set ++ * ++ * . the burst list is emptied ++ * ++ * . Q is inserted in the burst list, as Q may be the first queue ++ * in a possible new burst (then the burst list contains just Q ++ * after this step). ++ */ ++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq is already in the burst list or is part of a large ++ * burst, or finally has just been split, then there is ++ * nothing else to do. ++ */ ++ if (!hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq) || ++ time_is_after_eq_jiffies(bfqq->split_time + ++ msecs_to_jiffies(10))) ++ return; ++ ++ /* ++ * If bfqq's creation happens late enough, or bfqq belongs to ++ * a different group than the burst group, then the current ++ * burst is finished, and related data structures must be ++ * reset. ++ * ++ * In this respect, consider the special case where bfqq is ++ * the very first queue created after BFQ is selected for this ++ * device. In this case, last_ins_in_burst and ++ * burst_parent_entity are not yet significant when we get ++ * here. But it is easy to verify that, whether or not the ++ * following condition is true, bfqq will end up being ++ * inserted into the burst list. In particular the list will ++ * happen to contain only bfqq. And this is exactly what has ++ * to happen, as bfqq may be the first queue of the first ++ * burst. ++ */ ++ if (time_is_before_jiffies(bfqd->last_ins_in_burst + ++ bfqd->bfq_burst_interval) || ++ bfqq->entity.parent != bfqd->burst_parent_entity) { ++ bfqd->large_burst = false; ++ bfq_reset_burst_list(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, ++ "handle_burst: late activation or different group"); ++ goto end; ++ } ++ ++ /* ++ * If we get here, then bfqq is being activated shortly after the ++ * last queue. So, if the current burst is also large, we can mark ++ * bfqq as belonging to this large burst immediately. ++ */ ++ if (bfqd->large_burst) { ++ bfq_log_bfqq(bfqd, bfqq, "handle_burst: marked in burst"); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ goto end; ++ } ++ ++ /* ++ * If we get here, then a large-burst state has not yet been ++ * reached, but bfqq is being activated shortly after the last ++ * queue. Then we add bfqq to the burst. ++ */ ++ bfq_add_to_burst(bfqd, bfqq); ++end: ++ /* ++ * At this point, bfqq either has been added to the current ++ * burst or has caused the current burst to terminate and a ++ * possible new burst to start. In particular, in the second ++ * case, bfqq has become the first queue in the possible new ++ * burst. In both cases last_ins_in_burst needs to be moved ++ * forward. ++ */ ++ bfqd->last_ins_in_burst = jiffies; ++ ++} ++ ++static int bfq_bfqq_budget_left(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ return entity->budget - entity->service; ++} ++ ++/* ++ * If enough samples have been computed, return the current max budget ++ * stored in bfqd, which is dynamically updated according to the ++ * estimated disk peak rate; otherwise return the default max budget ++ */ ++static int bfq_max_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < bfq_stats_min_budgets) ++ return bfq_default_max_budget; ++ else ++ return bfqd->bfq_max_budget; ++} ++ ++/* ++ * Return min budget, which is a fraction of the current or default ++ * max budget (trying with 1/32) ++ */ ++static int bfq_min_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < bfq_stats_min_budgets) ++ return bfq_default_max_budget / 32; ++ else ++ return bfqd->bfq_max_budget / 32; ++} ++ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason); ++ ++/* ++ * The next function, invoked after the input queue bfqq switches from ++ * idle to busy, updates the budget of bfqq. The function also tells ++ * whether the in-service queue should be expired, by returning ++ * true. The purpose of expiring the in-service queue is to give bfqq ++ * the chance to possibly preempt the in-service queue, and the reason ++ * for preempting the in-service queue is to achieve one of the two ++ * goals below. ++ * ++ * 1. Guarantee to bfqq its reserved bandwidth even if bfqq has ++ * expired because it has remained idle. In particular, bfqq may have ++ * expired for one of the following two reasons: ++ * ++ * - BFQ_BFQQ_NO_MORE_REQUEST bfqq did not enjoy any device idling and ++ * did not make it to issue a new request before its last request ++ * was served; ++ * ++ * - BFQ_BFQQ_TOO_IDLE bfqq did enjoy device idling, but did not issue ++ * a new request before the expiration of the idling-time. ++ * ++ * Even if bfqq has expired for one of the above reasons, the process ++ * associated with the queue may be however issuing requests greedily, ++ * and thus be sensitive to the bandwidth it receives (bfqq may have ++ * remained idle for other reasons: CPU high load, bfqq not enjoying ++ * idling, I/O throttling somewhere in the path from the process to ++ * the I/O scheduler, ...). But if, after every expiration for one of ++ * the above two reasons, bfqq has to wait for the service of at least ++ * one full budget of another queue before being served again, then ++ * bfqq is likely to get a much lower bandwidth or resource time than ++ * its reserved ones. To address this issue, two countermeasures need ++ * to be taken. ++ * ++ * First, the budget and the timestamps of bfqq need to be updated in ++ * a special way on bfqq reactivation: they need to be updated as if ++ * bfqq did not remain idle and did not expire. In fact, if they are ++ * computed as if bfqq expired and remained idle until reactivation, ++ * then the process associated with bfqq is treated as if, instead of ++ * being greedy, it stopped issuing requests when bfqq remained idle, ++ * and restarts issuing requests only on this reactivation. In other ++ * words, the scheduler does not help the process recover the "service ++ * hole" between bfqq expiration and reactivation. As a consequence, ++ * the process receives a lower bandwidth than its reserved one. In ++ * contrast, to recover this hole, the budget must be updated as if ++ * bfqq was not expired at all before this reactivation, i.e., it must ++ * be set to the value of the remaining budget when bfqq was ++ * expired. Along the same line, timestamps need to be assigned the ++ * value they had the last time bfqq was selected for service, i.e., ++ * before last expiration. Thus timestamps need to be back-shifted ++ * with respect to their normal computation (see [1] for more details ++ * on this tricky aspect). ++ * ++ * Secondly, to allow the process to recover the hole, the in-service ++ * queue must be expired too, to give bfqq the chance to preempt it ++ * immediately. In fact, if bfqq has to wait for a full budget of the ++ * in-service queue to be completed, then it may become impossible to ++ * let the process recover the hole, even if the back-shifted ++ * timestamps of bfqq are lower than those of the in-service queue. If ++ * this happens for most or all of the holes, then the process may not ++ * receive its reserved bandwidth. In this respect, it is worth noting ++ * that, being the service of outstanding requests unpreemptible, a ++ * little fraction of the holes may however be unrecoverable, thereby ++ * causing a little loss of bandwidth. ++ * ++ * The last important point is detecting whether bfqq does need this ++ * bandwidth recovery. In this respect, the next function deems the ++ * process associated with bfqq greedy, and thus allows it to recover ++ * the hole, if: 1) the process is waiting for the arrival of a new ++ * request (which implies that bfqq expired for one of the above two ++ * reasons), and 2) such a request has arrived soon. The first ++ * condition is controlled through the flag non_blocking_wait_rq, ++ * while the second through the flag arrived_in_time. If both ++ * conditions hold, then the function computes the budget in the ++ * above-described special way, and signals that the in-service queue ++ * should be expired. Timestamp back-shifting is done later in ++ * __bfq_activate_entity. ++ * ++ * 2. Reduce latency. Even if timestamps are not backshifted to let ++ * the process associated with bfqq recover a service hole, bfqq may ++ * however happen to have, after being (re)activated, a lower finish ++ * timestamp than the in-service queue. That is, the next budget of ++ * bfqq may have to be completed before the one of the in-service ++ * queue. If this is the case, then preempting the in-service queue ++ * allows this goal to be achieved, apart from the unpreemptible, ++ * outstanding requests mentioned above. ++ * ++ * Unfortunately, regardless of which of the above two goals one wants ++ * to achieve, service trees need first to be updated to know whether ++ * the in-service queue must be preempted. To have service trees ++ * correctly updated, the in-service queue must be expired and ++ * rescheduled, and bfqq must be scheduled too. This is one of the ++ * most costly operations (in future versions, the scheduling ++ * mechanism may be re-designed in such a way to make it possible to ++ * know whether preemption is needed without needing to update service ++ * trees). In addition, queue preemptions almost always cause random ++ * I/O, and thus loss of throughput. Because of these facts, the next ++ * function adopts the following simple scheme to avoid both costly ++ * operations and too frequent preemptions: it requests the expiration ++ * of the in-service queue (unconditionally) only for queues that need ++ * to recover a hole, or that either are weight-raised or deserve to ++ * be weight-raised. ++ */ ++static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool arrived_in_time, ++ bool wr_or_deserves_wr) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfq_bfqq_non_blocking_wait_rq(bfqq) && arrived_in_time) { ++ /* ++ * We do not clear the flag non_blocking_wait_rq here, as ++ * the latter is used in bfq_activate_bfqq to signal ++ * that timestamps need to be back-shifted (and is ++ * cleared right after). ++ */ ++ ++ /* ++ * In next assignment we rely on that either ++ * entity->service or entity->budget are not updated ++ * on expiration if bfqq is empty (see ++ * __bfq_bfqq_recalc_budget). Thus both quantities ++ * remain unchanged after such an expiration, and the ++ * following statement therefore assigns to ++ * entity->budget the remaining budget on such an ++ * expiration. For clarity, entity->service is not ++ * updated on expiration in any case, and, in normal ++ * operation, is reset only when bfqq is selected for ++ * service (see bfq_get_next_queue). ++ */ ++ BUG_ON(bfqq->max_budget < 0); ++ entity->budget = min_t(unsigned long, ++ bfq_bfqq_budget_left(bfqq), ++ bfqq->max_budget); ++ ++ BUG_ON(entity->budget < 0); ++ return true; ++ } ++ ++ BUG_ON(bfqq->max_budget < 0); ++ entity->budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(bfqq->next_rq, bfqq)); ++ BUG_ON(entity->budget < 0); ++ ++ bfq_clear_bfqq_non_blocking_wait_rq(bfqq); ++ return wr_or_deserves_wr; ++} ++ ++static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ unsigned int old_wr_coeff, ++ bool wr_or_deserves_wr, ++ bool interactive, ++ bool in_burst, ++ bool soft_rt) ++{ ++ if (old_wr_coeff == 1 && wr_or_deserves_wr) { ++ /* start a weight-raising period */ ++ if (interactive) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ } else { ++ bfqq->wr_start_at_switch_to_srt = jiffies; ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff * ++ BFQ_SOFTRT_WEIGHT_FACTOR; ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ } ++ /* ++ * If needed, further reduce budget to make sure it is ++ * close to bfqq's backlog, so as to reduce the ++ * scheduling-error component due to a too large ++ * budget. Do not care about throughput consequences, ++ * but only about latency. Finally, do not assign a ++ * too small budget either, to avoid increasing ++ * latency by causing too frequent expirations. ++ */ ++ bfqq->entity.budget = min_t(unsigned long, ++ bfqq->entity.budget, ++ 2 * bfq_min_budget(bfqd)); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } else if (old_wr_coeff > 1) { ++ if (interactive) { /* update wr coeff and duration */ ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ } else if (in_burst) { ++ bfqq->wr_coeff = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq-> ++ wr_cur_max_time)); ++ } else if (soft_rt) { ++ /* ++ * The application is now or still meeting the ++ * requirements for being deemed soft rt. We ++ * can then correctly and safely (re)charge ++ * the weight-raising duration for the ++ * application with the weight-raising ++ * duration for soft rt applications. ++ * ++ * In particular, doing this recharge now, i.e., ++ * before the weight-raising period for the ++ * application finishes, reduces the probability ++ * of the following negative scenario: ++ * 1) the weight of a soft rt application is ++ * raised at startup (as for any newly ++ * created application), ++ * 2) since the application is not interactive, ++ * at a certain time weight-raising is ++ * stopped for the application, ++ * 3) at that time the application happens to ++ * still have pending requests, and hence ++ * is destined to not have a chance to be ++ * deemed soft rt before these requests are ++ * completed (see the comments to the ++ * function bfq_bfqq_softrt_next_start() ++ * for details on soft rt detection), ++ * 4) these pending requests experience a high ++ * latency because the application is not ++ * weight-raised while they are pending. ++ */ ++ if (bfqq->wr_cur_max_time != ++ bfqd->bfq_wr_rt_max_time) { ++ bfqq->wr_start_at_switch_to_srt = ++ bfqq->last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff * ++ BFQ_SOFTRT_WEIGHT_FACTOR; ++ bfq_log_bfqq(bfqd, bfqq, ++ "switching to soft_rt wr"); ++ } else ++ bfq_log_bfqq(bfqd, bfqq, ++ "moving forward soft_rt wr duration"); ++ bfqq->last_wr_start_finish = jiffies; ++ } ++ } ++} ++ ++static bool bfq_bfqq_idle_for_long_time(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ return bfqq->dispatched == 0 && ++ time_is_before_jiffies( ++ bfqq->budget_timeout + ++ bfqd->bfq_wr_min_idle_time); ++} ++ ++static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ int old_wr_coeff, ++ struct request *rq, ++ bool *interactive) ++{ ++ bool soft_rt, in_burst, wr_or_deserves_wr, ++ bfqq_wants_to_preempt, ++ idle_for_long_time = bfq_bfqq_idle_for_long_time(bfqd, bfqq), ++ /* ++ * See the comments on ++ * bfq_bfqq_update_budg_for_activation for ++ * details on the usage of the next variable. ++ */ ++ arrived_in_time = ktime_get_ns() <= ++ RQ_BIC(rq)->ttime.last_end_request + ++ bfqd->bfq_slice_idle * 3; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "bfq_add_request non-busy: " ++ "jiffies %lu, in_time %d, idle_long %d busyw %d " ++ "wr_coeff %u", ++ jiffies, arrived_in_time, ++ idle_for_long_time, ++ bfq_bfqq_non_blocking_wait_rq(bfqq), ++ old_wr_coeff); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq, ++ req_op(rq), rq->cmd_flags); ++ ++ /* ++ * bfqq deserves to be weight-raised if: ++ * - it is sync, ++ * - it does not belong to a large burst, ++ * - it has been idle for enough time or is soft real-time, ++ * - is linked to a bfq_io_cq (it is not shared in any sense) ++ */ ++ in_burst = bfq_bfqq_in_large_burst(bfqq); ++ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && ++ !in_burst && ++ time_is_before_jiffies(bfqq->soft_rt_next_start); ++ *interactive = ++ !in_burst && ++ idle_for_long_time; ++ wr_or_deserves_wr = bfqd->low_latency && ++ (bfqq->wr_coeff > 1 || ++ (bfq_bfqq_sync(bfqq) && ++ bfqq->bic && (*interactive || soft_rt))); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "bfq_add_request: " ++ "in_burst %d, " ++ "soft_rt %d (next %lu), inter %d, bic %p", ++ bfq_bfqq_in_large_burst(bfqq), soft_rt, ++ bfqq->soft_rt_next_start, ++ *interactive, ++ bfqq->bic); ++ ++ /* ++ * Using the last flag, update budget and check whether bfqq ++ * may want to preempt the in-service queue. ++ */ ++ bfqq_wants_to_preempt = ++ bfq_bfqq_update_budg_for_activation(bfqd, bfqq, ++ arrived_in_time, ++ wr_or_deserves_wr); ++ ++ /* ++ * If bfqq happened to be activated in a burst, but has been ++ * idle for much more than an interactive queue, then we ++ * assume that, in the overall I/O initiated in the burst, the ++ * I/O associated with bfqq is finished. So bfqq does not need ++ * to be treated as a queue belonging to a burst ++ * anymore. Accordingly, we reset bfqq's in_large_burst flag ++ * if set, and remove bfqq from the burst list if it's ++ * there. We do not decrement burst_size, because the fact ++ * that bfqq does not need to belong to the burst list any ++ * more does not invalidate the fact that bfqq was created in ++ * a burst. ++ */ ++ if (likely(!bfq_bfqq_just_created(bfqq)) && ++ idle_for_long_time && ++ time_is_before_jiffies( ++ bfqq->budget_timeout + ++ msecs_to_jiffies(10000))) { ++ hlist_del_init(&bfqq->burst_list_node); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ } ++ ++ bfq_clear_bfqq_just_created(bfqq); ++ ++ if (!bfq_bfqq_IO_bound(bfqq)) { ++ if (arrived_in_time) { ++ bfqq->requests_within_timer++; ++ if (bfqq->requests_within_timer >= ++ bfqd->bfq_requests_within_timer) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ } else ++ bfqq->requests_within_timer = 0; ++ bfq_log_bfqq(bfqd, bfqq, "requests in time %d", ++ bfqq->requests_within_timer); ++ } ++ ++ if (bfqd->low_latency) { ++ if (unlikely(time_is_after_jiffies(bfqq->split_time))) ++ /* wraparound */ ++ bfqq->split_time = ++ jiffies - bfqd->bfq_wr_min_idle_time - 1; ++ ++ if (time_is_before_jiffies(bfqq->split_time + ++ bfqd->bfq_wr_min_idle_time)) { ++ bfq_update_bfqq_wr_on_rq_arrival(bfqd, bfqq, ++ old_wr_coeff, ++ wr_or_deserves_wr, ++ *interactive, ++ in_burst, ++ soft_rt); ++ ++ if (old_wr_coeff != bfqq->wr_coeff) ++ bfqq->entity.prio_changed = 1; ++ } ++ } ++ ++ bfqq->last_idle_bklogged = jiffies; ++ bfqq->service_from_backlogged = 0; ++ bfq_clear_bfqq_softrt_update(bfqq); ++ ++ bfq_add_bfqq_busy(bfqd, bfqq); ++ ++ /* ++ * Expire in-service queue only if preemption may be needed ++ * for guarantees. In this respect, the function ++ * next_queue_may_preempt just checks a simple, necessary ++ * condition, and not a sufficient condition based on ++ * timestamps. In fact, for the latter condition to be ++ * evaluated, timestamps would need first to be updated, and ++ * this operation is quite costly (see the comments on the ++ * function bfq_bfqq_update_budg_for_activation). ++ */ ++ if (bfqd->in_service_queue && bfqq_wants_to_preempt && ++ bfqd->in_service_queue->wr_coeff < bfqq->wr_coeff && ++ next_queue_may_preempt(bfqd)) { ++ struct bfq_queue *in_serv = ++ bfqd->in_service_queue; ++ BUG_ON(in_serv == bfqq); ++ ++ bfq_bfqq_expire(bfqd, bfqd->in_service_queue, ++ false, BFQ_BFQQ_PREEMPTED); ++ BUG_ON(in_serv->entity.budget < 0); ++ } ++} ++ ++static void bfq_add_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *next_rq, *prev; ++ unsigned int old_wr_coeff = bfqq->wr_coeff; ++ bool interactive = false; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_request: size %u %s", ++ blk_rq_sectors(rq), rq_is_sync(rq) ? "S" : "A"); ++ ++ if (bfqq->wr_coeff > 1) /* queue is being weight-raised */ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ bfqq->queued[rq_is_sync(rq)]++; ++ bfqd->queued++; ++ ++ elv_rb_add(&bfqq->sort_list, rq); ++ ++ /* ++ * Check if this request is a better next-to-serve candidate. ++ */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); ++ BUG_ON(!next_rq); ++ bfqq->next_rq = next_rq; ++ ++ /* ++ * Adjust priority tree position, if next_rq changes. ++ */ ++ if (prev != bfqq->next_rq) ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ ++ if (!bfq_bfqq_busy(bfqq)) /* switching to busy ... */ ++ bfq_bfqq_handle_idle_busy_switch(bfqd, bfqq, old_wr_coeff, ++ rq, &interactive); ++ else { ++ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && ++ time_is_before_jiffies( ++ bfqq->last_wr_start_finish + ++ bfqd->bfq_wr_min_inter_arr_async)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ ++ bfqd->wr_busy_queues++; ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "non-idle wrais starting, " ++ "wr_max_time %u wr_busy %d", ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqd->wr_busy_queues); ++ } ++ if (prev != bfqq->next_rq) ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ /* ++ * Assign jiffies to last_wr_start_finish in the following ++ * cases: ++ * ++ * . if bfqq is not going to be weight-raised, because, for ++ * non weight-raised queues, last_wr_start_finish stores the ++ * arrival time of the last request; as of now, this piece ++ * of information is used only for deciding whether to ++ * weight-raise async queues ++ * ++ * . if bfqq is not weight-raised, because, if bfqq is now ++ * switching to weight-raised, then last_wr_start_finish ++ * stores the time when weight-raising starts ++ * ++ * . if bfqq is interactive, because, regardless of whether ++ * bfqq is currently weight-raised, the weight-raising ++ * period must start or restart (this case is considered ++ * separately because it is not detected by the above ++ * conditions, if bfqq is already weight-raised) ++ * ++ * last_wr_start_finish has to be updated also if bfqq is soft ++ * real-time, because the weight-raising period is constantly ++ * restarted on idle-to-busy transitions for these queues, but ++ * this is already done in bfq_bfqq_handle_idle_busy_switch if ++ * needed. ++ */ ++ if (bfqd->low_latency && ++ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) ++ bfqq->last_wr_start_finish = jiffies; ++} ++ ++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, ++ struct bio *bio) ++{ ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (!bic) ++ return NULL; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ if (bfqq) ++ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); ++ ++ return NULL; ++} ++ ++static sector_t get_sdist(sector_t last_pos, struct request *rq) ++{ ++ sector_t sdist = 0; ++ ++ if (last_pos) { ++ if (last_pos < blk_rq_pos(rq)) ++ sdist = blk_rq_pos(rq) - last_pos; ++ else ++ sdist = last_pos - blk_rq_pos(rq); ++ } ++ ++ return sdist; ++} ++ ++static void bfq_activate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ bfqd->rq_in_driver++; ++} ++ ++static void bfq_deactivate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ BUG_ON(bfqd->rq_in_driver == 0); ++ bfqd->rq_in_driver--; ++} ++ ++static void bfq_remove_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ const int sync = rq_is_sync(rq); ++ ++ BUG_ON(bfqq->entity.service > bfqq->entity.budget && ++ bfqq == bfqd->in_service_queue); ++ ++ if (bfqq->next_rq == rq) { ++ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (rq->queuelist.prev != &rq->queuelist) ++ list_del_init(&rq->queuelist); ++ BUG_ON(bfqq->queued[sync] == 0); ++ bfqq->queued[sync]--; ++ bfqd->queued--; ++ elv_rb_del(&bfqq->sort_list, rq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ BUG_ON(bfqq->entity.budget < 0); ++ ++ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) { ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ ++ /* bfqq emptied. In normal operation, when ++ * bfqq is empty, bfqq->entity.service and ++ * bfqq->entity.budget must contain, ++ * respectively, the service received and the ++ * budget used last time bfqq emptied. These ++ * facts do not hold in this case, as at least ++ * this last removal occurred while bfqq is ++ * not in service. To avoid inconsistencies, ++ * reset both bfqq->entity.service and ++ * bfqq->entity.budget. ++ */ ++ bfqq->entity.budget = bfqq->entity.service = 0; ++ } ++ ++ /* ++ * Remove queue from request-position tree as it is empty. ++ */ ++ if (bfqq->pos_root) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ } ++ ++ if (rq->cmd_flags & REQ_META) { ++ BUG_ON(bfqq->meta_pending == 0); ++ bfqq->meta_pending--; ++ } ++ bfqg_stats_update_io_remove(bfqq_group(bfqq), req_op(rq), ++ rq->cmd_flags); ++} ++ ++static int bfq_merge(struct request_queue *q, struct request **req, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct request *__rq; ++ ++ __rq = bfq_find_rq_fmerge(bfqd, bio); ++ if (__rq && elv_bio_merge_ok(__rq, bio)) { ++ *req = __rq; ++ return ELEVATOR_FRONT_MERGE; ++ } ++ ++ return ELEVATOR_NO_MERGE; ++} ++ ++static void bfq_merged_request(struct request_queue *q, struct request *req, ++ int type) ++{ ++ if (type == ELEVATOR_FRONT_MERGE && ++ rb_prev(&req->rb_node) && ++ blk_rq_pos(req) < ++ blk_rq_pos(container_of(rb_prev(&req->rb_node), ++ struct request, rb_node))) { ++ struct bfq_queue *bfqq = RQ_BFQQ(req); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *prev, *next_rq; ++ ++ /* Reposition request in its sort_list */ ++ elv_rb_del(&bfqq->sort_list, req); ++ elv_rb_add(&bfqq->sort_list, req); ++ /* Choose next request to be served for bfqq */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, ++ bfqd->last_position); ++ BUG_ON(!next_rq); ++ bfqq->next_rq = next_rq; ++ /* ++ * If next_rq changes, update both the queue's budget to ++ * fit the new request and the queue's position in its ++ * rq_pos_tree. ++ */ ++ if (prev != bfqq->next_rq) { ++ bfq_updated_next_req(bfqd, bfqq); ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ } ++ } ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfq_bio_merged(struct request_queue *q, struct request *req, ++ struct bio *bio) ++{ ++ bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio_op(bio), ++ bio->bi_opf); ++} ++#endif ++ ++static void bfq_merged_requests(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *next_bfqq = RQ_BFQQ(next); ++ ++ /* ++ * If next and rq belong to the same bfq_queue and next is older ++ * than rq, then reposition rq in the fifo (by substituting next ++ * with rq). Otherwise, if next and rq belong to different ++ * bfq_queues, never reposition rq: in fact, we would have to ++ * reposition it with respect to next's position in its own fifo, ++ * which would most certainly be too expensive with respect to ++ * the benefits. ++ */ ++ if (bfqq == next_bfqq && ++ !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && ++ next->fifo_time < rq->fifo_time) { ++ list_del_init(&rq->queuelist); ++ list_replace_init(&next->queuelist, &rq->queuelist); ++ rq->fifo_time = next->fifo_time; ++ } ++ ++ if (bfqq->next_rq == next) ++ bfqq->next_rq = rq; ++ ++ bfq_remove_request(next); ++ bfqg_stats_update_io_merged(bfqq_group(bfqq), req_op(next), ++ next->cmd_flags); ++} ++ ++/* Must be called with bfqq != NULL */ ++static void bfq_bfqq_end_wr(struct bfq_queue *bfqq) ++{ ++ BUG_ON(!bfqq); ++ ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues--; ++ bfqq->wr_coeff = 1; ++ bfqq->wr_cur_max_time = 0; ++ bfqq->last_wr_start_finish = jiffies; ++ /* ++ * Trigger a weight change on the next invocation of ++ * __bfq_entity_update_weight_prio. ++ */ ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "end_wr: wrais ending at %lu, rais_max_time %u", ++ bfqq->last_wr_start_finish, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "end_wr: wr_busy %d", ++ bfqq->bfqd->wr_busy_queues); ++} ++ ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ if (bfqg->async_bfqq[i][j]) ++ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); ++ if (bfqg->async_idle_bfqq) ++ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); ++} ++ ++static void bfq_end_wr(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ bfq_end_wr_async(bfqd); ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++} ++ ++static sector_t bfq_io_struct_pos(void *io_struct, bool request) ++{ ++ if (request) ++ return blk_rq_pos(io_struct); ++ else ++ return ((struct bio *)io_struct)->bi_iter.bi_sector; ++} ++ ++static int bfq_rq_close_to_sector(void *io_struct, bool request, ++ sector_t sector) ++{ ++ return abs(bfq_io_struct_pos(io_struct, request) - sector) <= ++ BFQQ_CLOSE_THR; ++} ++ ++static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ sector_t sector) ++{ ++ struct rb_root *root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree; ++ struct rb_node *parent, *node; ++ struct bfq_queue *__bfqq; ++ ++ if (RB_EMPTY_ROOT(root)) ++ return NULL; ++ ++ /* ++ * First, if we find a request starting at the end of the last ++ * request, choose it. ++ */ ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); ++ if (__bfqq) ++ return __bfqq; ++ ++ /* ++ * If the exact sector wasn't found, the parent of the NULL leaf ++ * will contain the closest sector (rq_pos_tree sorted by ++ * next_request position). ++ */ ++ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) ++ return __bfqq; ++ ++ if (blk_rq_pos(__bfqq->next_rq) < sector) ++ node = rb_next(&__bfqq->pos_node); ++ else ++ node = rb_prev(&__bfqq->pos_node); ++ if (!node) ++ return NULL; ++ ++ __bfqq = rb_entry(node, struct bfq_queue, pos_node); ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) ++ return __bfqq; ++ ++ return NULL; ++} ++ ++static struct bfq_queue *bfq_find_close_cooperator(struct bfq_data *bfqd, ++ struct bfq_queue *cur_bfqq, ++ sector_t sector) ++{ ++ struct bfq_queue *bfqq; ++ ++ /* ++ * We shall notice if some of the queues are cooperating, ++ * e.g., working closely on the same area of the device. In ++ * that case, we can group them together and: 1) don't waste ++ * time idling, and 2) serve the union of their requests in ++ * the best possible order for throughput. ++ */ ++ bfqq = bfqq_find_close(bfqd, cur_bfqq, sector); ++ if (!bfqq || bfqq == cur_bfqq) ++ return NULL; ++ ++ return bfqq; ++} ++ ++static struct bfq_queue * ++bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return NULL; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return NULL; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++ ++ /* ++ * Merging is just a redirection: the requests of the process ++ * owning one of the two queues are redirected to the other queue. ++ * The latter queue, in its turn, is set as shared if this is the ++ * first time that the requests of some process are redirected to ++ * it. ++ * ++ * We redirect bfqq to new_bfqq and not the opposite, because we ++ * are in the context of the process owning bfqq, hence we have ++ * the io_cq of this process. So we can immediately configure this ++ * io_cq to redirect the requests of the process to new_bfqq. ++ * ++ * NOTE, even if new_bfqq coincides with the in-service queue, the ++ * io_cq of new_bfqq is not available, because, if the in-service ++ * queue is shared, bfqd->in_service_bic may not point to the ++ * io_cq of the in-service queue. ++ * Redirecting the requests of the process owning bfqq to the ++ * currently in-service queue is in any case the best option, as ++ * we feed the in-service queue with new requests close to the ++ * last request served and, by doing so, hopefully increase the ++ * throughput. ++ */ ++ bfqq->new_bfqq = new_bfqq; ++ new_bfqq->ref += process_refs; ++ return new_bfqq; ++} ++ ++static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, ++ struct bfq_queue *new_bfqq) ++{ ++ if (bfq_class_idle(bfqq) || bfq_class_idle(new_bfqq) || ++ (bfqq->ioprio_class != new_bfqq->ioprio_class)) ++ return false; ++ ++ /* ++ * If either of the queues has already been detected as seeky, ++ * then merging it with the other queue is unlikely to lead to ++ * sequential I/O. ++ */ ++ if (BFQQ_SEEKY(bfqq) || BFQQ_SEEKY(new_bfqq)) ++ return false; ++ ++ /* ++ * Interleaved I/O is known to be done by (some) applications ++ * only for reads, so it does not make sense to merge async ++ * queues. ++ */ ++ if (!bfq_bfqq_sync(bfqq) || !bfq_bfqq_sync(new_bfqq)) ++ return false; ++ ++ return true; ++} ++ ++/* ++ * If this function returns true, then bfqq cannot be merged. The idea ++ * is that true cooperation happens very early after processes start ++ * to do I/O. Usually, late cooperations are just accidental false ++ * positives. In case bfqq is weight-raised, such false positives ++ * would evidently degrade latency guarantees for bfqq. ++ */ ++bool wr_from_too_long(struct bfq_queue *bfqq) ++{ ++ return bfqq->wr_coeff > 1 && ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ msecs_to_jiffies(100)); ++} ++ ++/* ++ * Attempt to schedule a merge of bfqq with the currently in-service ++ * queue or with a close queue among the scheduled queues. Return ++ * NULL if no merge was scheduled, a pointer to the shared bfq_queue ++ * structure otherwise. ++ * ++ * The OOM queue is not allowed to participate to cooperation: in fact, since ++ * the requests temporarily redirected to the OOM queue could be redirected ++ * again to dedicated queues at any time, the state needed to correctly ++ * handle merging with the OOM queue would be quite complex and expensive ++ * to maintain. Besides, in such a critical condition as an out of memory, ++ * the benefits of queue merging may be little relevant, or even negligible. ++ * ++ * Weight-raised queues can be merged only if their weight-raising ++ * period has just started. In fact cooperating processes are usually ++ * started together. Thus, with this filter we avoid false positives ++ * that would jeopardize low-latency guarantees. ++ * ++ * WARNING: queue merging may impair fairness among non-weight raised ++ * queues, for at least two reasons: 1) the original weight of a ++ * merged queue may change during the merged state, 2) even being the ++ * weight the same, a merged queue may be bloated with many more ++ * requests than the ones produced by its originally-associated ++ * process. ++ */ ++static struct bfq_queue * ++bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ void *io_struct, bool request) ++{ ++ struct bfq_queue *in_service_bfqq, *new_bfqq; ++ ++ if (bfqq->new_bfqq) ++ return bfqq->new_bfqq; ++ ++ if (io_struct && wr_from_too_long(bfqq) && ++ likely(bfqq != &bfqd->oom_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have looked for coop, but bfq%d wr", ++ bfqq->pid); ++ ++ if (!io_struct || ++ wr_from_too_long(bfqq) || ++ unlikely(bfqq == &bfqd->oom_bfqq)) ++ return NULL; ++ ++ /* If there is only one backlogged queue, don't search. */ ++ if (bfqd->busy_queues == 1) ++ return NULL; ++ ++ in_service_bfqq = bfqd->in_service_queue; ++ ++ if (in_service_bfqq && in_service_bfqq != bfqq && ++ bfqd->in_service_bic && wr_from_too_long(in_service_bfqq) ++ && likely(in_service_bfqq == &bfqd->oom_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have tried merge with in-service-queue, but wr"); ++ ++ if (!in_service_bfqq || in_service_bfqq == bfqq || ++ !bfqd->in_service_bic || wr_from_too_long(in_service_bfqq) || ++ unlikely(in_service_bfqq == &bfqd->oom_bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && ++ bfqq->entity.parent == in_service_bfqq->entity.parent && ++ bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) { ++ new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); ++ if (new_bfqq) ++ return new_bfqq; ++ } ++ /* ++ * Check whether there is a cooperator among currently scheduled ++ * queues. The only thing we need is that the bio/request is not ++ * NULL, as we need it to establish whether a cooperator exists. ++ */ ++check_scheduled: ++ new_bfqq = bfq_find_close_cooperator(bfqd, bfqq, ++ bfq_io_struct_pos(io_struct, request)); ++ ++ BUG_ON(new_bfqq && bfqq->entity.parent != new_bfqq->entity.parent); ++ ++ if (new_bfqq && wr_from_too_long(new_bfqq) && ++ likely(new_bfqq != &bfqd->oom_bfqq) && ++ bfq_may_be_close_cooperator(bfqq, new_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have merged with bfq%d, but wr", ++ new_bfqq->pid); ++ ++ if (new_bfqq && !wr_from_too_long(new_bfqq) && ++ likely(new_bfqq != &bfqd->oom_bfqq) && ++ bfq_may_be_close_cooperator(bfqq, new_bfqq)) ++ return bfq_setup_merge(bfqq, new_bfqq); ++ ++ return NULL; ++} ++ ++static void bfq_bfqq_save_state(struct bfq_queue *bfqq) ++{ ++ struct bfq_io_cq *bic = bfqq->bic; ++ ++ /* ++ * If !bfqq->bic, the queue is already shared or its requests ++ * have already been redirected to a shared queue; both idle window ++ * and weight raising state have already been saved. Do nothing. ++ */ ++ if (!bic) ++ return; ++ ++ bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); ++ bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); ++ bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); ++ bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); ++ bic->saved_wr_coeff = bfqq->wr_coeff; ++ bic->saved_wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt; ++ bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++} ++ ++static void bfq_get_bic_reference(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic has a non-NULL value, the bic to which it belongs ++ * is about to begin using a shared bfq_queue. ++ */ ++ if (bfqq->bic) ++ atomic_long_inc(&bfqq->bic->icq.ioc->refcount); ++} ++ ++static void ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (unsigned long) new_bfqq->pid); ++ /* Save weight raising and idle window of the merged queues */ ++ bfq_bfqq_save_state(bfqq); ++ bfq_bfqq_save_state(new_bfqq); ++ if (bfq_bfqq_IO_bound(bfqq)) ++ bfq_mark_bfqq_IO_bound(new_bfqq); ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ /* ++ * If bfqq is weight-raised, then let new_bfqq inherit ++ * weight-raising. To reduce false positives, neglect the case ++ * where bfqq has just been created, but has not yet made it ++ * to be weight-raised (which may happen because EQM may merge ++ * bfqq even before bfq_add_request is executed for the first ++ * time for bfqq). Handling this case would however be very ++ * easy, thanks to the flag just_created. ++ */ ++ if (new_bfqq->wr_coeff == 1 && bfqq->wr_coeff > 1) { ++ new_bfqq->wr_coeff = bfqq->wr_coeff; ++ new_bfqq->wr_cur_max_time = bfqq->wr_cur_max_time; ++ new_bfqq->last_wr_start_finish = bfqq->last_wr_start_finish; ++ new_bfqq->wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt; ++ if (bfq_bfqq_busy(new_bfqq)) ++ bfqd->wr_busy_queues++; ++ new_bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, new_bfqq, ++ "wr start after merge with %d, rais_max_time %u", ++ bfqq->pid, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ if (bfqq->wr_coeff > 1) { /* bfqq has given its wr to new_bfqq */ ++ bfqq->wr_coeff = 1; ++ bfqq->entity.prio_changed = 1; ++ if (bfq_bfqq_busy(bfqq)) ++ bfqd->wr_busy_queues--; ++ } ++ ++ bfq_log_bfqq(bfqd, new_bfqq, "merge_bfqqs: wr_busy %d", ++ bfqd->wr_busy_queues); ++ ++ /* ++ * Grab a reference to the bic, to prevent it from being destroyed ++ * before being possibly touched by a bfq_split_bfqq(). ++ */ ++ bfq_get_bic_reference(bfqq); ++ bfq_get_bic_reference(new_bfqq); ++ /* ++ * Merge queues (that is, let bic redirect its requests to new_bfqq) ++ */ ++ bic_set_bfqq(bic, new_bfqq, 1); ++ bfq_mark_bfqq_coop(new_bfqq); ++ /* ++ * new_bfqq now belongs to at least two bics (it is a shared queue): ++ * set new_bfqq->bic to NULL. bfqq either: ++ * - does not belong to any bic any more, and hence bfqq->bic must ++ * be set to NULL, or ++ * - is a queue whose owning bics have already been redirected to a ++ * different queue, hence the queue is destined to not belong to ++ * any bic soon and bfqq->bic is already NULL (therefore the next ++ * assignment causes no harm). ++ */ ++ new_bfqq->bic = NULL; ++ bfqq->bic = NULL; ++ bfq_put_queue(bfqq); ++} ++ ++static int bfq_allow_bio_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq, *new_bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return false; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (!bic) ++ return false; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ /* ++ * We take advantage of this function to perform an early merge ++ * of the queues of possible cooperating processes. ++ */ ++ if (bfqq) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); ++ if (new_bfqq) { ++ bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); ++ /* ++ * If we get here, the bio will be queued in the ++ * shared queue, i.e., new_bfqq, so use new_bfqq ++ * to decide whether bio and rq can be merged. ++ */ ++ bfqq = new_bfqq; ++ } ++ } ++ ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static int bfq_allow_rq_merge(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ return RQ_BFQQ(rq) == RQ_BFQQ(next); ++} ++ ++/* ++ * Set the maximum time for the in-service queue to consume its ++ * budget. This prevents seeky processes from lowering the throughput. ++ * In practice, a time-slice service scheme is used with seeky ++ * processes. ++ */ ++static void bfq_set_budget_timeout(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ unsigned int timeout_coeff; ++ ++ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) ++ timeout_coeff = 1; ++ else ++ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ ++ bfqd->last_budget_start = ktime_get(); ++ ++ bfqq->budget_timeout = jiffies + ++ bfqd->bfq_timeout * timeout_coeff; ++ ++ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", ++ jiffies_to_msecs(bfqd->bfq_timeout * timeout_coeff)); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq) { ++ bfqg_stats_update_avg_queue_size(bfqq_group(bfqq)); ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ if (time_is_before_jiffies(bfqq->last_wr_start_finish) && ++ bfqq->wr_coeff > 1 && ++ bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time && ++ time_is_before_jiffies(bfqq->budget_timeout)) { ++ /* ++ * For soft real-time queues, move the start ++ * of the weight-raising period forward by the ++ * time the queue has not received any ++ * service. Otherwise, a relatively long ++ * service delay is likely to cause the ++ * weight-raising period of the queue to end, ++ * because of the short duration of the ++ * weight-raising period of a soft real-time ++ * queue. It is worth noting that this move ++ * is not so dangerous for the other queues, ++ * because soft real-time queues are not ++ * greedy. ++ * ++ * To not add a further variable, we use the ++ * overloaded field budget_timeout to ++ * determine for how long the queue has not ++ * received service, i.e., how much time has ++ * elapsed since the queue expired. However, ++ * this is a little imprecise, because ++ * budget_timeout is set to jiffies if bfqq ++ * not only expires, but also remains with no ++ * request. ++ */ ++ bfqq->last_wr_start_finish += jiffies - ++ max_t(unsigned long, bfqq->last_wr_start_finish, ++ bfqq->budget_timeout); ++ if (time_is_after_jiffies(bfqq->last_wr_start_finish)) { ++ pr_crit( ++ "BFQ WARNING:last %lu budget %lu jiffies %lu", ++ bfqq->last_wr_start_finish, ++ bfqq->budget_timeout, ++ jiffies); ++ pr_crit("diff %lu", jiffies - ++ max_t(unsigned long, ++ bfqq->last_wr_start_finish, ++ bfqq->budget_timeout)); ++ bfqq->last_wr_start_finish = jiffies; ++ } ++ } ++ ++ bfq_set_budget_timeout(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %d", ++ bfqq->entity.budget); ++ } else ++ bfq_log(bfqd, "set_in_service_queue: NULL"); ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ ++static void bfq_arm_slice_timer(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ struct bfq_io_cq *bic; ++ u32 sl; ++ ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Processes have exited, don't wait. */ ++ bic = bfqd->in_service_bic; ++ if (!bic || atomic_read(&bic->icq.ioc->active_ref) == 0) ++ return; ++ ++ bfq_mark_bfqq_wait_request(bfqq); ++ ++ /* ++ * We don't want to idle for seeks, but we do want to allow ++ * fair distribution of slice time for a process doing back-to-back ++ * seeks. So allow a little bit of time for him to submit a new rq. ++ * ++ * To prevent processes with (partly) seeky workloads from ++ * being too ill-treated, grant them a small fraction of the ++ * assigned budget before reducing the waiting time to ++ * BFQ_MIN_TT. This happened to help reduce latency. ++ */ ++ sl = bfqd->bfq_slice_idle; ++ /* ++ * Unless the queue is being weight-raised or the scenario is ++ * asymmetric, grant only minimum idle time if the queue ++ * is seeky. A long idling is preserved for a weight-raised ++ * queue, or, more in general, in an asymemtric scenario, ++ * because a long idling is needed for guaranteeing to a queue ++ * its reserved share of the throughput (in particular, it is ++ * needed if the queue has a higher weight than some other ++ * queue). ++ */ ++ if (BFQQ_SEEKY(bfqq) && bfqq->wr_coeff == 1 && ++ bfq_symmetric_scenario(bfqd)) ++ sl = min_t(u32, sl, BFQ_MIN_TT); ++ ++ bfqd->last_idling_start = ktime_get(); ++ hrtimer_start(&bfqd->idle_slice_timer, ns_to_ktime(sl), ++ HRTIMER_MODE_REL); ++ bfqg_stats_set_start_idle_time(bfqq_group(bfqq)); ++ bfq_log(bfqd, "arm idle: %ld/%ld ms", ++ sl / NSEC_PER_MSEC, bfqd->bfq_slice_idle / NSEC_PER_MSEC); ++} ++ ++/* ++ * In autotuning mode, max_budget is dynamically recomputed as the ++ * amount of sectors transferred in timeout at the estimated peak ++ * rate. This enables BFQ to utilize a full timeslice with a full ++ * budget, even if the in-service queue is served at peak rate. And ++ * this maximises throughput with sequential workloads. ++ */ ++static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd) ++{ ++ return (u64)bfqd->peak_rate * USEC_PER_MSEC * ++ jiffies_to_msecs(bfqd->bfq_timeout)>>BFQ_RATE_SHIFT; ++} ++ ++/* ++ * Update parameters related to throughput and responsiveness, as a ++ * function of the estimated peak rate. See comments on ++ * bfq_calc_max_budget(), and on T_slow and T_fast arrays. ++ */ ++void update_thr_responsiveness_params(struct bfq_data *bfqd) ++{ ++ int dev_type = blk_queue_nonrot(bfqd->queue); ++ ++ if (bfqd->bfq_user_max_budget == 0) { ++ bfqd->bfq_max_budget = ++ bfq_calc_max_budget(bfqd); ++ BUG_ON(bfqd->bfq_max_budget < 0); ++ bfq_log(bfqd, "new max_budget = %d", ++ bfqd->bfq_max_budget); ++ } ++ ++ if (bfqd->device_speed == BFQ_BFQD_FAST && ++ bfqd->peak_rate < device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_SLOW; ++ bfqd->RT_prod = R_slow[dev_type] * ++ T_slow[dev_type]; ++ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && ++ bfqd->peak_rate > device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ bfqd->RT_prod = R_fast[dev_type] * ++ T_fast[dev_type]; ++ } ++ ++ bfq_log(bfqd, ++"dev_type %s dev_speed_class = %s (%llu sects/sec), thresh %llu setcs/sec", ++ dev_type == 0 ? "ROT" : "NONROT", ++ bfqd->device_speed == BFQ_BFQD_FAST ? "FAST" : "SLOW", ++ bfqd->device_speed == BFQ_BFQD_FAST ? ++ (USEC_PER_SEC*(u64)R_fast[dev_type])>>BFQ_RATE_SHIFT : ++ (USEC_PER_SEC*(u64)R_slow[dev_type])>>BFQ_RATE_SHIFT, ++ (USEC_PER_SEC*(u64)device_speed_thresh[dev_type])>> ++ BFQ_RATE_SHIFT); ++} ++ ++void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq) ++{ ++ if (rq != NULL) { /* new rq dispatch now, reset accordingly */ ++ bfqd->last_dispatch = bfqd->first_dispatch = ktime_get_ns() ; ++ bfqd->peak_rate_samples = 1; ++ bfqd->sequential_samples = 0; ++ bfqd->tot_sectors_dispatched = bfqd->last_rq_max_size = ++ blk_rq_sectors(rq); ++ } else /* no new rq dispatched, just reset the number of samples */ ++ bfqd->peak_rate_samples = 0; /* full re-init on next disp. */ ++ ++ bfq_log(bfqd, ++ "reset_rate_computation at end, sample %u/%u tot_sects %llu", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ bfqd->tot_sectors_dispatched); ++} ++ ++void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq) ++{ ++ u32 rate, weight, divisor; ++ ++ /* ++ * For the convergence property to hold (see comments on ++ * bfq_update_peak_rate()) and for the assessment to be ++ * reliable, a minimum number of samples must be present, and ++ * a minimum amount of time must have elapsed. If not so, do ++ * not compute new rate. Just reset parameters, to get ready ++ * for a new evaluation attempt. ++ */ ++ if (bfqd->peak_rate_samples < BFQ_RATE_MIN_SAMPLES || ++ bfqd->delta_from_first < BFQ_RATE_MIN_INTERVAL) { ++ bfq_log(bfqd, ++ "update_rate_reset: only resetting, delta_first %lluus samples %d", ++ bfqd->delta_from_first>>10, bfqd->peak_rate_samples); ++ goto reset_computation; ++ } ++ ++ /* ++ * If a new request completion has occurred after last ++ * dispatch, then, to approximate the rate at which requests ++ * have been served by the device, it is more precise to ++ * extend the observation interval to the last completion. ++ */ ++ bfqd->delta_from_first = ++ max_t(u64, bfqd->delta_from_first, ++ bfqd->last_completion - bfqd->first_dispatch); ++ ++ BUG_ON(bfqd->delta_from_first == 0); ++ /* ++ * Rate computed in sects/usec, and not sects/nsec, for ++ * precision issues. ++ */ ++ rate = div64_ul(bfqd->tot_sectors_dispatched<delta_from_first, NSEC_PER_USEC)); ++ ++ bfq_log(bfqd, ++"update_rate_reset: tot_sects %llu delta_first %lluus rate %llu sects/s (%d)", ++ bfqd->tot_sectors_dispatched, bfqd->delta_from_first>>10, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ rate > 20< 20M sectors/sec) ++ */ ++ if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 && ++ rate <= bfqd->peak_rate) || ++ rate > 20<peak_rate_samples, bfqd->sequential_samples, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ goto reset_computation; ++ } else { ++ bfq_log(bfqd, ++ "update_rate_reset: do update, samples %u/%u rate/peak %llu/%llu", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ } ++ ++ /* ++ * We have to update the peak rate, at last! To this purpose, ++ * we use a low-pass filter. We compute the smoothing constant ++ * of the filter as a function of the 'weight' of the new ++ * measured rate. ++ * ++ * As can be seen in next formulas, we define this weight as a ++ * quantity proportional to how sequential the workload is, ++ * and to how long the observation time interval is. ++ * ++ * The weight runs from 0 to 8. The maximum value of the ++ * weight, 8, yields the minimum value for the smoothing ++ * constant. At this minimum value for the smoothing constant, ++ * the measured rate contributes for half of the next value of ++ * the estimated peak rate. ++ * ++ * So, the first step is to compute the weight as a function ++ * of how sequential the workload is. Note that the weight ++ * cannot reach 9, because bfqd->sequential_samples cannot ++ * become equal to bfqd->peak_rate_samples, which, in its ++ * turn, holds true because bfqd->sequential_samples is not ++ * incremented for the first sample. ++ */ ++ weight = (9 * bfqd->sequential_samples) / bfqd->peak_rate_samples; ++ ++ /* ++ * Second step: further refine the weight as a function of the ++ * duration of the observation interval. ++ */ ++ weight = min_t(u32, 8, ++ div_u64(weight * bfqd->delta_from_first, ++ BFQ_RATE_REF_INTERVAL)); ++ ++ /* ++ * Divisor ranging from 10, for minimum weight, to 2, for ++ * maximum weight. ++ */ ++ divisor = 10 - weight; ++ BUG_ON(divisor == 0); ++ ++ /* ++ * Finally, update peak rate: ++ * ++ * peak_rate = peak_rate * (divisor-1) / divisor + rate / divisor ++ */ ++ bfqd->peak_rate *= divisor-1; ++ bfqd->peak_rate /= divisor; ++ rate /= divisor; /* smoothing constant alpha = 1/divisor */ ++ ++ bfq_log(bfqd, ++ "update_rate_reset: divisor %d tmp_peak_rate %llu tmp_rate %u", ++ divisor, ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT), ++ (u32)((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT)); ++ ++ BUG_ON(bfqd->peak_rate == 0); ++ BUG_ON(bfqd->peak_rate > 20<peak_rate += rate; ++ update_thr_responsiveness_params(bfqd); ++ BUG_ON(bfqd->peak_rate > 20<peak_rate_samples == 0) { /* first dispatch */ ++ bfq_log(bfqd, ++ "update_peak_rate: goto reset, samples %d", ++ bfqd->peak_rate_samples) ; ++ bfq_reset_rate_computation(bfqd, rq); ++ goto update_last_values; /* will add one sample */ ++ } ++ ++ /* ++ * Device idle for very long: the observation interval lasting ++ * up to this dispatch cannot be a valid observation interval ++ * for computing a new peak rate (similarly to the late- ++ * completion event in bfq_completed_request()). Go to ++ * update_rate_and_reset to have the following three steps ++ * taken: ++ * - close the observation interval at the last (previous) ++ * request dispatch or completion ++ * - compute rate, if possible, for that observation interval ++ * - start a new observation interval with this dispatch ++ */ ++ if (now_ns - bfqd->last_dispatch > 100*NSEC_PER_MSEC && ++ bfqd->rq_in_driver == 0) { ++ bfq_log(bfqd, ++"update_peak_rate: jumping to updating&resetting delta_last %lluus samples %d", ++ (now_ns - bfqd->last_dispatch)>>10, ++ bfqd->peak_rate_samples) ; ++ goto update_rate_and_reset; ++ } ++ ++ /* Update sampling information */ ++ bfqd->peak_rate_samples++; ++ ++ if ((bfqd->rq_in_driver > 0 || ++ now_ns - bfqd->last_completion < BFQ_MIN_TT) ++ && get_sdist(bfqd->last_position, rq) < BFQQ_SEEK_THR) ++ bfqd->sequential_samples++; ++ ++ bfqd->tot_sectors_dispatched += blk_rq_sectors(rq); ++ ++ /* Reset max observed rq size every 32 dispatches */ ++ if (likely(bfqd->peak_rate_samples % 32)) ++ bfqd->last_rq_max_size = ++ max_t(u32, blk_rq_sectors(rq), bfqd->last_rq_max_size); ++ else ++ bfqd->last_rq_max_size = blk_rq_sectors(rq); ++ ++ bfqd->delta_from_first = now_ns - bfqd->first_dispatch; ++ ++ bfq_log(bfqd, ++ "update_peak_rate: added samples %u/%u tot_sects %llu delta_first %lluus", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ bfqd->tot_sectors_dispatched, ++ bfqd->delta_from_first>>10); ++ ++ /* Target observation interval not yet reached, go on sampling */ ++ if (bfqd->delta_from_first < BFQ_RATE_REF_INTERVAL) ++ goto update_last_values; ++ ++update_rate_and_reset: ++ bfq_update_rate_reset(bfqd, rq); ++update_last_values: ++ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ bfqd->last_dispatch = now_ns; ++ ++ bfq_log(bfqd, ++ "update_peak_rate: delta_first %lluus last_pos %llu peak_rate %llu", ++ (now_ns - bfqd->first_dispatch)>>10, ++ (unsigned long long) bfqd->last_position, ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ bfq_log(bfqd, ++ "update_peak_rate: samples at end %d", bfqd->peak_rate_samples); ++} ++ ++/* ++ * Move request from internal lists to the dispatch list of the request queue ++ */ ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * For consistency, the next instruction should have been executed ++ * after removing the request from the queue and dispatching it. ++ * We execute instead this instruction before bfq_remove_request() ++ * (and hence introduce a temporary inconsistency), for efficiency. ++ * In fact, in a forced_dispatch, this prevents two counters related ++ * to bfqq->dispatched to risk to be uselessly decremented if bfqq ++ * is not in service, and then to be incremented again after ++ * incrementing bfqq->dispatched. ++ */ ++ bfqq->dispatched++; ++ bfq_update_peak_rate(q->elevator->elevator_data, rq); ++ ++ bfq_remove_request(rq); ++ elv_dispatch_sort(q, rq); ++} ++ ++/* ++ * Return expired entry, or NULL to just start from scratch in rbtree. ++ */ ++static struct request *bfq_check_fifo(struct bfq_queue *bfqq) ++{ ++ struct request *rq = NULL; ++ ++ if (bfq_bfqq_fifo_expire(bfqq)) ++ return NULL; ++ ++ bfq_mark_bfqq_fifo_expire(bfqq); ++ ++ if (list_empty(&bfqq->fifo)) ++ return NULL; ++ ++ rq = rq_entry_fifo(bfqq->fifo.next); ++ ++ if (ktime_get_ns() < rq->fifo_time) ++ return NULL; ++ ++ return rq; ++} ++ ++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ /* ++ * If this bfqq is shared between multiple processes, check ++ * to make sure that those processes are still issuing I/Os ++ * within the mean seek distance. If not, it may be time to ++ * break the queues apart again. ++ */ ++ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) ++ bfq_mark_bfqq_split_coop(bfqq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ if (bfqq->dispatched == 0) ++ /* ++ * Overloading budget_timeout field to store ++ * the time at which the queue remains with no ++ * backlog and no outstanding request; used by ++ * the weight-raising mechanism. ++ */ ++ bfqq->budget_timeout = jiffies; ++ ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ } else { ++ bfq_activate_bfqq(bfqd, bfqq); ++ /* ++ * Resort priority tree of potential close cooperators. ++ */ ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ } ++} ++ ++/** ++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. ++ * @bfqd: device data. ++ * @bfqq: queue to update. ++ * @reason: reason for expiration. ++ * ++ * Handle the feedback on @bfqq budget at queue expiration. ++ * See the body for detailed comments. ++ */ ++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ enum bfqq_expiration reason) ++{ ++ struct request *next_rq; ++ int budget, min_budget; ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ min_budget = bfq_min_budget(bfqd); ++ ++ if (bfqq->wr_coeff == 1) ++ budget = bfqq->max_budget; ++ else /* ++ * Use a constant, low budget for weight-raised queues, ++ * to help achieve a low latency. Keep it slightly higher ++ * than the minimum possible budget, to cause a little ++ * bit fewer expirations. ++ */ ++ budget = 2 * min_budget; ++ ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %d, budg left %d", ++ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %d, min budg %d", ++ budget, bfq_min_budget(bfqd)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", ++ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); ++ ++ if (bfq_bfqq_sync(bfqq) && bfqq->wr_coeff == 1) { ++ switch (reason) { ++ /* ++ * Caveat: in all the following cases we trade latency ++ * for throughput. ++ */ ++ case BFQ_BFQQ_TOO_IDLE: ++ /* ++ * This is the only case where we may reduce ++ * the budget: if there is no request of the ++ * process still waiting for completion, then ++ * we assume (tentatively) that the timer has ++ * expired because the batch of requests of ++ * the process could have been served with a ++ * smaller budget. Hence, betting that ++ * process will behave in the same way when it ++ * becomes backlogged again, we reduce its ++ * next budget. As long as we guess right, ++ * this budget cut reduces the latency ++ * experienced by the process. ++ * ++ * However, if there are still outstanding ++ * requests, then the process may have not yet ++ * issued its next request just because it is ++ * still waiting for the completion of some of ++ * the still outstanding ones. So in this ++ * subcase we do not reduce its budget, on the ++ * contrary we increase it to possibly boost ++ * the throughput, as discussed in the ++ * comments to the BUDGET_TIMEOUT case. ++ */ ++ if (bfqq->dispatched > 0) /* still outstanding reqs */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ else { ++ if (budget > 5 * min_budget) ++ budget -= 4 * min_budget; ++ else ++ budget = min_budget; ++ } ++ break; ++ case BFQ_BFQQ_BUDGET_TIMEOUT: ++ /* ++ * We double the budget here because it gives ++ * the chance to boost the throughput if this ++ * is not a seeky process (and has bumped into ++ * this timeout because of, e.g., ZBR). ++ */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_BUDGET_EXHAUSTED: ++ /* ++ * The process still has backlog, and did not ++ * let either the budget timeout or the disk ++ * idling timeout expire. Hence it is not ++ * seeky, has a short thinktime and may be ++ * happy with a higher budget too. So ++ * definitely increase the budget of this good ++ * candidate to boost the disk throughput. ++ */ ++ budget = min(budget * 4, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_NO_MORE_REQUESTS: ++ /* ++ * For queues that expire for this reason, it ++ * is particularly important to keep the ++ * budget close to the actual service they ++ * need. Doing so reduces the timestamp ++ * misalignment problem described in the ++ * comments in the body of ++ * __bfq_activate_entity. In fact, suppose ++ * that a queue systematically expires for ++ * BFQ_BFQQ_NO_MORE_REQUESTS and presents a ++ * new request in time to enjoy timestamp ++ * back-shifting. The larger the budget of the ++ * queue is with respect to the service the ++ * queue actually requests in each service ++ * slot, the more times the queue can be ++ * reactivated with the same virtual finish ++ * time. It follows that, even if this finish ++ * time is pushed to the system virtual time ++ * to reduce the consequent timestamp ++ * misalignment, the queue unjustly enjoys for ++ * many re-activations a lower finish time ++ * than all newly activated queues. ++ * ++ * The service needed by bfqq is measured ++ * quite precisely by bfqq->entity.service. ++ * Since bfqq does not enjoy device idling, ++ * bfqq->entity.service is equal to the number ++ * of sectors that the process associated with ++ * bfqq requested to read/write before waiting ++ * for request completions, or blocking for ++ * other reasons. ++ */ ++ budget = max_t(int, bfqq->entity.service, min_budget); ++ break; ++ default: ++ return; ++ } ++ } else if (!bfq_bfqq_sync(bfqq)) ++ /* ++ * Async queues get always the maximum possible ++ * budget, as for them we do not care about latency ++ * (in addition, their ability to dispatch is limited ++ * by the charging factor). ++ */ ++ budget = bfqd->bfq_max_budget; ++ ++ bfqq->max_budget = budget; ++ ++ if (bfqd->budgets_assigned >= bfq_stats_min_budgets && ++ !bfqd->bfq_user_max_budget) ++ bfqq->max_budget = min(bfqq->max_budget, bfqd->bfq_max_budget); ++ ++ /* ++ * If there is still backlog, then assign a new budget, making ++ * sure that it is large enough for the next request. Since ++ * the finish time of bfqq must be kept in sync with the ++ * budget, be sure to call __bfq_bfqq_expire() *after* this ++ * update. ++ * ++ * If there is no backlog, then no need to update the budget; ++ * it will be updated on the arrival of a new request. ++ */ ++ next_rq = bfqq->next_rq; ++ if (next_rq) { ++ BUG_ON(reason == BFQ_BFQQ_TOO_IDLE || ++ reason == BFQ_BFQQ_NO_MORE_REQUESTS); ++ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %d", ++ next_rq ? blk_rq_sectors(next_rq) : 0, ++ bfqq->entity.budget); ++} ++ ++/* ++ * Return true if the process associated with bfqq is "slow". The slow ++ * flag is used, in addition to the budget timeout, to reduce the ++ * amount of service provided to seeky processes, and thus reduce ++ * their chances to lower the throughput. More details in the comments ++ * on the function bfq_bfqq_expire(). ++ * ++ * An important observation is in order: as discussed in the comments ++ * on the function bfq_update_peak_rate(), with devices with internal ++ * queues, it is hard if ever possible to know when and for how long ++ * an I/O request is processed by the device (apart from the trivial ++ * I/O pattern where a new request is dispatched only after the ++ * previous one has been completed). This makes it hard to evaluate ++ * the real rate at which the I/O requests of each bfq_queue are ++ * served. In fact, for an I/O scheduler like BFQ, serving a ++ * bfq_queue means just dispatching its requests during its service ++ * slot (i.e., until the budget of the queue is exhausted, or the ++ * queue remains idle, or, finally, a timeout fires). But, during the ++ * service slot of a bfq_queue, around 100 ms at most, the device may ++ * be even still processing requests of bfq_queues served in previous ++ * service slots. On the opposite end, the requests of the in-service ++ * bfq_queue may be completed after the service slot of the queue ++ * finishes. ++ * ++ * Anyway, unless more sophisticated solutions are used ++ * (where possible), the sum of the sizes of the requests dispatched ++ * during the service slot of a bfq_queue is probably the only ++ * approximation available for the service received by the bfq_queue ++ * during its service slot. And this sum is the quantity used in this ++ * function to evaluate the I/O speed of a process. ++ */ ++static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ bool compensate, enum bfqq_expiration reason, ++ unsigned long *delta_ms) ++{ ++ ktime_t delta_ktime; ++ u32 delta_usecs; ++ bool slow = BFQQ_SEEKY(bfqq); /* if delta too short, use seekyness */ ++ ++ if (!bfq_bfqq_sync(bfqq)) ++ return false; ++ ++ if (compensate) ++ delta_ktime = bfqd->last_idling_start; ++ else ++ delta_ktime = ktime_get(); ++ delta_ktime = ktime_sub(delta_ktime, bfqd->last_budget_start); ++ delta_usecs = ktime_to_us(delta_ktime); ++ ++ /* don't trust short/unrealistic values. */ ++ if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) { ++ if (blk_queue_nonrot(bfqd->queue)) ++ /* ++ * give same worst-case guarantees as idling ++ * for seeky ++ */ ++ *delta_ms = BFQ_MIN_TT / NSEC_PER_MSEC; ++ else /* charge at least one seek */ ++ *delta_ms = bfq_slice_idle / NSEC_PER_MSEC; ++ ++ bfq_log(bfqd, "bfq_bfqq_is_slow: unrealistic %u", delta_usecs); ++ ++ return slow; ++ } ++ ++ *delta_ms = delta_usecs / USEC_PER_MSEC; ++ ++ /* ++ * Use only long (> 20ms) intervals to filter out excessive ++ * spikes in service rate estimation. ++ */ ++ if (delta_usecs > 20000) { ++ /* ++ * Caveat for rotational devices: processes doing I/O ++ * in the slower disk zones tend to be slow(er) even ++ * if not seeky. In this respect, the estimated peak ++ * rate is likely to be an average over the disk ++ * surface. Accordingly, to not be too harsh with ++ * unlucky processes, a process is deemed slow only if ++ * its rate has been lower than half of the estimated ++ * peak rate. ++ */ ++ slow = bfqq->entity.service < bfqd->bfq_max_budget / 2; ++ bfq_log(bfqd, "bfq_bfqq_is_slow: relative rate %d/%d", ++ bfqq->entity.service, bfqd->bfq_max_budget); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "bfq_bfqq_is_slow: slow %d", slow); ++ ++ return slow; ++} ++ ++/* ++ * To be deemed as soft real-time, an application must meet two ++ * requirements. First, the application must not require an average ++ * bandwidth higher than the approximate bandwidth required to playback or ++ * record a compressed high-definition video. ++ * The next function is invoked on the completion of the last request of a ++ * batch, to compute the next-start time instant, soft_rt_next_start, such ++ * that, if the next request of the application does not arrive before ++ * soft_rt_next_start, then the above requirement on the bandwidth is met. ++ * ++ * The second requirement is that the request pattern of the application is ++ * isochronous, i.e., that, after issuing a request or a batch of requests, ++ * the application stops issuing new requests until all its pending requests ++ * have been completed. After that, the application may issue a new batch, ++ * and so on. ++ * For this reason the next function is invoked to compute ++ * soft_rt_next_start only for applications that meet this requirement, ++ * whereas soft_rt_next_start is set to infinity for applications that do ++ * not. ++ * ++ * Unfortunately, even a greedy application may happen to behave in an ++ * isochronous way if the CPU load is high. In fact, the application may ++ * stop issuing requests while the CPUs are busy serving other processes, ++ * then restart, then stop again for a while, and so on. In addition, if ++ * the disk achieves a low enough throughput with the request pattern ++ * issued by the application (e.g., because the request pattern is random ++ * and/or the device is slow), then the application may meet the above ++ * bandwidth requirement too. To prevent such a greedy application to be ++ * deemed as soft real-time, a further rule is used in the computation of ++ * soft_rt_next_start: soft_rt_next_start must be higher than the current ++ * time plus the maximum time for which the arrival of a request is waited ++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. ++ * This filters out greedy applications, as the latter issue instead their ++ * next request as soon as possible after the last one has been completed ++ * (in contrast, when a batch of requests is completed, a soft real-time ++ * application spends some time processing data). ++ * ++ * Unfortunately, the last filter may easily generate false positives if ++ * only bfqd->bfq_slice_idle is used as a reference time interval and one ++ * or both the following cases occur: ++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher ++ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with ++ * HZ=100. ++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing ++ * for a while, then suddenly 'jump' by several units to recover the lost ++ * increments. This seems to happen, e.g., inside virtual machines. ++ * To address this issue, we do not use as a reference time interval just ++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In ++ * particular we add the minimum number of jiffies for which the filter ++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual ++ * machines. ++ */ ++static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, ++"softrt_next_start: service_blkg %lu soft_rate %u sects/sec interval %u", ++ bfqq->service_from_backlogged, ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies_to_msecs(HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate)); ++ ++ return max(bfqq->last_idle_bklogged + ++ HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4); ++} ++ ++/* ++ * Return the farthest future time instant according to jiffies ++ * macros. ++ */ ++static unsigned long bfq_greatest_from_now(void) ++{ ++ return jiffies + MAX_JIFFY_OFFSET; ++} ++ ++/* ++ * Return the farthest past time instant according to jiffies ++ * macros. ++ */ ++static unsigned long bfq_smallest_from_now(void) ++{ ++ return jiffies - MAX_JIFFY_OFFSET; ++} ++ ++/** ++ * bfq_bfqq_expire - expire a queue. ++ * @bfqd: device owning the queue. ++ * @bfqq: the queue to expire. ++ * @compensate: if true, compensate for the time spent idling. ++ * @reason: the reason causing the expiration. ++ * ++ * If the process associated with bfqq does slow I/O (e.g., because it ++ * issues random requests), we charge bfqq with the time it has been ++ * in service instead of the service it has received (see ++ * bfq_bfqq_charge_time for details on how this goal is achieved). As ++ * a consequence, bfqq will typically get higher timestamps upon ++ * reactivation, and hence it will be rescheduled as if it had ++ * received more service than what it has actually received. In the ++ * end, bfqq receives less service in proportion to how slowly its ++ * associated process consumes its budgets (and hence how seriously it ++ * tends to lower the throughput). In addition, this time-charging ++ * strategy guarantees time fairness among slow processes. In ++ * contrast, if the process associated with bfqq is not slow, we ++ * charge bfqq exactly with the service it has received. ++ * ++ * Charging time to the first type of queues and the exact service to ++ * the other has the effect of using the WF2Q+ policy to schedule the ++ * former on a timeslice basis, without violating service domain ++ * guarantees among the latter. ++ */ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason) ++{ ++ bool slow; ++ unsigned long delta = 0; ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ /* ++ * Check whether the process is slow (see bfq_bfqq_is_slow). ++ */ ++ slow = bfq_bfqq_is_slow(bfqd, bfqq, compensate, reason, &delta); ++ ++ /* ++ * Increase service_from_backlogged before next statement, ++ * because the possible next invocation of ++ * bfq_bfqq_charge_time would likely inflate ++ * entity->service. In contrast, service_from_backlogged must ++ * contain real service, to enable the soft real-time ++ * heuristic to correctly compute the bandwidth consumed by ++ * bfqq. ++ */ ++ bfqq->service_from_backlogged += entity->service; ++ ++ /* ++ * As above explained, charge slow (typically seeky) and ++ * timed-out queues with the time and not the service ++ * received, to favor sequential workloads. ++ * ++ * Processes doing I/O in the slower disk zones will tend to ++ * be slow(er) even if not seeky. Therefore, since the ++ * estimated peak rate is actually an average over the disk ++ * surface, these processes may timeout just for bad luck. To ++ * avoid punishing them, do not charge time to processes that ++ * succeeded in consuming at least 2/3 of their budget. This ++ * allows BFQ to preserve enough elasticity to still perform ++ * bandwidth, and not time, distribution with little unlucky ++ * or quasi-sequential processes. ++ */ ++ if (bfqq->wr_coeff == 1 && ++ (slow || ++ (reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ bfq_bfqq_budget_left(bfqq) >= entity->budget / 3))) ++ bfq_bfqq_charge_time(bfqd, bfqq, delta); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ if (reason == BFQ_BFQQ_TOO_IDLE && ++ entity->service <= 2 * entity->budget / 10) ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ if (bfqd->low_latency && bfqq->wr_coeff == 1) ++ bfqq->last_wr_start_finish = jiffies; ++ ++ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * If we get here, and there are no outstanding ++ * requests, then the request pattern is isochronous ++ * (see the comments on the function ++ * bfq_bfqq_softrt_next_start()). Thus we can compute ++ * soft_rt_next_start. If, instead, the queue still ++ * has outstanding requests, then we have to wait for ++ * the completion of all the outstanding requests to ++ * discover whether the request pattern is actually ++ * isochronous. ++ */ ++ BUG_ON(bfqd->busy_queues < 1); ++ if (bfqq->dispatched == 0) { ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, "new soft_rt_next %lu", ++ bfqq->soft_rt_next_start); ++ } else { ++ /* ++ * The application is still waiting for the ++ * completion of one or more requests: ++ * prevent it from possibly being incorrectly ++ * deemed as soft real-time by setting its ++ * soft_rt_next_start to infinity. In fact, ++ * without this assignment, the application ++ * would be incorrectly deemed as soft ++ * real-time if: ++ * 1) it issued a new request before the ++ * completion of all its in-flight ++ * requests, and ++ * 2) at that time, its soft_rt_next_start ++ * happened to be in the past. ++ */ ++ bfqq->soft_rt_next_start = ++ bfq_greatest_from_now(); ++ /* ++ * Schedule an update of soft_rt_next_start to when ++ * the task may be discovered to be isochronous. ++ */ ++ bfq_mark_bfqq_softrt_update(bfqq); ++ } ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "expire (%d, slow %d, num_disp %d, idle_win %d, weight %d)", ++ reason, slow, bfqq->dispatched, ++ bfq_bfqq_idle_window(bfqq), entity->weight); ++ ++ /* ++ * Increase, decrease or leave budget unchanged according to ++ * reason. ++ */ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); ++ BUG_ON(bfqq->next_rq == NULL && ++ bfqq->entity.budget < bfqq->entity.service); ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED && ++ !bfq_class_idle(bfqq)); ++ ++ if (!bfq_bfqq_busy(bfqq) && ++ reason != BFQ_BFQQ_BUDGET_TIMEOUT && ++ reason != BFQ_BFQQ_BUDGET_EXHAUSTED) ++ bfq_mark_bfqq_non_blocking_wait_rq(bfqq); ++} ++ ++/* ++ * Budget timeout is not implemented through a dedicated timer, but ++ * just checked on request arrivals and completions, as well as on ++ * idle timer expirations. ++ */ ++static bool bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) ++{ ++ return time_is_before_eq_jiffies(bfqq->budget_timeout); ++} ++ ++/* ++ * If we expire a queue that is actively waiting (i.e., with the ++ * device idled) for the arrival of a new request, then we may incur ++ * the timestamp misalignment problem described in the body of the ++ * function __bfq_activate_entity. Hence we return true only if this ++ * condition does not hold, or if the queue is slow enough to deserve ++ * only to be kicked off for preserving a high throughput. ++ */ ++static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "may_budget_timeout: wait_request %d left %d timeout %d", ++ bfq_bfqq_wait_request(bfqq), ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, ++ bfq_bfqq_budget_timeout(bfqq)); ++ ++ return (!bfq_bfqq_wait_request(bfqq) || ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) ++ && ++ bfq_bfqq_budget_timeout(bfqq); ++} ++ ++/* ++ * For a queue that becomes empty, device idling is allowed only if ++ * this function returns true for that queue. As a consequence, since ++ * device idling plays a critical role for both throughput boosting ++ * and service guarantees, the return value of this function plays a ++ * critical role as well. ++ * ++ * In a nutshell, this function returns true only if idling is ++ * beneficial for throughput or, even if detrimental for throughput, ++ * idling is however necessary to preserve service guarantees (low ++ * latency, desired throughput distribution, ...). In particular, on ++ * NCQ-capable devices, this function tries to return false, so as to ++ * help keep the drives' internal queues full, whenever this helps the ++ * device boost the throughput without causing any service-guarantee ++ * issue. ++ * ++ * In more detail, the return value of this function is obtained by, ++ * first, computing a number of boolean variables that take into ++ * account throughput and service-guarantee issues, and, then, ++ * combining these variables in a logical expression. Most of the ++ * issues taken into account are not trivial. We discuss these issues ++ * while introducing the variables. ++ */ ++static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ bool idling_boosts_thr, idling_boosts_thr_without_issues, ++ idling_needed_for_service_guarantees, ++ asymmetric_scenario; ++ ++ if (bfqd->strict_guarantees) ++ return true; ++ ++ /* ++ * The next variable takes into account the cases where idling ++ * boosts the throughput. ++ * ++ * The value of the variable is computed considering, first, that ++ * idling is virtually always beneficial for the throughput if: ++ * (a) the device is not NCQ-capable, or ++ * (b) regardless of the presence of NCQ, the device is rotational ++ * and the request pattern for bfqq is I/O-bound and sequential. ++ * ++ * Secondly, and in contrast to the above item (b), idling an ++ * NCQ-capable flash-based device would not boost the ++ * throughput even with sequential I/O; rather it would lower ++ * the throughput in proportion to how fast the device ++ * is. Accordingly, the next variable is true if any of the ++ * above conditions (a) and (b) is true, and, in particular, ++ * happens to be false if bfqd is an NCQ-capable flash-based ++ * device. ++ */ ++ idling_boosts_thr = !bfqd->hw_tag || ++ (!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && ++ bfq_bfqq_idle_window(bfqq)); ++ ++ /* ++ * The value of the next variable, ++ * idling_boosts_thr_without_issues, is equal to that of ++ * idling_boosts_thr, unless a special case holds. In this ++ * special case, described below, idling may cause problems to ++ * weight-raised queues. ++ * ++ * When the request pool is saturated (e.g., in the presence ++ * of write hogs), if the processes associated with ++ * non-weight-raised queues ask for requests at a lower rate, ++ * then processes associated with weight-raised queues have a ++ * higher probability to get a request from the pool ++ * immediately (or at least soon) when they need one. Thus ++ * they have a higher probability to actually get a fraction ++ * of the device throughput proportional to their high ++ * weight. This is especially true with NCQ-capable drives, ++ * which enqueue several requests in advance, and further ++ * reorder internally-queued requests. ++ * ++ * For this reason, we force to false the value of ++ * idling_boosts_thr_without_issues if there are weight-raised ++ * busy queues. In this case, and if bfqq is not weight-raised, ++ * this guarantees that the device is not idled for bfqq (if, ++ * instead, bfqq is weight-raised, then idling will be ++ * guaranteed by another variable, see below). Combined with ++ * the timestamping rules of BFQ (see [1] for details), this ++ * behavior causes bfqq, and hence any sync non-weight-raised ++ * queue, to get a lower number of requests served, and thus ++ * to ask for a lower number of requests from the request ++ * pool, before the busy weight-raised queues get served ++ * again. This often mitigates starvation problems in the ++ * presence of heavy write workloads and NCQ, thereby ++ * guaranteeing a higher application and system responsiveness ++ * in these hostile scenarios. ++ */ ++ idling_boosts_thr_without_issues = idling_boosts_thr && ++ bfqd->wr_busy_queues == 0; ++ ++ /* ++ * There is then a case where idling must be performed not ++ * for throughput concerns, but to preserve service ++ * guarantees. ++ * ++ * To introduce this case, we can note that allowing the drive ++ * to enqueue more than one request at a time, and hence ++ * delegating de facto final scheduling decisions to the ++ * drive's internal scheduler, entails loss of control on the ++ * actual request service order. In particular, the critical ++ * situation is when requests from different processes happen ++ * to be present, at the same time, in the internal queue(s) ++ * of the drive. In such a situation, the drive, by deciding ++ * the service order of the internally-queued requests, does ++ * determine also the actual throughput distribution among ++ * these processes. But the drive typically has no notion or ++ * concern about per-process throughput distribution, and ++ * makes its decisions only on a per-request basis. Therefore, ++ * the service distribution enforced by the drive's internal ++ * scheduler is likely to coincide with the desired ++ * device-throughput distribution only in a completely ++ * symmetric scenario where: ++ * (i) each of these processes must get the same throughput as ++ * the others; ++ * (ii) all these processes have the same I/O pattern ++ * (either sequential or random). ++ * In fact, in such a scenario, the drive will tend to treat ++ * the requests of each of these processes in about the same ++ * way as the requests of the others, and thus to provide ++ * each of these processes with about the same throughput ++ * (which is exactly the desired throughput distribution). In ++ * contrast, in any asymmetric scenario, device idling is ++ * certainly needed to guarantee that bfqq receives its ++ * assigned fraction of the device throughput (see [1] for ++ * details). ++ * ++ * We address this issue by controlling, actually, only the ++ * symmetry sub-condition (i), i.e., provided that ++ * sub-condition (i) holds, idling is not performed, ++ * regardless of whether sub-condition (ii) holds. In other ++ * words, only if sub-condition (i) holds, then idling is ++ * allowed, and the device tends to be prevented from queueing ++ * many requests, possibly of several processes. The reason ++ * for not controlling also sub-condition (ii) is that we ++ * exploit preemption to preserve guarantees in case of ++ * symmetric scenarios, even if (ii) does not hold, as ++ * explained in the next two paragraphs. ++ * ++ * Even if a queue, say Q, is expired when it remains idle, Q ++ * can still preempt the new in-service queue if the next ++ * request of Q arrives soon (see the comments on ++ * bfq_bfqq_update_budg_for_activation). If all queues and ++ * groups have the same weight, this form of preemption, ++ * combined with the hole-recovery heuristic described in the ++ * comments on function bfq_bfqq_update_budg_for_activation, ++ * are enough to preserve a correct bandwidth distribution in ++ * the mid term, even without idling. In fact, even if not ++ * idling allows the internal queues of the device to contain ++ * many requests, and thus to reorder requests, we can rather ++ * safely assume that the internal scheduler still preserves a ++ * minimum of mid-term fairness. The motivation for using ++ * preemption instead of idling is that, by not idling, ++ * service guarantees are preserved without minimally ++ * sacrificing throughput. In other words, both a high ++ * throughput and its desired distribution are obtained. ++ * ++ * More precisely, this preemption-based, idleless approach ++ * provides fairness in terms of IOPS, and not sectors per ++ * second. This can be seen with a simple example. Suppose ++ * that there are two queues with the same weight, but that ++ * the first queue receives requests of 8 sectors, while the ++ * second queue receives requests of 1024 sectors. In ++ * addition, suppose that each of the two queues contains at ++ * most one request at a time, which implies that each queue ++ * always remains idle after it is served. Finally, after ++ * remaining idle, each queue receives very quickly a new ++ * request. It follows that the two queues are served ++ * alternatively, preempting each other if needed. This ++ * implies that, although both queues have the same weight, ++ * the queue with large requests receives a service that is ++ * 1024/8 times as high as the service received by the other ++ * queue. ++ * ++ * On the other hand, device idling is performed, and thus ++ * pure sector-domain guarantees are provided, for the ++ * following queues, which are likely to need stronger ++ * throughput guarantees: weight-raised queues, and queues ++ * with a higher weight than other queues. When such queues ++ * are active, sub-condition (i) is false, which triggers ++ * device idling. ++ * ++ * According to the above considerations, the next variable is ++ * true (only) if sub-condition (i) holds. To compute the ++ * value of this variable, we not only use the return value of ++ * the function bfq_symmetric_scenario(), but also check ++ * whether bfqq is being weight-raised, because ++ * bfq_symmetric_scenario() does not take into account also ++ * weight-raised queues (see comments on ++ * bfq_weights_tree_add()). ++ * ++ * As a side note, it is worth considering that the above ++ * device-idling countermeasures may however fail in the ++ * following unlucky scenario: if idling is (correctly) ++ * disabled in a time period during which all symmetry ++ * sub-conditions hold, and hence the device is allowed to ++ * enqueue many requests, but at some later point in time some ++ * sub-condition stops to hold, then it may become impossible ++ * to let requests be served in the desired order until all ++ * the requests already queued in the device have been served. ++ */ ++ asymmetric_scenario = bfqq->wr_coeff > 1 || ++ !bfq_symmetric_scenario(bfqd); ++ ++ /* ++ * Finally, there is a case where maximizing throughput is the ++ * best choice even if it may cause unfairness toward ++ * bfqq. Such a case is when bfqq became active in a burst of ++ * queue activations. Queues that became active during a large ++ * burst benefit only from throughput, as discussed in the ++ * comments on bfq_handle_burst. Thus, if bfqq became active ++ * in a burst and not idling the device maximizes throughput, ++ * then the device must no be idled, because not idling the ++ * device provides bfqq and all other queues in the burst with ++ * maximum benefit. Combining this and the above case, we can ++ * now establish when idling is actually needed to preserve ++ * service guarantees. ++ */ ++ idling_needed_for_service_guarantees = ++ asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq); ++ ++ /* ++ * We have now all the components we need to compute the return ++ * value of the function, which is true only if both the following ++ * conditions hold: ++ * 1) bfqq is sync, because idling make sense only for sync queues; ++ * 2) idling either boosts the throughput (without issues), or ++ * is necessary to preserve service guarantees. ++ */ ++ bfq_log_bfqq(bfqd, bfqq, "may_idle: sync %d idling_boosts_thr %d", ++ bfq_bfqq_sync(bfqq), idling_boosts_thr); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "may_idle: wr_busy %d boosts %d IO-bound %d guar %d", ++ bfqd->wr_busy_queues, ++ idling_boosts_thr_without_issues, ++ bfq_bfqq_IO_bound(bfqq), ++ idling_needed_for_service_guarantees); ++ ++ return bfq_bfqq_sync(bfqq) && ++ (idling_boosts_thr_without_issues || ++ idling_needed_for_service_guarantees); ++} ++ ++/* ++ * If the in-service queue is empty but the function bfq_bfqq_may_idle ++ * returns true, then: ++ * 1) the queue must remain in service and cannot be expired, and ++ * 2) the device must be idled to wait for the possible arrival of a new ++ * request for the queue. ++ * See the comments on the function bfq_bfqq_may_idle for the reasons ++ * why performing device idling is the best choice to boost the throughput ++ * and preserve service guarantees when bfq_bfqq_may_idle itself ++ * returns true. ++ */ ++static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && ++ bfq_bfqq_may_idle(bfqq); ++} ++ ++/* ++ * Select a queue for service. If we have a current queue in service, ++ * check whether to continue servicing it, or retrieve and set a new one. ++ */ ++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ struct request *next_rq; ++ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ ++ bfqq = bfqd->in_service_queue; ++ if (!bfqq) ++ goto new_queue; ++ ++ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); ++ ++ if (bfq_may_expire_for_budg_timeout(bfqq) && ++ !hrtimer_active(&bfqd->idle_slice_timer) && ++ !bfq_bfqq_must_idle(bfqq)) ++ goto expire; ++ ++ next_rq = bfqq->next_rq; ++ /* ++ * If bfqq has requests queued and it has enough budget left to ++ * serve them, keep the queue, otherwise expire it. ++ */ ++ if (next_rq) { ++ if (bfq_serv_to_charge(next_rq, bfqq) > ++ bfq_bfqq_budget_left(bfqq)) { ++ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; ++ goto expire; ++ } else { ++ /* ++ * The idle timer may be pending because we may ++ * not disable disk idling even when a new request ++ * arrives. ++ */ ++ if (bfq_bfqq_wait_request(bfqq)) { ++ BUG_ON(!hrtimer_active(&bfqd->idle_slice_timer)); ++ /* ++ * If we get here: 1) at least a new request ++ * has arrived but we have not disabled the ++ * timer because the request was too small, ++ * 2) then the block layer has unplugged ++ * the device, causing the dispatch to be ++ * invoked. ++ * ++ * Since the device is unplugged, now the ++ * requests are probably large enough to ++ * provide a reasonable throughput. ++ * So we disable idling. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqg_stats_update_idle_time(bfqq_group(bfqq)); ++ } ++ goto keep_queue; ++ } ++ } ++ ++ /* ++ * No requests pending. However, if the in-service queue is idling ++ * for a new request, or has requests waiting for a completion and ++ * may idle after their completion, then keep it anyway. ++ */ ++ if (hrtimer_active(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_may_idle(bfqq))) { ++ bfqq = NULL; ++ goto keep_queue; ++ } ++ ++ reason = BFQ_BFQQ_NO_MORE_REQUESTS; ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, false, reason); ++new_queue: ++ bfqq = bfq_set_in_service_queue(bfqd); ++ bfq_log(bfqd, "select_queue: new queue %d returned", ++ bfqq ? bfqq->pid : 0); ++keep_queue: ++ return bfqq; ++} ++ ++static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ ++ BUG_ON(bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time && ++ time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != ++ entity->orig_weight * bfqq->wr_coeff); ++ if (entity->prio_changed) ++ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ ++ /* ++ * If the queue was activated in a burst, or too much ++ * time has elapsed from the beginning of this ++ * weight-raising period, then end weight raising. ++ */ ++ if (bfq_bfqq_in_large_burst(bfqq)) ++ bfq_bfqq_end_wr(bfqq); ++ else if (time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time)) { ++ if (bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time || ++ time_is_before_jiffies(bfqq->wr_start_at_switch_to_srt + ++ bfq_wr_duration(bfqd))) ++ bfq_bfqq_end_wr(bfqq); ++ else { ++ /* switch back to interactive wr */ ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ bfqq->last_wr_start_finish = ++ bfqq->wr_start_at_switch_to_srt; ++ BUG_ON(time_is_after_jiffies( ++ bfqq->last_wr_start_finish)); ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "back to interactive wr"); ++ } ++ } ++ } ++ /* Update weight both if it must be raised and if it must be lowered */ ++ if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); ++} ++ ++/* ++ * Dispatch one request from bfqq, moving it to the request queue ++ * dispatch list. ++ */ ++static int bfq_dispatch_request(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ struct request *rq; ++ unsigned long service_to_charge; ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Follow expired path, else get first next available. */ ++ rq = bfq_check_fifo(bfqq); ++ if (!rq) ++ rq = bfqq->next_rq; ++ service_to_charge = bfq_serv_to_charge(rq, bfqq); ++ ++ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { ++ /* ++ * This may happen if the next rq is chosen in fifo order ++ * instead of sector order. The budget is properly ++ * dimensioned to be always sufficient to serve the next ++ * request only if it is chosen in sector order. The reason ++ * is that it would be quite inefficient and little useful ++ * to always make sure that the budget is large enough to ++ * serve even the possible next rq in fifo order. ++ * In fact, requests are seldom served in fifo order. ++ * ++ * Expire the queue for budget exhaustion, and make sure ++ * that the next act_budget is enough to serve the next ++ * request, even if it comes from the fifo expired path. ++ */ ++ bfqq->next_rq = rq; ++ /* ++ * Since this dispatch is failed, make sure that ++ * a new one will be performed ++ */ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ goto expire; ++ } ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ /* Finally, insert request into driver dispatch list. */ ++ bfq_bfqq_served(bfqq, service_to_charge); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ bfq_dispatch_insert(bfqd->queue, rq); ++ ++ /* ++ * If weight raising has to terminate for bfqq, then next ++ * function causes an immediate update of bfqq's weight, ++ * without waiting for next activation. As a consequence, on ++ * expiration, bfqq will be timestamped as if has never been ++ * weight-raised during this service slot, even if it has ++ * received part or even most of the service as a ++ * weight-raised queue. This inflates bfqq's timestamps, which ++ * is beneficial, as bfqq is then more willing to leave the ++ * device immediately to possible other weight-raised queues. ++ */ ++ bfq_update_wr_data(bfqd, bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "dispatched %u sec req (%llu), budg left %d", ++ blk_rq_sectors(rq), ++ (unsigned long long) blk_rq_pos(rq), ++ bfq_bfqq_budget_left(bfqq)); ++ ++ dispatched++; ++ ++ if (!bfqd->in_service_bic) { ++ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); ++ bfqd->in_service_bic = RQ_BIC(rq); ++ } ++ ++ if (bfqd->busy_queues > 1 && bfq_class_idle(bfqq)) ++ goto expire; ++ ++ return dispatched; ++ ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, false, BFQ_BFQQ_BUDGET_EXHAUSTED); ++ return dispatched; ++} ++ ++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ ++ while (bfqq->next_rq) { ++ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); ++ dispatched++; ++ } ++ ++ BUG_ON(!list_empty(&bfqq->fifo)); ++ return dispatched; ++} ++ ++/* ++ * Drain our current requests. ++ * Used for barriers and when switching io schedulers on-the-fly. ++ */ ++static int bfq_forced_dispatch(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *n; ++ struct bfq_service_tree *st; ++ int dispatched = 0; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq) ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ /* ++ * Loop through classes, and be careful to leave the scheduler ++ * in a consistent state, as feedback mechanisms and vtime ++ * updates cannot be disabled during the process. ++ */ ++ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { ++ st = bfq_entity_service_tree(&bfqq->entity); ++ ++ dispatched += __bfq_forced_dispatch_bfqq(bfqq); ++ ++ bfqq->max_budget = bfq_max_budget(bfqd); ++ bfq_forget_idle(st); ++ } ++ ++ BUG_ON(bfqd->busy_queues != 0); ++ ++ return dispatched; ++} ++ ++static int bfq_dispatch_requests(struct request_queue *q, int force) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq; ++ ++ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); ++ ++ if (bfqd->busy_queues == 0) ++ return 0; ++ ++ if (unlikely(force)) ++ return bfq_forced_dispatch(bfqd); ++ ++ /* ++ * Force device to serve one request at a time if ++ * strict_guarantees is true. Forcing this service scheme is ++ * currently the ONLY way to guarantee that the request ++ * service order enforced by the scheduler is respected by a ++ * queueing device. Otherwise the device is free even to make ++ * some unlucky request wait for as long as the device ++ * wishes. ++ * ++ * Of course, serving one request at at time may cause loss of ++ * throughput. ++ */ ++ if (bfqd->strict_guarantees && bfqd->rq_in_driver > 0) ++ return 0; ++ ++ bfqq = bfq_select_queue(bfqd); ++ if (!bfqq) ++ return 0; ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ BUG_ON(bfq_bfqq_wait_request(bfqq)); ++ ++ if (!bfq_dispatch_request(bfqd, bfqq)) ++ return 0; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dispatched %s request", ++ bfq_bfqq_sync(bfqq) ? "sync" : "async"); ++ ++ BUG_ON(bfqq->next_rq == NULL && ++ bfqq->entity.budget < bfqq->entity.service); ++ return 1; ++} ++ ++/* ++ * Task holds one reference to the queue, dropped when task exits. Each rq ++ * in-flight on this queue also holds a reference, dropped when rq is freed. ++ * ++ * Queue lock must be held here. ++ */ ++static void bfq_put_queue(struct bfq_queue *bfqq) ++{ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_group *bfqg = bfqq_group(bfqq); ++#endif ++ ++ BUG_ON(bfqq->ref <= 0); ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref); ++ bfqq->ref--; ++ if (bfqq->ref) ++ return; ++ ++ BUG_ON(rb_first(&bfqq->sort_list)); ++ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); ++ BUG_ON(bfqq->entity.tree); ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq->bfqd->in_service_queue == bfqq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ /* ++ * The fact that this queue is being destroyed does not ++ * invalidate the fact that this queue may have been ++ * activated during the current burst. As a consequence, ++ * although the queue does not exist anymore, and hence ++ * needs to be removed from the burst list if there, ++ * the burst size has not to be decremented. ++ */ ++ hlist_del_init(&bfqq->burst_list_node); ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p freed", bfqq); ++ ++ kmem_cache_free(bfq_pool, bfqq); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ bfqg_put(bfqg); ++#endif ++} ++ ++static void bfq_put_cooperator(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *__bfqq, *next; ++ ++ /* ++ * If this queue was scheduled to merge with another queue, be ++ * sure to drop the reference taken on that queue (and others in ++ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. ++ */ ++ __bfqq = bfqq->new_bfqq; ++ while (__bfqq) { ++ if (__bfqq == bfqq) ++ break; ++ next = __bfqq->new_bfqq; ++ bfq_put_queue(__bfqq); ++ __bfqq = next; ++ } ++} ++ ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ if (bfqq == bfqd->in_service_queue) { ++ __bfq_bfqq_expire(bfqd, bfqq); ++ bfq_schedule_dispatch(bfqd); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, bfqq->ref); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++} ++ ++static void bfq_init_icq(struct io_cq *icq) ++{ ++ icq_to_bic(icq)->ttime.last_end_request = ktime_get_ns() - (1ULL<<32); ++} ++ ++static void bfq_exit_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ if (bic_to_bfqq(bic, false)) { ++ bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, false)); ++ bic_set_bfqq(bic, NULL, false); ++ } ++ ++ if (bic_to_bfqq(bic, true)) { ++ /* ++ * If the bic is using a shared queue, put the reference ++ * taken on the io_context when the bic started using a ++ * shared bfq_queue. ++ */ ++ if (bfq_bfqq_coop(bic_to_bfqq(bic, true))) ++ put_io_context(icq->ioc); ++ bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, true)); ++ bic_set_bfqq(bic, NULL, true); ++ } ++} ++ ++/* ++ * Update the entity prio values; note that the new values will not ++ * be used until the next (re)activation. ++ */ ++static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ struct task_struct *tsk = current; ++ int ioprio_class; ++ ++ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ switch (ioprio_class) { ++ default: ++ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, ++ "bfq: bad prio class %d\n", ioprio_class); ++ case IOPRIO_CLASS_NONE: ++ /* ++ * No prio set, inherit CPU scheduling settings. ++ */ ++ bfqq->new_ioprio = task_nice_ioprio(tsk); ++ bfqq->new_ioprio_class = task_nice_ioclass(tsk); ++ break; ++ case IOPRIO_CLASS_RT: ++ bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->new_ioprio_class = IOPRIO_CLASS_RT; ++ break; ++ case IOPRIO_CLASS_BE: ++ bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->new_ioprio_class = IOPRIO_CLASS_BE; ++ break; ++ case IOPRIO_CLASS_IDLE: ++ bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE; ++ bfqq->new_ioprio = 7; ++ bfq_clear_bfqq_idle_window(bfqq); ++ break; ++ } ++ ++ if (bfqq->new_ioprio >= IOPRIO_BE_NR) { ++ pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n", ++ bfqq->new_ioprio); ++ BUG(); ++ } ++ ++ bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio); ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "set_next_ioprio_data: bic_class %d prio %d class %d", ++ ioprio_class, bfqq->new_ioprio, bfqq->new_ioprio_class); ++} ++ ++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_queue *bfqq; ++ unsigned long uninitialized_var(flags); ++ int ioprio = bic->icq.ioc->ioprio; ++ ++ /* ++ * This condition may trigger on a newly created bic, be sure to ++ * drop the lock before returning. ++ */ ++ if (unlikely(!bfqd) || likely(bic->ioprio == ioprio)) ++ return; ++ ++ bic->ioprio = ioprio; ++ ++ bfqq = bic_to_bfqq(bic, false); ++ if (bfqq) { ++ bfq_put_queue(bfqq); ++ bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic); ++ bic_set_bfqq(bic, bfqq, false); ++ bfq_log_bfqq(bfqd, bfqq, ++ "check_ioprio_change: bfqq %p %d", ++ bfqq, bfqq->ref); ++ } ++ ++ bfqq = bic_to_bfqq(bic, true); ++ if (bfqq) ++ bfq_set_next_ioprio_data(bfqq, bic); ++} ++ ++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic, pid_t pid, int is_sync) ++{ ++ RB_CLEAR_NODE(&bfqq->entity.rb_node); ++ INIT_LIST_HEAD(&bfqq->fifo); ++ INIT_HLIST_NODE(&bfqq->burst_list_node); ++ BUG_ON(!hlist_unhashed(&bfqq->burst_list_node)); ++ ++ bfqq->ref = 0; ++ bfqq->bfqd = bfqd; ++ ++ if (bic) ++ bfq_set_next_ioprio_data(bfqq, bic); ++ ++ if (is_sync) { ++ if (!bfq_class_idle(bfqq)) ++ bfq_mark_bfqq_idle_window(bfqq); ++ bfq_mark_bfqq_sync(bfqq); ++ bfq_mark_bfqq_just_created(bfqq); ++ } else ++ bfq_clear_bfqq_sync(bfqq); ++ bfq_mark_bfqq_IO_bound(bfqq); ++ ++ /* Tentative initial value to trade off between thr and lat */ ++ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; ++ bfqq->pid = pid; ++ ++ bfqq->wr_coeff = 1; ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->wr_start_at_switch_to_srt = bfq_smallest_from_now(); ++ bfqq->budget_timeout = bfq_smallest_from_now(); ++ bfqq->split_time = bfq_smallest_from_now(); ++ ++ /* ++ * Set to the value for which bfqq will not be deemed as ++ * soft rt when it becomes backlogged. ++ */ ++ bfqq->soft_rt_next_start = bfq_greatest_from_now(); ++ ++ /* first request is almost certainly seeky */ ++ bfqq->seek_history = 1; ++} ++ ++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int ioprio_class, int ioprio) ++{ ++ switch (ioprio_class) { ++ case IOPRIO_CLASS_RT: ++ return &bfqg->async_bfqq[0][ioprio]; ++ case IOPRIO_CLASS_NONE: ++ ioprio = IOPRIO_NORM; ++ /* fall through */ ++ case IOPRIO_CLASS_BE: ++ return &bfqg->async_bfqq[1][ioprio]; ++ case IOPRIO_CLASS_IDLE: ++ return &bfqg->async_idle_bfqq; ++ default: ++ BUG(); ++ } ++} ++ ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bio *bio, bool is_sync, ++ struct bfq_io_cq *bic) ++{ ++ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ struct bfq_queue **async_bfqq = NULL; ++ struct bfq_queue *bfqq; ++ struct bfq_group *bfqg; ++ ++ rcu_read_lock(); ++ ++ bfqg = bfq_find_set_group(bfqd, bio_blkcg(bio)); ++ if (!bfqg) { ++ bfqq = &bfqd->oom_bfqq; ++ goto out; ++ } ++ ++ if (!is_sync) { ++ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ++ ioprio); ++ bfqq = *async_bfqq; ++ if (bfqq) ++ goto out; ++ } ++ ++ bfqq = kmem_cache_alloc_node(bfq_pool, GFP_NOWAIT | __GFP_ZERO, ++ bfqd->queue->node); ++ ++ if (bfqq) { ++ bfq_init_bfqq(bfqd, bfqq, bic, current->pid, ++ is_sync); ++ bfq_init_entity(&bfqq->entity, bfqg); ++ bfq_log_bfqq(bfqd, bfqq, "allocated"); ++ } else { ++ bfqq = &bfqd->oom_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); ++ goto out; ++ } ++ ++ /* ++ * Pin the queue now that it's allocated, scheduler exit will ++ * prune it. ++ */ ++ if (async_bfqq) { ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", ++ bfqq, bfqq->ref); ++ *async_bfqq = bfqq; ++ } ++ ++out: ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref); ++ rcu_read_unlock(); ++ return bfqq; ++} ++ ++static void bfq_update_io_thinktime(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic) ++{ ++ struct bfq_ttime *ttime = &bic->ttime; ++ u64 elapsed = ktime_get_ns() - bic->ttime.last_end_request; ++ ++ elapsed = min_t(u64, elapsed, 2 * bfqd->bfq_slice_idle); ++ ++ ttime->ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; ++ ttime->ttime_total = div_u64(7*ttime->ttime_total + 256*elapsed, 8); ++ ttime->ttime_mean = div64_ul(ttime->ttime_total + 128, ++ ttime->ttime_samples); ++} ++ ++static void ++bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ bfqq->seek_history <<= 1; ++ bfqq->seek_history |= ++ get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR; ++} ++ ++/* ++ * Disable idle window if the process thinks too long or seeks so much that ++ * it doesn't matter. ++ */ ++static void bfq_update_idle_window(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ int enable_idle; ++ ++ /* Don't idle for async or idle io prio class. */ ++ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) ++ return; ++ ++ /* Idle window just restored, statistics are meaningless. */ ++ if (time_is_after_eq_jiffies(bfqq->split_time + ++ bfqd->bfq_wr_min_idle_time)) ++ return; ++ ++ enable_idle = bfq_bfqq_idle_window(bfqq); ++ ++ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || ++ bfqd->bfq_slice_idle == 0 || ++ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && ++ bfqq->wr_coeff == 1)) ++ enable_idle = 0; ++ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { ++ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && ++ bfqq->wr_coeff == 1) ++ enable_idle = 0; ++ else ++ enable_idle = 1; ++ } ++ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", ++ enable_idle); ++ ++ if (enable_idle) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++} ++ ++/* ++ * Called when a new fs request (rq) is added to bfqq. Check if there's ++ * something we should do about it. ++ */ ++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ struct bfq_io_cq *bic = RQ_BIC(rq); ++ ++ if (rq->cmd_flags & REQ_META) ++ bfqq->meta_pending++; ++ ++ bfq_update_io_thinktime(bfqd, bic); ++ bfq_update_io_seektime(bfqd, bfqq, rq); ++ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || ++ !BFQQ_SEEKY(bfqq)) ++ bfq_update_idle_window(bfqd, bfqq, bic); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "rq_enqueued: idle_window=%d (seeky %d)", ++ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq)); ++ ++ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ ++ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { ++ bool small_req = bfqq->queued[rq_is_sync(rq)] == 1 && ++ blk_rq_sectors(rq) < 32; ++ bool budget_timeout = bfq_bfqq_budget_timeout(bfqq); ++ ++ /* ++ * There is just this request queued: if the request ++ * is small and the queue is not to be expired, then ++ * just exit. ++ * ++ * In this way, if the device is being idled to wait ++ * for a new request from the in-service queue, we ++ * avoid unplugging the device and committing the ++ * device to serve just a small request. On the ++ * contrary, we wait for the block layer to decide ++ * when to unplug the device: hopefully, new requests ++ * will be merged to this one quickly, then the device ++ * will be unplugged and larger requests will be ++ * dispatched. ++ */ ++ if (small_req && !budget_timeout) ++ return; ++ ++ /* ++ * A large enough request arrived, or the queue is to ++ * be expired: in both cases disk idling is to be ++ * stopped, so clear wait_request flag and reset ++ * timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqg_stats_update_idle_time(bfqq_group(bfqq)); ++ ++ /* ++ * The queue is not empty, because a new request just ++ * arrived. Hence we can safely expire the queue, in ++ * case of budget timeout, without risking that the ++ * timestamps of the queue are not updated correctly. ++ * See [1] for more details. ++ */ ++ if (budget_timeout) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_BUDGET_TIMEOUT); ++ ++ /* ++ * Let the request rip immediately, or let a new queue be ++ * selected if bfqq has just been expired. ++ */ ++ __blk_run_queue(bfqd->queue); ++ } ++} ++ ++static void bfq_insert_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ /* ++ * An unplug may trigger a requeue of a request from the device ++ * driver: make sure we are in process context while trying to ++ * merge two bfq_queues. ++ */ ++ if (!in_interrupt()) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); ++ if (new_bfqq) { ++ if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) ++ new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); ++ /* ++ * Release the request's reference to the old bfqq ++ * and make sure one is taken to the shared queue. ++ */ ++ new_bfqq->allocated[rq_data_dir(rq)]++; ++ bfqq->allocated[rq_data_dir(rq)]--; ++ new_bfqq->ref++; ++ bfq_clear_bfqq_just_created(bfqq); ++ bfq_put_queue(bfqq); ++ if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) ++ bfq_merge_bfqqs(bfqd, RQ_BIC(rq), ++ bfqq, new_bfqq); ++ rq->elv.priv[1] = new_bfqq; ++ bfqq = new_bfqq; ++ } ++ } ++ ++ bfq_add_request(rq); ++ ++ rq->fifo_time = ktime_get_ns() + ++ jiffies_to_nsecs(bfqd->bfq_fifo_expire[rq_is_sync(rq)]); ++ list_add_tail(&rq->queuelist, &bfqq->fifo); ++ ++ bfq_rq_enqueued(bfqd, bfqq, rq); ++} ++ ++static void bfq_update_hw_tag(struct bfq_data *bfqd) ++{ ++ bfqd->max_rq_in_driver = max_t(int, bfqd->max_rq_in_driver, ++ bfqd->rq_in_driver); ++ ++ if (bfqd->hw_tag == 1) ++ return; ++ ++ /* ++ * This sample is valid if the number of outstanding requests ++ * is large enough to allow a queueing behavior. Note that the ++ * sum is not exact, as it's not taking into account deactivated ++ * requests. ++ */ ++ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) ++ return; ++ ++ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) ++ return; ++ ++ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; ++ bfqd->max_rq_in_driver = 0; ++ bfqd->hw_tag_samples = 0; ++} ++ ++static void bfq_completed_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ u64 now_ns; ++ u32 delta_us; ++ ++ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left", ++ blk_rq_sectors(rq)); ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ bfq_update_hw_tag(bfqd); ++ ++ BUG_ON(!bfqd->rq_in_driver); ++ BUG_ON(!bfqq->dispatched); ++ bfqd->rq_in_driver--; ++ bfqq->dispatched--; ++ bfqg_stats_update_completion(bfqq_group(bfqq), ++ rq_start_time_ns(rq), ++ rq_io_start_time_ns(rq), req_op(rq), ++ rq->cmd_flags); ++ ++ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ /* ++ * Set budget_timeout (which we overload to store the ++ * time at which the queue remains with no backlog and ++ * no outstanding request; used by the weight-raising ++ * mechanism). ++ */ ++ bfqq->budget_timeout = jiffies; ++ ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ } ++ ++ now_ns = ktime_get_ns(); ++ ++ RQ_BIC(rq)->ttime.last_end_request = now_ns; ++ ++ /* ++ * Using us instead of ns, to get a reasonable precision in ++ * computing rate in next check. ++ */ ++ delta_us = div_u64(now_ns - bfqd->last_completion, NSEC_PER_USEC); ++ ++ bfq_log(bfqd, "rq_completed: delta %uus/%luus max_size %u rate %llu/%llu", ++ delta_us, BFQ_MIN_TT/NSEC_PER_USEC, bfqd->last_rq_max_size, ++ (USEC_PER_SEC* ++ (u64)((bfqd->last_rq_max_size<>BFQ_RATE_SHIFT, ++ (USEC_PER_SEC*(u64)(1UL<<(BFQ_RATE_SHIFT-10)))>>BFQ_RATE_SHIFT); ++ ++ /* ++ * If the request took rather long to complete, and, according ++ * to the maximum request size recorded, this completion latency ++ * implies that the request was certainly served at a very low ++ * rate (less than 1M sectors/sec), then the whole observation ++ * interval that lasts up to this time instant cannot be a ++ * valid time interval for computing a new peak rate. Invoke ++ * bfq_update_rate_reset to have the following three steps ++ * taken: ++ * - close the observation interval at the last (previous) ++ * request dispatch or completion ++ * - compute rate, if possible, for that observation interval ++ * - reset to zero samples, which will trigger a proper ++ * re-initialization of the observation interval on next ++ * dispatch ++ */ ++ if (delta_us > BFQ_MIN_TT/NSEC_PER_USEC && ++ (bfqd->last_rq_max_size<last_completion = now_ns; ++ ++ /* ++ * If we are waiting to discover whether the request pattern ++ * of the task associated with the queue is actually ++ * isochronous, and both requisites for this condition to hold ++ * are now satisfied, then compute soft_rt_next_start (see the ++ * comments on the function bfq_bfqq_softrt_next_start()). We ++ * schedule this delayed check when bfqq expires, if it still ++ * has in-flight requests. ++ */ ++ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ ++ /* ++ * If this is the in-service queue, check if it needs to be expired, ++ * or if we want to idle in case it has no pending requests. ++ */ ++ if (bfqd->in_service_queue == bfqq) { ++ if (bfqq->dispatched == 0 && bfq_bfqq_must_idle(bfqq)) { ++ bfq_arm_slice_timer(bfqd); ++ goto out; ++ } else if (bfq_may_expire_for_budg_timeout(bfqq)) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_BUDGET_TIMEOUT); ++ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && ++ (bfqq->dispatched == 0 || ++ !bfq_bfqq_may_idle(bfqq))) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_NO_MORE_REQUESTS); ++ } ++ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ ++out: ++ return; ++} ++ ++static int __bfq_may_queue(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { ++ bfq_clear_bfqq_must_alloc(bfqq); ++ return ELV_MQUEUE_MUST; ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++static int bfq_may_queue(struct request_queue *q, int op, int op_flags) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Don't force setup of a queue from here, as a call to may_queue ++ * does not necessarily imply that a request actually will be ++ * queued. So just lookup a possibly existing queue, or return ++ * 'may queue' if that fails. ++ */ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (!bic) ++ return ELV_MQUEUE_MAY; ++ ++ bfqq = bic_to_bfqq(bic, rw_is_sync(op, op_flags)); ++ if (bfqq) ++ return __bfq_may_queue(bfqq); ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++/* ++ * Queue lock held here. ++ */ ++static void bfq_put_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ if (bfqq) { ++ const int rw = rq_data_dir(rq); ++ ++ BUG_ON(!bfqq->allocated[rw]); ++ bfqq->allocated[rw]--; ++ ++ rq->elv.priv[0] = NULL; ++ rq->elv.priv[1] = NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/* ++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this ++ * was the last process referring to that bfqq. ++ */ ++static struct bfq_queue * ++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ ++ put_io_context(bic->icq.ioc); ++ ++ if (bfqq_process_refs(bfqq) == 1) { ++ bfqq->pid = current->pid; ++ bfq_clear_bfqq_coop(bfqq); ++ bfq_clear_bfqq_split_coop(bfqq); ++ return bfqq; ++ } ++ ++ bic_set_bfqq(bic, NULL, 1); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++ return NULL; ++} ++ ++/* ++ * Allocate bfq data structures associated with this request. ++ */ ++static int bfq_set_request(struct request_queue *q, struct request *rq, ++ struct bio *bio, gfp_t gfp_mask) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); ++ const int rw = rq_data_dir(rq); ++ const int is_sync = rq_is_sync(rq); ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ bool split = false; ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ bfq_check_ioprio_change(bic, bio); ++ ++ if (!bic) ++ goto queue_fail; ++ ++ bfq_bic_update_cgroup(bic, bio); ++ ++new_queue: ++ bfqq = bic_to_bfqq(bic, is_sync); ++ if (!bfqq || bfqq == &bfqd->oom_bfqq) { ++ if (bfqq) ++ bfq_put_queue(bfqq); ++ bfqq = bfq_get_queue(bfqd, bio, is_sync, bic); ++ BUG_ON(!hlist_unhashed(&bfqq->burst_list_node)); ++ ++ bic_set_bfqq(bic, bfqq, is_sync); ++ if (split && is_sync) { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: was_in_list %d " ++ "was_in_large_burst %d " ++ "large burst in progress %d", ++ bic->was_in_burst_list, ++ bic->saved_in_large_burst, ++ bfqd->large_burst); ++ ++ if ((bic->was_in_burst_list && bfqd->large_burst) || ++ bic->saved_in_large_burst) { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: marking in " ++ "large burst"); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ } else { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: clearing in " ++ "large burst"); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ if (bic->was_in_burst_list) ++ hlist_add_head(&bfqq->burst_list_node, ++ &bfqd->burst_list); ++ } ++ bfqq->split_time = jiffies; ++ } ++ } else { ++ /* If the queue was seeky for too long, break it apart. */ ++ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { ++ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); ++ ++ /* Update bic before losing reference to bfqq */ ++ if (bfq_bfqq_in_large_burst(bfqq)) ++ bic->saved_in_large_burst = true; ++ ++ bfqq = bfq_split_bfqq(bic, bfqq); ++ split = true; ++ if (!bfqq) ++ goto new_queue; ++ } ++ } ++ ++ bfqq->allocated[rw]++; ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, bfqq->ref); ++ ++ rq->elv.priv[0] = bic; ++ rq->elv.priv[1] = bfqq; ++ ++ /* ++ * If a bfq_queue has only one process reference, it is owned ++ * by only one bfq_io_cq: we can set the bic field of the ++ * bfq_queue to the address of that structure. Also, if the ++ * queue has just been split, mark a flag so that the ++ * information is available to the other scheduler hooks. ++ */ ++ if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { ++ bfqq->bic = bic; ++ if (split) { ++ /* ++ * If the queue has just been split from a shared ++ * queue, restore the idle window and the possible ++ * weight raising period. ++ */ ++ bfq_bfqq_resume_state(bfqq, bic); ++ } ++ } ++ ++ if (unlikely(bfq_bfqq_just_created(bfqq))) ++ bfq_handle_burst(bfqd, bfqq); ++ ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 0; ++ ++queue_fail: ++ bfq_schedule_dispatch(bfqd); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 1; ++} ++ ++static void bfq_kick_queue(struct work_struct *work) ++{ ++ struct bfq_data *bfqd = ++ container_of(work, struct bfq_data, unplug_work); ++ struct request_queue *q = bfqd->queue; ++ ++ spin_lock_irq(q->queue_lock); ++ __blk_run_queue(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++/* ++ * Handler of the expiration of the timer running if the in-service queue ++ * is idling inside its time slice. ++ */ ++static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer) ++{ ++ struct bfq_data *bfqd = container_of(timer, struct bfq_data, ++ idle_slice_timer); ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ enum bfqq_expiration reason; ++ ++ spin_lock_irqsave(bfqd->queue->queue_lock, flags); ++ ++ bfqq = bfqd->in_service_queue; ++ /* ++ * Theoretical race here: the in-service queue can be NULL or ++ * different from the queue that was idling if the timer handler ++ * spins on the queue_lock and a new request arrives for the ++ * current queue and there is a full dispatch cycle that changes ++ * the in-service queue. This can hardly happen, but in the worst ++ * case we just expire a queue too early. ++ */ ++ if (bfqq) { ++ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); ++ bfq_clear_bfqq_wait_request(bfqq); ++ ++ if (bfq_bfqq_budget_timeout(bfqq)) ++ /* ++ * Also here the queue can be safely expired ++ * for budget timeout without wasting ++ * guarantees ++ */ ++ reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) ++ /* ++ * The queue may not be empty upon timer expiration, ++ * because we may not disable the timer when the ++ * first request of the in-service queue arrives ++ * during disk idling. ++ */ ++ reason = BFQ_BFQQ_TOO_IDLE; ++ else ++ goto schedule_dispatch; ++ ++ bfq_bfqq_expire(bfqd, bfqq, true, reason); ++ } ++ ++schedule_dispatch: ++ bfq_schedule_dispatch(bfqd); ++ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); ++ return HRTIMER_NORESTART; ++} ++ ++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) ++{ ++ hrtimer_cancel(&bfqd->idle_slice_timer); ++ cancel_work_sync(&bfqd->unplug_work); ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void __bfq_put_async_bfqq(struct bfq_data *bfqd, ++ struct bfq_queue **bfqq_ptr) ++{ ++ struct bfq_group *root_group = bfqd->root_group; ++ struct bfq_queue *bfqq = *bfqq_ptr; ++ ++ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); ++ if (bfqq) { ++ bfq_bfqq_move(bfqd, bfqq, root_group); ++ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ *bfqq_ptr = NULL; ++ } ++} ++ ++/* ++ * Release all the bfqg references to its async queues. If we are ++ * deallocating the group these queues may still contain requests, so ++ * we reparent them to the root cgroup (i.e., the only one that will ++ * exist for sure until all the requests on a device are gone). ++ */ ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); ++ ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); ++} ++#endif ++ ++static void bfq_exit_queue(struct elevator_queue *e) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ struct request_queue *q = bfqd->queue; ++ struct bfq_queue *bfqq, *n; ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ spin_lock_irq(q->queue_lock); ++ ++ BUG_ON(bfqd->in_service_queue); ++ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ ++ spin_unlock_irq(q->queue_lock); ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ BUG_ON(hrtimer_active(&bfqd->idle_slice_timer)); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_deactivate_policy(q, &blkcg_policy_bfq); ++#else ++ kfree(bfqd->root_group); ++#endif ++ ++ kfree(bfqd); ++} ++ ++static void bfq_init_root_group(struct bfq_group *root_group, ++ struct bfq_data *bfqd) ++{ ++ int i; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ root_group->entity.parent = NULL; ++ root_group->my_entity = NULL; ++ root_group->bfqd = bfqd; ++#endif ++ root_group->rq_pos_tree = RB_ROOT; ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ root_group->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++} ++ ++static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) ++{ ++ struct bfq_data *bfqd; ++ struct elevator_queue *eq; ++ ++ eq = elevator_alloc(q, e); ++ if (!eq) ++ return -ENOMEM; ++ ++ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); ++ if (!bfqd) { ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ eq->elevator_data = bfqd; ++ ++ /* ++ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. ++ * Grab a permanent reference to it, so that the normal code flow ++ * will not attempt to free it. ++ */ ++ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0); ++ bfqd->oom_bfqq.ref++; ++ bfqd->oom_bfqq.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; ++ bfqd->oom_bfqq.new_ioprio_class = IOPRIO_CLASS_BE; ++ bfqd->oom_bfqq.entity.new_weight = ++ bfq_ioprio_to_weight(bfqd->oom_bfqq.new_ioprio); ++ ++ /* oom_bfqq does not participate to bursts */ ++ bfq_clear_bfqq_just_created(&bfqd->oom_bfqq); ++ /* ++ * Trigger weight initialization, according to ioprio, at the ++ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio ++ * class won't be changed any more. ++ */ ++ bfqd->oom_bfqq.entity.prio_changed = 1; ++ ++ bfqd->queue = q; ++ ++ spin_lock_irq(q->queue_lock); ++ q->elevator = eq; ++ spin_unlock_irq(q->queue_lock); ++ ++ bfqd->root_group = bfq_create_group_hierarchy(bfqd, q->node); ++ if (!bfqd->root_group) ++ goto out_free; ++ bfq_init_root_group(bfqd->root_group, bfqd); ++ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); ++ ++ hrtimer_init(&bfqd->idle_slice_timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); ++ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; ++ ++ bfqd->queue_weights_tree = RB_ROOT; ++ bfqd->group_weights_tree = RB_ROOT; ++ ++ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); ++ ++ INIT_LIST_HEAD(&bfqd->active_list); ++ INIT_LIST_HEAD(&bfqd->idle_list); ++ INIT_HLIST_HEAD(&bfqd->burst_list); ++ ++ bfqd->hw_tag = -1; ++ ++ bfqd->bfq_max_budget = bfq_default_max_budget; ++ ++ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; ++ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; ++ bfqd->bfq_back_max = bfq_back_max; ++ bfqd->bfq_back_penalty = bfq_back_penalty; ++ bfqd->bfq_slice_idle = bfq_slice_idle; ++ bfqd->bfq_class_idle_last_service = 0; ++ bfqd->bfq_timeout = bfq_timeout; ++ ++ bfqd->bfq_requests_within_timer = 120; ++ ++ bfqd->bfq_large_burst_thresh = 8; ++ bfqd->bfq_burst_interval = msecs_to_jiffies(180); ++ ++ bfqd->low_latency = true; ++ ++ /* ++ * Trade-off between responsiveness and fairness. ++ */ ++ bfqd->bfq_wr_coeff = 30; ++ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); ++ bfqd->bfq_wr_max_time = 0; ++ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); ++ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); ++ bfqd->bfq_wr_max_softrt_rate = 7000; /* ++ * Approximate rate required ++ * to playback or record a ++ * high-definition compressed ++ * video. ++ */ ++ bfqd->wr_busy_queues = 0; ++ ++ /* ++ * Begin by assuming, optimistically, that the device is a ++ * high-speed one, and that its peak rate is equal to 2/3 of ++ * the highest reference rate. ++ */ ++ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * ++ T_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)] * 2 / 3; ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ ++ return 0; ++ ++out_free: ++ kfree(bfqd); ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++} ++ ++static void bfq_slab_kill(void) ++{ ++ kmem_cache_destroy(bfq_pool); ++} ++ ++static int __init bfq_slab_setup(void) ++{ ++ bfq_pool = KMEM_CACHE(bfq_queue, 0); ++ if (!bfq_pool) ++ return -ENOMEM; ++ return 0; ++} ++ ++static ssize_t bfq_var_show(unsigned int var, char *page) ++{ ++ return sprintf(page, "%u\n", var); ++} ++ ++static ssize_t bfq_var_store(unsigned long *var, const char *page, ++ size_t count) ++{ ++ unsigned long new_val; ++ int ret = kstrtoul(page, 10, &new_val); ++ ++ if (ret == 0) ++ *var = new_val; ++ ++ return count; ++} ++ ++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ ++ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? ++ jiffies_to_msecs(bfqd->bfq_wr_max_time) : ++ jiffies_to_msecs(bfq_wr_duration(bfqd))); ++} ++ ++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_queue *bfqq; ++ struct bfq_data *bfqd = e->elevator_data; ++ ssize_t num_char = 0; ++ ++ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", ++ bfqd->queued); ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ num_char += sprintf(page + num_char, "Active:\n"); ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, nr_queued %d %d, ", ++ bfqq->pid, ++ bfqq->entity.weight, ++ bfqq->queued[0], ++ bfqq->queued[1]); ++ num_char += sprintf(page + num_char, ++ "dur %d/%u\n", ++ jiffies_to_msecs( ++ jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ num_char += sprintf(page + num_char, "Idle:\n"); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ ++ return num_char; ++} ++ ++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ u64 __data = __VAR; \ ++ if (__CONV == 1) \ ++ __data = jiffies_to_msecs(__data); \ ++ else if (__CONV == 2) \ ++ __data = div_u64(__data, NSEC_PER_MSEC); \ ++ return bfq_var_show(__data, (page)); \ ++} ++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 2); ++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 2); ++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); ++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); ++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 2); ++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); ++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout, 1); ++SHOW_FUNCTION(bfq_strict_guarantees_show, bfqd->strict_guarantees, 0); ++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); ++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); ++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); ++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); ++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, ++ 1); ++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); ++#undef SHOW_FUNCTION ++ ++#define USEC_SHOW_FUNCTION(__FUNC, __VAR) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ u64 __data = __VAR; \ ++ __data = div_u64(__data, NSEC_PER_USEC); \ ++ return bfq_var_show(__data, (page)); \ ++} ++USEC_SHOW_FUNCTION(bfq_slice_idle_us_show, bfqd->bfq_slice_idle); ++#undef USEC_SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ ++static ssize_t \ ++__FUNC(struct elevator_queue *e, const char *page, size_t count) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long uninitialized_var(__data); \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ if (__CONV == 1) \ ++ *(__PTR) = msecs_to_jiffies(__data); \ ++ else if (__CONV == 2) \ ++ *(__PTR) = (u64)__data * NSEC_PER_MSEC; \ ++ else \ ++ *(__PTR) = __data; \ ++ return ret; \ ++} ++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, ++ INT_MAX, 2); ++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, ++ INT_MAX, 2); ++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); ++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, ++ INT_MAX, 0); ++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 2); ++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, ++ 1); ++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, ++ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, ++ INT_MAX, 0); ++#undef STORE_FUNCTION ++ ++#define USEC_STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \ ++static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long __data; \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ *(__PTR) = (u64)__data * NSEC_PER_USEC; \ ++ return ret; \ ++} ++USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0, ++ UINT_MAX); ++#undef USEC_STORE_FUNCTION ++ ++/* do nothing for the moment */ ++static ssize_t bfq_weights_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ return count; ++} ++ ++static ssize_t bfq_max_budget_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data == 0) ++ bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); ++ else { ++ if (__data > INT_MAX) ++ __data = INT_MAX; ++ bfqd->bfq_max_budget = __data; ++ } ++ ++ bfqd->bfq_user_max_budget = __data; ++ ++ return ret; ++} ++ ++/* ++ * Leaving this name to preserve name compatibility with cfq ++ * parameters, but this timeout is used for both sync and async. ++ */ ++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data < 1) ++ __data = 1; ++ else if (__data > INT_MAX) ++ __data = INT_MAX; ++ ++ bfqd->bfq_timeout = msecs_to_jiffies(__data); ++ if (bfqd->bfq_user_max_budget == 0) ++ bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); ++ ++ return ret; ++} ++ ++static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (!bfqd->strict_guarantees && __data == 1 ++ && bfqd->bfq_slice_idle < 8 * NSEC_PER_MSEC) ++ bfqd->bfq_slice_idle = 8 * NSEC_PER_MSEC; ++ ++ bfqd->strict_guarantees = __data; ++ ++ return ret; ++} ++ ++static ssize_t bfq_low_latency_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (__data == 0 && bfqd->low_latency != 0) ++ bfq_end_wr(bfqd); ++ bfqd->low_latency = __data; ++ ++ return ret; ++} ++ ++#define BFQ_ATTR(name) \ ++ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) ++ ++static struct elv_fs_entry bfq_attrs[] = { ++ BFQ_ATTR(fifo_expire_sync), ++ BFQ_ATTR(fifo_expire_async), ++ BFQ_ATTR(back_seek_max), ++ BFQ_ATTR(back_seek_penalty), ++ BFQ_ATTR(slice_idle), ++ BFQ_ATTR(slice_idle_us), ++ BFQ_ATTR(max_budget), ++ BFQ_ATTR(timeout_sync), ++ BFQ_ATTR(strict_guarantees), ++ BFQ_ATTR(low_latency), ++ BFQ_ATTR(wr_coeff), ++ BFQ_ATTR(wr_max_time), ++ BFQ_ATTR(wr_rt_max_time), ++ BFQ_ATTR(wr_min_idle_time), ++ BFQ_ATTR(wr_min_inter_arr_async), ++ BFQ_ATTR(wr_max_softrt_rate), ++ BFQ_ATTR(weights), ++ __ATTR_NULL ++}; ++ ++static struct elevator_type iosched_bfq = { ++ .ops = { ++ .elevator_merge_fn = bfq_merge, ++ .elevator_merged_fn = bfq_merged_request, ++ .elevator_merge_req_fn = bfq_merged_requests, ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ .elevator_bio_merged_fn = bfq_bio_merged, ++#endif ++ .elevator_allow_bio_merge_fn = bfq_allow_bio_merge, ++ .elevator_allow_rq_merge_fn = bfq_allow_rq_merge, ++ .elevator_dispatch_fn = bfq_dispatch_requests, ++ .elevator_add_req_fn = bfq_insert_request, ++ .elevator_activate_req_fn = bfq_activate_request, ++ .elevator_deactivate_req_fn = bfq_deactivate_request, ++ .elevator_completed_req_fn = bfq_completed_request, ++ .elevator_former_req_fn = elv_rb_former_request, ++ .elevator_latter_req_fn = elv_rb_latter_request, ++ .elevator_init_icq_fn = bfq_init_icq, ++ .elevator_exit_icq_fn = bfq_exit_icq, ++ .elevator_set_req_fn = bfq_set_request, ++ .elevator_put_req_fn = bfq_put_request, ++ .elevator_may_queue_fn = bfq_may_queue, ++ .elevator_init_fn = bfq_init_queue, ++ .elevator_exit_fn = bfq_exit_queue, ++ }, ++ .icq_size = sizeof(struct bfq_io_cq), ++ .icq_align = __alignof__(struct bfq_io_cq), ++ .elevator_attrs = bfq_attrs, ++ .elevator_name = "bfq", ++ .elevator_owner = THIS_MODULE, ++}; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static struct blkcg_policy blkcg_policy_bfq = { ++ .dfl_cftypes = bfq_blkg_files, ++ .legacy_cftypes = bfq_blkcg_legacy_files, ++ ++ .cpd_alloc_fn = bfq_cpd_alloc, ++ .cpd_init_fn = bfq_cpd_init, ++ .cpd_bind_fn = bfq_cpd_init, ++ .cpd_free_fn = bfq_cpd_free, ++ ++ .pd_alloc_fn = bfq_pd_alloc, ++ .pd_init_fn = bfq_pd_init, ++ .pd_offline_fn = bfq_pd_offline, ++ .pd_free_fn = bfq_pd_free, ++ .pd_reset_stats_fn = bfq_pd_reset_stats, ++}; ++#endif ++ ++static int __init bfq_init(void) ++{ ++ int ret; ++ char msg[50] = "BFQ I/O-scheduler: v8r4"; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ret = blkcg_policy_register(&blkcg_policy_bfq); ++ if (ret) ++ return ret; ++#endif ++ ++ ret = -ENOMEM; ++ if (bfq_slab_setup()) ++ goto err_pol_unreg; ++ ++ /* ++ * Times to load large popular applications for the typical ++ * systems installed on the reference devices (see the ++ * comments before the definitions of the next two ++ * arrays). Actually, we use slightly slower values, as the ++ * estimated peak rate tends to be smaller than the actual ++ * peak rate. The reason for this last fact is that estimates ++ * are computed over much shorter time intervals than the long ++ * intervals typically used for benchmarking. Why? First, to ++ * adapt more quickly to variations. Second, because an I/O ++ * scheduler cannot rely on a peak-rate-evaluation workload to ++ * be run for a long time. ++ */ ++ T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */ ++ T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */ ++ T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */ ++ T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */ ++ ++ /* ++ * Thresholds that determine the switch between speed classes ++ * (see the comments before the definition of the array ++ * device_speed_thresh). These thresholds are biased towards ++ * transitions to the fast class. This is safer than the ++ * opposite bias. In fact, a wrong transition to the slow ++ * class results in short weight-raising periods, because the ++ * speed of the device then tends to be higher that the ++ * reference peak rate. On the opposite end, a wrong ++ * transition to the fast class tends to increase ++ * weight-raising periods, because of the opposite reason. ++ */ ++ device_speed_thresh[0] = (4 * R_slow[0]) / 3; ++ device_speed_thresh[1] = (4 * R_slow[1]) / 3; ++ ++ ret = elv_register(&iosched_bfq); ++ if (ret) ++ goto err_pol_unreg; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ strcat(msg, " (with cgroups support)"); ++#endif ++ pr_info("%s", msg); ++ ++ return 0; ++ ++err_pol_unreg: ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_policy_unregister(&blkcg_policy_bfq); ++#endif ++ return ret; ++} ++ ++static void __exit bfq_exit(void) ++{ ++ elv_unregister(&iosched_bfq); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_policy_unregister(&blkcg_policy_bfq); ++#endif ++ bfq_slab_kill(); ++} ++ ++module_init(bfq_init); ++module_exit(bfq_exit); ++ ++MODULE_AUTHOR("Arianna Avanzini, Fabio Checconi, Paolo Valente"); ++MODULE_LICENSE("GPL"); +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-sched.c linux-4.8-bfq/block/bfq-sched.c +--- linux-4.8/block/bfq-sched.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-sched.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,1501 @@ ++/* ++ * BFQ: Hierarchical B-WF2Q+ scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ */ ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++#define for_each_entity(entity) \ ++ for (; entity ; entity = entity->parent) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) ++ ++ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd); ++ ++static void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++ struct bfq_entity *bfqg_entity; ++ struct bfq_group *bfqg; ++ struct bfq_sched_data *group_sd; ++ ++ BUG_ON(!next_in_service); ++ ++ group_sd = next_in_service->sched_data; ++ ++ bfqg = container_of(group_sd, struct bfq_group, sched_data); ++ /* ++ * bfq_group's my_entity field is not NULL only if the group ++ * is not the root group. We must not touch the root entity ++ * as it must never become an in-service entity. ++ */ ++ bfqg_entity = bfqg->my_entity; ++ if (bfqg_entity) ++ bfqg_entity->budget = next_in_service->budget; ++} ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ struct bfq_entity *next_in_service; ++ struct bfq_queue *bfqq; ++ ++ if (sd->in_service_entity) ++ /* will update/requeue at the end of service */ ++ return 0; ++ ++ /* ++ * NOTE: this can be improved in many ways, such as returning ++ * 1 (and thus propagating upwards the update) only when the ++ * budget changes, or caching the bfqq that will be scheduled ++ * next from this subtree. By now we worry more about ++ * correctness than about performance... ++ */ ++ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); ++ sd->next_in_service = next_in_service; ++ ++ if (next_in_service) ++ bfq_update_budget(next_in_service); ++ else ++ goto exit; ++ ++ bfqq = bfq_entity_to_bfqq(next_in_service); ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_next_in_service: chosen this queue"); ++ else { ++ struct bfq_group *bfqg = ++ container_of(next_in_service, ++ struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_next_in_service: chosen this entity"); ++ } ++exit: ++ return 1; ++} ++ ++static void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++ WARN_ON(sd->next_in_service != entity); ++} ++#else ++#define for_each_entity(entity) \ ++ for (; entity ; entity = NULL) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (parent = NULL; entity ; entity = parent) ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ return 0; ++} ++ ++static void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++} ++ ++static void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++} ++#endif ++ ++/* ++ * Shift for timestamp calculations. This actually limits the maximum ++ * service allowed in one timestamp delta (small shift values increase it), ++ * the maximum total weight that can be used for the queues in the system ++ * (big shift values increase it), and the period of virtual time ++ * wraparounds. ++ */ ++#define WFQ_SERVICE_SHIFT 22 ++ ++/** ++ * bfq_gt - compare two timestamps. ++ * @a: first ts. ++ * @b: second ts. ++ * ++ * Return @a > @b, dealing with wrapping correctly. ++ */ ++static int bfq_gt(u64 a, u64 b) ++{ ++ return (s64)(a - b) > 0; ++} ++ ++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = NULL; ++ ++ BUG_ON(!entity); ++ ++ if (!entity->my_sched_data) ++ bfqq = container_of(entity, struct bfq_queue, entity); ++ ++ return bfqq; ++} ++ ++ ++/** ++ * bfq_delta - map service into the virtual time domain. ++ * @service: amount of service. ++ * @weight: scale factor (weight of an entity or weight sum). ++ */ ++static u64 bfq_delta(unsigned long service, unsigned long weight) ++{ ++ u64 d = (u64)service << WFQ_SERVICE_SHIFT; ++ ++ do_div(d, weight); ++ return d; ++} ++ ++/** ++ * bfq_calc_finish - assign the finish time to an entity. ++ * @entity: the entity to act upon. ++ * @service: the service to be charged to the entity. ++ */ ++static void bfq_calc_finish(struct bfq_entity *entity, unsigned long service) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned long long start, finish, delta; ++ ++ BUG_ON(entity->weight == 0); ++ ++ entity->finish = entity->start + ++ bfq_delta(service, entity->weight); ++ ++ start = ((entity->start>>10)*1000)>>12; ++ finish = ((entity->finish>>10)*1000)>>12; ++ delta = ((bfq_delta(service, entity->weight)>>10)*1000)>>12; ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: start %llu, finish %llu, delta %llu", ++ start, finish, delta); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "calc_finish group: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "calc_finish group: start %llu, finish %llu, delta %llu", ++ start, finish, delta); ++#endif ++ } ++} ++ ++/** ++ * bfq_entity_of - get an entity from a node. ++ * @node: the node field of the entity. ++ * ++ * Convert a node pointer to the relative entity. This is used only ++ * to simplify the logic of some functions and not as the generic ++ * conversion mechanism because, e.g., in the tree walking functions, ++ * the check for a %NULL value would be redundant. ++ */ ++static struct bfq_entity *bfq_entity_of(struct rb_node *node) ++{ ++ struct bfq_entity *entity = NULL; ++ ++ if (node) ++ entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ return entity; ++} ++ ++/** ++ * bfq_extract - remove an entity from a tree. ++ * @root: the tree root. ++ * @entity: the entity to remove. ++ */ ++static void bfq_extract(struct rb_root *root, struct bfq_entity *entity) ++{ ++ BUG_ON(entity->tree != root); ++ ++ entity->tree = NULL; ++ rb_erase(&entity->rb_node, root); ++} ++ ++/** ++ * bfq_idle_extract - extract an entity from the idle tree. ++ * @st: the service tree of the owning @entity. ++ * @entity: the entity being removed. ++ */ ++static void bfq_idle_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *next; ++ ++ BUG_ON(entity->tree != &st->idle); ++ ++ if (entity == st->first_idle) { ++ next = rb_next(&entity->rb_node); ++ st->first_idle = bfq_entity_of(next); ++ } ++ ++ if (entity == st->last_idle) { ++ next = rb_prev(&entity->rb_node); ++ st->last_idle = bfq_entity_of(next); ++ } ++ ++ bfq_extract(&st->idle, entity); ++ ++ if (bfqq) ++ list_del(&bfqq->bfqq_list); ++} ++ ++/** ++ * bfq_insert - generic tree insertion. ++ * @root: tree root. ++ * @entity: entity to insert. ++ * ++ * This is used for the idle and the active tree, since they are both ++ * ordered by finish time. ++ */ ++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) ++{ ++ struct bfq_entity *entry; ++ struct rb_node **node = &root->rb_node; ++ struct rb_node *parent = NULL; ++ ++ BUG_ON(entity->tree); ++ ++ while (*node) { ++ parent = *node; ++ entry = rb_entry(parent, struct bfq_entity, rb_node); ++ ++ if (bfq_gt(entry->finish, entity->finish)) ++ node = &parent->rb_left; ++ else ++ node = &parent->rb_right; ++ } ++ ++ rb_link_node(&entity->rb_node, parent, node); ++ rb_insert_color(&entity->rb_node, root); ++ ++ entity->tree = root; ++} ++ ++/** ++ * bfq_update_min - update the min_start field of a entity. ++ * @entity: the entity to update. ++ * @node: one of its children. ++ * ++ * This function is called when @entity may store an invalid value for ++ * min_start due to updates to the active tree. The function assumes ++ * that the subtree rooted at @node (which may be its left or its right ++ * child) has a valid min_start value. ++ */ ++static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node) ++{ ++ struct bfq_entity *child; ++ ++ if (node) { ++ child = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entity->min_start, child->min_start)) ++ entity->min_start = child->min_start; ++ } ++} ++ ++/** ++ * bfq_update_active_node - recalculate min_start. ++ * @node: the node to update. ++ * ++ * @node may have changed position or one of its children may have moved, ++ * this function updates its min_start value. The left and right subtrees ++ * are assumed to hold a correct min_start value. ++ */ ++static void bfq_update_active_node(struct rb_node *node) ++{ ++ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->min_start = entity->start; ++ bfq_update_min(entity, node->rb_right); ++ bfq_update_min(entity, node->rb_left); ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_active_node: new min_start %llu", ++ ((entity->min_start>>10)*1000)>>12); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_active_node: new min_start %llu", ++ ((entity->min_start>>10)*1000)>>12); ++#endif ++ } ++} ++ ++/** ++ * bfq_update_active_tree - update min_start for the whole active tree. ++ * @node: the starting node. ++ * ++ * @node must be the deepest modified node after an update. This function ++ * updates its min_start using the values held by its children, assuming ++ * that they did not change, and then updates all the nodes that may have ++ * changed in the path to the root. The only nodes that may have changed ++ * are the ones in the path or their siblings. ++ */ ++static void bfq_update_active_tree(struct rb_node *node) ++{ ++ struct rb_node *parent; ++ ++up: ++ bfq_update_active_node(node); ++ ++ parent = rb_parent(node); ++ if (!parent) ++ return; ++ ++ if (node == parent->rb_left && parent->rb_right) ++ bfq_update_active_node(parent->rb_right); ++ else if (parent->rb_left) ++ bfq_update_active_node(parent->rb_left); ++ ++ node = parent; ++ goto up; ++} ++ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++ ++/** ++ * bfq_active_insert - insert an entity in the active tree of its ++ * group/device. ++ * @st: the service tree of the entity. ++ * @entity: the entity being inserted. ++ * ++ * The active tree is ordered by finish time, but an extra key is kept ++ * per each node, containing the minimum value for the start times of ++ * its children (and the node itself), so it's possible to search for ++ * the eligible node with the lowest finish time in logarithmic time. ++ */ ++static void bfq_active_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node = &entity->rb_node; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ bfq_insert(&st->active, entity); ++ ++ if (node->rb_left) ++ node = node->rb_left; ++ else if (node->rb_right) ++ node = node->rb_right; ++ ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ bfqg->active_entities++; ++ } ++#endif ++} ++ ++/** ++ * bfq_ioprio_to_weight - calc a weight from an ioprio. ++ * @ioprio: the ioprio value to convert. ++ */ ++static unsigned short bfq_ioprio_to_weight(int ioprio) ++{ ++ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); ++ return (IOPRIO_BE_NR - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF; ++} ++ ++/** ++ * bfq_weight_to_ioprio - calc an ioprio from a weight. ++ * @weight: the weight value to convert. ++ * ++ * To preserve as much as possible the old only-ioprio user interface, ++ * 0 is used as an escape ioprio value for weights (numerically) equal or ++ * larger than IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF. ++ */ ++static unsigned short bfq_weight_to_ioprio(int weight) ++{ ++ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); ++ return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight < 0 ? ++ 0 : IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight; ++} ++ ++static void bfq_get_entity(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) { ++ bfqq->ref++; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", ++ bfqq, bfqq->ref); ++ } ++} ++ ++/** ++ * bfq_find_deepest - find the deepest node that an extraction can modify. ++ * @node: the node being removed. ++ * ++ * Do the first step of an extraction in an rb tree, looking for the ++ * node that will replace @node, and returning the deepest node that ++ * the following modifications to the tree can touch. If @node is the ++ * last node in the tree return %NULL. ++ */ ++static struct rb_node *bfq_find_deepest(struct rb_node *node) ++{ ++ struct rb_node *deepest; ++ ++ if (!node->rb_right && !node->rb_left) ++ deepest = rb_parent(node); ++ else if (!node->rb_right) ++ deepest = node->rb_left; ++ else if (!node->rb_left) ++ deepest = node->rb_right; ++ else { ++ deepest = rb_next(node); ++ if (deepest->rb_right) ++ deepest = deepest->rb_right; ++ else if (rb_parent(deepest) != node) ++ deepest = rb_parent(deepest); ++ } ++ ++ return deepest; ++} ++ ++/** ++ * bfq_active_extract - remove an entity from the active tree. ++ * @st: the service_tree containing the tree. ++ * @entity: the entity being removed. ++ */ ++static void bfq_active_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ node = bfq_find_deepest(&entity->rb_node); ++ bfq_extract(&st->active, entity); ++ ++ if (node) ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq) ++ list_del(&bfqq->bfqq_list); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_remove(bfqd, entity, ++ &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ BUG_ON(!bfqg->active_entities); ++ bfqg->active_entities--; ++ } ++#endif ++} ++ ++/** ++ * bfq_idle_insert - insert an entity into the idle tree. ++ * @st: the service tree containing the tree. ++ * @entity: the entity to insert. ++ */ ++static void bfq_idle_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (!first_idle || bfq_gt(first_idle->finish, entity->finish)) ++ st->first_idle = entity; ++ if (!last_idle || bfq_gt(entity->finish, last_idle->finish)) ++ st->last_idle = entity; ++ ++ bfq_insert(&st->idle, entity); ++ ++ if (bfqq) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); ++} ++ ++/** ++ * bfq_forget_entity - remove an entity from the wfq trees. ++ * @st: the service tree. ++ * @entity: the entity being removed. ++ * ++ * Update the device status and forget everything about @entity, putting ++ * the device reference to it, if it is a queue. Entities belonging to ++ * groups are not refcounted. ++ */ ++static void bfq_forget_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(!entity->on_st); ++ ++ entity->on_st = 0; ++ st->wsum -= entity->weight; ++ if (bfqq) { ++ sd = entity->sched_data; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/** ++ * bfq_put_idle_entity - release the idle tree ref of an entity. ++ * @st: service tree for the entity. ++ * @entity: the entity being released. ++ */ ++static void bfq_put_idle_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ bfq_idle_extract(st, entity); ++ bfq_forget_entity(st, entity); ++} ++ ++/** ++ * bfq_forget_idle - update the idle tree if necessary. ++ * @st: the service tree to act upon. ++ * ++ * To preserve the global O(log N) complexity we only remove one entry here; ++ * as the idle tree will not grow indefinitely this can be done safely. ++ */ ++static void bfq_forget_idle(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (RB_EMPTY_ROOT(&st->active) && last_idle && ++ !bfq_gt(last_idle->finish, st->vtime)) { ++ /* ++ * Forget the whole idle tree, increasing the vtime past ++ * the last finish time of idle entities. ++ */ ++ st->vtime = last_idle->finish; ++ } ++ ++ if (first_idle && !bfq_gt(first_idle->finish, st->vtime)) ++ bfq_put_idle_entity(st, first_idle); ++} ++ ++static struct bfq_service_tree * ++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_service_tree *new_st = old_st; ++ ++ if (entity->prio_changed) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned int prev_weight, new_weight; ++ struct bfq_data *bfqd = NULL; ++ struct rb_root *root; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd; ++ struct bfq_group *bfqg; ++#endif ++ ++ if (bfqq) ++ bfqd = bfqq->bfqd; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ sd = entity->my_sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++ BUG_ON(!bfqd); ++ } ++#endif ++ ++ BUG_ON(old_st->wsum < entity->weight); ++ old_st->wsum -= entity->weight; ++ ++ if (entity->new_weight != entity->orig_weight) { ++ if (entity->new_weight < BFQ_MIN_WEIGHT || ++ entity->new_weight > BFQ_MAX_WEIGHT) { ++ pr_crit("update_weight_prio: new_weight %d\n", ++ entity->new_weight); ++ if (entity->new_weight < BFQ_MIN_WEIGHT) ++ entity->new_weight = BFQ_MIN_WEIGHT; ++ else ++ entity->new_weight = BFQ_MAX_WEIGHT; ++ } ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) ++ bfqq->ioprio = ++ bfq_weight_to_ioprio(entity->orig_weight); ++ } ++ ++ if (bfqq) ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ entity->prio_changed = 0; ++ ++ /* ++ * NOTE: here we may be changing the weight too early, ++ * this will cause unfairness. The correct approach ++ * would have required additional complexity to defer ++ * weight changes to the proper time instants (i.e., ++ * when entity->finish <= old_st->vtime). ++ */ ++ new_st = bfq_entity_service_tree(entity); ++ ++ prev_weight = entity->weight; ++ new_weight = entity->orig_weight * ++ (bfqq ? bfqq->wr_coeff : 1); ++ /* ++ * If the weight of the entity changes, remove the entity ++ * from its old weight counter (if there is a counter ++ * associated with the entity), and add it to the counter ++ * associated with its new weight. ++ */ ++ if (prev_weight != new_weight) { ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "weight changed %d %d(%d %d)", ++ prev_weight, new_weight, ++ entity->orig_weight, ++ bfqq->wr_coeff); ++ ++ root = bfqq ? &bfqd->queue_weights_tree : ++ &bfqd->group_weights_tree; ++ bfq_weights_tree_remove(bfqd, entity, root); ++ } ++ entity->weight = new_weight; ++ /* ++ * Add the entity to its weights tree only if it is ++ * not associated with a weight-raised queue. ++ */ ++ if (prev_weight != new_weight && ++ (bfqq ? bfqq->wr_coeff == 1 : 1)) ++ /* If we get here, root has been initialized. */ ++ bfq_weights_tree_add(bfqd, entity, root); ++ ++ new_st->wsum += entity->weight; ++ ++ if (new_st != old_st) ++ entity->start = new_st->vtime; ++ } ++ ++ return new_st; ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg); ++#endif ++ ++/** ++ * bfq_bfqq_served - update the scheduler status after selection for ++ * service. ++ * @bfqq: the queue being served. ++ * @served: bytes to transfer. ++ * ++ * NOTE: this can be optimized, as the timestamps of upper level entities ++ * are synchronized every time a new bfqq is selected for service. By now, ++ * we keep it to better check consistency. ++ */ ++static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st; ++ ++ for_each_entity(entity) { ++ st = bfq_entity_service_tree(entity); ++ ++ entity->service += served; ++ ++ BUG_ON(st->wsum == 0); ++ ++ st->vtime += bfq_delta(served, st->wsum); ++ bfq_forget_idle(st); ++ } ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ bfqg_stats_set_start_empty_time(bfqq_group(bfqq)); ++#endif ++ st = bfq_entity_service_tree(&bfqq->entity); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs, vtime %llu on %p", ++ served, ((st->vtime>>10)*1000)>>12, st); ++} ++ ++/** ++ * bfq_bfqq_charge_time - charge an amount of service equivalent to the length ++ * of the time interval during which bfqq has been in ++ * service. ++ * @bfqd: the device ++ * @bfqq: the queue that needs a service update. ++ * @time_ms: the amount of time during which the queue has received service ++ * ++ * If a queue does not consume its budget fast enough, then providing ++ * the queue with service fairness may impair throughput, more or less ++ * severely. For this reason, queues that consume their budget slowly ++ * are provided with time fairness instead of service fairness. This ++ * goal is achieved through the BFQ scheduling engine, even if such an ++ * engine works in the service, and not in the time domain. The trick ++ * is charging these queues with an inflated amount of service, equal ++ * to the amount of service that they would have received during their ++ * service slot if they had been fast, i.e., if their requests had ++ * been dispatched at a rate equal to the estimated peak rate. ++ * ++ * It is worth noting that time fairness can cause important ++ * distortions in terms of bandwidth distribution, on devices with ++ * internal queueing. The reason is that I/O requests dispatched ++ * during the service slot of a queue may be served after that service ++ * slot is finished, and may have a total processing time loosely ++ * correlated with the duration of the service slot. This is ++ * especially true for short service slots. ++ */ ++static void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ unsigned long time_ms) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ int tot_serv_to_charge = entity->service; ++ unsigned int timeout_ms = jiffies_to_msecs(bfq_timeout); ++ ++ if (time_ms > 0 && time_ms < timeout_ms) ++ tot_serv_to_charge = ++ (bfqd->bfq_max_budget * time_ms) / timeout_ms; ++ ++ if (tot_serv_to_charge < entity->service) ++ tot_serv_to_charge = entity->service; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "charge_time: %lu/%u ms, %d/%d/%d sectors", ++ time_ms, timeout_ms, entity->service, ++ tot_serv_to_charge, entity->budget); ++ ++ /* Increase budget to avoid inconsistencies */ ++ if (tot_serv_to_charge > entity->budget) ++ entity->budget = tot_serv_to_charge; ++ ++ bfq_bfqq_served(bfqq, ++ max_t(int, 0, tot_serv_to_charge - entity->service)); ++} ++ ++/** ++ * __bfq_activate_entity - activate an entity. ++ * @entity: the entity being activated. ++ * @non_blocking_wait_rq: true if this entity was waiting for a request ++ * ++ * Called whenever an entity is activated, i.e., it is not active and one ++ * of its children receives a new request, or has to be reactivated due to ++ * budget exhaustion. It uses the current budget of the entity (and the ++ * service received if @entity is active) of the queue to calculate its ++ * timestamps. ++ */ ++static void __bfq_activate_entity(struct bfq_entity *entity, ++ bool non_blocking_wait_rq) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ bool backshifted = false; ++ ++ BUG_ON(!sd); ++ BUG_ON(!st); ++ if (entity == sd->in_service_entity) { ++ BUG_ON(entity->tree); ++ /* ++ * If we are requeueing the current entity we have ++ * to take care of not charging to it service it has ++ * not received. ++ */ ++ bfq_calc_finish(entity, entity->service); ++ entity->start = entity->finish; ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) { ++ /* ++ * Requeueing an entity due to a change of some ++ * next_in_service entity below it. We reuse the ++ * old start time. ++ */ ++ bfq_active_extract(st, entity); ++ } else { ++ unsigned long long min_vstart; ++ ++ /* See comments on bfq_fqq_update_budg_for_activation */ ++ if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) { ++ backshifted = true; ++ min_vstart = entity->finish; ++ } else ++ min_vstart = st->vtime; ++ ++ if (entity->tree == &st->idle) { ++ /* ++ * Must be on the idle tree, bfq_idle_extract() will ++ * check for that. ++ */ ++ bfq_idle_extract(st, entity); ++ entity->start = bfq_gt(min_vstart, entity->finish) ? ++ min_vstart : entity->finish; ++ } else { ++ /* ++ * The finish time of the entity may be invalid, and ++ * it is in the past for sure, otherwise the queue ++ * would have been on the idle tree. ++ */ ++ entity->start = min_vstart; ++ st->wsum += entity->weight; ++ bfq_get_entity(entity); ++ ++ BUG_ON(entity->on_st); ++ entity->on_st = 1; ++ } ++ } ++ ++ st = __bfq_entity_update_weight_prio(st, entity); ++ bfq_calc_finish(entity, entity->budget); ++ ++ /* ++ * If some queues enjoy backshifting for a while, then their ++ * (virtual) finish timestamps may happen to become lower and ++ * lower than the system virtual time. In particular, if ++ * these queues often happen to be idle for short time ++ * periods, and during such time periods other queues with ++ * higher timestamps happen to be busy, then the backshifted ++ * timestamps of the former queues can become much lower than ++ * the system virtual time. In fact, to serve the queues with ++ * higher timestamps while the ones with lower timestamps are ++ * idle, the system virtual time may be pushed-up to much ++ * higher values than the finish timestamps of the idle ++ * queues. As a consequence, the finish timestamps of all new ++ * or newly activated queues may end up being much larger than ++ * those of lucky queues with backshifted timestamps. The ++ * latter queues may then monopolize the device for a lot of ++ * time. This would simply break service guarantees. ++ * ++ * To reduce this problem, push up a little bit the ++ * backshifted timestamps of the queue associated with this ++ * entity (only a queue can happen to have the backshifted ++ * flag set): just enough to let the finish timestamp of the ++ * queue be equal to the current value of the system virtual ++ * time. This may introduce a little unfairness among queues ++ * with backshifted timestamps, but it does not break ++ * worst-case fairness guarantees. ++ * ++ * As a special case, if bfqq is weight-raised, push up ++ * timestamps much less, to keep very low the probability that ++ * this push up causes the backshifted finish timestamps of ++ * weight-raised queues to become higher than the backshifted ++ * finish timestamps of non weight-raised queues. ++ */ ++ if (backshifted && bfq_gt(st->vtime, entity->finish)) { ++ unsigned long delta = st->vtime - entity->finish; ++ ++ if (bfqq) ++ delta /= bfqq->wr_coeff; ++ ++ entity->start += delta; ++ entity->finish += delta; ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__activate_entity: new queue finish %llu", ++ ((entity->finish>>10)*1000)>>12); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__activate_entity: new group finish %llu", ++ ((entity->finish>>10)*1000)>>12); ++#endif ++ } ++ } ++ ++ bfq_active_insert(st, entity); ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__activate_entity: queue %seligible in st %p", ++ entity->start <= st->vtime ? "" : "non ", st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__activate_entity: group %seligible in st %p", ++ entity->start <= st->vtime ? "" : "non ", st); ++#endif ++ } ++} ++ ++/** ++ * bfq_activate_entity - activate an entity and its ancestors if necessary. ++ * @entity: the entity to activate. ++ * @non_blocking_wait_rq: true if this entity was waiting for a request ++ * ++ * Activate @entity and all the entities on the path from it to the root. ++ */ ++static void bfq_activate_entity(struct bfq_entity *entity, ++ bool non_blocking_wait_rq) ++{ ++ struct bfq_sched_data *sd; ++ ++ for_each_entity(entity) { ++ BUG_ON(!entity); ++ __bfq_activate_entity(entity, non_blocking_wait_rq); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ /* ++ * No need to propagate the activation to the ++ * upper entities, as they will be updated when ++ * the in-service entity is rescheduled. ++ */ ++ break; ++ } ++} ++ ++/** ++ * __bfq_deactivate_entity - deactivate an entity from its service tree. ++ * @entity: the entity to deactivate. ++ * @requeue: if false, the entity will not be put into the idle tree. ++ * ++ * Deactivate an entity, independently from its previous state. If the ++ * entity was not on a service tree just return, otherwise if it is on ++ * any scheduler tree, extract it from that tree, and if necessary ++ * and if the caller did not specify @requeue, put it on the idle tree. ++ * ++ * Return %1 if the caller should update the entity hierarchy, i.e., ++ * if the entity was in service or if it was the next_in_service for ++ * its sched_data; return %0 otherwise. ++ */ ++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st; ++ int was_in_service; ++ int ret = 0; ++ ++ if (sd == NULL || !entity->on_st) /* never activated, or inactive */ ++ return 0; ++ ++ st = bfq_entity_service_tree(entity); ++ was_in_service = entity == sd->in_service_entity; ++ ++ BUG_ON(was_in_service && entity->tree); ++ ++ if (was_in_service) { ++ bfq_calc_finish(entity, entity->service); ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) ++ bfq_active_extract(st, entity); ++ else if (entity->tree == &st->idle) ++ bfq_idle_extract(st, entity); ++ else if (entity->tree) ++ BUG(); ++ ++ if (was_in_service || sd->next_in_service == entity) ++ ret = bfq_update_next_in_service(sd); ++ ++ if (!requeue || !bfq_gt(entity->finish, st->vtime)) ++ bfq_forget_entity(st, entity); ++ else ++ bfq_idle_insert(st, entity); ++ ++ BUG_ON(sd->in_service_entity == entity); ++ BUG_ON(sd->next_in_service == entity); ++ ++ return ret; ++} ++ ++/** ++ * bfq_deactivate_entity - deactivate an entity. ++ * @entity: the entity to deactivate. ++ * @requeue: true if the entity can be put on the idle tree ++ */ ++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd; ++ struct bfq_entity *parent; ++ ++ for_each_entity_safe(entity, parent) { ++ sd = entity->sched_data; ++ ++ if (!__bfq_deactivate_entity(entity, requeue)) ++ /* ++ * next_in_service has not been changed, so ++ * no upwards update is needed ++ */ ++ break; ++ ++ if (sd->next_in_service) ++ /* ++ * The parent entity is still backlogged, ++ * because next_in_service is not NULL, and ++ * next_in_service has been updated (see ++ * comment on the body of the above if): ++ * upwards update of the schedule is needed. ++ */ ++ goto update; ++ ++ /* ++ * If we get here, then the parent is no more backlogged and ++ * we want to propagate the deactivation upwards. ++ */ ++ requeue = 1; ++ } ++ ++ return; ++ ++update: ++ entity = parent; ++ for_each_entity(entity) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ __bfq_activate_entity(entity, false); ++ ++ sd = entity->sched_data; ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "invoking udpdate_next for this queue"); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, ++ struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "invoking udpdate_next for this entity"); ++ } ++#endif ++ if (!bfq_update_next_in_service(sd)) ++ break; ++ } ++} ++ ++/** ++ * bfq_update_vtime - update vtime if necessary. ++ * @st: the service tree to act upon. ++ * ++ * If necessary update the service tree vtime to have at least one ++ * eligible entity, skipping to its start time. Assumes that the ++ * active tree of the device is not empty. ++ * ++ * NOTE: this hierarchical implementation updates vtimes quite often, ++ * we may end up with reactivated processes getting timestamps after a ++ * vtime skip done because we needed a ->first_active entity on some ++ * intermediate node. ++ */ ++static void bfq_update_vtime(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry; ++ struct rb_node *node = st->active.rb_node; ++ ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entry->min_start, st->vtime)) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entry); ++ st->vtime = entry->min_start; ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_vtime: new vtime %llu %p", ++ ((st->vtime>>10)*1000)>>12, st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entry, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_vtime: new vtime %llu %p", ++ ((st->vtime>>10)*1000)>>12, st); ++ } ++#endif ++ bfq_forget_idle(st); ++ } ++} ++ ++/** ++ * bfq_first_active_entity - find the eligible entity with ++ * the smallest finish time ++ * @st: the service tree to select from. ++ * ++ * This function searches the first schedulable entity, starting from the ++ * root of the tree and going on the left every time on this side there is ++ * a subtree with at least one eligible (start >= vtime) entity. The path on ++ * the right is followed only if a) the left subtree contains no eligible ++ * entities and b) no eligible entity has been found yet. ++ */ ++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry, *first = NULL; ++ struct rb_node *node = st->active.rb_node; ++ ++ while (node) { ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++left: ++ if (!bfq_gt(entry->start, st->vtime)) ++ first = entry; ++ ++ BUG_ON(bfq_gt(entry->min_start, st->vtime)); ++ ++ if (node->rb_left) { ++ entry = rb_entry(node->rb_left, ++ struct bfq_entity, rb_node); ++ if (!bfq_gt(entry->min_start, st->vtime)) { ++ node = node->rb_left; ++ goto left; ++ } ++ } ++ if (first) ++ break; ++ node = node->rb_right; ++ } ++ ++ BUG_ON(!first && !RB_EMPTY_ROOT(&st->active)); ++ return first; ++} ++ ++/** ++ * __bfq_lookup_next_entity - return the first eligible entity in @st. ++ * @st: the service tree. ++ * ++ * Update the virtual time in @st and return the first eligible entity ++ * it contains. ++ */ ++static struct bfq_entity * ++__bfq_lookup_next_entity(struct bfq_service_tree *st, bool force) ++{ ++ struct bfq_entity *entity, *new_next_in_service = NULL; ++ struct bfq_queue *bfqq; ++ ++ if (RB_EMPTY_ROOT(&st->active)) ++ return NULL; ++ ++ bfq_update_vtime(st); ++ entity = bfq_first_active_entity(st); ++ BUG_ON(bfq_gt(entity->start, st->vtime)); ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__lookup_next: start %llu vtime %llu st %p", ++ ((entity->start>>10)*1000)>>12, ++ ((st->vtime>>10)*1000)>>12, st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__lookup_next: start %llu vtime %llu st %p", ++ ((entity->start>>10)*1000)>>12, ++ ((st->vtime>>10)*1000)>>12, st); ++ } ++#endif ++ ++ /* ++ * If the chosen entity does not match with the sched_data's ++ * next_in_service and we are forcedly serving the IDLE priority ++ * class tree, bubble up budget update. ++ */ ++ if (unlikely(force && entity != entity->sched_data->next_in_service)) { ++ new_next_in_service = entity; ++ for_each_entity(new_next_in_service) ++ bfq_update_budget(new_next_in_service); ++ } ++ ++ return entity; ++} ++ ++/** ++ * bfq_lookup_next_entity - return the first eligible entity in @sd. ++ * @sd: the sched_data. ++ * @extract: if true the returned entity will be also extracted from @sd. ++ * ++ * NOTE: since we cache the next_in_service entity at each level of the ++ * hierarchy, the complexity of the lookup can be decreased with ++ * absolutely no effort just returning the cached next_in_service value; ++ * we prefer to do full lookups to test the consistency of * the data ++ * structures. ++ */ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_service_tree *st = sd->service_tree; ++ struct bfq_entity *entity; ++ int i = 0; ++ ++ BUG_ON(sd->in_service_entity); ++ ++ /* ++ * Choose from idle class, if needed to guarantee a minimum ++ * bandwidth to this class. This should also mitigate ++ * priority-inversion problems in case a low priority task is ++ * holding file system resources. ++ */ ++ if (bfqd && ++ jiffies - bfqd->bfq_class_idle_last_service > ++ BFQ_CL_IDLE_TIMEOUT) { ++ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, ++ true); ++ if (entity) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "idle chosen from st %p %d", ++ st + BFQ_IOPRIO_CLASSES - 1, ++ BFQ_IOPRIO_CLASSES - 1); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "idle chosen from st %p %d", ++ st + BFQ_IOPRIO_CLASSES - 1, ++ BFQ_IOPRIO_CLASSES - 1); ++ } ++#endif ++ i = BFQ_IOPRIO_CLASSES - 1; ++ bfqd->bfq_class_idle_last_service = jiffies; ++ sd->next_in_service = entity; ++ } ++ } ++ for (; i < BFQ_IOPRIO_CLASSES; i++) { ++ entity = __bfq_lookup_next_entity(st + i, false); ++ if (entity) { ++ if (bfqd != NULL) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "chosen from st %p %d", ++ st + i, i); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "chosen from st %p %d", ++ st + i, i); ++ } ++#endif ++ } ++ ++ if (extract) { ++ bfq_check_next_in_service(sd, entity); ++ bfq_active_extract(st + i, entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ } ++ break; ++ } ++ } ++ ++ return entity; ++} ++ ++static bool next_queue_may_preempt(struct bfq_data *bfqd) ++{ ++ struct bfq_sched_data *sd = &bfqd->root_group->sched_data; ++ ++ return sd->next_in_service != sd->in_service_entity; ++} ++ ++/* ++ * Get next queue for service. ++ */ ++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_entity *entity = NULL; ++ struct bfq_sched_data *sd; ++ struct bfq_queue *bfqq; ++ ++ BUG_ON(bfqd->in_service_queue); ++ ++ if (bfqd->busy_queues == 0) ++ return NULL; ++ ++ sd = &bfqd->root_group->sched_data; ++ for (; sd ; sd = entity->my_sched_data) { ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ if (entity) { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "get_next_queue: lookup in this group"); ++ } else ++ bfq_log_bfqg(bfqd, bfqd->root_group, ++ "get_next_queue: lookup in root group"); ++#endif ++ ++ entity = bfq_lookup_next_entity(sd, 1, bfqd); ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "get_next_queue: this queue, finish %llu", ++ (((entity->finish>>10)*1000)>>10)>>2); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "get_next_queue: this entity, finish %llu", ++ (((entity->finish>>10)*1000)>>10)>>2); ++ } ++#endif ++ ++ BUG_ON(!entity); ++ entity->service = 0; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ BUG_ON(!bfqq); ++ ++ return bfqq; ++} ++ ++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) ++{ ++ if (bfqd->in_service_bic) { ++ put_io_context(bfqd->in_service_bic->icq.ioc); ++ bfqd->in_service_bic = NULL; ++ } ++ ++ bfq_clear_bfqq_wait_request(bfqd->in_service_queue); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqd->in_service_queue = NULL; ++} ++ ++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ bfq_deactivate_entity(entity, requeue); ++} ++ ++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_activate_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq)); ++ bfq_clear_bfqq_non_blocking_wait_rq(bfqq); ++} ++ ++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg); ++ ++/* ++ * Called when the bfqq no longer has requests pending, remove it from ++ * the service tree. ++ */ ++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "del from busy"); ++ ++ bfq_clear_bfqq_busy(bfqq); ++ ++ BUG_ON(bfqd->busy_queues == 0); ++ bfqd->busy_queues--; ++ ++ if (!bfqq->dispatched) ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues--; ++ ++ bfqg_stats_update_dequeue(bfqq_group(bfqq)); ++ ++ BUG_ON(bfqq->entity.budget < 0); ++ ++ bfq_deactivate_bfqq(bfqd, bfqq, requeue); ++ ++ BUG_ON(bfqq->entity.budget < 0); ++} ++ ++/* ++ * Called when an inactive queue receives a new request. ++ */ ++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "add to busy"); ++ ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ bfq_mark_bfqq_busy(bfqq); ++ bfqd->busy_queues++; ++ ++ if (!bfqq->dispatched) ++ if (bfqq->wr_coeff == 1) ++ bfq_weights_tree_add(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues++; ++} +diff -w -uNr '--exclude=.git' linux-4.8/block/Kconfig.iosched linux-4.8-bfq/block/Kconfig.iosched +--- linux-4.8/block/Kconfig.iosched 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/block/Kconfig.iosched 2016-10-18 12:57:57.691164881 +0200 +@@ -39,6 +39,25 @@ + ---help--- + Enable group IO scheduling in CFQ. + ++config IOSCHED_BFQ ++ tristate "BFQ I/O scheduler" ++ default n ++ ---help--- ++ The BFQ I/O scheduler tries to distribute bandwidth among ++ all processes according to their weights. ++ It aims at distributing the bandwidth as desired, independently of ++ the disk parameters and with any workload. It also tries to ++ guarantee low latency to interactive and soft real-time ++ applications. If compiled built-in (saying Y here), BFQ can ++ be configured to support hierarchical scheduling. ++ ++config BFQ_GROUP_IOSCHED ++ bool "BFQ hierarchical scheduling support" ++ depends on IOSCHED_BFQ && BLK_CGROUP ++ default n ++ ---help--- ++ Enable hierarchical scheduling in BFQ, using the blkio controller. ++ + choice + prompt "Default I/O scheduler" + default DEFAULT_CFQ +@@ -52,6 +71,16 @@ + config DEFAULT_CFQ + bool "CFQ" if IOSCHED_CFQ=y + ++ config DEFAULT_BFQ ++ bool "BFQ" if IOSCHED_BFQ=y ++ help ++ Selects BFQ as the default I/O scheduler which will be ++ used by default for all block devices. ++ The BFQ I/O scheduler aims at distributing the bandwidth ++ as desired, independently of the disk parameters and with ++ any workload. It also tries to guarantee low latency to ++ interactive and soft real-time applications. ++ + config DEFAULT_NOOP + bool "No-op" + +@@ -61,6 +90,7 @@ + string + default "deadline" if DEFAULT_DEADLINE + default "cfq" if DEFAULT_CFQ ++ default "bfq" if DEFAULT_BFQ + default "noop" if DEFAULT_NOOP + + endmenu +diff -w -uNr '--exclude=.git' linux-4.8/block/Makefile linux-4.8-bfq/block/Makefile +--- linux-4.8/block/Makefile 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/block/Makefile 2016-10-18 12:57:57.691164881 +0200 +@@ -18,6 +18,7 @@ + obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o + obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o + obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o ++obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o + + obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o + obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o +diff -w -uNr '--exclude=.git' linux-4.8/include/linux/blkdev.h linux-4.8-bfq/include/linux/blkdev.h +--- linux-4.8/include/linux/blkdev.h 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/include/linux/blkdev.h 2016-10-18 12:57:59.951179412 +0200 +@@ -45,7 +45,7 @@ + * Maximum number of blkcg policies allowed to be registered concurrently. + * Defined here to simplify include dependency. + */ +-#define BLKCG_MAX_POLS 2 ++#define BLKCG_MAX_POLS 3 + + typedef void (rq_end_io_fn)(struct request *, int); + diff --git a/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch b/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch new file mode 100644 index 00000000..cece1d9f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch @@ -0,0 +1,213 @@ + +From: Sabrina Dubroca + +https://bugzilla.redhat.com/show_bug.cgi?id=1375944 +https://patchwork.ozlabs.org/patch/680412/ + + +Currently, GRO can do unlimited recursion through the gro_receive +handlers. This was fixed for tunneling protocols by limiting tunnel GRO +to one level with encap_mark, but both VLAN and TEB still have this +problem. Thus, the kernel is vulnerable to a stack overflow, if we +receive a packet composed entirely of VLAN headers. + +This patch adds a recursion counter to the GRO layer to prevent stack +overflow. When a gro_receive function hits the recursion limit, GRO is +aborted for this skb and it is processed normally. + +Thanks to Vladimír Beneš for the initial bug report. + +Fixes: CVE-2016-7039 +Fixes: 9b174d88c257 ("net: Add Transparent Ethernet Bridging GRO support.") +Fixes: 66e5133f19e9 ("vlan: Add GRO support for non hardware accelerated vlan") +Signed-off-by: Sabrina Dubroca +Reviewed-by: Jiri Benc +Acked-by: Hannes Frederic Sowa + + +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 3c20e87bb761..16af1ce99233 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk, + + skb_gro_pull(skb, gh_len); + skb_gro_postpull_rcsum(skb, gh, gh_len); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index e7d16687538b..c1639a3e95a4 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -583,7 +583,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk, + } + } + +- pp = eth_gro_receive(head, skb); ++ pp = call_gro_receive(eth_gro_receive, head, skb); + flush = 0; + + out: +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 136ae6bbe81e..11a7218c3661 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2169,7 +2169,10 @@ struct napi_gro_cb { + /* Used to determine if flush_id can be ignored */ + u8 is_atomic:1; + +- /* 5 bit hole */ ++ /* Number of gro_receive callbacks this packet already went through */ ++ u8 recursion_counter:4; ++ ++ /* 1 bit hole */ + + /* used to support CHECKSUM_COMPLETE for tunneling protocols */ + __wsum csum; +@@ -2180,6 +2183,25 @@ struct napi_gro_cb { + + #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) + ++#define GRO_RECURSION_LIMIT 15 ++static inline int gro_recursion_inc_test(struct sk_buff *skb) ++{ ++ return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT; ++} ++ ++typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *); ++static inline struct sk_buff **call_gro_receive(gro_receive_t cb, ++ struct sk_buff **head, ++ struct sk_buff *skb) ++{ ++ if (gro_recursion_inc_test(skb)) { ++ NAPI_GRO_CB(skb)->flush |= 1; ++ return NULL; ++ } ++ ++ return cb(head, skb); ++} ++ + struct packet_type { + __be16 type; /* This is really htons(ether_type). */ + struct net_device *dev; /* NULL is wildcarded here */ +diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c +index 8de138d3306b..f2531ad66b68 100644 +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -664,7 +664,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head, + + skb_gro_pull(skb, sizeof(*vhdr)); + skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr)); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/core/dev.c b/net/core/dev.c +index f1fe26f66458..f7cd4b8b035d 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4511,6 +4511,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff + NAPI_GRO_CB(skb)->flush = 0; + NAPI_GRO_CB(skb)->free = 0; + NAPI_GRO_CB(skb)->encap_mark = 0; ++ NAPI_GRO_CB(skb)->recursion_counter = 0; + NAPI_GRO_CB(skb)->is_fou = 0; + NAPI_GRO_CB(skb)->is_atomic = 1; + NAPI_GRO_CB(skb)->gro_remcsum_start = 0; +diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c +index 66dff5e3d772..02acfff36028 100644 +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -439,7 +439,7 @@ struct sk_buff **eth_gro_receive(struct sk_buff **head, + + skb_gro_pull(skb, sizeof(*eh)); + skb_gro_postpull_rcsum(skb, eh, sizeof(*eh)); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 1effc986739e..9648c97e541f 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1391,7 +1391,7 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) + skb_gro_pull(skb, sizeof(*iph)); + skb_set_transport_header(skb, skb_gro_offset(skb)); + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c +index cf50f7e2b012..030d1531e897 100644 +--- a/net/ipv4/fou.c ++++ b/net/ipv4/fou.c +@@ -249,7 +249,7 @@ static struct sk_buff **fou_gro_receive(struct sock *sk, + if (!ops || !ops->callbacks.gro_receive) + goto out_unlock; + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +@@ -441,7 +441,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk, + if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + goto out_unlock; + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c +index 96e0efecefa6..d5cac99170b1 100644 +--- a/net/ipv4/gre_offload.c ++++ b/net/ipv4/gre_offload.c +@@ -229,7 +229,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head, + /* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/ + skb_gro_postpull_rcsum(skb, greh, grehlen); + +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index f9333c963607..7b5879bcd08b 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -295,7 +295,13 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb, + + skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */ + skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); +- pp = udp_sk(sk)->gro_receive(sk, head, skb); ++ ++ if (gro_recursion_inc_test(skb)) { ++ flush = 1; ++ pp = NULL; ++ } else { ++ pp = udp_sk(sk)->gro_receive(sk, head, skb); ++ } + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index e7bfd55899a3..1fcf61f1cbc3 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -246,7 +246,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, + + skb_gro_postpull_rcsum(skb, iph, nlen); + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); diff --git a/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch b/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch new file mode 100644 index 00000000..536fce2e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch @@ -0,0 +1,426 @@ + +From: Larry Finger + +In commit d86e64768859 ("rtlwifi: rtl818x: constify local structures"), +the configuration struct for most of the drivers was changed to be +constant. The problem is that five of the modified drivers need to be +able to update the firmware name based on the exact model of the card. +As the file names were stored in one of the members of that struct, +these drivers would fail with a kernel BUG splat when they tried to +update the firmware name. + +Rather than reverting the previous commit, I used a suggestion by +Johannes Berg and made the firmware file name pointers be local to +the routines that update the software variables. + +The configuration struct of rtl8192cu, which was not touched in the +previous patch, is now constantfied. + +Fixes: d86e64768859 ("rtlwifi: rtl818x: constify local structures") +Suggested-by: Johannes Berg +Signed-off-by: Larry Finger +Cc: Stable +Cc: Julia Lawall +--- + +V2 - Fix warnings that were generated for some compiler versions. +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 2 +- + drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 8 ++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c | 13 +++++-------- + drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c | 12 ++++++------ + drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 6 +++--- + drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c | 8 ++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c | 9 +++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c | 12 +++++------- + drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 6 +++--- + drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 18 +++++++++--------- + drivers/net/wireless/realtek/rtlwifi/wifi.h | 2 -- + 11 files changed, 45 insertions(+), 51 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c +index f95760c..8e7f23c 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -111,7 +111,7 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, + if (!err) + goto found_alt; + } +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); ++ pr_err("Selected firmware is not available\n"); + rtlpriv->max_fw_size = 0; + return; + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c +index e7b11b4..f361808 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c +@@ -86,6 +86,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tid; ++ char *fw_name; + + rtl8188ee_bt_reg_init(hw); + rtlpriv->dm.dm_initialgain_enable = 1; +@@ -169,10 +170,10 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8188efw.bin"; ++ fw_name = "rtlwifi/rtl8188efw.bin"; + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -284,7 +285,6 @@ static const struct rtl_hal_cfg rtl88ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl88e_pci", +- .fw_name = "rtlwifi/rtl8188efw.bin", + .ops = &rtl8188ee_hal_ops, + .mod_params = &rtl88ee_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +index 5c46a98..691ddef 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +@@ -92,6 +92,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ char *fw_name = "rtlwifi/rtl8192cfwU.bin"; + + rtl8192ce_bt_reg_init(hw); + +@@ -163,15 +164,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) + } + + /* request fw */ +- if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && +- !IS_92C_SERIAL(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; +- else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; ++ if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) ++ fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + + rtlpriv->max_fw_size = 0x4000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -258,7 +256,6 @@ static const struct rtl_hal_cfg rtl92ce_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92c_pci", +- .fw_name = "rtlwifi/rtl8192cfw.bin", + .ops = &rtl8192ce_hal_ops, + .mod_params = &rtl92ce_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +index 92588e0..b84e13a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +@@ -55,6 +55,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; ++ char *fw_name; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -73,18 +74,18 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) + } + if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && + !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_A.bin"; + } else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_B.bin"; + } else { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; + } + /* provide name of alternative file */ + rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin"; +- pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); ++ pr_info("Loading firmware %s\n", fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, +- rtlpriv->cfg->fw_name, rtlpriv->io.dev, ++ fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + return err; + } +@@ -183,7 +184,6 @@ static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { + + static struct rtl_hal_cfg rtl92cu_hal_cfg = { + .name = "rtl92c_usb", +- .fw_name = "rtlwifi/rtl8192cufw.bin", + .ops = &rtl8192cu_hal_ops, + .mod_params = &rtl92cu_mod_params, + .usb_interface_cfg = &rtl92cu_interface_cfg, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +index a9c39eb..2d65e40 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +@@ -88,6 +88,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) + u8 tid; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); ++ char *fw_name = "rtlwifi/rtl8192defw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -177,10 +178,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) + + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); +- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); ++ pr_info("Loading firmware file %s\n", fw_name); + + /* request fw */ +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -262,7 +263,6 @@ static const struct rtl_hal_cfg rtl92de_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8192de", +- .fw_name = "rtlwifi/rtl8192defw.bin", + .ops = &rtl8192de_hal_ops, + .mod_params = &rtl92de_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c +index ac299cb..46b605de3 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c +@@ -91,6 +91,7 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; ++ char *fw_name; + + rtl92ee_bt_reg_init(hw); + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; +@@ -170,11 +171,11 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) + } + + /* request fw */ +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192eefw.bin"; ++ fw_name = "rtlwifi/rtl8192eefw.bin"; + + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -266,7 +267,6 @@ static const struct rtl_hal_cfg rtl92ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92ee_pci", +- .fw_name = "rtlwifi/rtl8192eefw.bin", + .ops = &rtl8192ee_hal_ops, + .mod_params = &rtl92ee_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +index a652d45..998cefb 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -85,12 +85,13 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_firmware *pfirmware = NULL; ++ char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); ++ pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; + return; + } +@@ -113,6 +114,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; + u16 earlyrxthreshold = 7; ++ char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -210,9 +212,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) + rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 + + sizeof(struct fw_hdr); + pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" +- "Loading firmware %s\n", rtlpriv->cfg->fw_name); ++ "Loading firmware %s\n", fw_name); + /* request fw */ +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); + if (err) { +@@ -306,7 +308,6 @@ static const struct rtl_hal_cfg rtl92se_hal_cfg = { + .bar_id = 1, + .write_readback = false, + .name = "rtl92s_pci", +- .fw_name = "rtlwifi/rtl8192sefw.bin", + .ops = &rtl8192se_hal_ops, + .mod_params = &rtl92se_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c +index 89c828a..c51a9e8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c +@@ -94,6 +94,7 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int err = 0; ++ char *fw_name = "rtlwifi/rtl8723fw.bin"; + + rtl8723e_bt_reg_init(hw); + +@@ -176,14 +177,12 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + +- if (IS_VENDOR_8723_A_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin"; +- else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin"; ++ if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) ++ fw_name = "rtlwifi/rtl8723fw_B.bin"; + + rtlpriv->max_fw_size = 0x6000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -280,7 +279,6 @@ static const struct rtl_hal_cfg rtl8723e_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723e_pci", +- .fw_name = "rtlwifi/rtl8723efw.bin", + .ops = &rtl8723e_hal_ops, + .mod_params = &rtl8723e_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c +index 20b53f0..847644d 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c +@@ -91,6 +91,7 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); ++ char *fw_name = "rtlwifi/rtl8723befw.bin"; + + rtl8723be_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); +@@ -184,8 +185,8 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) + } + + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -280,7 +281,6 @@ static const struct rtl_hal_cfg rtl8723be_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723be_pci", +- .fw_name = "rtlwifi/rtl8723befw.bin", + .ops = &rtl8723be_hal_ops, + .mod_params = &rtl8723be_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +index 22f687b1..297938e 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +@@ -93,6 +93,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ char *fw_name, *wowlan_fw_name; + + rtl8821ae_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); +@@ -203,17 +204,17 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin"; +- rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin"; ++ fw_name = "rtlwifi/rtl8812aefw.bin"; ++ wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin"; + } else { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin"; +- rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin"; ++ fw_name = "rtlwifi/rtl8821aefw.bin"; ++ wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin"; + } + + rtlpriv->max_fw_size = 0x8000; + /*load normal firmware*/ +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -222,9 +223,9 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + /*load wowlan firmware*/ +- pr_info("Using firmware %s\n", rtlpriv->cfg->wowlan_fw_name); ++ pr_info("Using firmware %s\n", wowlan_fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, +- rtlpriv->cfg->wowlan_fw_name, ++ wowlan_fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_wowlan_fw_cb); + if (err) { +@@ -320,7 +321,6 @@ static const struct rtl_hal_cfg rtl8821ae_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8821ae_pci", +- .fw_name = "rtlwifi/rtl8821aefw.bin", + .ops = &rtl8821ae_hal_ops, + .mod_params = &rtl8821ae_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 595f7d5..dafe486 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2278,9 +2278,7 @@ struct rtl_hal_cfg { + u8 bar_id; + bool write_readback; + char *name; +- char *fw_name; + char *alt_fw_name; +- char *wowlan_fw_name; + struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + struct rtl_hal_usbint_cfg *usb_interface_cfg; diff --git a/kernel/kernel/files/patches/mageia/nvmepatch1-V4.patch b/kernel/kernel/files/patches/mageia/nvmepatch1-V4.patch new file mode 100644 index 00000000..9bcefef0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/nvmepatch1-V4.patch @@ -0,0 +1,111 @@ +diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c +index e947e298a737..44009105f8c8 100644 +--- a/drivers/nvme/host/scsi.c ++++ b/drivers/nvme/host/scsi.c +@@ -72,15 +72,6 @@ static int sg_version_num = 30534; /* 2 digits for each component */ + #define ALL_LUNS_RETURNED 0x02 + #define ALL_WELL_KNOWN_LUNS_RETURNED 0x01 + #define RESTRICTED_LUNS_RETURNED 0x00 +-#define NVME_POWER_STATE_START_VALID 0x00 +-#define NVME_POWER_STATE_ACTIVE 0x01 +-#define NVME_POWER_STATE_IDLE 0x02 +-#define NVME_POWER_STATE_STANDBY 0x03 +-#define NVME_POWER_STATE_LU_CONTROL 0x07 +-#define POWER_STATE_0 0 +-#define POWER_STATE_1 1 +-#define POWER_STATE_2 2 +-#define POWER_STATE_3 3 + #define DOWNLOAD_SAVE_ACTIVATE 0x05 + #define DOWNLOAD_SAVE_DEFER_ACTIVATE 0x0E + #define ACTIVATE_DEFERRED_MICROCODE 0x0F +@@ -1229,64 +1220,6 @@ static void nvme_trans_fill_read_cap(u8 *response, struct nvme_id_ns *id_ns, + + /* Start Stop Unit Helper Functions */ + +-static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr, +- u8 pc, u8 pcmod, u8 start) +-{ +- int res; +- int nvme_sc; +- struct nvme_id_ctrl *id_ctrl; +- int lowest_pow_st; /* max npss = lowest power consumption */ +- unsigned ps_desired = 0; +- +- nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl); +- res = nvme_trans_status_code(hdr, nvme_sc); +- if (res) +- return res; +- +- lowest_pow_st = max(POWER_STATE_0, (int)(id_ctrl->npss - 1)); +- kfree(id_ctrl); +- +- switch (pc) { +- case NVME_POWER_STATE_START_VALID: +- /* Action unspecified if POWER CONDITION MODIFIER != 0 */ +- if (pcmod == 0 && start == 0x1) +- ps_desired = POWER_STATE_0; +- if (pcmod == 0 && start == 0x0) +- ps_desired = lowest_pow_st; +- break; +- case NVME_POWER_STATE_ACTIVE: +- /* Action unspecified if POWER CONDITION MODIFIER != 0 */ +- if (pcmod == 0) +- ps_desired = POWER_STATE_0; +- break; +- case NVME_POWER_STATE_IDLE: +- /* Action unspecified if POWER CONDITION MODIFIER != [0,1,2] */ +- if (pcmod == 0x0) +- ps_desired = POWER_STATE_1; +- else if (pcmod == 0x1) +- ps_desired = POWER_STATE_2; +- else if (pcmod == 0x2) +- ps_desired = POWER_STATE_3; +- break; +- case NVME_POWER_STATE_STANDBY: +- /* Action unspecified if POWER CONDITION MODIFIER != [0,1] */ +- if (pcmod == 0x0) +- ps_desired = max(POWER_STATE_0, (lowest_pow_st - 2)); +- else if (pcmod == 0x1) +- ps_desired = max(POWER_STATE_0, (lowest_pow_st - 1)); +- break; +- case NVME_POWER_STATE_LU_CONTROL: +- default: +- res = nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, +- ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, +- SCSI_ASCQ_CAUSE_NOT_REPORTABLE); +- break; +- } +- nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_POWER_MGMT, ps_desired, 0, +- NULL); +- return nvme_trans_status_code(hdr, nvme_sc); +-} +- + static int nvme_trans_send_activate_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, + u8 buffer_id) + { +@@ -2235,11 +2168,10 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns, + static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, + u8 *cmd) + { +- u8 immed, pcmod, pc, no_flush, start; ++ u8 immed, pcmod, no_flush, start; + + immed = cmd[1] & 0x01; + pcmod = cmd[3] & 0x0f; +- pc = (cmd[4] & 0xf0) >> 4; + no_flush = cmd[4] & 0x04; + start = cmd[4] & 0x01; + +@@ -2254,8 +2186,8 @@ static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, + if (res) + return res; + } +- /* Setup the expected power state transition */ +- return nvme_trans_power_state(ns, hdr, pc, pcmod, start); ++ ++ return 0; + } + } + +-- +2.7.4 diff --git a/kernel/kernel/files/patches/mageia/nvmepatch2-V4.patch b/kernel/kernel/files/patches/mageia/nvmepatch2-V4.patch new file mode 100644 index 00000000..454cb4a5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/nvmepatch2-V4.patch @@ -0,0 +1,107 @@ +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 2feacc70bf61..b92a7f767bfc 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -597,7 +597,7 @@ int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid, + } + + int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, +- dma_addr_t dma_addr, u32 *result) ++ void *buffer, size_t buflen, u32 *result) + { + struct nvme_command c; + struct nvme_completion cqe; +@@ -606,10 +606,9 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, + memset(&c, 0, sizeof(c)); + c.features.opcode = nvme_admin_get_features; + c.features.nsid = cpu_to_le32(nsid); +- c.features.dptr.prp1 = cpu_to_le64(dma_addr); + c.features.fid = cpu_to_le32(fid); + +- ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, ++ ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, buffer, buflen, 0, + NVME_QID_ANY, 0, 0); + if (ret >= 0 && result) + *result = le32_to_cpu(cqe.result); +@@ -617,7 +616,7 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, + } + + int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, +- dma_addr_t dma_addr, u32 *result) ++ void *buffer, size_t buflen, u32 *result) + { + struct nvme_command c; + struct nvme_completion cqe; +@@ -625,12 +624,11 @@ int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + + memset(&c, 0, sizeof(c)); + c.features.opcode = nvme_admin_set_features; +- c.features.dptr.prp1 = cpu_to_le64(dma_addr); + c.features.fid = cpu_to_le32(fid); + c.features.dword11 = cpu_to_le32(dword11); + +- ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, +- NVME_QID_ANY, 0, 0); ++ ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, ++ buffer, buflen, 0, NVME_QID_ANY, 0, 0); + if (ret >= 0 && result) + *result = le32_to_cpu(cqe.result); + return ret; +@@ -664,7 +662,7 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) + u32 result; + int status, nr_io_queues; + +- status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, 0, ++ status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, + &result); + if (status < 0) + return status; +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index ab18b78102bf..c2151761ec5f 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -292,9 +292,9 @@ int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid, + struct nvme_id_ns **id); + int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log); + int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, +- dma_addr_t dma_addr, u32 *result); ++ void *buffer, size_t buflen, u32 *result); + int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, +- dma_addr_t dma_addr, u32 *result); ++ void *buffer, size_t buflen, u32 *result); + int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); + void nvme_start_keep_alive(struct nvme_ctrl *ctrl); + void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); +diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c +index 44009105f8c8..c2a0a1c7d05d 100644 +--- a/drivers/nvme/host/scsi.c ++++ b/drivers/nvme/host/scsi.c +@@ -906,7 +906,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr, + kfree(smart_log); + + /* Get Features for Temp Threshold */ +- res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, 0, ++ res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, NULL, 0, + &feature_resp); + if (res != NVME_SC_SUCCESS) + temp_c_thresh = LOG_TEMP_UNKNOWN; +@@ -1039,7 +1039,7 @@ static int nvme_trans_fill_caching_page(struct nvme_ns *ns, + if (len < MODE_PAGE_CACHING_LEN) + return -EINVAL; + +- nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, 0, ++ nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, NULL, 0, + &feature_resp); + res = nvme_trans_status_code(hdr, nvme_sc); + if (res) +@@ -1328,7 +1328,7 @@ static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr, + case MODE_PAGE_CACHING: + dword11 = ((mode_page[2] & CACHING_MODE_PAGE_WCE_MASK) ? 1 : 0); + nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, +- dword11, 0, NULL); ++ dword11, NULL, 0, NULL); + res = nvme_trans_status_code(hdr, nvme_sc); + break; + case MODE_PAGE_CONTROL: +-- +2.7.4 diff --git a/kernel/kernel/files/patches/mageia/nvmepatch3-V4.patch b/kernel/kernel/files/patches/mageia/nvmepatch3-V4.patch new file mode 100644 index 00000000..797c4681 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/nvmepatch3-V4.patch @@ -0,0 +1,264 @@ +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index b92a7f767bfc..a143c72c3d0d 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -56,6 +56,11 @@ EXPORT_SYMBOL_GPL(nvme_max_retries); + static int nvme_char_major; + module_param(nvme_char_major, int, 0); + ++static unsigned long default_ps_max_latency_us = 25000; ++module_param(default_ps_max_latency_us, ulong, 0644); ++MODULE_PARM_DESC(ps_max_latency_us, ++ "default max power saving latency; overridden per device in sysfs"); ++ + static LIST_HEAD(nvme_ctrl_list); + static DEFINE_SPINLOCK(dev_list_lock); + +@@ -1205,6 +1210,98 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, + blk_queue_write_cache(q, vwc, vwc); + } + ++static void nvme_configure_apst(struct nvme_ctrl *ctrl) ++{ ++ /* ++ * APST (Autonomous Power State Transition) lets us program a ++ * table of power state transitions that the controller will ++ * perform automatically. We configure it with a simple ++ * heuristic: we are willing to spend at most 2% of the time ++ * transitioning between power states. Therefore, when running ++ * in any given state, we will enter the next lower-power ++ * non-operational state after waiting 100 * (enlat + exlat) ++ * microseconds, as long as that state's total latency is under ++ * the requested maximum latency. ++ * ++ * We will not autonomously enter any non-operational state for ++ * which the total latency exceeds ps_max_latency_us. Users ++ * can set ps_max_latency_us to zero to turn off APST. ++ */ ++ ++ unsigned apste; ++ struct nvme_feat_auto_pst *table; ++ int ret; ++ ++ if (!ctrl->apsta) ++ return; /* APST isn't supported. */ ++ ++ if (ctrl->npss > 31) { ++ dev_warn(ctrl->device, "NPSS is invalid; not using APST\n"); ++ return; ++ } ++ ++ table = kzalloc(sizeof(*table), GFP_KERNEL); ++ if (!table) ++ return; ++ ++ if (ctrl->ps_max_latency_us == 0) { ++ /* Turn off APST. */ ++ apste = 0; ++ } else { ++ __le64 target = cpu_to_le64(0); ++ int state; ++ ++ /* ++ * Walk through all states from lowest- to highest-power. ++ * According to the spec, lower-numbered states use more ++ * power. NPSS, despite the name, is the index of the ++ * lowest-power state, not the number of states. ++ */ ++ for (state = (int)ctrl->npss; state >= 0; state--) { ++ u64 total_latency_us, transition_ms; ++ ++ if (target) ++ table->entries[state] = target; ++ ++ /* ++ * Is this state a useful non-operational state for ++ * higher-power states to autonomously transition to? ++ */ ++ if (!(ctrl->psd[state].flags & 2)) ++ continue; /* It's an operational state. */ ++ ++ total_latency_us = ++ (u64)cpu_to_le32(ctrl->psd[state].entry_lat) + ++ + cpu_to_le32(ctrl->psd[state].exit_lat); ++ if (total_latency_us > ctrl->ps_max_latency_us) ++ continue; ++ ++ /* ++ * This state is good. Use it as the APST idle ++ * target for higher power states. ++ */ ++ transition_ms = total_latency_us + 19; ++ do_div(transition_ms, 20); ++ if (transition_ms >= (1 << 24)) ++ transition_ms = (1 << 24); ++ ++ target = cpu_to_le64((state << 3) | ++ (transition_ms << 8)); ++ } ++ ++ apste = 1; ++ } ++ ++ ret = nvme_set_features(ctrl, NVME_FEAT_AUTO_PST, apste, ++ table, sizeof(*table), NULL); ++ if (ret) ++ dev_err(ctrl->device, "failed to set APST feature (%d)\n", ret); ++ ++ kfree(table); ++} ++ ++static struct attribute_group nvme_dev_dynamic_attrs_group; ++ + /* + * Initialize the cached copies of the Identify data and various controller + * register in our nvme_ctrl structure. This should be called as soon as +@@ -1271,6 +1368,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) + ctrl->sgls = le32_to_cpu(id->sgls); + ctrl->kas = le16_to_cpu(id->kas); + ++ ctrl->npss = id->npss; ++ ctrl->apsta = id->apsta; ++ memcpy(ctrl->psd, id->psd, sizeof(ctrl->psd)); ++ + if (ctrl->ops->is_fabrics) { + ctrl->icdoff = le16_to_cpu(id->icdoff); + ctrl->ioccsz = le32_to_cpu(id->ioccsz); +@@ -1294,6 +1395,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) + } + + kfree(id); ++ ++ nvme_configure_apst(ctrl); ++ ++ sysfs_update_group(&ctrl->device->kobj, &nvme_dev_dynamic_attrs_group); + return ret; + } + EXPORT_SYMBOL_GPL(nvme_init_identify); +@@ -1564,6 +1669,41 @@ static ssize_t nvme_sysfs_show_address(struct device *dev, + } + static DEVICE_ATTR(address, S_IRUGO, nvme_sysfs_show_address, NULL); + ++static ssize_t nvme_sysfs_show_ps_max_latency_us( ++ struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ ++ return snprintf(buf, PAGE_SIZE, "%llu\n", ctrl->ps_max_latency_us); ++} ++ ++static ssize_t nvme_sysfs_store_ps_max_latency_us( ++ struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ int ret; ++ u64 val; ++ ++ ret = kstrtoull(buf, 10, &val); ++ if (ret) ++ return ret; ++ ++ if (ctrl->ps_max_latency_us != val) { ++ ctrl->ps_max_latency_us = val; ++ nvme_configure_apst(ctrl); ++ } ++ ++ return size; ++} ++ ++static DEVICE_ATTR(ps_max_latency_us, 0644, ++ nvme_sysfs_show_ps_max_latency_us, ++ nvme_sysfs_store_ps_max_latency_us); ++ + static struct attribute *nvme_dev_attrs[] = { + &dev_attr_reset_controller.attr, + &dev_attr_rescan_controller.attr, +@@ -1605,8 +1745,33 @@ static struct attribute_group nvme_dev_attrs_group = { + .is_visible = nvme_dev_attrs_are_visible, + }; + ++static struct attribute *nvme_dev_dynamic_attrs[] = { ++ &dev_attr_ps_max_latency_us.attr, ++ NULL ++}; ++ ++static umode_t nvme_dev_dynamic_attrs_are_visible(struct kobject *kobj, ++ struct attribute *a, int n) ++{ ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ ++ if (a == &dev_attr_ps_max_latency_us.attr) { ++ if (!ctrl->apsta) ++ return 0; ++ } ++ ++ return a->mode; ++} ++ ++static struct attribute_group nvme_dev_dynamic_attrs_group = { ++ .attrs = nvme_dev_dynamic_attrs, ++ .is_visible = nvme_dev_dynamic_attrs_are_visible, ++}; ++ + static const struct attribute_group *nvme_dev_attr_groups[] = { + &nvme_dev_attrs_group, ++ &nvme_dev_dynamic_attrs_group, + NULL, + }; + +@@ -1991,6 +2156,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, + ctrl->quirks = quirks; + INIT_WORK(&ctrl->scan_work, nvme_scan_work); + INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); ++ ctrl->ps_max_latency_us = default_ps_max_latency_us; + + ret = nvme_set_instance(ctrl); + if (ret) +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index c2151761ec5f..16d51006afc0 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -129,13 +129,19 @@ struct nvme_ctrl { + u32 vs; + u32 sgls; + u16 kas; ++ u8 npss; ++ u8 apsta; + unsigned int kato; + bool subsystem; + unsigned long quirks; ++ struct nvme_id_power_state psd[32]; + struct work_struct scan_work; + struct work_struct async_event_work; + struct delayed_work ka_work; + ++ /* Power saving configuration */ ++ u64 ps_max_latency_us; ++ + /* Fabrics only */ + u16 sqsize; + u32 ioccsz; +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index d8b37bab2887..a76237dac4b0 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -543,6 +543,12 @@ struct nvme_dsm_range { + __le64 slba; + }; + ++/* Features */ ++ ++struct nvme_feat_auto_pst { ++ __le64 entries[32]; ++}; ++ + /* Admin commands */ + + enum nvme_admin_opcode { +-- +2.7.4 diff --git a/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch b/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch new file mode 100644 index 00000000..1b819dea --- /dev/null +++ b/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch @@ -0,0 +1,110 @@ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 2d24813..498ded6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2877,6 +2877,21 @@ skl_wm_plane_id(const struct intel_plane *plane) + } + + /* ++ * FIXME: We still don't have the proper code detect if we need to apply the WA, ++ * so assume we'll always need it in order to avoid underruns. ++ */ ++static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state) ++{ ++ struct drm_i915_private *dev_priv = to_i915(state->base.dev); ++ ++ if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) || ++ IS_KABYLAKE(dev_priv)) ++ return true; ++ ++ return false; ++} ++ ++/* + * SAGV dynamically adjusts the system agent voltage and clock frequencies + * depending on power and performance requirements. The display engine access + * to system memory is blocked during the adjustment time. Because of the +@@ -2979,9 +2994,10 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state) + struct drm_device *dev = state->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); +- struct drm_crtc *crtc; ++ struct intel_crtc *crtc; ++ struct intel_plane *plane; + enum pipe pipe; +- int level, plane; ++ int level, id, latency; + + /* + * SKL workaround: bspec recommends we disable the SAGV when we have +@@ -2996,27 +3012,35 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state) + + /* Since we're now guaranteed to only have one active CRTC... */ + pipe = ffs(intel_state->active_crtcs) - 1; +- crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ++ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + +- if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE) ++ if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + return false; ++ for_each_intel_plane_on_crtc(dev, crtc, plane) { ++ id = skl_wm_plane_id(plane); + +- for_each_plane(dev_priv, pipe, plane) { + /* Skip this plane if it's not enabled */ +- if (intel_state->wm_results.plane[pipe][plane][0] == 0) ++ if (intel_state->wm_results.plane[pipe][id][0] == 0) + continue; + + /* Find the highest enabled wm level for this plane */ + for (level = ilk_wm_max_level(dev); +- intel_state->wm_results.plane[pipe][plane][level] == 0; --level) ++ intel_state->wm_results.plane[pipe][id][level] == 0; --level) + { } + ++ latency = dev_priv->wm.skl_latency[level]; ++ ++ if (skl_needs_memory_bw_wa(intel_state) && ++ plane->base.state->fb->modifier[0] == ++ I915_FORMAT_MOD_X_TILED) ++ latency += 15; ++ + /* + * If any of the planes on this pipe don't enable wm levels + * that incur memory latencies higher then 30µs we can't enable + * the SAGV + */ +- if (dev_priv->wm.skl_latency[level] < SKL_SAGV_BLOCK_TIME) ++ if (latency < SKL_SAGV_BLOCK_TIME) + return false; + } + +@@ -3546,12 +3570,18 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + uint8_t cpp; + uint32_t width = 0, height = 0; + uint32_t plane_pixel_rate; ++ struct intel_atomic_state *state = ++ to_intel_atomic_state(cstate->base.state); ++ bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); + + if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { + *enabled = false; + return 0; + } + ++ if (apply_memory_bw_wa && fb->modifier[0] == I915_FORMAT_MOD_X_TILED) ++ latency += 15; ++ + width = drm_rect_width(&intel_pstate->src) >> 16; + height = drm_rect_height(&intel_pstate->src) >> 16; + +@@ -3593,6 +3623,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, + } + } + y_tile_minimum = plane_blocks_per_line * min_scanlines; ++ if (apply_memory_bw_wa) ++ y_tile_minimum *= 2; ++ + selected_result = max(method2, y_tile_minimum); + } else { + if ((ddb_allocation / plane_blocks_per_line) >= 1) From ae7db1a54f638aa10fb81904b8b92269aca3544a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Sat, 29 Oct 2016 18:24:41 +0300 Subject: [PATCH 06/11] kernel-4_8_4 w2 --- .../kernel/files/configs/kernel-x86_64-config | 4 ++- kernel/kernel/files/patches/mageia/series | 29 ++++++++++++++++--- kernel/kernel/pspec.xml | 17 ++++++++--- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index 32e72208..4776cea4 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.8.2 Kernel Configuration +# Linux/x86_64 4.8.4 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -369,6 +369,8 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_IOSCHED_BFQ=m +# CONFIG_BFQ_GROUP_IOSCHED is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 1eff6fc4..8906ee33 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -46,6 +46,8 @@ Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch ### base-cacheinfo-silence-DT-warnings.patch +kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch + ### ### i2c ### @@ -121,10 +123,15 @@ block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch # Include new BFQ I/O scheduler # (See http://algo.ing.unimo.it/people/paolo/disk_sched) -# DISABLED: 0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch -# DISABLED: 0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch -# DISABLED: 0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch -# DISABLED: 0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch +# +# Release of BFQ I/O scheduler v8r4 (rediffed from git https://github.com/linusw/linux-bfq) +linux-BFQ-v8r4.patch + +# Let NVME drives enter in power state +# (see https://github.com/damige/linux-nvme/tree/master/src) +nvmepatch1-V4.patch +nvmepatch2-V4.patch +nvmepatch3-V4.patch ### ### Char @@ -175,6 +182,14 @@ gpu-drm-mach64-linux-3.14-buildfix.patch gpu-drm-mach64-3.17-buildfix.patch gpu-drm-mach64-3.18-buildfix.patch +# Attempt to fix FIFO underrun problems: +# (from https://patchwork.freedesktop.org/patch/113642/ and +# from https://bugs.freedesktop.org/attachment.cgi?id=127264, reference from +# https://bugs.freedesktop.org/show_bug.cgi?id=97450). Does not completely resolve the +# issues but reduce. +drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch +skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch + ### ### Hardware Monitoring ### @@ -226,6 +241,12 @@ net-netfilter-psd.patch net-netfilter-psd-mdv.patch net-netfilter-psd-2.6.35-buildfix.patch +# rtlwifi regression +net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch + +# CVE-2016-7039 +net-add-recursion-limit-to-GRO.patch + ### ### Platform drivers ### diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index c1c1040a..09eda125 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,8 +28,8 @@ - patches/linux/patch-4.8.2.xz - + patches/linux/patch-4.8.4.xz + patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch @@ -40,6 +40,7 @@ patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch + patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch patches/mageia/pci-quirks-drop-devinit-exit.patch patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch @@ -58,6 +59,10 @@ patches/mageia/block-floppy-disable-pnp-modalias.patch patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch + patches/mageia/linux-BFQ-v8r4.patch + patches/mageia/nvmepatch1-V4.patch + patches/mageia/nvmepatch2-V4.patch + patches/mageia/nvmepatch3-V4.patch patches/mageia/fs-aufs-4.7.patch patches/mageia/fs-aufs-4.7-modular.patch patches/mageia/fs-aufs-4.7-ver-fix.patch @@ -81,6 +86,8 @@ patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch patches/mageia/gpu-drm-mach64-3.17-buildfix.patch patches/mageia/gpu-drm-mach64-3.18-buildfix.patch + patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch + patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -93,6 +100,8 @@ patches/mageia/net-netfilter-psd.patch patches/mageia/net-netfilter-psd-mdv.patch patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch + patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch + patches/mageia/net-add-recursion-limit-to-GRO.patch patches/mageia/platform-x86-add-shuttle-wmi-driver.patch patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch @@ -187,8 +196,8 @@ - 2016-10-18 - 4.8.2 + 2016-10-28 + 4.8.4 Version Bump. security From 081ac5acbfa2cfa3ba76dfe7d4c8579132d648b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Mon, 31 Oct 2016 10:17:38 +0200 Subject: [PATCH 07/11] 4_8_5 not ready --- .../kernel/files/configs/kernel-x86_64-config | 4 +- .../kernel/files/patches/linux/patch-4.8.5.xz | Bin 0 -> 82200 bytes ...-return-type-of-cpu_power_is_cpu_onl.patch | 49 ++ ...ir-Fix-incorrect-task-group-load_avg.patch | 73 --- kernel/kernel/files/patches/mageia/series | 88 +++- ...d_mode_in_SAGV_check_on_a7fac751ddba.patch | 110 ---- ...-arm-clk-imx35-fix-name-for-ckil-clk.patch | 37 ++ ...ol-creation-for-output-driver-widget.patch | 41 ++ ...d-variable-in-snd_soc_dapm_get_volsw.patch | 42 ++ ...or-_enum_double-mux-s-second-channel.patch | 35 ++ ...fix-obsoleted-initializers-for-array.patch | 85 ++++ ...fix-obsoleted-initializers-for-array.patch | 96 ++++ ...-code-in-soc_tplg_dapm_widget_create.patch | 31 ++ ...riodic_chan_stat_support-wmi-service.patch | 58 +++ ...0k-fix-reporting-channel-survey-data.patch | 37 ++ ...in-management-path-in-push-txq-logic.patch | 81 +++ ...hput-regression-in-multi-client-mode.patch | 54 ++ ...neous-dma_free_coherent-in-tmc_probe.patch | 37 ++ ...h-ce-add-missing-async-import-export.patch | 64 +++ ...alue-check-in-ccp_dmaengine_register.patch | 33 ++ ...-iv-buffer-size-in-crypto_gcm_setkey.patch | 35 ++ ...ult-creq-state-during-initialization.patch | 80 +++ ...mation-context-for-each-dequeued-req.patch | 40 ++ ...ne-ipu-remove-bogus-no_irq-reference.patch | 56 ++ ...g-back-after-multi-head-was-disabled.patch | 46 ++ ...method-to-reduce-computational-error.patch | 53 ++ ...pu-dce10-disable-hpd-on-local-panels.patch | 62 +++ ...missing-drm_mode_config_cleanup-call.patch | 31 ++ ...pu-dce11-disable-hpd-on-local-panels.patch | 62 +++ ...gpu-dce8-disable-hpd-on-local-panels.patch | 87 ++++ ...-drm-amdgpu-fix-ib-alignment-for-uvd.patch | 30 ++ ...ext-reset_counter-in-amdgpu_ctx_init.patch | 37 ++ ...ssue-when-using-clk_register_divider.patch | 50 ++ ...ze-when-determining-865g-stolen-base.patch | 118 +++++ ...e-drm-i915-allow-dp-to-work-w-o-edid.patch | 111 ++++ ...g-regardless-of-dpll_sdvo_high_speed.patch | 76 +++ ...-cache-pwm-alternate-increment-value.patch | 79 +++ ...ernate-increment-on-backlight-enable.patch | 70 +++ ..._per_line-on-watermarks-calculations.patch | 111 ++++ ...9-fix-the-watermark-res_blocks-value.patch | 75 +++ ...wawmmemoryreadlatency-implementation.patch | 91 ++++ ...scanlines-for-y-tile-is-not-always-4.patch | 133 +++++ ...nes-actually-affected-by-ddb-changes.patch | 92 ++++ ...le-drm-i915-introduce-intel_has_sagv.patch | 103 ++++ ...e-mmiodebug-before-a-register-access.patch | 43 ++ ...-kbl-also-needs-to-run-the-sagv-code.patch | 64 +++ ...-in-atomic_commit-into-it-s-own-hook.patch | 162 ++++++ ...g-hpd-handling-into-the-hotplug-work.patch | 102 ++++ ...-not-skl-only-so-rename-a-few-things.patch | 179 +++++++ ...e-watermarks-if-they-haven-t-changed.patch | 79 +++ ...h-changed-wms-get-added-to-the-state.patch | 43 ++ ...lues-atomically-with-wms-plane-attrs.patch | 479 ++++++++++++++++++ ...arks-atomically-during-plane-updates.patch | 335 ++++++++++++ ...lias-obj-phys_handle-and-obj-userptr.patch | 61 +++ ...dule-owner-through-to-dma_buf_export.patch | 78 +++ ...method-to-reduce-computational-error.patch | 48 ++ ...-narrow-asic_init-for-virtualization.patch | 33 ++ ...deon-si-dpm-fix-phase-shedding-setup.patch | 40 ++ ...hen-the-cs-reads-from-render-targets.patch | 225 ++++++++ ...t-the-user-space-command-buffer-size.patch | 42 ++ ...-generic_chip-add-irq_unmap-callback.patch | 68 +++ ...table-hid-add-quirk-for-akai-midimix.patch | 50 ++ ...ail-if-pm_runtime_get_sync-returns-0.patch | 44 ++ ...x-broken-i40e_config_rss_aq-function.patch | 155 ++++++ .../stable-i40e-remove-a-stray-unlock.patch | 32 ++ ...i1-move-iowait_init-to-priv-allocate.patch | 55 ++ ...e-ib-mlx5-fix-steering-resource-leak.patch | 31 ++ ...stable-ib-qib-remove-qpt_mask-global.patch | 89 ++++ ...-ib-rdmavt-correct-sparse-annotation.patch | 44 ++ ...-fix-off-by-one-on-devnr-limit-check.patch | 35 ++ ...ng-error-code-assignment-before-test.patch | 33 ++ ...rved-hugepages-during-memory-offline.patch | 140 +++++ ...-correct-aid-value-during-tdls-setup.patch | 36 ++ ...ect-after-interface-disabled-enabled.patch | 39 ++ ...id-bit-when-setting-file-permissions.patch | 408 +++++++++++++++ ...-of-uninitialized-pointer-bq-charger.patch | 55 ++ ...heck-live-status-before-reading-edid.patch | 142 ++++++ ...able-rt2x00usb-fix-error-return-code.patch | 37 ++ ...-cleanly-in-the-system-shutdown-path.patch | 80 +++ ...master_put-in-device-remove-function.patch | 33 ++ ...ng-android-ion-hisi-fix-dependencies.patch | 40 ++ ...010-declare-private-functions-static.patch | 41 ++ ...nterruptible_timeout-return-handling.patch | 44 ++ ...eu-fix-scheduling-while-atomic-splat.patch | 45 ++ ...lock_phase-bit-of-display-controller.patch | 33 ++ ...io-fix-dmem_region_start-computation.patch | 36 ++ kernel/kernel/pspec.xml | 93 +++- 87 files changed, 6539 insertions(+), 195 deletions(-) create mode 100644 kernel/kernel/files/patches/linux/patch-4.8.5.xz create mode 100644 kernel/kernel/files/patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch delete mode 100644 kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch delete mode 100644 kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch create mode 100644 kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index 4776cea4..b2b211b7 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.8.4 Kernel Configuration +# Linux/x86_64 4.8.5 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -2256,7 +2256,7 @@ CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m CONFIG_NET_TEAM_MODE_LOADBALANCE=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m -# CONFIG_IPVLAN is not set +CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m # CONFIG_GTP is not set diff --git a/kernel/kernel/files/patches/linux/patch-4.8.5.xz b/kernel/kernel/files/patches/linux/patch-4.8.5.xz new file mode 100644 index 0000000000000000000000000000000000000000..d3cf432b7b27cdaab726fb26dfb45af26302b7c4 GIT binary patch literal 82200 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 +Date: Fri, 9 Sep 2016 10:19:02 -0700 +Subject: [PATCH] cpupower: Correct return type of cpu_power_is_cpu_online in + cpufreq +To: Thomas Renninger +Cc: linux-pm@vger.kernel.org +Cc: linux-kernel@vger.kernel.org + +When converting to a shared library in ac5a181d065d ("cpupower: Add +cpuidle parts into library"), cpu_freq_cpu_exists was converted to +cpupower_is_cpu_online. cpu_req_cpu_exists returned 0 on success and +-ENOSYS on failure whereas cpupower_is_cpu_online returns 1 on success. +Check for the correct return value in cpufreq-set. + +See https://bugzilla.redhat.com/show_bug.cgi?id=1374212 + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Reported-by: Julian Seward +Signed-off-by: Laura Abbott +--- + tools/power/cpupower/utils/cpufreq-set.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c +index b4bf769..8971d71 100644 +--- a/tools/power/cpupower/utils/cpufreq-set.c ++++ b/tools/power/cpupower/utils/cpufreq-set.c +@@ -296,7 +296,7 @@ int cmd_freq_set(int argc, char **argv) + struct cpufreq_affected_cpus *cpus; + + if (!bitmask_isbitset(cpus_chosen, cpu) || +- cpupower_is_cpu_online(cpu)) ++ cpupower_is_cpu_online(cpu) != 1) + continue; + + cpus = cpufreq_get_related_cpus(cpu); +@@ -316,7 +316,7 @@ int cmd_freq_set(int argc, char **argv) + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu) || +- cpupower_is_cpu_online(cpu)) ++ cpupower_is_cpu_online(cpu) != 1) + continue; + + if (cpupower_is_cpu_online(cpu) != 1) +-- +2.10.0 + diff --git a/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch b/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch deleted file mode 100644 index 3c7c7279..00000000 --- a/kernel/kernel/files/patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b5a9b340789b2b24c6896bcf7a065c31a4db671c Mon Sep 17 00:00:00 2001 -From: Vincent Guittot -Date: Wed, 19 Oct 2016 14:45:23 +0200 -Subject: [PATCH] sched/fair: Fix incorrect task group ->load_avg - -A scheduler performance regression has been reported by Joseph Salisbury, -which he bisected back to: - - 3d30544f0212 ("sched/fair: Apply more PELT fixes) - -The regression triggers when several levels of task groups are involved -(read: SystemD) and cpu_possible_mask != cpu_present_mask. - -The root cause is that group entity's load (tg_child->se[i]->avg.load_avg) -is initialized to scale_load_down(se->load.weight). During the creation of -a child task group, its group entities on possible CPUs are attached to -parent's cfs_rq (tg_parent) and their loads are added to the parent's load -(tg_parent->load_avg) with update_tg_load_avg(). - -But only the load on online CPUs will then be updated to reflect real load, -whereas load on other CPUs will stay at the initial value. - -The result is a tg_parent->load_avg that is higher than the real load, the -weight of group entities (tg_parent->se[i]->load.weight) on online CPUs is -smaller than it should be, and the task group gets a less running time than -what it could expect. - -( This situation can be detected with /proc/sched_debug. The ".tg_load_avg" - of the task group will be much higher than sum of ".tg_load_avg_contrib" - of online cfs_rqs of the task group. ) - -The load of group entities don't have to be intialized to something else -than 0 because their load will increase when an entity is attached. - -Reported-by: Joseph Salisbury -Tested-by: Dietmar Eggemann -Signed-off-by: Vincent Guittot -Acked-by: Peter Zijlstra -Cc: # 4.8.x -Cc: Linus Torvalds -Cc: Peter Zijlstra -Cc: Thomas Gleixner -Cc: joonwoop@codeaurora.org -Fixes: 3d30544f0212 ("sched/fair: Apply more PELT fixes) -Link: http://lkml.kernel.org/r/1476881123-10159-1-git-send-email-vincent.guittot@linaro.org -Signed-off-by: Ingo Molnar ---- - kernel/sched/fair.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 76ee7de..d941c97 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -690,7 +690,14 @@ void init_entity_runnable_average(struct sched_entity *se) - * will definitely be update (after enqueue). - */ - sa->period_contrib = 1023; -- sa->load_avg = scale_load_down(se->load.weight); -+ /* -+ * Tasks are intialized with full load to be seen as heavy tasks until -+ * they get a chance to stabilize to their real load level. -+ * Group entities are intialized with zero load to reflect the fact that -+ * nothing has been attached to the task group yet. -+ */ -+ if (entity_is_task(se)) -+ sa->load_avg = scale_load_down(se->load.weight); - sa->load_sum = sa->load_avg * LOAD_AVG_MAX; - /* - * At this point, util_avg won't be used in select_task_rq_fair anyway --- -2.10.1 - diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 8906ee33..5f3d0487 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -14,6 +14,86 @@ ### ### Stable Queue ### +stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch +stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch +stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch +stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch +stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch +stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch +stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch +stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch +stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch +stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch +stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch +stable-drm-radeon-narrow-asic_init-for-virtualization.patch +stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch +stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch +stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch +stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch +stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch +stable-hid-add-quirk-for-akai-midimix.patch +stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch +stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch +stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch +stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch +stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch +stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch +stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch +stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch +stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch +stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch +stable-drm-i915-introduce-intel_has_sagv.patch +stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch +stable-revert-drm-i915-check-live-status-before-reading-edid.patch +stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch +stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch +stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch +stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch +stable-drm-i915-allow-dp-to-work-w-o-edid.patch +stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch +stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch +stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch +stable-rt2x00usb-fix-error-return-code.patch +stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch +stable-genirq-generic_chip-add-irq_unmap-callback.patch +stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch +stable-uio-fix-dmem_region_start-computation.patch +stable-arm-clk-imx35-fix-name-for-ckil-clk.patch +stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch +stable-i40e-remove-a-stray-unlock.patch +stable-i40e-fix-broken-i40e_config_rss_aq-function.patch +stable-mwifiex-correct-aid-value-during-tdls-setup.patch +stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch +stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch +stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch +stable-ath10k-fix-reporting-channel-survey-data.patch +stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch +stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch +stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch +stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch +stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch +stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch +stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch +stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch +stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch +stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch +stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch +stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch +stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch +stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch +stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch +stable-staging-android-ion-hisi-fix-dependencies.patch +stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch +stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch +stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch +stable-staging-ks7010-declare-private-functions-static.patch +stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch +stable-ib-rdmavt-correct-sparse-annotation.patch +stable-ib-qib-remove-qpt_mask-global.patch +stable-ib-mlx5-fix-steering-resource-leak.patch +stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch +stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch +stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch ### ### Arch x86 @@ -46,7 +126,10 @@ Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch ### base-cacheinfo-silence-DT-warnings.patch -kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch +# Patch for having the cpupower setting the governor +# (from https://bugzilla.kernel.org/show_bug.cgi?id=135391, same as +# https://bugzilla.redhat.com/show_bug.cgi?id=1374212) +kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch ### ### i2c @@ -184,11 +267,10 @@ gpu-drm-mach64-3.18-buildfix.patch # Attempt to fix FIFO underrun problems: # (from https://patchwork.freedesktop.org/patch/113642/ and -# from https://bugs.freedesktop.org/attachment.cgi?id=127264, reference from +# also from https://bugs.freedesktop.org/attachment.cgi?id=127264, first reference from # https://bugs.freedesktop.org/show_bug.cgi?id=97450). Does not completely resolve the # issues but reduce. drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch -skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch ### ### Hardware Monitoring diff --git a/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch b/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch deleted file mode 100644 index 1b819dea..00000000 --- a/kernel/kernel/files/patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch +++ /dev/null @@ -1,110 +0,0 @@ -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index 2d24813..498ded6 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -2877,6 +2877,21 @@ skl_wm_plane_id(const struct intel_plane *plane) - } - - /* -+ * FIXME: We still don't have the proper code detect if we need to apply the WA, -+ * so assume we'll always need it in order to avoid underruns. -+ */ -+static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state) -+{ -+ struct drm_i915_private *dev_priv = to_i915(state->base.dev); -+ -+ if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) || -+ IS_KABYLAKE(dev_priv)) -+ return true; -+ -+ return false; -+} -+ -+/* - * SAGV dynamically adjusts the system agent voltage and clock frequencies - * depending on power and performance requirements. The display engine access - * to system memory is blocked during the adjustment time. Because of the -@@ -2979,9 +2994,10 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state) - struct drm_device *dev = state->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); -- struct drm_crtc *crtc; -+ struct intel_crtc *crtc; -+ struct intel_plane *plane; - enum pipe pipe; -- int level, plane; -+ int level, id, latency; - - /* - * SKL workaround: bspec recommends we disable the SAGV when we have -@@ -2996,27 +3012,35 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state) - - /* Since we're now guaranteed to only have one active CRTC... */ - pipe = ffs(intel_state->active_crtcs) - 1; -- crtc = dev_priv->pipe_to_crtc_mapping[pipe]; -+ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); - -- if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE) -+ if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - return false; -+ for_each_intel_plane_on_crtc(dev, crtc, plane) { -+ id = skl_wm_plane_id(plane); - -- for_each_plane(dev_priv, pipe, plane) { - /* Skip this plane if it's not enabled */ -- if (intel_state->wm_results.plane[pipe][plane][0] == 0) -+ if (intel_state->wm_results.plane[pipe][id][0] == 0) - continue; - - /* Find the highest enabled wm level for this plane */ - for (level = ilk_wm_max_level(dev); -- intel_state->wm_results.plane[pipe][plane][level] == 0; --level) -+ intel_state->wm_results.plane[pipe][id][level] == 0; --level) - { } - -+ latency = dev_priv->wm.skl_latency[level]; -+ -+ if (skl_needs_memory_bw_wa(intel_state) && -+ plane->base.state->fb->modifier[0] == -+ I915_FORMAT_MOD_X_TILED) -+ latency += 15; -+ - /* - * If any of the planes on this pipe don't enable wm levels - * that incur memory latencies higher then 30µs we can't enable - * the SAGV - */ -- if (dev_priv->wm.skl_latency[level] < SKL_SAGV_BLOCK_TIME) -+ if (latency < SKL_SAGV_BLOCK_TIME) - return false; - } - -@@ -3546,12 +3570,18 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, - uint8_t cpp; - uint32_t width = 0, height = 0; - uint32_t plane_pixel_rate; -+ struct intel_atomic_state *state = -+ to_intel_atomic_state(cstate->base.state); -+ bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); - - if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { - *enabled = false; - return 0; - } - -+ if (apply_memory_bw_wa && fb->modifier[0] == I915_FORMAT_MOD_X_TILED) -+ latency += 15; -+ - width = drm_rect_width(&intel_pstate->src) >> 16; - height = drm_rect_height(&intel_pstate->src) >> 16; - -@@ -3593,6 +3623,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, - } - } - y_tile_minimum = plane_blocks_per_line * min_scanlines; -+ if (apply_memory_bw_wa) -+ y_tile_minimum *= 2; -+ - selected_result = max(method2, y_tile_minimum); - } else { - if ((ddb_allocation / plane_blocks_per_line) >= 1) diff --git a/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch b/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch new file mode 100644 index 00000000..04c91a98 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch @@ -0,0 +1,37 @@ +From fcff03813a7c612873303037cef5ba0329850c35 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Thu, 8 Sep 2016 11:30:21 +0200 +Subject: ARM: clk-imx35: fix name for ckil clk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit fcff03813a7c612873303037cef5ba0329850c35 upstream. + +This fixes + [ 0.000000] i.MX clk 82: register failed with -17 +because the name is duplicated. + +Signed-off-by: Uwe Kleine-König +Fixes: 3713e3f5e927 ("clk: imx35: define two clocks for rtc") +Acked-by: Shawn Guo +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/imx/clk-imx35.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/imx/clk-imx35.c ++++ b/drivers/clk/imx/clk-imx35.c +@@ -115,7 +115,7 @@ static void __init _mx35_clocks_init(voi + } + + clk[ckih] = imx_clk_fixed("ckih", 24000000); +- clk[ckil] = imx_clk_fixed("ckih", 32768); ++ clk[ckil] = imx_clk_fixed("ckil", 32768); + clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); + clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); + diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch new file mode 100644 index 00000000..d7cd051d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch @@ -0,0 +1,41 @@ +From a3930ed060df4ccf2a06cf0b68738dec3e6ff89a Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 27 Aug 2016 19:28:00 +0800 +Subject: ASoC: dapm: Fix kcontrol creation for output driver widget + +From: Chen-Yu Tsai + +commit a3930ed060df4ccf2a06cf0b68738dec3e6ff89a upstream. + +Commit d88429a695a4 ("ASoC: dapm: Add output driver widget") added +the snd_soc_dapm_out_drv ID for the output driver widget, which is +the same as the PGA widget, with a later power sequence number. + +Commit 19a2557b76d6 ("ASoC: dapm: Add kcontrol support for PGAs") +then added kcontrol support for PGA widgets, but failed to account +for output driver widgets. Attempts to use kcontrols with output +driver widgets result in silent failures, with the developer having +little idea about what went on. + +Add snd_soc_dapm_out_drv to the switch/case block under snd_soc_dapm_pga +in dapm_create_or_share_kcontrol, since they are essentially the same. + +Fixes: 19a2557b76d6 (ASoC: dapm: Add kcontrol support for PGAs) +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-dapm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + case snd_soc_dapm_pga: ++ case snd_soc_dapm_out_drv: + wname_in_long_name = true; + kcname_in_long_name = true; + break; diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch new file mode 100644 index 00000000..014bcdc0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch @@ -0,0 +1,42 @@ +From 01ad5e7de67b408d9b48b437b06a9938ddf460b5 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 27 Aug 2016 19:27:58 +0800 +Subject: ASoC: dapm: Fix possible uninitialized variable in snd_soc_dapm_get_volsw() + +From: Chen-Yu Tsai + +commit 01ad5e7de67b408d9b48b437b06a9938ddf460b5 upstream. + +If soc_dapm_read() fails, val will be uninitialized, and bogus values +will be written later: + + ret = soc_dapm_read(dapm, reg, &val); + val = (val >> shift) & mask; + +However, the compiler does not give a warning. Return on error before +val is really used to avoid this. + +This is similar to the commit 6912831623c5 ("ASoC: dapm: Fix +uninitialized variable in snd_soc_dapm_get_enum_double()") + +Fixes: ce0fc93ae56e (ASoC: Add DAPM support at the component level) +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-dapm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kc + } + mutex_unlock(&card->dapm_mutex); + ++ if (ret) ++ return ret; ++ + if (invert) + ucontrol->value.integer.value[0] = max - val; + else diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch new file mode 100644 index 00000000..737cd33e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch @@ -0,0 +1,35 @@ +From 071133a209354f39d4e5785d5a6a390e03241841 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 27 Aug 2016 19:27:59 +0800 +Subject: ASoC: dapm: Fix value setting for _ENUM_DOUBLE MUX's second channel + +From: Chen-Yu Tsai + +commit 071133a209354f39d4e5785d5a6a390e03241841 upstream. + +The value for the second channel in _ENUM_DOUBLE (double channel) MUXs +is not correctly updated, due to using the wrong bit shift. + +Use the correct bit shift, so both channels toggle together. + +Fixes: 3727b4968453 (ASoC: dapm: Consolidate MUXs and value MUXs) +Signed-off-by: Chen-Yu Tsai +Reviewed-by: Charles Keepax +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-dapm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -3203,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct + if (e->shift_l != e->shift_r) { + if (item[1] > e->items) + return -EINVAL; +- val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; ++ val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; + mask |= e->mask << e->shift_r; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch new file mode 100644 index 00000000..610d3216 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch @@ -0,0 +1,85 @@ +From 43d443dc257c00ef3a3f940b6abfb7537c4fcbe8 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 27 Sep 2016 07:45:09 +0900 +Subject: ASoC: sst-bxt-da7219_max98357a: fix obsoleted initializers for array + +From: Takashi Sakamoto + +commit 43d443dc257c00ef3a3f940b6abfb7537c4fcbe8 upstream. + +Sparse reports below warnings. + +bxt_da7219_max98357a.c:250:9: warning: obsolete array initializer, use C99 syntax +bxt_da7219_max98357a.c:275:9: warning: obsolete array initializer, use C99 syntax +bxt_da7219_max98357a.c:290:9: warning: obsolete array initializer, use C99 syntax +bxt_da7219_max98357a.c:304:9: warning: obsolete array initializer, use C99 syntax +bxt_da7219_max98357a.c:317:9: warning: obsolete array initializer, use C99 syntax + +There's no need to use obsoleted way. This commit fixes it. + +Fixes: 723bad3fef8b (ASoC: Intel: Add Broxton-P Dialog Maxim machine driver) +Signed-off-by: Takashi Sakamoto +Acked-by: Vinod Koul +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/intel/boards/bxt_da7219_max98357a.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c ++++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c +@@ -255,7 +255,7 @@ static struct snd_soc_ops broxton_da7219 + /* broxton digital audio interface glue - connects codec <--> CPU */ + static struct snd_soc_dai_link broxton_dais[] = { + /* Front End DAI links */ +- [BXT_DPCM_AUDIO_PB] ++ [BXT_DPCM_AUDIO_PB] = + { + .name = "Bxt Audio Port", + .stream_name = "Audio", +@@ -271,7 +271,7 @@ static struct snd_soc_dai_link broxton_d + .dpcm_playback = 1, + .ops = &broxton_da7219_fe_ops, + }, +- [BXT_DPCM_AUDIO_CP] ++ [BXT_DPCM_AUDIO_CP] = + { + .name = "Bxt Audio Capture Port", + .stream_name = "Audio Record", +@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_d + .dpcm_capture = 1, + .ops = &broxton_da7219_fe_ops, + }, +- [BXT_DPCM_AUDIO_REF_CP] ++ [BXT_DPCM_AUDIO_REF_CP] = + { + .name = "Bxt Audio Reference cap", + .stream_name = "Refcap", +@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_d + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI1_PB] ++ [BXT_DPCM_AUDIO_HDMI1_PB] = + { + .name = "Bxt HDMI Port1", + .stream_name = "Hdmi1", +@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_d + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI2_PB] ++ [BXT_DPCM_AUDIO_HDMI2_PB] = + { + .name = "Bxt HDMI Port2", + .stream_name = "Hdmi2", +@@ -326,7 +326,7 @@ static struct snd_soc_dai_link broxton_d + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI3_PB] ++ [BXT_DPCM_AUDIO_HDMI3_PB] = + { + .name = "Bxt HDMI Port3", + .stream_name = "Hdmi3", diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch new file mode 100644 index 00000000..9d9c7243 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch @@ -0,0 +1,96 @@ +From 5919a3898136aae4d2cb4b18b44f70f7b185aa47 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 27 Sep 2016 07:45:08 +0900 +Subject: ASoC: sst-bxt-rt298: fix obsoleted initializers for array + +From: Takashi Sakamoto + +commit 5919a3898136aae4d2cb4b18b44f70f7b185aa47 upstream. + +Sparse reports below warnings. + +bxt_rt298.c:275:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:290:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:304:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:317:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:331:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:344:9: warning: obsolete array initializer, use C99 syntax +bxt_rt298.c:357:9: warning: obsolete array initializer, use C99 syntax + +There's no need to use obsoleted way. This commit fixes it. + +Fixes: 76016322ec56 (ASoC: Intel: Add Broxton-P machine driver) +Signed-off-by: Takashi Sakamoto +Acked-by: Vinod Koul +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/intel/boards/bxt_rt298.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/sound/soc/intel/boards/bxt_rt298.c ++++ b/sound/soc/intel/boards/bxt_rt298.c +@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_ + /* broxton digital audio interface glue - connects codec <--> CPU */ + static struct snd_soc_dai_link broxton_rt298_dais[] = { + /* Front End DAI links */ +- [BXT_DPCM_AUDIO_PB] ++ [BXT_DPCM_AUDIO_PB] = + { + .name = "Bxt Audio Port", + .stream_name = "Audio", +@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_r + .dpcm_playback = 1, + .ops = &broxton_rt286_fe_ops, + }, +- [BXT_DPCM_AUDIO_CP] ++ [BXT_DPCM_AUDIO_CP] = + { + .name = "Bxt Audio Capture Port", + .stream_name = "Audio Record", +@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_r + .dpcm_capture = 1, + .ops = &broxton_rt286_fe_ops, + }, +- [BXT_DPCM_AUDIO_REF_CP] ++ [BXT_DPCM_AUDIO_REF_CP] = + { + .name = "Bxt Audio Reference cap", + .stream_name = "refcap", +@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_r + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_DMIC_CP] ++ [BXT_DPCM_AUDIO_DMIC_CP] = + { + .name = "Bxt Audio DMIC cap", + .stream_name = "dmiccap", +@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_r + .dynamic = 1, + .ops = &broxton_dmic_ops, + }, +- [BXT_DPCM_AUDIO_HDMI1_PB] ++ [BXT_DPCM_AUDIO_HDMI1_PB] = + { + .name = "Bxt HDMI Port1", + .stream_name = "Hdmi1", +@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_r + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI2_PB] ++ [BXT_DPCM_AUDIO_HDMI2_PB] = + { + .name = "Bxt HDMI Port2", + .stream_name = "Hdmi2", +@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_r + .nonatomic = 1, + .dynamic = 1, + }, +- [BXT_DPCM_AUDIO_HDMI3_PB] ++ [BXT_DPCM_AUDIO_HDMI3_PB] = + { + .name = "Bxt HDMI Port3", + .stream_name = "Hdmi3", diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch b/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch new file mode 100644 index 00000000..f029224c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch @@ -0,0 +1,31 @@ +From 8ae3ea48df0d746b663057cf0b972a18d0777b7b Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Wed, 10 Aug 2016 13:43:12 +0000 +Subject: ASoC: topology: Fix error return code in soc_tplg_dapm_widget_create() + +From: Wei Yongjun + +commit 8ae3ea48df0d746b663057cf0b972a18d0777b7b upstream. + +Fix to return error code -ENOMEM instead of 0 when failed to create +widget, as done elsewhere in this function. + +Fixes: 8a9782346dcc ("ASoC: topology: Add topology core") +Signed-off-by: Wei Yongjun +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-topology.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/soc/soc-topology.c ++++ b/sound/soc/soc-topology.c +@@ -1475,6 +1475,7 @@ widget: + if (widget == NULL) { + dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", + w->name); ++ ret = -ENOMEM; + goto hdr_err; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch new file mode 100644 index 00000000..d29be132 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch @@ -0,0 +1,58 @@ +From 64ed5771aca2fcfb8ea440fc679741054011fd7e Mon Sep 17 00:00:00 2001 +From: Tamizh chelvam +Date: Tue, 2 Aug 2016 16:13:14 +0530 +Subject: ath10k: Add WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT wmi service + +From: Tamizh chelvam + +commit 64ed5771aca2fcfb8ea440fc679741054011fd7e upstream. + +WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT service has missed in +the commit 7e247a9e88dc ("ath10k: add dynamic tx mode switch +config support for qca4019"). This patch adds the service to +avoid mismatch between host and target. + +Fixes: 7e247a9e88dc ("ath10k: add dynamic tx mode switch config support for qca4019") +Signed-off-by: Tamizh chelvam +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath10k/wmi.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -180,6 +180,7 @@ enum wmi_service { + WMI_SERVICE_MESH_NON_11S, + WMI_SERVICE_PEER_STATS, + WMI_SERVICE_RESTRT_CHNL_SUPPORT, ++ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, + WMI_SERVICE_TX_MODE_PUSH_ONLY, + WMI_SERVICE_TX_MODE_PUSH_PULL, + WMI_SERVICE_TX_MODE_DYNAMIC, +@@ -305,6 +306,7 @@ enum wmi_10_4_service { + WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT, + WMI_10_4_SERVICE_PEER_STATS, + WMI_10_4_SERVICE_MESH_11S, ++ WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, + WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, + WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, + WMI_10_4_SERVICE_TX_MODE_DYNAMIC, +@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int + SVCSTR(WMI_SERVICE_MESH_NON_11S); + SVCSTR(WMI_SERVICE_PEER_STATS); + SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT); ++ SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT); + SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY); + SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL); + SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC); +@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(cons + WMI_SERVICE_PEER_STATS, len); + SVCMAP(WMI_10_4_SERVICE_MESH_11S, + WMI_SERVICE_MESH_11S, len); ++ SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, ++ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len); + SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, + WMI_SERVICE_TX_MODE_PUSH_ONLY, len); + SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch new file mode 100644 index 00000000..463c00aa --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch @@ -0,0 +1,37 @@ +From 77eb3d693182b4eaa88c6ba406fbb92b1f1bd636 Mon Sep 17 00:00:00 2001 +From: Ashok Raj Nagarajan +Date: Fri, 2 Sep 2016 10:59:53 +0530 +Subject: ath10k: fix reporting channel survey data + +From: Ashok Raj Nagarajan + +commit 77eb3d693182b4eaa88c6ba406fbb92b1f1bd636 upstream. + +When user requests for survey dump data, driver is providing wrong survey +information. This information we sent is the survey data that we have +collected during previous user request. + +This issue occurs because we request survey dump for wrong channel. With +this change, we correctly display the correct and current survey +information to userspace. + +Fixes: fa7937e3d5c2 ("ath10k: update bss channel survey information") +Signed-off-by: Ashok Raj Nagarajan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -6558,7 +6558,7 @@ static int ath10k_get_survey(struct ieee + goto exit; + } + +- ath10k_mac_update_bss_chan_survey(ar, survey->channel); ++ ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]); + + spin_lock_bh(&ar->data_lock); + memcpy(survey, ar_survey, sizeof(*survey)); diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch new file mode 100644 index 00000000..4e94923d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch @@ -0,0 +1,81 @@ +From e4fd726f21cdae0dc9cea6cbfcb7e27f21393f88 Mon Sep 17 00:00:00 2001 +From: Ashok Raj Nagarajan +Date: Thu, 18 Aug 2016 15:30:04 +0530 +Subject: ath10k: fix sending frame in management path in push txq logic + +From: Ashok Raj Nagarajan + +commit e4fd726f21cdae0dc9cea6cbfcb7e27f21393f88 upstream. + +In the wake tx queue path, we are not checking if the frame to be sent +takes management path or not. For eg. QOS null func frame coming here will +take the management path. Since we are not incrementing the descriptor +counter (num_pending_mgmt_tx) w.r.t tx management, on tx completion it is +possible to see negative values. + +When the above counter reaches a negative value, we will not be sending a +probe response out. + + if (is_presp && + ar->hw_params.max_probe_resp_desc_thres < htt->num_pending_mgmt_tx) + +For IPQ4019, max_probe_resp_desc_thres (u32) is 24 is compared against +num_pending_mgmt_tx (int) and the above condtions comes true if the counter +is negative and we drop the probe response. + +To avoid this, check on the wake tx queue path as well for the tx path of +the frame and increment the appropriate counters + +Fixes: cac085524cf1 "ath10k: move mgmt descriptor limit handle under mgmt_tx" +Signed-off-by: Ashok Raj Nagarajan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3777,7 +3777,9 @@ int ath10k_mac_tx_push_txq(struct ieee80 + enum ath10k_hw_txrx_mode txmode; + enum ath10k_mac_tx_path txpath; + struct sk_buff *skb; ++ struct ieee80211_hdr *hdr; + size_t skb_len; ++ bool is_mgmt, is_presp; + int ret; + + spin_lock_bh(&ar->htt.tx_lock); +@@ -3801,6 +3803,22 @@ int ath10k_mac_tx_push_txq(struct ieee80 + skb_len = skb->len; + txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); + txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); ++ is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT); ++ ++ if (is_mgmt) { ++ hdr = (struct ieee80211_hdr *)skb->data; ++ is_presp = ieee80211_is_probe_resp(hdr->frame_control); ++ ++ spin_lock_bh(&ar->htt.tx_lock); ++ ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp); ++ ++ if (ret) { ++ ath10k_htt_tx_dec_pending(htt); ++ spin_unlock_bh(&ar->htt.tx_lock); ++ return ret; ++ } ++ spin_unlock_bh(&ar->htt.tx_lock); ++ } + + ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb); + if (unlikely(ret)) { +@@ -3808,6 +3826,8 @@ int ath10k_mac_tx_push_txq(struct ieee80 + + spin_lock_bh(&ar->htt.tx_lock); + ath10k_htt_tx_dec_pending(htt); ++ if (is_mgmt) ++ ath10k_htt_tx_mgmt_dec_pending(htt); + spin_unlock_bh(&ar->htt.tx_lock); + + return ret; diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch new file mode 100644 index 00000000..965cd1a1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch @@ -0,0 +1,54 @@ +From 18f53fe0f30331e826b075709ed7b26b9283235e Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Fri, 2 Sep 2016 19:46:10 +0300 +Subject: ath10k: fix throughput regression in multi client mode + +From: Rajkumar Manoharan + +commit 18f53fe0f30331e826b075709ed7b26b9283235e upstream. + +commit 7a0adc83f34d ("ath10k: improve tx scheduling") is causing +severe throughput drop in multi client mode. This issue is originally +reported in veriwave setup with 50 clients with TCP downlink traffic. +While increasing number of clients, the average throughput drops +gradually. With 50 clients, the combined peak throughput is decreased +to 98 Mbps whereas reverting given commit restored it to 550 Mbps. + +Processing txqs for every tx completion is causing overhead. Ideally for +management frame tx completion, pending txqs processing can be avoided. +The change partly reverts the commit "ath10k: improve tx scheduling". +Processing pending txqs after all skbs tx completion will yeild enough +room to burst tx frames. + +Fixes: 7a0adc83f34d ("ath10k: improve tx scheduling") +Signed-off-by: Rajkumar Manoharan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 2 ++ + drivers/net/wireless/ath/ath10k/txrx.c | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -2394,6 +2394,8 @@ static void ath10k_htt_txrx_compl_task(u + skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q); + spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags); + ++ ath10k_mac_tx_push_pending(ar); ++ + spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); + skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); + spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); +--- a/drivers/net/wireless/ath/ath10k/txrx.c ++++ b/drivers/net/wireless/ath/ath10k/txrx.c +@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_h + ieee80211_tx_status(htt->ar->hw, msdu); + /* we do not own the msdu anymore */ + +- ath10k_mac_tx_push_pending(ar); +- + return 0; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch b/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch new file mode 100644 index 00000000..b3e6eb41 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch @@ -0,0 +1,37 @@ +From 481e46fe7a88557b66330cbb047b25cc13eff4b9 Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Thu, 25 Aug 2016 15:18:54 -0600 +Subject: coresight: Remove erroneous dma_free_coherent in tmc_probe + +From: Suzuki K Poulose + +commit 481e46fe7a88557b66330cbb047b25cc13eff4b9 upstream. + +commit de5461970b3e9e194 ("coresight: tmc: allocating memory when needed") +removed the static allocation of buffer for the trace data in ETR mode in +tmc_probe. However it failed to remove the "devm_free_coherent" in +tmc_probe when the probe fails due to other reasons. This patch gets +rid of the incorrect dma_free_coherent() call. + +Fixes: commit de5461970b3e9e194 ("coresight: tmc: allocating memory when needed") +Cc: Mathieu Poirier +Signed-off-by: Suzuki K Poulose +Signed-off-by: Mathieu Poirier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/coresight/coresight-tmc.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/hwtracing/coresight/coresight-tmc.c ++++ b/drivers/hwtracing/coresight/coresight-tmc.c +@@ -388,9 +388,6 @@ static int tmc_probe(struct amba_device + err_misc_register: + coresight_unregister(drvdata->csdev); + err_devm_kzalloc: +- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) +- dma_free_coherent(dev, drvdata->size, +- drvdata->vaddr, drvdata->paddr); + return ret; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch b/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch new file mode 100644 index 00000000..5253ef79 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch @@ -0,0 +1,64 @@ +From ed4767d612fd2c39e2c4c69eba484c1219dcddb6 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 1 Sep 2016 14:25:42 +0100 +Subject: crypto: arm/ghash-ce - add missing async import/export + +From: Ard Biesheuvel + +commit ed4767d612fd2c39e2c4c69eba484c1219dcddb6 upstream. + +Since commit 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero"), +all ahash drivers are required to implement import()/export(), and must have +a non-zero statesize. Fix this for the ARM Crypto Extensions GHASH +implementation. + +Fixes: 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero") +Signed-off-by: Ard Biesheuvel +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/crypto/ghash-ce-glue.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/arch/arm/crypto/ghash-ce-glue.c ++++ b/arch/arm/crypto/ghash-ce-glue.c +@@ -220,6 +220,27 @@ static int ghash_async_digest(struct aha + } + } + ++static int ghash_async_import(struct ahash_request *req, const void *in) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ ++ desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm); ++ desc->flags = req->base.flags; ++ ++ return crypto_shash_import(desc, in); ++} ++ ++static int ghash_async_export(struct ahash_request *req, void *out) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ ++ return crypto_shash_export(desc, out); ++} ++ + static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) + { +@@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg + .final = ghash_async_final, + .setkey = ghash_async_setkey, + .digest = ghash_async_digest, ++ .import = ghash_async_import, ++ .export = ghash_async_export, + .halg.digestsize = GHASH_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct ghash_desc_ctx), + .halg.base = { + .cra_name = "ghash", + .cra_driver_name = "ghash-ce", diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch b/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch new file mode 100644 index 00000000..2685ecb5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch @@ -0,0 +1,33 @@ +From 7514e3688811e610640ec2201ca14dfebfe13442 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 17 Sep 2016 16:01:22 +0000 +Subject: crypto: ccp - Fix return value check in ccp_dmaengine_register() + +From: Wei Yongjun + +commit 7514e3688811e610640ec2201ca14dfebfe13442 upstream. + +Fix the retrn value check which testing the wrong variable +in ccp_dmaengine_register(). + +Fixes: 58ea8abf4904 ("crypto: ccp - Register the CCP as a DMA resource") +Signed-off-by: Wei Yongjun +Acked-by: Gary R Hook +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/ccp/ccp-dmaengine.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/ccp/ccp-dmaengine.c ++++ b/drivers/crypto/ccp/ccp-dmaengine.c +@@ -650,7 +650,7 @@ int ccp_dmaengine_register(struct ccp_de + dma_desc_cache_name = devm_kasprintf(ccp->dev, GFP_KERNEL, + "%s-dmaengine-desc-cache", + ccp->name); +- if (!dma_cmd_cache_name) ++ if (!dma_desc_cache_name) + return -ENOMEM; + ccp->dma_desc_cache = kmem_cache_create(dma_desc_cache_name, + sizeof(struct ccp_dma_desc), diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch b/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch new file mode 100644 index 00000000..7a66373f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch @@ -0,0 +1,35 @@ +From 50d2e6dc1f83db0563c7d6603967bf9585ce934b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ondrej=20Mosn=C3=A1=C4=8Dek?= +Date: Fri, 23 Sep 2016 10:47:32 +0200 +Subject: crypto: gcm - Fix IV buffer size in crypto_gcm_setkey + +From: Ondrej Mosnáček + +commit 50d2e6dc1f83db0563c7d6603967bf9585ce934b upstream. + +The cipher block size for GCM is 16 bytes, and thus the CTR transform +used in crypto_gcm_setkey() will also expect a 16-byte IV. However, +the code currently reserves only 8 bytes for the IV, causing +an out-of-bounds access in the CTR transform. This patch fixes +the issue by setting the size of the IV buffer to 16 bytes. + +Fixes: 84c911523020 ("[CRYPTO] gcm: Add support for async ciphers") +Signed-off-by: Ondrej Mosnacek +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/gcm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/gcm.c ++++ b/crypto/gcm.c +@@ -117,7 +117,7 @@ static int crypto_gcm_setkey(struct cryp + struct crypto_skcipher *ctr = ctx->ctr; + struct { + be128 hash; +- u8 iv[8]; ++ u8 iv[16]; + + struct crypto_gcm_setkey_result result; + diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch new file mode 100644 index 00000000..6d98c6f5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch @@ -0,0 +1,80 @@ +From 57cfda1ac74e58767f6305bd1ea3449177425460 Mon Sep 17 00:00:00 2001 +From: Romain Perier +Date: Tue, 9 Aug 2016 11:03:19 +0200 +Subject: crypto: marvell - Don't overwrite default creq->state during initialization + +From: Romain Perier + +commit 57cfda1ac74e58767f6305bd1ea3449177425460 upstream. + +Currently, in mv_cesa_{md5,sha1,sha256}_init creq->state is initialized +before the call to mv_cesa_ahash_init. This is wrong because this +function fills creq with zero by using memset, so its 'state' that +contains the default DIGEST is overwritten. This commit fixes the issue +by initializing creq->state just after the call to mv_cesa_ahash_init. + +Fixes: commit b0ef51067cb4 ("crypto: marvell/cesa - initialize hash...") +Signed-off-by: Romain Perier +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/marvell/hash.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/crypto/marvell/hash.c ++++ b/drivers/crypto/marvell/hash.c +@@ -805,13 +805,14 @@ static int mv_cesa_md5_init(struct ahash + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5); ++ ++ mv_cesa_ahash_init(req, &tmpl, true); ++ + creq->state[0] = MD5_H0; + creq->state[1] = MD5_H1; + creq->state[2] = MD5_H2; + creq->state[3] = MD5_H3; + +- mv_cesa_ahash_init(req, &tmpl, true); +- + return 0; + } + +@@ -873,14 +874,15 @@ static int mv_cesa_sha1_init(struct ahas + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1); ++ ++ mv_cesa_ahash_init(req, &tmpl, false); ++ + creq->state[0] = SHA1_H0; + creq->state[1] = SHA1_H1; + creq->state[2] = SHA1_H2; + creq->state[3] = SHA1_H3; + creq->state[4] = SHA1_H4; + +- mv_cesa_ahash_init(req, &tmpl, false); +- + return 0; + } + +@@ -942,6 +944,9 @@ static int mv_cesa_sha256_init(struct ah + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256); ++ ++ mv_cesa_ahash_init(req, &tmpl, false); ++ + creq->state[0] = SHA256_H0; + creq->state[1] = SHA256_H1; + creq->state[2] = SHA256_H2; +@@ -951,8 +956,6 @@ static int mv_cesa_sha256_init(struct ah + creq->state[6] = SHA256_H6; + creq->state[7] = SHA256_H7; + +- mv_cesa_ahash_init(req, &tmpl, false); +- + return 0; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch new file mode 100644 index 00000000..18fb155e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch @@ -0,0 +1,40 @@ +From 09951d83fc58a6f772de09c08e370f6d9970dbb6 Mon Sep 17 00:00:00 2001 +From: Romain Perier +Date: Tue, 9 Aug 2016 11:03:18 +0200 +Subject: crypto: marvell - Update transformation context for each dequeued req + +From: Romain Perier + +commit 09951d83fc58a6f772de09c08e370f6d9970dbb6 upstream. + +So far, sub part of mv_cesa_int was responsible of dequeuing complete +requests, then call the 'cleanup' operation on these reqs and call the +crypto api callback 'complete'. The problem is that the transformation +context 'ctx' is retrieved only once before the while loop. Which means +that the wrong 'cleanup' operation might be called on the wrong type of +cesa requests, it can lead to memory corruptions with this message: + +marvell-cesa f1090000.crypto: dma_pool_free cesa_padding, 5a5a5a5a/5a5a5a5a (bad dma) + +This commit fixes the issue, by updating the transformation context for +each dequeued cesa request. + +Fixes: commit 85030c5168f1 ("crypto: marvell - Add support for chai...") +Signed-off-by: Romain Perier +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/marvell/cesa.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/crypto/marvell/cesa.c ++++ b/drivers/crypto/marvell/cesa.c +@@ -166,6 +166,7 @@ static irqreturn_t mv_cesa_int(int irq, + if (!req) + break; + ++ ctx = crypto_tfm_ctx(req->tfm); + mv_cesa_complete_req(ctx, req, 0); + } + } diff --git a/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch b/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch new file mode 100644 index 00000000..dda0b6d5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch @@ -0,0 +1,56 @@ +From 86c7e6836479c4045a9a81ed5ea76c51d719f9c1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Sat, 3 Sep 2016 01:22:02 +0200 +Subject: dmaengine: ipu: remove bogus NO_IRQ reference + +From: Arnd Bergmann + +commit 86c7e6836479c4045a9a81ed5ea76c51d719f9c1 upstream. + +A workaround for a warning introduced a use of the NO_IRQ +macro that should have been gone for a long time. + +It is clear from the code that the value cannot actually +be used, but apparently there was a configuration at +some point that caused a warning, so instead of just +reverting that patch, this rearranges the code in a way that +the warning cannot reappear. + +Signed-off-by: Arnd Bergmann +Fixes: 6ef41cf6f721 ("dmaengine :ipu: change ipu_irq_handler() to remove compile warning") +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/ipu/ipu_irq.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/dma/ipu/ipu_irq.c ++++ b/drivers/dma/ipu/ipu_irq.c +@@ -286,22 +286,21 @@ static void ipu_irq_handler(struct irq_d + raw_spin_unlock(&bank_lock); + while ((line = ffs(status))) { + struct ipu_irq_map *map; +- unsigned int irq = NO_IRQ; ++ unsigned int irq; + + line--; + status &= ~(1UL << line); + + raw_spin_lock(&bank_lock); + map = src2map(32 * i + line); +- if (map) +- irq = map->irq; +- raw_spin_unlock(&bank_lock); +- + if (!map) { ++ raw_spin_unlock(&bank_lock); + pr_err("IPU: Interrupt on unmapped source %u bank %d\n", + line, i); + continue; + } ++ irq = map->irq; ++ raw_spin_unlock(&bank_lock); + generic_handle_irq(irq); + } + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch b/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch new file mode 100644 index 00000000..849b1ee5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch @@ -0,0 +1,46 @@ +From 9716ebc38dfabe6c8e5e3c809e9f3c61dd3740f9 Mon Sep 17 00:00:00 2001 +From: Rex Zhu +Date: Wed, 14 Sep 2016 13:20:34 +0800 +Subject: drm/amd/powerplay: fix mclk not switching back after multi-head was disabled + +From: Rex Zhu + +commit 9716ebc38dfabe6c8e5e3c809e9f3c61dd3740f9 upstream. + +Signed-off-by: Rex Zhu +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c | 2 ++ + drivers/gpu/drm/amd/powerplay/eventmgr/psm.c | 3 ++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c ++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c +@@ -262,6 +262,8 @@ static const pem_event_action * const di + unblock_adjust_power_state_tasks, + set_cpu_power_state, + notify_hw_power_source_tasks, ++ get_2d_performance_state_tasks, ++ set_performance_state_tasks, + /* updateDALConfigurationTasks, + variBrightDisplayConfigurationChangeTasks, */ + adjust_power_state_tasks, +--- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c ++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c +@@ -100,11 +100,12 @@ int psm_adjust_power_state_dynamic(struc + if (requested == NULL) + return 0; + ++ phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); ++ + if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal))) + equal = false; + + if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { +- phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); + phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); + hwmgr->current_ps = requested; + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch new file mode 100644 index 00000000..a99ae3e7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch @@ -0,0 +1,53 @@ +From dc8184aa8621ee8048652496884d9f40d4bb407f Mon Sep 17 00:00:00 2001 +From: Rex Zhu +Date: Mon, 10 Oct 2016 15:57:21 +0800 +Subject: drm/amdgpu: change vblank_time's calculation method to reduce computational error. + +From: Rex Zhu + +commit dc8184aa8621ee8048652496884d9f40d4bb407f upstream. + +Signed-off-by: Rex Zhu +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct a + printk("\n"); + } + ++ + u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) + { + struct drm_device *dev = adev->ddev; + struct drm_crtc *crtc; + struct amdgpu_crtc *amdgpu_crtc; +- u32 line_time_us, vblank_lines; ++ u32 vblank_in_pixels; + u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ + + if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + amdgpu_crtc = to_amdgpu_crtc(crtc); + if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { +- line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / +- amdgpu_crtc->hw_mode.clock; +- vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - ++ vblank_in_pixels = ++ amdgpu_crtc->hw_mode.crtc_htotal * ++ (amdgpu_crtc->hw_mode.crtc_vblank_end - + amdgpu_crtc->hw_mode.crtc_vdisplay + +- (amdgpu_crtc->v_border * 2); +- vblank_time_us = vblank_lines * line_time_us; ++ (amdgpu_crtc->v_border * 2)); ++ ++ vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock; + break; + } + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch new file mode 100644 index 00000000..7a7aa723 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch @@ -0,0 +1,62 @@ +From e96ec90f496603c48e0945f8bdeb4cdf3088cbba Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 28 Sep 2016 12:41:50 -0400 +Subject: drm/amdgpu/dce10: disable hpd on local panels + +From: Alex Deucher + +commit e96ec90f496603c48e0945f8bdeb4cdf3088cbba upstream. + +Otherwise we can get a hotplug interrupt storm when +we turn the panel off if hpd interrupts were enabled +by the bios. + +bug: +https://bugs.freedesktop.org/show_bug.cgi?id=97471 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +@@ -425,16 +425,6 @@ static void dce_v10_0_hpd_init(struct am + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } +- + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + idx = 0; +@@ -458,6 +448,19 @@ static void dce_v10_0_hpd_init(struct am + continue; + } + ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); ++ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); ++ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); ++ continue; ++ } ++ + tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); + tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); + WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch new file mode 100644 index 00000000..de149bf4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch @@ -0,0 +1,31 @@ +From 140c94da3c3338c0ff4cc127cf9bec87905ca83c Mon Sep 17 00:00:00 2001 +From: Grazvydas Ignotas +Date: Mon, 3 Oct 2016 00:06:45 +0300 +Subject: drm/amdgpu/dce11: add missing drm_mode_config_cleanup call + +From: Grazvydas Ignotas + +commit 140c94da3c3338c0ff4cc127cf9bec87905ca83c upstream. + +All other amdgpu/dce_v* files have this call, it's only mysteriously +missing from dce_v11_0.c since the file was added and causes leaks. + +Fixes: aaa36a976bbb ("drm/amdgpu: Add initial VI support") +Signed-off-by: Grazvydas Ignotas +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -3112,6 +3112,7 @@ static int dce_v11_0_sw_fini(void *handl + + dce_v11_0_afmt_fini(adev); + ++ drm_mode_config_cleanup(adev->ddev); + adev->mode_info.mode_config_initialized = false; + + return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch new file mode 100644 index 00000000..a6a83cd3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch @@ -0,0 +1,62 @@ +From 3a9d993ee9809c217f4322623a9b78c8d17fdd1f Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 28 Sep 2016 12:43:33 -0400 +Subject: drm/amdgpu/dce11: disable hpd on local panels + +From: Alex Deucher + +commit 3a9d993ee9809c217f4322623a9b78c8d17fdd1f upstream. + +Otherwise we can get a hotplug interrupt storm when +we turn the panel off if hpd interrupts were enabled +by the bios. + +bug: +https://bugs.freedesktop.org/show_bug.cgi?id=97471 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -443,16 +443,6 @@ static void dce_v11_0_hpd_init(struct am + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } +- + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + idx = 0; +@@ -476,6 +466,19 @@ static void dce_v11_0_hpd_init(struct am + continue; + } + ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); ++ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); ++ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); ++ continue; ++ } ++ + tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); + tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); + WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch new file mode 100644 index 00000000..63cda139 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch @@ -0,0 +1,87 @@ +From 324082586cc5918e3230f0b2f326656c653201eb Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 28 Sep 2016 12:44:20 -0400 +Subject: drm/amdgpu/dce8: disable hpd on local panels + +From: Alex Deucher + +commit 324082586cc5918e3230f0b2f326656c653201eb upstream. + +Otherwise we can get a hotplug interrupt storm when +we turn the panel off if hpd interrupts were enabled +by the bios. + +bug: +https://bugs.freedesktop.org/show_bug.cgi?id=97471 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 48 +++++++++++++++++++++++++++------- + 1 file changed, 39 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +@@ -395,15 +395,6 @@ static void dce_v8_0_hpd_init(struct amd + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); + +- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || +- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { +- /* don't try to enable hpd on eDP or LVDS avoid breaking the +- * aux dp channel on imac and help (but not completely fix) +- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 +- * also avoid interrupt storms during dpms. +- */ +- continue; +- } + switch (amdgpu_connector->hpd.hpd) { + case AMDGPU_HPD_1: + WREG32(mmDC_HPD1_CONTROL, tmp); +@@ -426,6 +417,45 @@ static void dce_v8_0_hpd_init(struct amd + default: + break; + } ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || ++ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ /* don't try to enable hpd on eDP or LVDS avoid breaking the ++ * aux dp channel on imac and help (but not completely fix) ++ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 ++ * also avoid interrupt storms during dpms. ++ */ ++ u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl; ++ ++ switch (amdgpu_connector->hpd.hpd) { ++ case AMDGPU_HPD_1: ++ dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_2: ++ dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_3: ++ dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_4: ++ dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_5: ++ dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL; ++ break; ++ case AMDGPU_HPD_6: ++ dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL; ++ break; ++ default: ++ continue; ++ } ++ ++ dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg); ++ dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; ++ WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl); ++ continue; ++ } ++ + dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd); + amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd); + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch new file mode 100644 index 00000000..6e9010ec --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch @@ -0,0 +1,30 @@ +From c4795ca642b8bd76b5b6ffba41ba909543273d43 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 22 Aug 2016 16:31:36 -0400 +Subject: drm/amdgpu: fix IB alignment for UVD + +From: Alex Deucher + +commit c4795ca642b8bd76b5b6ffba41ba909543273d43 upstream. + +According to the hw team, it should be 16, not 8. + +Cc: Peter Fang +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -292,7 +292,7 @@ static int amdgpu_info_ioctl(struct drm_ + type = AMD_IP_BLOCK_TYPE_UVD; + ring_mask = adev->uvd.ring.ready ? 1 : 0; + ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; +- ib_size_alignment = 8; ++ ib_size_alignment = 16; + break; + case AMDGPU_HW_IP_VCE: + type = AMD_IP_BLOCK_TYPE_VCE; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch new file mode 100644 index 00000000..4343c2f3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch @@ -0,0 +1,37 @@ +From ce199ad690bd0a6ac6bf9e4df2c87b59d76f84da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= +Date: Tue, 4 Oct 2016 09:43:30 +0200 +Subject: drm/amdgpu: initialize the context reset_counter in amdgpu_ctx_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nicolai Hähnle + +commit ce199ad690bd0a6ac6bf9e4df2c87b59d76f84da upstream. + +Ensure that we really only report a GPU reset if one has happened since the +creation of the context. + +Signed-off-by: Nicolai Hähnle +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu + ctx->rings[i].sequence = 1; + ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; + } ++ ++ ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); ++ + /* create context entity for each ring */ + for (i = 0; i < adev->num_rings; i++) { + struct amdgpu_ring *ring = adev->rings[i]; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch b/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch new file mode 100644 index 00000000..92192a36 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch @@ -0,0 +1,50 @@ +From 6cc4758ae91c0582f07e3c94c7de1ad0975feff5 Mon Sep 17 00:00:00 2001 +From: Stefan Agner +Date: Fri, 2 Sep 2016 11:23:37 -0700 +Subject: drm/fsl-dcu: fix endian issue when using clk_register_divider + +From: Stefan Agner + +commit 6cc4758ae91c0582f07e3c94c7de1ad0975feff5 upstream. + +Since using clk_register_divider to setup the pixel clock, regmap +is no longer used. Regmap did take care of DCU using different +endianness. Check endianness using the device-tree property +"big-endian" to determine the location of DIV_RATIO. + +Fixes: 2d701449bce1 ("drm/fsl-dcu: use common clock framework for pixel clock divider") +Reported-by: Meng Yi +Signed-off-by: Stefan Agner +Tested-by: Meng Yi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +@@ -330,6 +330,7 @@ static int fsl_dcu_drm_probe(struct plat + const char *pix_clk_in_name; + const struct of_device_id *id; + int ret; ++ u8 div_ratio_shift = 0; + + fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL); + if (!fsl_dev) +@@ -382,11 +383,14 @@ static int fsl_dcu_drm_probe(struct plat + pix_clk_in = fsl_dev->clk; + } + ++ if (of_property_read_bool(dev->of_node, "big-endian")) ++ div_ratio_shift = 24; ++ + pix_clk_in_name = __clk_get_name(pix_clk_in); + snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name); + fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name, + pix_clk_in_name, 0, base + DCU_DIV_RATIO, +- 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); ++ div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); + if (IS_ERR(fsl_dev->pix_clk)) { + dev_err(dev, "failed to register pix clk\n"); + ret = PTR_ERR(fsl_dev->pix_clk); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch new file mode 100644 index 00000000..70ad7ba4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch @@ -0,0 +1,118 @@ +From d721b02fd00bf133580f431b82ef37f3b746dfb2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 8 Aug 2016 13:58:39 +0300 +Subject: drm/i915: Account for TSEG size when determining 865G stolen base +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit d721b02fd00bf133580f431b82ef37f3b746dfb2 upstream. + +Looks like the TSEG lives just above TOUD, stolen comes after TSEG. + +The spec seems somewhat self-contradictory in places, in the ESMRAMC +register desctription it says: + TSEG Size: + 10=(TOUD + 512 KB) to TOUD + 11 =(TOUD + 1 MB) to TOUD + +so that agrees with TSEG being at TOUD. But the example given +elsehwere in the spec says: + + TOUD equals 62.5 MB = 03E7FFFFh + TSEG selected as 512 KB in size, + Graphics local memory selected as 1 MB in size + General System RAM available in system = 62.5 MB + General system RAM range00000000h to 03E7FFFFh + TSEG address range03F80000h to 03FFFFFFh + TSEG pre-allocated from03F80000h to 03FFFFFFh + Graphics local memory pre-allocated from03E80000h to 03F7FFFFh + +so here we have TSEG above stolen. + +Real world evidence agrees with the TOUD->TSEG->stolen order however, so +let's fix up the code to account for the TSEG size. + +Cc: Taketo Kabe +Cc: Chris Wilson +Cc: Daniel Vetter +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: x86@kernel.org +Fixes: 0ad98c74e093 ("drm/i915: Determine the stolen memory base address on gen2") +Fixes: a4dff76924fe ("x86/gpu: Add Intel graphics stolen memory quirk for gen2 platforms") +Reported-by: Taketo Kabe +Tested-by: Taketo Kabe +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96473 +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/1470653919-27251-1-git-send-email-ville.syrjala@linux.intel.com +Link: http://download.intel.com/design/chipsets/datashts/25251405.pdf +Reviewed-by: Chris Wilson +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/early-quirks.c | 9 ++------- + drivers/gpu/drm/i915/i915_gem_stolen.c | 23 +++++++++++++++++------ + 2 files changed, 19 insertions(+), 13 deletions(-) + +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -317,16 +317,11 @@ static phys_addr_t __init i85x_stolen_ba + static phys_addr_t __init i865_stolen_base(int num, int slot, int func, + size_t stolen_size) + { +- u16 toud; ++ u16 toud = 0; + +- /* +- * FIXME is the graphics stolen memory region +- * always at TOUD? Ie. is it always the last +- * one to be allocated by the BIOS? +- */ + toud = read_pci_config_16(0, 0, 0, I865_TOUD); + +- return (phys_addr_t)toud << 16; ++ return (phys_addr_t)(toud << 16) + i845_tseg_size(); + } + + static phys_addr_t __init gen3_stolen_base(int num, int slot, int func, +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -115,17 +115,28 @@ static unsigned long i915_stolen_to_phys + + base = bsm & INTEL_BSM_MASK; + } else if (IS_I865G(dev)) { ++ u32 tseg_size = 0; + u16 toud = 0; ++ u8 tmp; ++ ++ pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), ++ I845_ESMRAMC, &tmp); ++ ++ if (tmp & TSEG_ENABLE) { ++ switch (tmp & I845_TSEG_SIZE_MASK) { ++ case I845_TSEG_SIZE_512K: ++ tseg_size = KB(512); ++ break; ++ case I845_TSEG_SIZE_1M: ++ tseg_size = MB(1); ++ break; ++ } ++ } + +- /* +- * FIXME is the graphics stolen memory region +- * always at TOUD? Ie. is it always the last +- * one to be allocated by the BIOS? +- */ + pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0), + I865_TOUD, &toud); + +- base = toud << 16; ++ base = (toud << 16) + tseg_size; + } else if (IS_I85X(dev)) { + u32 tseg_size = 0; + u32 tom; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch new file mode 100644 index 00000000..418c1e77 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch @@ -0,0 +1,111 @@ +From 16c83fad79ca912b8b5bbdcb5272794a2be41262 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 3 Oct 2016 10:55:16 +0300 +Subject: drm/i915: Allow DP to work w/o EDID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 16c83fad79ca912b8b5bbdcb5272794a2be41262 upstream. + +Allow returning "connected" or "unknown" connector status for DP branch +devices that don't have an EDID. Currently we'd claim the thing as +"disconnected" if there is no EDID. + +This stuff used to broken already, I think, but it got more broken by +commit f21a21983ef1 ("drm/i915: Splitting intel_dp_detect") + +Cc: Damien Cassou +Cc: freedesktop.org@gp.mailgun.org +Cc: Arno +Cc: Shubhangi Shrivastava +Cc: Sivakumar Thulasimani +Cc: Ander Conselvan de Oliveira +Tested-by: Arno +Fixes: f21a21983ef1 ("drm/i915: Splitting intel_dp_detect") +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83348 +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/1475481316-8194-2-git-send-email-ville.syrjala@linux.intel.com +Reviewed-by: Ander Conselvan de Oliveira +(cherry picked from commit 5cb651a7959310ef4dbb0b93f005b10286789656) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dp.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -4207,7 +4207,7 @@ intel_dp_unset_edid(struct intel_dp *int + intel_dp->has_audio = false; + } + +-static void ++static enum drm_connector_status + intel_dp_long_pulse(struct intel_connector *intel_connector) + { + struct drm_connector *connector = &intel_connector->base; +@@ -4232,7 +4232,7 @@ intel_dp_long_pulse(struct intel_connect + else + status = connector_status_disconnected; + +- if (status != connector_status_connected) { ++ if (status == connector_status_disconnected) { + intel_dp->compliance_test_active = 0; + intel_dp->compliance_test_type = 0; + intel_dp->compliance_test_data = 0; +@@ -4284,8 +4284,8 @@ intel_dp_long_pulse(struct intel_connect + intel_dp->aux.i2c_defer_count = 0; + + intel_dp_set_edid(intel_dp); +- +- status = connector_status_connected; ++ if (is_edp(intel_dp) || intel_connector->detect_edid) ++ status = connector_status_connected; + intel_dp->detect_done = true; + + /* Try to read the source of the interrupt */ +@@ -4303,12 +4303,11 @@ intel_dp_long_pulse(struct intel_connect + } + + out: +- if ((status != connector_status_connected) && +- (intel_dp->is_mst == false)) ++ if (status != connector_status_connected && !intel_dp->is_mst) + intel_dp_unset_edid(intel_dp); + + intel_display_power_put(to_i915(dev), power_domain); +- return; ++ return status; + } + + static enum drm_connector_status +@@ -4317,7 +4316,7 @@ intel_dp_detect(struct drm_connector *co + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &intel_dig_port->base; +- struct intel_connector *intel_connector = to_intel_connector(connector); ++ enum drm_connector_status status = connector->status; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); +@@ -4332,14 +4331,11 @@ intel_dp_detect(struct drm_connector *co + + /* If full detect is not performed yet, do a full detect */ + if (!intel_dp->detect_done) +- intel_dp_long_pulse(intel_dp->attached_connector); ++ status = intel_dp_long_pulse(intel_dp->attached_connector); + + intel_dp->detect_done = false; + +- if (is_edp(intel_dp) || intel_connector->detect_edid) +- return connector_status_connected; +- else +- return connector_status_disconnected; ++ return status; + } + + static void diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch new file mode 100644 index 00000000..4cf6873a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch @@ -0,0 +1,76 @@ +From a3fd4c67af3d8a81d241b3d51b3525f36f1d68bb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 26 Sep 2016 11:30:46 +0300 +Subject: drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit a3fd4c67af3d8a81d241b3d51b3525f36f1d68bb upstream. + +DPLL_SDVO_HIGH_SPEED must be set for SDVO/HDMI/DP, but nowhere is it +forbidden to set it for LVDS/CRT as well. So let's also set it on +CRT to make it possible to share the DPLL between HDMI and CRT. + +What that bit apparently does is enable the x5 clock to the port, +which then pumps out the bits on both edges of the clock. The DAC +doesn't need that clock since it's not pumping out bits, but I don't +think it hurts to have the DPLL output that clock anyway. + +This is fairly important on IVB since it has only two DPLLs with three +pipes. So trying to drive three or more PCH ports with three pipes +is only possible when at least one of the DPLLs gets shared between +two of the pipes. + +SNB doesn't really need to do this since it has only two pipes. It could +be done to avoid enabling the second DPLL at all in certain cases, but +I'm not sure that's such a huge win. So let's not do it for SNB, at +least for now. On ILK it never makes sense as the DPLLs can't be shared. + +v2: Just always enable the high speed clock to keep things simple (Daniel) + Beef up the commit message a bit (Daniel) + +Cc: Nick Yamane +Cc: Daniel Vetter +Tested-by: Nick Yamane +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97204 +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/1474878646-17711-1-git-send-email-ville.syrjala@linux.intel.com +Reviewed-by: Ander Conselvan de Oliveira +(cherry picked from commit 7d7f8633a82763577727762ff3ac1df3017cb8fe) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9007,6 +9007,24 @@ static void ironlake_compute_dpll(struct + if (intel_crtc_has_dp_encoder(crtc_state)) + dpll |= DPLL_SDVO_HIGH_SPEED; + ++ /* ++ * The high speed IO clock is only really required for ++ * SDVO/HDMI/DP, but we also enable it for CRT to make it ++ * possible to share the DPLL between CRT and HDMI. Enabling ++ * the clock needlessly does no real harm, except use up a ++ * bit of power potentially. ++ * ++ * We'll limit this to IVB with 3 pipes, since it has only two ++ * DPLLs and so DPLL sharing is the only way to get three pipes ++ * driving PCH ports at the same time. On SNB we could do this, ++ * and potentially avoid enabling the second DPLL, but it's not ++ * clear if it''s a win or loss power wise. No point in doing ++ * this on ILK at all since it has a fixed DPLL<->pipe mapping. ++ */ ++ if (INTEL_INFO(dev_priv)->num_pipes == 3 && ++ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) ++ dpll |= DPLL_SDVO_HIGH_SPEED; ++ + /* compute bitmask from p1 value */ + dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + /* also FPA1 */ diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch new file mode 100644 index 00000000..800bedae --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch @@ -0,0 +1,79 @@ +From 16e1203db8ab740c912ea62761fdf27d7811b886 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 19 Sep 2016 13:35:25 +0300 +Subject: drm/i915/backlight: setup and cache pwm alternate increment value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jani Nikula + +commit 16e1203db8ab740c912ea62761fdf27d7811b886 upstream. + +This will also be needed later on when setting up the alternate +increment in backlight enable. + +Cc: Shawn Lee +Reviewed-by: Ville Syrjälä +Signed-off-by: Jani Nikula +Link: http://patchwork.freedesktop.org/patch/msgid/9984b20bc59aee90b83caf59ce91f3fb122c9627.1474281249.git.jani.nikula@intel.com +(cherry picked from commit 32b421e79e6b546da1d469f1229403ac9142d695) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_drv.h | 1 + + drivers/gpu/drm/i915/intel_panel.c | 14 +++++++++++--- + 2 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -236,6 +236,7 @@ struct intel_panel { + bool enabled; + bool combination_mode; /* gen 2/4 only */ + bool active_low_pwm; ++ bool alternate_pwm_increment; /* lpt+ */ + + /* PWM chip */ + bool util_pin_active_low; /* bxt+ */ +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -1242,10 +1242,10 @@ static u32 bxt_hz_to_pwm(struct intel_co + */ + static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + { +- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); ++ struct intel_panel *panel = &connector->panel; + u32 mul; + +- if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY) ++ if (panel->backlight.alternate_pwm_increment) + mul = 128; + else + mul = 16; +@@ -1261,9 +1261,10 @@ static u32 spt_hz_to_pwm(struct intel_co + static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); ++ struct intel_panel *panel = &connector->panel; + u32 mul, clock; + +- if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY) ++ if (panel->backlight.alternate_pwm_increment) + mul = 16; + else + mul = 128; +@@ -1414,6 +1415,13 @@ static int lpt_setup_backlight(struct in + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pch_ctl1, pch_ctl2, val; ++ bool alt; ++ ++ if (HAS_PCH_LPT(dev_priv)) ++ alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; ++ else ++ alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; ++ panel->backlight.alternate_pwm_increment = alt; + + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch new file mode 100644 index 00000000..97d4e08a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch @@ -0,0 +1,70 @@ +From 915b417946030e1f365c63728875cffd8db8e880 Mon Sep 17 00:00:00 2001 +From: Shawn Lee +Date: Mon, 19 Sep 2016 13:35:26 +0300 +Subject: drm/i915/backlight: setup backlight pwm alternate increment on backlight enable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Shawn Lee + +commit 915b417946030e1f365c63728875cffd8db8e880 upstream. + +Backlight enable is supposed to do a full setup of the backlight. We +were missing the PWM alternate increment bit in the south chicken +registers on lpt+ pch. This potentially caused a PWM frequency change +when the chicken register value was lost e.g. on suspend. + +v2 by Jani, rebase on the patch caching alt increment + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97486 +References: https://bugs.freedesktop.org/show_bug.cgi?id=67454 +Cc: Cooper Chiou +Cc: Wei Shun Chen +Cc: Gary C Wang +Reviewed-by: Ville Syrjälä +Signed-off-by: Shawn Lee +Signed-off-by: Jani Nikula +Link: http://patchwork.freedesktop.org/patch/msgid/8265f5935bd31c039ddfc82819d26c2ca1ae9cba.1474281249.git.jani.nikula@intel.com +(cherry picked from commit e29aff05f239f8dd24e9ee7816fd96726e20105a) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_panel.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -841,7 +841,7 @@ static void lpt_enable_backlight(struct + { + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; +- u32 pch_ctl1, pch_ctl2; ++ u32 pch_ctl1, pch_ctl2, schicken; + + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { +@@ -850,6 +850,22 @@ static void lpt_enable_backlight(struct + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); + } + ++ if (HAS_PCH_LPT(dev_priv)) { ++ schicken = I915_READ(SOUTH_CHICKEN2); ++ if (panel->backlight.alternate_pwm_increment) ++ schicken |= LPT_PWM_GRANULARITY; ++ else ++ schicken &= ~LPT_PWM_GRANULARITY; ++ I915_WRITE(SOUTH_CHICKEN2, schicken); ++ } else { ++ schicken = I915_READ(SOUTH_CHICKEN1); ++ if (panel->backlight.alternate_pwm_increment) ++ schicken |= SPT_PWM_GRANULARITY; ++ else ++ schicken &= ~SPT_PWM_GRANULARITY; ++ I915_WRITE(SOUTH_CHICKEN1, schicken); ++ } ++ + pch_ctl2 = panel->backlight.max << 16; + I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); + diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch new file mode 100644 index 00000000..0b3edb20 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch @@ -0,0 +1,111 @@ +From cf6c525a31fac11b0775b8c06c00a508c6356d9b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:32 -0300 +Subject: drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations + +From: Paulo Zanoni + +commit cf6c525a31fac11b0775b8c06c00a508c6356d9b upstream. + +The confusing thing is that plane_blocks_per_line is listed as part of +the method 2 calculation but is also used for other things. We +calculated it in two different places and different ways: one inside +skl_wm_method2() and the other inside skl_compute_plane_wm(). The +skl_wm_method2() implementation is the one that matches the +specification. + +With this patch we fix the skl_compute_plane_wm() calculation and just +pass it as a parameter to skl_wm_method2(). We also take care to not +modify the value of plane_bytes_per_line since we're going to rely on +it having a correct value in later patches. + +This should affect the watermarks for Linear and Y-tiled. + +From my analysis, it looks like the two plane_blocks_per_line +variables got out of sync on 0fda65680e92, but we can't really say +that commit was a regression, it looks like just an incomplete fix. +There's always the possibility that 0fda65680e92 matched our +specification at that time, and then later the specification changed. + +v2: Try to add a "Fixes" tag (Maarten). + +Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling") +Cc: Tvrtko Ursulin +Reviewed-by: Lyude +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-7-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 7a1a8aed67e0a60772defe3f6499eb340da48634) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 39 +++++++++++++++------------------------ + 1 file changed, 15 insertions(+), 24 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3475,30 +3475,14 @@ static uint32_t skl_wm_method1(uint32_t + } + + static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, +- uint32_t horiz_pixels, uint8_t cpp, +- uint64_t tiling, uint32_t latency, +- uint32_t y_min_scanlines) ++ uint32_t latency, uint32_t plane_blocks_per_line) + { + uint32_t ret; +- uint32_t plane_bytes_per_line, plane_blocks_per_line; + uint32_t wm_intermediate_val; + + if (latency == 0) + return UINT_MAX; + +- plane_bytes_per_line = horiz_pixels * cpp; +- +- if (tiling == I915_FORMAT_MOD_Y_TILED || +- tiling == I915_FORMAT_MOD_Yf_TILED) { +- plane_bytes_per_line *= y_min_scanlines; +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); +- plane_blocks_per_line /= y_min_scanlines; +- } else if (tiling == DRM_FORMAT_MOD_NONE) { +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; +- } else { +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); +- } +- + wm_intermediate_val = latency * pixel_rate; + ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) * + plane_blocks_per_line; +@@ -3587,17 +3571,24 @@ static int skl_compute_plane_wm(const st + y_min_scanlines = 4; + } + ++ plane_bytes_per_line = width * cpp; ++ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || ++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { ++ plane_blocks_per_line = ++ DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512); ++ plane_blocks_per_line /= y_min_scanlines; ++ } else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) { ++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) ++ + 1; ++ } else { ++ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); ++ } ++ + method1 = skl_wm_method1(plane_pixel_rate, cpp, latency); + method2 = skl_wm_method2(plane_pixel_rate, + cstate->base.adjusted_mode.crtc_htotal, +- width, +- cpp, +- fb->modifier[0], + latency, +- y_min_scanlines); +- +- plane_bytes_per_line = width * cpp; +- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); ++ plane_blocks_per_line); + + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch new file mode 100644 index 00000000..9cd60dd2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch @@ -0,0 +1,75 @@ +From 73fed0ef8567f1e1cba079994353e60208ded964 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:33 -0300 +Subject: drm/i915/gen9: fix the watermark res_blocks value + +From: Paulo Zanoni + +commit 73fed0ef8567f1e1cba079994353e60208ded964 upstream. + +We forgot the "res_blocks += y_tile_minimum" that's described on step +V of our documentation. + +Again, this should only affect the Y tiling cases. + +It looks like the relevant code was introduced in 0fda65680e92, but +there's always the possibility that it matched our specification when +it was introduced, and then the specification changed while the code +stayed the same. So we can't really say this was a regression, but +let's try to add a "Fixes" tag anyway to help backporting. + +v2: Try to add a "Fixes" tag (Maarten). + +Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling") +Cc: Tvrtko Ursulin +Reviewed-by: Lyude +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-8-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 75676ed423a6acf9e2b1df52fbc036a51e11fb7a) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3533,7 +3533,7 @@ static int skl_compute_plane_wm(const st + uint8_t cpp; + uint32_t width = 0, height = 0; + uint32_t plane_pixel_rate; +- uint32_t y_min_scanlines; ++ uint32_t y_tile_minimum, y_min_scanlines; + + if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { + *enabled = false; +@@ -3590,10 +3590,10 @@ static int skl_compute_plane_wm(const st + latency, + plane_blocks_per_line); + ++ y_tile_minimum = plane_blocks_per_line * y_min_scanlines; ++ + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { +- uint32_t y_tile_minimum = plane_blocks_per_line * +- y_min_scanlines; + selected_result = max(method2, y_tile_minimum); + } else { + if ((ddb_allocation / plane_blocks_per_line) >= 1) +@@ -3607,10 +3607,12 @@ static int skl_compute_plane_wm(const st + + if (level >= 1 && level <= 7) { + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || +- fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) ++ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { ++ res_blocks += y_tile_minimum; + res_lines += y_min_scanlines; +- else ++ } else { + res_blocks++; ++ } + } + + if (res_blocks >= ddb_allocation || res_lines > 31) { diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch new file mode 100644 index 00000000..54ffa0ea --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch @@ -0,0 +1,91 @@ +From 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:30 -0300 +Subject: drm/i915/gen9: fix the WaWmMemoryReadLatency implementation + +From: Paulo Zanoni + +commit 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 upstream. + +Bspec says: + "The mailbox response data may not account for memory read latency. + If the mailbox response data for level 0 is 0us, add 2 microseconds + to the result for each valid level." + +This means we should only do the +2 in case wm[0] == 0, not always. + +So split the sanitizing implementation from the WA implementation and +fix the WA implementation. + +v2: Add Fixes tag (Maarten). + +Fixes: 367294be7c25 ("drm/i915/gen9: Add 2us read latency to WM level") +Cc: Vandana Kannan +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-5-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 0727e40a48a1d08cf54ce2c01e120864b92e59bf) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++-------------------- + 1 file changed, 22 insertions(+), 20 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct + GEN9_MEM_LATENCY_LEVEL_MASK; + + /* ++ * If a level n (n > 1) has a 0us latency, all levels m (m >= n) ++ * need to be disabled. We make sure to sanitize the values out ++ * of the punit to satisfy this requirement. ++ */ ++ for (level = 1; level <= max_level; level++) { ++ if (wm[level] == 0) { ++ for (i = level + 1; i <= max_level; i++) ++ wm[i] = 0; ++ break; ++ } ++ } ++ ++ /* + * WaWmMemoryReadLatency:skl + * + * punit doesn't take into account the read latency so we need +- * to add 2us to the various latency levels we retrieve from +- * the punit. +- * - W0 is a bit special in that it's the only level that +- * can't be disabled if we want to have display working, so +- * we always add 2us there. +- * - For levels >=1, punit returns 0us latency when they are +- * disabled, so we respect that and don't add 2us then +- * +- * Additionally, if a level n (n > 1) has a 0us latency, all +- * levels m (m >= n) need to be disabled. We make sure to +- * sanitize the values out of the punit to satisfy this +- * requirement. ++ * to add 2us to the various latency levels we retrieve from the ++ * punit when level 0 response data us 0us. + */ +- wm[0] += 2; +- for (level = 1; level <= max_level; level++) +- if (wm[level] != 0) ++ if (wm[0] == 0) { ++ wm[0] += 2; ++ for (level = 1; level <= max_level; level++) { ++ if (wm[level] == 0) ++ break; + wm[level] += 2; +- else { +- for (i = level + 1; i <= max_level; i++) +- wm[i] = 0; +- +- break; + } ++ } ++ + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + uint64_t sskpd = I915_READ64(MCH_SSKPD); + diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch new file mode 100644 index 00000000..43111119 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch @@ -0,0 +1,133 @@ +From ccc1057477bc99678896b51adce6b6ee4019dc37 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:31 -0300 +Subject: drm/i915/gen9: minimum scanlines for Y tile is not always 4 + +From: Paulo Zanoni + +commit ccc1057477bc99678896b51adce6b6ee4019dc37 upstream. + +During watermarks calculations, this value is used in 3 different +places. Only one of them was not using a hardcoded 4. Move the code up +so everybody can benefit from the actual value. + +This should only help on situations with Y tiling + 90/270 rotation + +1 or 2 bpp or NV12. + +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-6-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 1186fa85eb9b3cc0589990fbc39617e50e38759a) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 56 ++++++++++++++++++++++------------------ + 1 file changed, 32 insertions(+), 24 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3476,7 +3476,8 @@ static uint32_t skl_wm_method1(uint32_t + + static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + uint32_t horiz_pixels, uint8_t cpp, +- uint64_t tiling, uint32_t latency) ++ uint64_t tiling, uint32_t latency, ++ uint32_t y_min_scanlines) + { + uint32_t ret; + uint32_t plane_bytes_per_line, plane_blocks_per_line; +@@ -3489,9 +3490,9 @@ static uint32_t skl_wm_method2(uint32_t + + if (tiling == I915_FORMAT_MOD_Y_TILED || + tiling == I915_FORMAT_MOD_Yf_TILED) { +- plane_bytes_per_line *= 4; ++ plane_bytes_per_line *= y_min_scanlines; + plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); +- plane_blocks_per_line /= 4; ++ plane_blocks_per_line /= y_min_scanlines; + } else if (tiling == DRM_FORMAT_MOD_NONE) { + plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; + } else { +@@ -3548,6 +3549,7 @@ static int skl_compute_plane_wm(const st + uint8_t cpp; + uint32_t width = 0, height = 0; + uint32_t plane_pixel_rate; ++ uint32_t y_min_scanlines; + + if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { + *enabled = false; +@@ -3563,38 +3565,44 @@ static int skl_compute_plane_wm(const st + cpp = drm_format_plane_cpp(fb->pixel_format, 0); + plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); + ++ if (intel_rotation_90_or_270(pstate->rotation)) { ++ int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? ++ drm_format_plane_cpp(fb->pixel_format, 1) : ++ drm_format_plane_cpp(fb->pixel_format, 0); ++ ++ switch (cpp) { ++ case 1: ++ y_min_scanlines = 16; ++ break; ++ case 2: ++ y_min_scanlines = 8; ++ break; ++ default: ++ WARN(1, "Unsupported pixel depth for rotation"); ++ case 4: ++ y_min_scanlines = 4; ++ break; ++ } ++ } else { ++ y_min_scanlines = 4; ++ } ++ + method1 = skl_wm_method1(plane_pixel_rate, cpp, latency); + method2 = skl_wm_method2(plane_pixel_rate, + cstate->base.adjusted_mode.crtc_htotal, + width, + cpp, + fb->modifier[0], +- latency); ++ latency, ++ y_min_scanlines); + + plane_bytes_per_line = width * cpp; + plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); + + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { +- uint32_t min_scanlines = 4; +- uint32_t y_tile_minimum; +- if (intel_rotation_90_or_270(pstate->rotation)) { +- int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? +- drm_format_plane_cpp(fb->pixel_format, 1) : +- drm_format_plane_cpp(fb->pixel_format, 0); +- +- switch (cpp) { +- case 1: +- min_scanlines = 16; +- break; +- case 2: +- min_scanlines = 8; +- break; +- case 8: +- WARN(1, "Unsupported pixel depth for rotation"); +- } +- } +- y_tile_minimum = plane_blocks_per_line * min_scanlines; ++ uint32_t y_tile_minimum = plane_blocks_per_line * ++ y_min_scanlines; + selected_result = max(method2, y_tile_minimum); + } else { + if ((ddb_allocation / plane_blocks_per_line) >= 1) +@@ -3609,7 +3617,7 @@ static int skl_compute_plane_wm(const st + if (level >= 1 && level <= 7) { + if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) +- res_lines += 4; ++ res_lines += y_min_scanlines; + else + res_blocks++; + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch new file mode 100644 index 00000000..8fec07d2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch @@ -0,0 +1,92 @@ +From be5c571b2ff3a164d2e14ccc100cb5b2b3d3fb7c Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 29 Sep 2016 16:36:48 -0300 +Subject: drm/i915/gen9: only add the planes actually affected by ddb changes + +From: Paulo Zanoni + +commit be5c571b2ff3a164d2e14ccc100cb5b2b3d3fb7c upstream. + +We were previously adding all the planes owned by the CRTC even when +the ddb partitioning didn't change for them. As a consequence, a lot +of functions were being called when we were just moving the cursor +around the screen, such as skylake_update_primary_plane(). + +This was causing flickering on the primary plane when moving the +cursor. I'm not 100% sure which operation caused the flickering, but +we were writing to a lot of registers, so it could be any of these +writes. With this patch, just moving the mouse won't add the primary +plane to the commit since it won't trigger a change in DDB +partitioning. + +v2: Use skl_ddb_entry_equal() (Lyude). +v3: Change Reported-and-bisected-by: to Reported-by: for checkpatch + +Fixes: 05a76d3d6ad1 ("drm/i915/skl: Ensure pipes with changed wms get added to the state") +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97888 +Cc: Mike Lothian +Reported-by: Mike Lothian +Signed-off-by: Paulo Zanoni +Signed-off-by: Lyude +Link: http://patchwork.freedesktop.org/patch/msgid/1475177808-29955-1-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 7f60e200e254cd53ad1bd74a56bdd23e813ac4b7) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3940,6 +3940,41 @@ pipes_modified(struct drm_atomic_state * + return ret; + } + ++int ++skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) ++{ ++ struct drm_atomic_state *state = cstate->base.state; ++ struct drm_device *dev = state->dev; ++ struct drm_crtc *crtc = cstate->base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); ++ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; ++ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; ++ struct drm_plane_state *plane_state; ++ struct drm_plane *plane; ++ enum pipe pipe = intel_crtc->pipe; ++ int id; ++ ++ WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); ++ ++ drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { ++ id = skl_wm_plane_id(to_intel_plane(plane)); ++ ++ if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], ++ &new_ddb->plane[pipe][id]) && ++ skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id], ++ &new_ddb->y_plane[pipe][id])) ++ continue; ++ ++ plane_state = drm_atomic_get_plane_state(state, plane); ++ if (IS_ERR(plane_state)) ++ return PTR_ERR(plane_state); ++ } ++ ++ return 0; ++} ++ + static int + skl_compute_ddb(struct drm_atomic_state *state) + { +@@ -4004,7 +4039,7 @@ skl_compute_ddb(struct drm_atomic_state + if (ret) + return ret; + +- ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); ++ ret = skl_ddb_add_affected_planes(cstate); + if (ret) + return ret; + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch new file mode 100644 index 00000000..c25ade40 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch @@ -0,0 +1,103 @@ +From 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:28 -0300 +Subject: drm/i915: introduce intel_has_sagv() + +From: Paulo Zanoni + +commit 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e upstream. + +And use it to move knowledge about the SAGV-supporting platforms from +the callers to the SAGV code. + +We'll add more platforms to intel_has_sagv(), so IMHO it makes more +sense to move all this to a single function instead of patching all +the callers every time we add SAGV support to a new platform. + +v2: Move I915_SAGV_NOT_CONTROLLED to the new function (Lyude). + +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-3-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 56feca91973459d0b62cbb2610b62d341025ed89) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 5 ++--- + drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++---- + 2 files changed, 20 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -13891,7 +13891,7 @@ static void intel_atomic_commit_tail(str + * SKL workaround: bspec recommends we disable the SAGV when we + * have more then one pipe enabled + */ +- if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state)) ++ if (!intel_can_enable_sagv(state)) + intel_disable_sagv(dev_priv); + + intel_modeset_verify_disabled(dev); +@@ -13949,8 +13949,7 @@ static void intel_atomic_commit_tail(str + intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); + } + +- if (IS_SKYLAKE(dev_priv) && intel_state->modeset && +- intel_can_enable_sagv(state)) ++ if (intel_state->modeset && intel_can_enable_sagv(state)) + intel_enable_sagv(dev_priv); + + drm_atomic_helper_commit_hw_done(state); +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2878,6 +2878,13 @@ skl_wm_plane_id(const struct intel_plane + } + } + ++static bool ++intel_has_sagv(struct drm_i915_private *dev_priv) ++{ ++ return IS_SKYLAKE(dev_priv) && ++ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED; ++} ++ + /* + * SAGV dynamically adjusts the system agent voltage and clock frequencies + * depending on power and performance requirements. The display engine access +@@ -2894,8 +2901,10 @@ intel_enable_sagv(struct drm_i915_privat + { + int ret; + +- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || +- dev_priv->sagv_status == I915_SAGV_ENABLED) ++ if (!intel_has_sagv(dev_priv)) ++ return 0; ++ ++ if (dev_priv->sagv_status == I915_SAGV_ENABLED) + return 0; + + DRM_DEBUG_KMS("Enabling the SAGV\n"); +@@ -2943,8 +2952,10 @@ intel_disable_sagv(struct drm_i915_priva + { + int ret, result; + +- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || +- dev_priv->sagv_status == I915_SAGV_DISABLED) ++ if (!intel_has_sagv(dev_priv)) ++ return 0; ++ ++ if (dev_priv->sagv_status == I915_SAGV_DISABLED) + return 0; + + DRM_DEBUG_KMS("Disabling the SAGV\n"); +@@ -2985,6 +2996,9 @@ bool intel_can_enable_sagv(struct drm_at + enum pipe pipe; + int level, plane; + ++ if (!intel_has_sagv(dev_priv)) ++ return false; ++ + /* + * SKL workaround: bspec recommends we disable the SAGV when we have + * more then one pipe enabled diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch new file mode 100644 index 00000000..85b64a22 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch @@ -0,0 +1,43 @@ +From f856f847b22c52be82f712ea6ada946c6db884d7 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 3 Oct 2016 13:45:14 +0100 +Subject: drm/i915: Just clear the mmiodebug before a register access + +From: Chris Wilson + +commit f856f847b22c52be82f712ea6ada946c6db884d7 upstream. + +When we enable the per-register access mmiodebug, it is to detect which +access is illegal. Reporting on earlier untraced access outside of the +mmiodebug does not help debugging (as the suspicion is immediately put +upon the current register which is not at fault)! + +References: https://bugs.freedesktop.org/show_bug.cgi?id=97985 +Signed-off-by: Chris Wilson +Cc: Mika Kuoppala +Reviewed-by: Mika Kuoppala +Link: http://patchwork.freedesktop.org/patch/msgid/20161003124516.12388-1-chris@chris-wilson.co.uk +(cherry picked from commit dda960335e020835f7f1c12760e7f0b525b451e2) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_uncore.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -796,10 +796,9 @@ __unclaimed_reg_debug(struct drm_i915_pr + const bool read, + const bool before) + { +- if (WARN(check_for_unclaimed_mmio(dev_priv), +- "Unclaimed register detected %s %s register 0x%x\n", +- before ? "before" : "after", +- read ? "reading" : "writing to", ++ if (WARN(check_for_unclaimed_mmio(dev_priv) && !before, ++ "Unclaimed %s register 0x%x\n", ++ read ? "read from" : "write to", + i915_mmio_reg_offset(reg))) + i915.mmio_debug--; /* Only report the first N failures */ + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch new file mode 100644 index 00000000..ef3c31b9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch @@ -0,0 +1,64 @@ +From 17777d61f4a87d7b6d5585e8fdffa83773c594e7 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:29 -0300 +Subject: drm/i915/kbl: KBL also needs to run the SAGV code + +From: Paulo Zanoni + +commit 17777d61f4a87d7b6d5585e8fdffa83773c594e7 upstream. + +According to BSpec, it's the "core CPUs" that need the code, which +means SKL and KBL, but not BXT. + +I don't have a KBL to test this patch on it. + +v2: Only SKL should have I915_SAGV_NOT_CONTROLLED. + +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-4-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 6e3100ec21e7c774a0fc01e36a1e0739530c2f71) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2881,8 +2881,14 @@ skl_wm_plane_id(const struct intel_plane + static bool + intel_has_sagv(struct drm_i915_private *dev_priv) + { +- return IS_SKYLAKE(dev_priv) && +- dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED; ++ if (IS_KABYLAKE(dev_priv)) ++ return true; ++ ++ if (IS_SKYLAKE(dev_priv) && ++ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED) ++ return true; ++ ++ return false; + } + + /* +@@ -2920,7 +2926,7 @@ intel_enable_sagv(struct drm_i915_privat + * Some skl systems, pre-release machines in particular, + * don't actually have an SAGV. + */ +- if (ret == -ENXIO) { ++ if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); + dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; +@@ -2974,7 +2980,7 @@ intel_disable_sagv(struct drm_i915_priva + * Some skl systems, pre-release machines in particular, + * don't actually have an SAGV. + */ +- if (result == -ENXIO) { ++ if (IS_SKYLAKE(dev_priv) && result == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); + dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch new file mode 100644 index 00000000..e4402b0b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch @@ -0,0 +1,162 @@ +From 896e5bb022bce64e29ce2e1b2fc2a7476d311a15 Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Wed, 24 Aug 2016 07:48:09 +0200 +Subject: drm/i915: Move CRTC updating in atomic_commit into it's own hook +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lyude + +commit 896e5bb022bce64e29ce2e1b2fc2a7476d311a15 upstream. + +Since we have to write ddb allocations at the same time as we do other +plane updates, we're going to need to be able to control the order in +which we execute modesets on each pipe. The easiest way to do this is to +just factor this section of intel_atomic_commit_tail() +(intel_atomic_commit() for stable branches) into it's own function, and +add an appropriate display function hook for it. + +Based off of Matt Rope's suggestions + +Changes since v1: + - Drop pipe_config->base.active check in intel_update_crtcs() since we + check that before calling the function + +Signed-off-by: Lyude +Reviewed-by: Matt Roper +[omitting CC for stable, since this patch will need to be changed for +such backports first] +Cc: Ville Syrjälä +Cc: Daniel Vetter +Cc: Radhakrishna Sripada +Cc: Hans de Goede +Signed-off-by: Lyude +Signed-off-by: Maarten Lankhorst +Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-1-git-send-email-cpaul@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++++++----------- + 2 files changed, 54 insertions(+), 22 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -631,6 +631,8 @@ struct drm_i915_display_funcs { + struct intel_crtc_state *crtc_state); + void (*crtc_enable)(struct drm_crtc *crtc); + void (*crtc_disable)(struct drm_crtc *crtc); ++ void (*update_crtcs)(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask); + void (*audio_codec_enable)(struct drm_connector *connector, + struct intel_encoder *encoder, + const struct drm_display_mode *adjusted_mode); +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -13682,6 +13682,52 @@ static bool needs_vblank_wait(struct int + return false; + } + ++static void intel_update_crtc(struct drm_crtc *crtc, ++ struct drm_atomic_state *state, ++ struct drm_crtc_state *old_crtc_state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state); ++ bool modeset = needs_modeset(crtc->state); ++ ++ if (modeset) { ++ update_scanline_offset(intel_crtc); ++ dev_priv->display.crtc_enable(crtc); ++ } else { ++ intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); ++ } ++ ++ if (drm_atomic_get_existing_plane_state(state, crtc->primary)) { ++ intel_fbc_enable( ++ intel_crtc, pipe_config, ++ to_intel_plane_state(crtc->primary->state)); ++ } ++ ++ drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); ++ ++ if (needs_vblank_wait(pipe_config)) ++ *crtc_vblank_mask |= drm_crtc_mask(crtc); ++} ++ ++static void intel_update_crtcs(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_crtc *crtc; ++ struct drm_crtc_state *old_crtc_state; ++ int i; ++ ++ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { ++ if (!crtc->state->active) ++ continue; ++ ++ intel_update_crtc(crtc, state, old_crtc_state, ++ crtc_vblank_mask); ++ } ++} ++ + static void intel_atomic_commit_tail(struct drm_atomic_state *state) + { + struct drm_device *dev = state->dev; +@@ -13780,17 +13826,9 @@ static void intel_atomic_commit_tail(str + intel_modeset_verify_disabled(dev); + } + +- /* Now enable the clocks, plane, pipe, and connectors that we set up. */ ++ /* Complete the events for pipes that have now been disabled */ + for_each_crtc_in_state(state, crtc, old_crtc_state, i) { +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + bool modeset = needs_modeset(crtc->state); +- struct intel_crtc_state *pipe_config = +- to_intel_crtc_state(crtc->state); +- +- if (modeset && crtc->state->active) { +- update_scanline_offset(to_intel_crtc(crtc)); +- dev_priv->display.crtc_enable(crtc); +- } + + /* Complete events for now disable pipes here. */ + if (modeset && !crtc->state->active && crtc->state->event) { +@@ -13800,21 +13838,11 @@ static void intel_atomic_commit_tail(str + + crtc->state->event = NULL; + } +- +- if (!modeset) +- intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); +- +- if (crtc->state->active && +- drm_atomic_get_existing_plane_state(state, crtc->primary)) +- intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state)); +- +- if (crtc->state->active) +- drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); +- +- if (pipe_config->base.active && needs_vblank_wait(pipe_config)) +- crtc_vblank_mask |= 1 << i; + } + ++ /* Now enable the clocks, plane, pipe, and connectors that we set up. */ ++ dev_priv->display.update_crtcs(state, &crtc_vblank_mask); ++ + /* FIXME: We should call drm_atomic_helper_commit_hw_done() here + * already, but still need the state for the delayed optimization. To + * fix this: +@@ -15275,6 +15303,8 @@ void intel_init_display_hooks(struct drm + dev_priv->display.crtc_disable = i9xx_crtc_disable; + } + ++ dev_priv->display.update_crtcs = intel_update_crtcs; ++ + /* Returns the core display clock speed */ + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) + dev_priv->display.get_display_clock_speed = diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch new file mode 100644 index 00000000..5cb94eba --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch @@ -0,0 +1,102 @@ +From 1015811609c0328b5ed670d07748591b837e74eb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 3 Oct 2016 10:55:15 +0300 +Subject: drm/i915: Move long hpd handling into the hotplug work +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 1015811609c0328b5ed670d07748591b837e74eb upstream. + +We can't rely on connector->status in the detect() hook if the long hpd +was already handled by the dig_port_work as that won't update +connector->status. Thus we have to defer the long hpd handling entirely +until the hotplug work runs to avoid the double long hpd handling +the "detect_done" flag is trying to prevent. + +We'll start to depend on connector->status being up to date in a +following patch. + +Cc: Damien Cassou +Cc: freedesktop.org@gp.mailgun.org +Cc: Arno +Cc: Shubhangi Shrivastava +Cc: Sivakumar Thulasimani +Cc: Ander Conselvan de Oliveira +Tested-by: Arno +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83348 +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/1475481316-8194-1-git-send-email-ville.syrjala@linux.intel.com +Reviewed-by: Ander Conselvan de Oliveira +(cherry picked from commit 27d4efc5591a5853de54713bc717de73c8951e17) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dp.c | 48 +++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 25 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -4696,36 +4696,34 @@ intel_dp_hpd_pulse(struct intel_digital_ + port_name(intel_dig_port->port), + long_hpd ? "long" : "short"); + ++ if (long_hpd) { ++ intel_dp->detect_done = false; ++ return IRQ_NONE; ++ } ++ + power_domain = intel_display_port_aux_power_domain(intel_encoder); + intel_display_power_get(dev_priv, power_domain); + +- if (long_hpd) { +- intel_dp_long_pulse(intel_dp->attached_connector); +- if (intel_dp->is_mst) +- ret = IRQ_HANDLED; +- goto put_power; +- +- } else { +- if (intel_dp->is_mst) { +- if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { +- /* +- * If we were in MST mode, and device is not +- * there, get out of MST mode +- */ +- DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", +- intel_dp->is_mst, intel_dp->mst_mgr.mst_state); +- intel_dp->is_mst = false; +- drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, +- intel_dp->is_mst); +- goto put_power; +- } ++ if (intel_dp->is_mst) { ++ if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { ++ /* ++ * If we were in MST mode, and device is not ++ * there, get out of MST mode ++ */ ++ DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", ++ intel_dp->is_mst, intel_dp->mst_mgr.mst_state); ++ intel_dp->is_mst = false; ++ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, ++ intel_dp->is_mst); ++ intel_dp->detect_done = false; ++ goto put_power; + } ++ } + +- if (!intel_dp->is_mst) { +- if (!intel_dp_short_pulse(intel_dp)) { +- intel_dp_long_pulse(intel_dp->attached_connector); +- goto put_power; +- } ++ if (!intel_dp->is_mst) { ++ if (!intel_dp_short_pulse(intel_dp)) { ++ intel_dp->detect_done = false; ++ goto put_power; + } + } + diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch new file mode 100644 index 00000000..0397a5f6 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch @@ -0,0 +1,179 @@ +From 674f823b455cdb94d5773406c1caac170f87e1c4 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 22 Sep 2016 18:00:27 -0300 +Subject: drm/i915: SAGV is not SKL-only, so rename a few things + +From: Paulo Zanoni + +commit 674f823b455cdb94d5773406c1caac170f87e1c4 upstream. + +The plan is to introduce intel_has_sagv() and then use it to discover +which platforms actually support it. + +I thought about keeping the functions with their current skl names, +but found two problems: (i) skl_has_sagv() would become a very +confusing name, and (ii) intel_atomic_commit_tail() doesn't seem to be +calling any functions whose name start with a platform name, so the +"intel_" naming scheme seems make more sense than the "firstplatorm_" +naming scheme here. + +Reviewed-by: Lyude +Reviewed-by: Maarten Lankhorst +Signed-off-by: Paulo Zanoni +Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-2-git-send-email-paulo.r.zanoni@intel.com +(cherry picked from commit 16dcdc4edbcf5cb130004737f2548401776170f1) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.h | 10 +++++----- + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + drivers/gpu/drm/i915/intel_drv.h | 6 +++--- + drivers/gpu/drm/i915/intel_pm.c | 26 +++++++++++++------------- + 4 files changed, 25 insertions(+), 25 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1967,11 +1967,11 @@ struct drm_i915_private { + struct vlv_s0ix_state vlv_s0ix_state; + + enum { +- I915_SKL_SAGV_UNKNOWN = 0, +- I915_SKL_SAGV_DISABLED, +- I915_SKL_SAGV_ENABLED, +- I915_SKL_SAGV_NOT_CONTROLLED +- } skl_sagv_status; ++ I915_SAGV_UNKNOWN = 0, ++ I915_SAGV_DISABLED, ++ I915_SAGV_ENABLED, ++ I915_SAGV_NOT_CONTROLLED ++ } sagv_status; + + struct { + /* +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -13891,8 +13891,8 @@ static void intel_atomic_commit_tail(str + * SKL workaround: bspec recommends we disable the SAGV when we + * have more then one pipe enabled + */ +- if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) +- skl_disable_sagv(dev_priv); ++ if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state)) ++ intel_disable_sagv(dev_priv); + + intel_modeset_verify_disabled(dev); + } +@@ -13950,8 +13950,8 @@ static void intel_atomic_commit_tail(str + } + + if (IS_SKYLAKE(dev_priv) && intel_state->modeset && +- skl_can_enable_sagv(state)) +- skl_enable_sagv(dev_priv); ++ intel_can_enable_sagv(state)) ++ intel_enable_sagv(dev_priv); + + drm_atomic_helper_commit_hw_done(state); + +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1717,9 +1717,9 @@ void ilk_wm_get_hw_state(struct drm_devi + void skl_wm_get_hw_state(struct drm_device *dev); + void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */); +-bool skl_can_enable_sagv(struct drm_atomic_state *state); +-int skl_enable_sagv(struct drm_i915_private *dev_priv); +-int skl_disable_sagv(struct drm_i915_private *dev_priv); ++bool intel_can_enable_sagv(struct drm_atomic_state *state); ++int intel_enable_sagv(struct drm_i915_private *dev_priv); ++int intel_disable_sagv(struct drm_i915_private *dev_priv); + bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, + const struct skl_ddb_allocation *new, + enum pipe pipe); +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2890,12 +2890,12 @@ skl_wm_plane_id(const struct intel_plane + * - We're not using an interlaced display configuration + */ + int +-skl_enable_sagv(struct drm_i915_private *dev_priv) ++intel_enable_sagv(struct drm_i915_private *dev_priv) + { + int ret; + +- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || +- dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED) ++ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || ++ dev_priv->sagv_status == I915_SAGV_ENABLED) + return 0; + + DRM_DEBUG_KMS("Enabling the SAGV\n"); +@@ -2913,19 +2913,19 @@ skl_enable_sagv(struct drm_i915_private + */ + if (ret == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); +- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; ++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; + } else if (ret < 0) { + DRM_ERROR("Failed to enable the SAGV\n"); + return ret; + } + +- dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED; ++ dev_priv->sagv_status = I915_SAGV_ENABLED; + return 0; + } + + static int +-skl_do_sagv_disable(struct drm_i915_private *dev_priv) ++intel_do_sagv_disable(struct drm_i915_private *dev_priv) + { + int ret; + uint32_t temp = GEN9_SAGV_DISABLE; +@@ -2939,19 +2939,19 @@ skl_do_sagv_disable(struct drm_i915_priv + } + + int +-skl_disable_sagv(struct drm_i915_private *dev_priv) ++intel_disable_sagv(struct drm_i915_private *dev_priv) + { + int ret, result; + +- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || +- dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED) ++ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || ++ dev_priv->sagv_status == I915_SAGV_DISABLED) + return 0; + + DRM_DEBUG_KMS("Disabling the SAGV\n"); + mutex_lock(&dev_priv->rps.hw_lock); + + /* bspec says to keep retrying for at least 1 ms */ +- ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1); ++ ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1); + mutex_unlock(&dev_priv->rps.hw_lock); + + if (ret == -ETIMEDOUT) { +@@ -2965,18 +2965,18 @@ skl_disable_sagv(struct drm_i915_private + */ + if (result == -ENXIO) { + DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); +- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; ++ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; + return 0; + } else if (result < 0) { + DRM_ERROR("Failed to disable the SAGV\n"); + return result; + } + +- dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED; ++ dev_priv->sagv_status = I915_SAGV_DISABLED; + return 0; + } + +-bool skl_can_enable_sagv(struct drm_atomic_state *state) ++bool intel_can_enable_sagv(struct drm_atomic_state *state) + { + struct drm_device *dev = state->dev; + struct drm_i915_private *dev_priv = to_i915(dev); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch new file mode 100644 index 00000000..4f468af0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch @@ -0,0 +1,79 @@ +From ccebc23b57c313229526dc76383ce82f5e0b9001 Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Mon, 29 Aug 2016 12:31:27 -0400 +Subject: drm/i915/skl: Don't try to update plane watermarks if they haven't changed + +From: Lyude + +commit ccebc23b57c313229526dc76383ce82f5e0b9001 upstream. + +i915 sometimes needs to disable planes in the middle of an atomic +commit, and then reenable them later in the same commit. Because of +this, we can't make the assumption that the state of the plane actually +changed. Since the state of the plane hasn't actually changed, neither +have it's watermarks. And if the watermarks hasn't changed then we +haven't populated skl_results with anything, which means we'll end up +zeroing out a plane's watermarks in the middle of the atomic commit +without restoring them later. + +Simple reproduction recipe: + - Get a SKL laptop, launch any kind of X session + - Get two extra monitors + - Keep hotplugging both displays (so that the display configuration + jumps from 1 active pipe to 3 active pipes and back) + - Eventually underrun + +Changes since v1: + - Fix incorrect use of "it's" +Changes since v2: + - Add reproduction recipe + +Signed-off-by: Lyude +Cc: Maarten Lankhorst +Fixes: 62e0fb880123 ("drm/i915/skl: Update plane watermarks atomically during plane updates") +Signed-off-by: Lyude +Testcase: kms_plane +Signed-off-by: Maarten Lankhorst +Link: http://patchwork.freedesktop.org/patch/msgid/1472488288-27280-1-git-send-email-cpaul@redhat.com +Cc: drm-intel-fixes@lists.freedesktop.org +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/gpu/drm/i915/intel_display.c | 7 ++++++- + drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3068,7 +3068,12 @@ static void skylake_disable_primary_plan + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + +- skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); ++ /* ++ * We only populate skl_results on watermark updates, and if the ++ * plane's visiblity isn't actually changing neither is its watermarks. ++ */ ++ if (!to_intel_plane_state(crtc->primary->state)->visible) ++ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); + + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -314,6 +314,14 @@ skl_disable_plane(struct drm_plane *dpla + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + ++ /* ++ * We only populate skl_results on watermark updates, and if the ++ * plane's visiblity isn't actually changing neither is its watermarks. ++ */ ++ if (!to_intel_plane_state(dplane->state)->visible) ++ skl_write_plane_wm(to_intel_crtc(crtc), ++ &dev_priv->wm.skl_results, plane); ++ + I915_WRITE(PLANE_CTL(pipe, plane), 0); + + I915_WRITE(PLANE_SURF(pipe, plane), 0); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch new file mode 100644 index 00000000..58ac3c6a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch @@ -0,0 +1,43 @@ +From 05a76d3d6ad1ee9f9814f88949cc9305fc165460 Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Wed, 17 Aug 2016 15:55:57 -0400 +Subject: drm/i915/skl: Ensure pipes with changed wms get added to the state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lyude + +commit 05a76d3d6ad1ee9f9814f88949cc9305fc165460 upstream. + +If we're enabling a pipe, we'll need to modify the watermarks on all +active planes. Since those planes won't be added to the state on +their own, we need to add them ourselves. + +Signed-off-by: Lyude +Reviewed-by: Matt Roper +Cc: Ville Syrjälä +Cc: Daniel Vetter +Cc: Radhakrishna Sripada +Cc: Hans de Goede +Signed-off-by: Maarten Lankhorst +Link: http://patchwork.freedesktop.org/patch/msgid/1471463761-26796-6-git-send-email-cpaul@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4065,6 +4065,10 @@ skl_compute_ddb(struct drm_atomic_state + ret = skl_ddb_add_affected_planes(cstate); + if (ret) + return ret; ++ ++ ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); ++ if (ret) ++ return ret; + } + + return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch new file mode 100644 index 00000000..492d656f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch @@ -0,0 +1,479 @@ +From 27082493e9c6371b05370a619ab9d2877c5f4726 Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Wed, 24 Aug 2016 07:48:10 +0200 +Subject: drm/i915/skl: Update DDB values atomically with wms/plane attrs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lyude + +commit 27082493e9c6371b05370a619ab9d2877c5f4726 upstream. + +Now that we can hook into update_crtcs and control the order in which we +update CRTCs at each modeset, we can finish the final step of fixing +Skylake's watermark handling by performing DDB updates at the same time +as plane updates and watermark updates. + +The first major change in this patch is skl_update_crtcs(), which +handles ensuring that we order each CRTC update in our atomic commits +properly so that they honor the DDB flush order. + +The second major change in this patch is the order in which we flush the +pipes. While the previous order may have worked, it can't be used in +this approach since it no longer will do the right thing. For example, +using the old ddb flush order: + +We have pipes A, B, and C enabled, and we're disabling C. Initial ddb +allocation looks like this: + +| A | B |xxxxxxx| + +Since we're performing the ddb updates after performing any CRTC +disablements in intel_atomic_commit_tail(), the space to the right of +pipe B is unallocated. + +1. Flush pipes with new allocation contained into old space. None + apply, so we skip this +2. Flush pipes having their allocation reduced, but overlapping with a + previous allocation. None apply, so we also skip this +3. Flush pipes that got more space allocated. This applies to A and B, + giving us the following update order: A, B + +This is wrong, since updating pipe A first will cause it to overlap with +B and potentially burst into flames. Our new order (see the code +comments for details) would update the pipes in the proper order: B, A. + +As well, we calculate the order for each DDB update during the check +phase, and reference it later in the commit phase when we hit +skl_update_crtcs(). + +This long overdue patch fixes the rest of the underruns on Skylake. + +Changes since v1: + - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm() +Changes since v2: + - Use the method for updating CRTCs that Ville suggested + - In skl_update_wm(), only copy the watermarks for the crtc that was + passed to us +Changes since v3: + - Small comment fix in skl_ddb_allocation_overlaps() +Changes since v4: + - Remove the second loop in intel_update_crtcs() and use Ville's + suggestion for updating the ddb allocations in the right order + - Get rid of the second loop and just use the ddb state as it updates + to determine what order to update everything in (thanks for the + suggestion Ville) + - Simplify skl_ddb_allocation_overlaps() + - Split actual overlap checking into it's own helper + +Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration") +Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation") +[omitting CC for stable, since this patch will need to be changed for +such backports first] + +Testcase: kms_cursor_legacy +Testcase: plane-all-modeset-transition +Signed-off-by: Lyude +Cc: Ville Syrjälä +Cc: Daniel Vetter +Cc: Radhakrishna Sripada +Cc: Hans de Goede +Cc: Matt Roper +Signed-off-by: Maarten Lankhorst +Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 93 ++++++++++++++-- + drivers/gpu/drm/i915/intel_drv.h | 7 + + drivers/gpu/drm/i915/intel_pm.c | 200 +++++++---------------------------- + 3 files changed, 132 insertions(+), 168 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -12967,16 +12967,23 @@ static void verify_wm_state(struct drm_c + hw_entry->start, hw_entry->end); + } + +- /* cursor */ +- hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; +- sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; +- +- if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { +- DRM_ERROR("mismatch in DDB state pipe %c cursor " +- "(expected (%u,%u), found (%u,%u))\n", +- pipe_name(pipe), +- sw_entry->start, sw_entry->end, +- hw_entry->start, hw_entry->end); ++ /* ++ * cursor ++ * If the cursor plane isn't active, we may not have updated it's ddb ++ * allocation. In that case since the ddb allocation will be updated ++ * once the plane becomes visible, we can skip this check ++ */ ++ if (intel_crtc->cursor_addr) { ++ hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; ++ sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; ++ ++ if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { ++ DRM_ERROR("mismatch in DDB state pipe %c cursor " ++ "(expected (%u,%u), found (%u,%u))\n", ++ pipe_name(pipe), ++ sw_entry->start, sw_entry->end, ++ hw_entry->start, hw_entry->end); ++ } + } + } + +@@ -13728,6 +13735,65 @@ static void intel_update_crtcs(struct dr + } + } + ++static void skl_update_crtcs(struct drm_atomic_state *state, ++ unsigned int *crtc_vblank_mask) ++{ ++ struct drm_device *dev = state->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); ++ struct drm_crtc *crtc; ++ struct drm_crtc_state *old_crtc_state; ++ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; ++ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; ++ unsigned int updated = 0; ++ bool progress; ++ enum pipe pipe; ++ ++ /* ++ * Whenever the number of active pipes changes, we need to make sure we ++ * update the pipes in the right order so that their ddb allocations ++ * never overlap with eachother inbetween CRTC updates. Otherwise we'll ++ * cause pipe underruns and other bad stuff. ++ */ ++ do { ++ int i; ++ progress = false; ++ ++ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { ++ bool vbl_wait = false; ++ unsigned int cmask = drm_crtc_mask(crtc); ++ pipe = to_intel_crtc(crtc)->pipe; ++ ++ if (updated & cmask || !crtc->state->active) ++ continue; ++ if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb, ++ pipe)) ++ continue; ++ ++ updated |= cmask; ++ ++ /* ++ * If this is an already active pipe, it's DDB changed, ++ * and this isn't the last pipe that needs updating ++ * then we need to wait for a vblank to pass for the ++ * new ddb allocation to take effect. ++ */ ++ if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) && ++ !crtc->state->active_changed && ++ intel_state->wm_results.dirty_pipes != updated) ++ vbl_wait = true; ++ ++ intel_update_crtc(crtc, state, old_crtc_state, ++ crtc_vblank_mask); ++ ++ if (vbl_wait) ++ intel_wait_for_vblank(dev, pipe); ++ ++ progress = true; ++ } ++ } while (progress); ++} ++ + static void intel_atomic_commit_tail(struct drm_atomic_state *state) + { + struct drm_device *dev = state->dev; +@@ -15303,8 +15369,6 @@ void intel_init_display_hooks(struct drm + dev_priv->display.crtc_disable = i9xx_crtc_disable; + } + +- dev_priv->display.update_crtcs = intel_update_crtcs; +- + /* Returns the core display clock speed */ + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) + dev_priv->display.get_display_clock_speed = +@@ -15394,6 +15458,11 @@ void intel_init_display_hooks(struct drm + skl_modeset_calc_cdclk; + } + ++ if (dev_priv->info.gen >= 9) ++ dev_priv->display.update_crtcs = skl_update_crtcs; ++ else ++ dev_priv->display.update_crtcs = intel_update_crtcs; ++ + switch (INTEL_INFO(dev_priv)->gen) { + case 2: + dev_priv->display.queue_flip = intel_gen2_queue_flip; +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1720,6 +1720,13 @@ void skl_ddb_get_hw_state(struct drm_i91 + bool skl_can_enable_sagv(struct drm_atomic_state *state); + int skl_enable_sagv(struct drm_i915_private *dev_priv); + int skl_disable_sagv(struct drm_i915_private *dev_priv); ++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe); ++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, ++ const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe); + void skl_write_cursor_wm(struct intel_crtc *intel_crtc, + const struct skl_wm_values *wm); + void skl_write_plane_wm(struct intel_crtc *intel_crtc, +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3843,6 +3843,11 @@ void skl_write_plane_wm(struct intel_crt + wm->plane[pipe][plane][level]); + } + I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); ++ ++ skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane), ++ &wm->ddb.plane[pipe][plane]); ++ skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane), ++ &wm->ddb.y_plane[pipe][plane]); + } + + void skl_write_cursor_wm(struct intel_crtc *intel_crtc, +@@ -3859,170 +3864,46 @@ void skl_write_cursor_wm(struct intel_cr + wm->plane[pipe][PLANE_CURSOR][level]); + } + I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); +-} +- +-static void skl_write_wm_values(struct drm_i915_private *dev_priv, +- const struct skl_wm_values *new) +-{ +- struct drm_device *dev = &dev_priv->drm; +- struct intel_crtc *crtc; +- +- for_each_intel_crtc(dev, crtc) { +- int i; +- enum pipe pipe = crtc->pipe; +- +- if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) +- continue; +- if (!crtc->active) +- continue; +- +- for (i = 0; i < intel_num_planes(crtc); i++) { +- skl_ddb_entry_write(dev_priv, +- PLANE_BUF_CFG(pipe, i), +- &new->ddb.plane[pipe][i]); +- skl_ddb_entry_write(dev_priv, +- PLANE_NV12_BUF_CFG(pipe, i), +- &new->ddb.y_plane[pipe][i]); +- } + +- skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), +- &new->ddb.plane[pipe][PLANE_CURSOR]); +- } ++ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ++ &wm->ddb.plane[pipe][PLANE_CURSOR]); + } + +-/* +- * When setting up a new DDB allocation arrangement, we need to correctly +- * sequence the times at which the new allocations for the pipes are taken into +- * account or we'll have pipes fetching from space previously allocated to +- * another pipe. +- * +- * Roughly the sequence looks like: +- * 1. re-allocate the pipe(s) with the allocation being reduced and not +- * overlapping with a previous light-up pipe (another way to put it is: +- * pipes with their new allocation strickly included into their old ones). +- * 2. re-allocate the other pipes that get their allocation reduced +- * 3. allocate the pipes having their allocation increased +- * +- * Steps 1. and 2. are here to take care of the following case: +- * - Initially DDB looks like this: +- * | B | C | +- * - enable pipe A. +- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C +- * allocation +- * | A | B | C | +- * +- * We need to sequence the re-allocation: C, B, A (and not B, C, A). +- */ +- +-static void +-skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) ++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe) + { +- int plane; +- +- DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); +- +- for_each_plane(dev_priv, pipe, plane) { +- I915_WRITE(PLANE_SURF(pipe, plane), +- I915_READ(PLANE_SURF(pipe, plane))); +- } +- I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); ++ return new->pipe[pipe].start == old->pipe[pipe].start && ++ new->pipe[pipe].end == old->pipe[pipe].end; + } + +-static bool +-skl_ddb_allocation_included(const struct skl_ddb_allocation *old, +- const struct skl_ddb_allocation *new, +- enum pipe pipe) ++static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, ++ const struct skl_ddb_entry *b) + { +- uint16_t old_size, new_size; +- +- old_size = skl_ddb_entry_size(&old->pipe[pipe]); +- new_size = skl_ddb_entry_size(&new->pipe[pipe]); +- +- return old_size != new_size && +- new->pipe[pipe].start >= old->pipe[pipe].start && +- new->pipe[pipe].end <= old->pipe[pipe].end; ++ return a->start < b->end && b->start < a->end; + } + +-static void skl_flush_wm_values(struct drm_i915_private *dev_priv, +- struct skl_wm_values *new_values) ++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, ++ const struct skl_ddb_allocation *old, ++ const struct skl_ddb_allocation *new, ++ enum pipe pipe) + { +- struct drm_device *dev = &dev_priv->drm; +- struct skl_ddb_allocation *cur_ddb, *new_ddb; +- bool reallocated[I915_MAX_PIPES] = {}; +- struct intel_crtc *crtc; +- enum pipe pipe; +- +- new_ddb = &new_values->ddb; +- cur_ddb = &dev_priv->wm.skl_hw.ddb; +- +- /* +- * First pass: flush the pipes with the new allocation contained into +- * the old space. +- * +- * We'll wait for the vblank on those pipes to ensure we can safely +- * re-allocate the freed space without this pipe fetching from it. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; +- +- pipe = crtc->pipe; +- +- if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) +- continue; +- +- skl_wm_flush_pipe(dev_priv, pipe, 1); +- intel_wait_for_vblank(dev, pipe); +- +- reallocated[pipe] = true; +- } +- +- +- /* +- * Second pass: flush the pipes that are having their allocation +- * reduced, but overlapping with a previous allocation. +- * +- * Here as well we need to wait for the vblank to make sure the freed +- * space is not used anymore. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; ++ struct drm_device *dev = state->dev; ++ struct intel_crtc *intel_crtc; ++ enum pipe otherp; + +- pipe = crtc->pipe; ++ for_each_intel_crtc(dev, intel_crtc) { ++ otherp = intel_crtc->pipe; + +- if (reallocated[pipe]) ++ if (otherp == pipe) + continue; + +- if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < +- skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { +- skl_wm_flush_pipe(dev_priv, pipe, 2); +- intel_wait_for_vblank(dev, pipe); +- reallocated[pipe] = true; +- } ++ if (skl_ddb_entries_overlap(&new->pipe[pipe], ++ &old->pipe[otherp])) ++ return true; + } + +- /* +- * Third pass: flush the pipes that got more space allocated. +- * +- * We don't need to actively wait for the update here, next vblank +- * will just get more DDB space with the correct WM values. +- */ +- for_each_intel_crtc(dev, crtc) { +- if (!crtc->active) +- continue; +- +- pipe = crtc->pipe; +- +- /* +- * At this point, only the pipes more space than before are +- * left to re-allocate. +- */ +- if (reallocated[pipe]) +- continue; +- +- skl_wm_flush_pipe(dev_priv, pipe, 3); +- } ++ return false; + } + + static int skl_update_pipe_wm(struct drm_crtc_state *cstate, +@@ -4224,7 +4105,7 @@ static void skl_update_wm(struct drm_crt + struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); + struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; +- int pipe; ++ enum pipe pipe = intel_crtc->pipe; + + if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) + return; +@@ -4233,15 +4114,22 @@ static void skl_update_wm(struct drm_crt + + mutex_lock(&dev_priv->wm.wm_mutex); + +- skl_write_wm_values(dev_priv, results); +- skl_flush_wm_values(dev_priv, results); +- + /* +- * Store the new configuration (but only for the pipes that have +- * changed; the other values weren't recomputed). ++ * If this pipe isn't active already, we're going to be enabling it ++ * very soon. Since it's safe to update a pipe's ddb allocation while ++ * the pipe's shut off, just do so here. Already active pipes will have ++ * their watermarks updated once we update their planes. + */ +- for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) +- skl_copy_wm_for_pipe(hw_vals, results, pipe); ++ if (crtc->state->active_changed) { ++ int plane; ++ ++ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) ++ skl_write_plane_wm(intel_crtc, results, plane); ++ ++ skl_write_cursor_wm(intel_crtc, results); ++ } ++ ++ skl_copy_wm_for_pipe(hw_vals, results, pipe); + + mutex_unlock(&dev_priv->wm.wm_mutex); + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch new file mode 100644 index 00000000..d9798c44 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch @@ -0,0 +1,335 @@ +From 62e0fb880123c98793e5c3ba8355501b0305e92e Mon Sep 17 00:00:00 2001 +From: Lyude +Date: Mon, 22 Aug 2016 12:50:08 -0400 +Subject: drm/i915/skl: Update plane watermarks atomically during plane updates +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lyude + +commit 62e0fb880123c98793e5c3ba8355501b0305e92e upstream. + +Thanks to Ville for suggesting this as a potential solution to pipe +underruns on Skylake. + +On Skylake all of the registers for configuring planes, including the +registers for configuring their watermarks, are double buffered. New +values written to them won't take effect until said registers are +"armed", which is done by writing to the PLANE_SURF (or in the case of +cursor planes, the CURBASE register) register. + +With this in mind, up until now we've been updating watermarks on skl +like this: + + non-modeset { + - calculate (during atomic check phase) + - finish_atomic_commit: + - intel_pre_plane_update: + - intel_update_watermarks() + - {vblank happens; new watermarks + old plane values => underrun } + - drm_atomic_helper_commit_planes_on_crtc: + - start vblank evasion + - write new plane registers + - end vblank evasion + } + + or + + modeset { + - calculate (during atomic check phase) + - finish_atomic_commit: + - crtc_enable: + - intel_update_watermarks() + - {vblank happens; new watermarks + old plane values => underrun } + - drm_atomic_helper_commit_planes_on_crtc: + - start vblank evasion + - write new plane registers + - end vblank evasion + } + +Now we update watermarks atomically like this: + + non-modeset { + - calculate (during atomic check phase) + - finish_atomic_commit: + - intel_pre_plane_update: + - intel_update_watermarks() (wm values aren't written yet) + - drm_atomic_helper_commit_planes_on_crtc: + - start vblank evasion + - write new plane registers + - write new wm values + - end vblank evasion + } + + modeset { + - calculate (during atomic check phase) + - finish_atomic_commit: + - crtc_enable: + - intel_update_watermarks() (actual wm values aren't written + yet) + - drm_atomic_helper_commit_planes_on_crtc: + - start vblank evasion + - write new plane registers + - write new wm values + - end vblank evasion + } + +So this patch moves all of the watermark writes into the right place; +inside of the vblank evasion where we update all of the registers for +each plane. While this patch doesn't fix everything, it does allow us to +update the watermark values in the way the hardware expects us to. + +Changes since original patch series: + - Remove mutex_lock/mutex_unlock since they don't do anything and we're + not touching global state + - Move skl_write_cursor_wm/skl_write_plane_wm functions into + intel_pm.c, make externally visible + - Add skl_write_plane_wm calls to skl_update_plane + - Fix conditional for for loop in skl_write_plane_wm (level < max_level + should be level <= max_level) + - Make diagram in commit more accurate to what's actually happening + - Add Fixes: + +Changes since v1: + - Use IS_GEN9() instead of IS_SKYLAKE() since these fixes apply to more + then just Skylake + - Update description to make it clear this patch doesn't fix everything + - Check if pipes were actually changed before writing watermarks + +Changes since v2: + - Write PIPE_WM_LINETIME during vblank evasion + +Changes since v3: + - Rebase against new SAGV patch changes + +Changes since v4: + - Add a parameter to choose what skl_wm_values struct to use when + writing new plane watermarks + +Changes since v5: + - Remove cursor ddb entry write in skl_write_cursor_wm(), defer until + patch 6 + - Write WM_LINETIME in intel_begin_crtc_commit() + +Changes since v6: + - Remove redundant dirty_pipes check in skl_write_plane_wm (we check + this in all places where we call this function, and it was supposed + to have been removed earlier anyway) + - In i9xx_update_cursor(), use dev_priv->info.gen >= 9 instead of + IS_GEN9(dev_priv). We do this everywhere else and I'd imagine this + needs to be done for gen10 as well + +Changes since v7: + - Fix rebase fail (unused variable obj) + - Make struct skl_wm_values *wm const + - Fix indenting + - Use INTEL_GEN() instead of dev_priv->info.gen + +Changes since v8: + - Don't forget calls to skl_write_plane_wm() when disabling planes + - Use INTEL_GEN(), not INTEL_INFO()->gen in intel_begin_crtc_commit() + +Fixes: 2d41c0b59afc ("drm/i915/skl: SKL Watermark Computation") +Signed-off-by: Lyude +Reviewed-by: Matt Roper +Cc: stable@vger.kernel.org +Cc: Ville Syrjälä +Cc: Daniel Vetter +Cc: Radhakrishna Sripada +Cc: Hans de Goede +Signed-off-by: Maarten Lankhorst +Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com +Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++- + drivers/gpu/drm/i915/intel_drv.h | 5 +++ + drivers/gpu/drm/i915/intel_pm.c | 50 +++++++++++++++++++++++------------ + drivers/gpu/drm/i915/intel_sprite.c | 6 ++++ + 4 files changed, 64 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane + struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; + int pipe = intel_crtc->pipe; + u32 plane_ctl, stride_div, stride; + u32 tile_height, plane_offset, plane_size; +@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane + intel_crtc->adjusted_x = x_offset; + intel_crtc->adjusted_y = y_offset; + ++ if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) ++ skl_write_plane_wm(intel_crtc, wm, 0); ++ + I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); + I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset); + I915_WRITE(PLANE_SIZE(pipe, 0), plane_size); +@@ -3061,7 +3065,10 @@ static void skylake_disable_primary_plan + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); +- int pipe = to_intel_crtc(crtc)->pipe; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int pipe = intel_crtc->pipe; ++ ++ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); + + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); +@@ -10306,9 +10313,13 @@ static void i9xx_update_cursor(struct dr + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; + int pipe = intel_crtc->pipe; + uint32_t cntl = 0; + ++ if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc)) ++ skl_write_cursor_wm(intel_crtc, wm); ++ + if (plane_state && plane_state->visible) { + cntl = MCURSOR_GAMMA_ENABLE; + switch (plane_state->base.crtc_w) { +@@ -14221,10 +14232,12 @@ static void intel_begin_crtc_commit(stru + struct drm_crtc_state *old_crtc_state) + { + struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *old_intel_state = + to_intel_crtc_state(old_crtc_state); + bool modeset = needs_modeset(crtc->state); ++ enum pipe pipe = intel_crtc->pipe; + + /* Perform vblank evasion around commit operation */ + intel_pipe_update_start(intel_crtc); +@@ -14239,8 +14252,12 @@ static void intel_begin_crtc_commit(stru + + if (to_intel_crtc_state(crtc->state)->update_pipe) + intel_update_pipe_config(intel_crtc, old_intel_state); +- else if (INTEL_INFO(dev)->gen >= 9) ++ else if (INTEL_GEN(dev_priv) >= 9) { + skl_detach_scalers(intel_crtc); ++ ++ I915_WRITE(PIPE_WM_LINETIME(pipe), ++ dev_priv->wm.skl_hw.wm_linetime[pipe]); ++ } + } + + static void intel_finish_crtc_commit(struct drm_crtc *crtc, +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1720,6 +1720,11 @@ void skl_ddb_get_hw_state(struct drm_i91 + bool skl_can_enable_sagv(struct drm_atomic_state *state); + int skl_enable_sagv(struct drm_i915_private *dev_priv); + int skl_disable_sagv(struct drm_i915_private *dev_priv); ++void skl_write_cursor_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm); ++void skl_write_plane_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm, ++ int plane); + uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); + bool ilk_disable_lp_wm(struct drm_device *dev); + int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3828,6 +3828,39 @@ static void skl_ddb_entry_write(struct d + I915_WRITE(reg, 0); + } + ++void skl_write_plane_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm, ++ int plane) ++{ ++ struct drm_crtc *crtc = &intel_crtc->base; ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ int level, max_level = ilk_wm_max_level(dev); ++ enum pipe pipe = intel_crtc->pipe; ++ ++ for (level = 0; level <= max_level; level++) { ++ I915_WRITE(PLANE_WM(pipe, plane, level), ++ wm->plane[pipe][plane][level]); ++ } ++ I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); ++} ++ ++void skl_write_cursor_wm(struct intel_crtc *intel_crtc, ++ const struct skl_wm_values *wm) ++{ ++ struct drm_crtc *crtc = &intel_crtc->base; ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = to_i915(dev); ++ int level, max_level = ilk_wm_max_level(dev); ++ enum pipe pipe = intel_crtc->pipe; ++ ++ for (level = 0; level <= max_level; level++) { ++ I915_WRITE(CUR_WM(pipe, level), ++ wm->plane[pipe][PLANE_CURSOR][level]); ++ } ++ I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); ++} ++ + static void skl_write_wm_values(struct drm_i915_private *dev_priv, + const struct skl_wm_values *new) + { +@@ -3835,7 +3868,7 @@ static void skl_write_wm_values(struct d + struct intel_crtc *crtc; + + for_each_intel_crtc(dev, crtc) { +- int i, level, max_level = ilk_wm_max_level(dev); ++ int i; + enum pipe pipe = crtc->pipe; + + if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) +@@ -3843,21 +3876,6 @@ static void skl_write_wm_values(struct d + if (!crtc->active) + continue; + +- I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]); +- +- for (level = 0; level <= max_level; level++) { +- for (i = 0; i < intel_num_planes(crtc); i++) +- I915_WRITE(PLANE_WM(pipe, i, level), +- new->plane[pipe][i][level]); +- I915_WRITE(CUR_WM(pipe, level), +- new->plane[pipe][PLANE_CURSOR][level]); +- } +- for (i = 0; i < intel_num_planes(crtc); i++) +- I915_WRITE(PLANE_WM_TRANS(pipe, i), +- new->plane_trans[pipe][i]); +- I915_WRITE(CUR_WM_TRANS(pipe), +- new->plane_trans[pipe][PLANE_CURSOR]); +- + for (i = 0; i < intel_num_planes(crtc); i++) { + skl_ddb_entry_write(dev_priv, + PLANE_BUF_CFG(pipe, i), +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_p + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); ++ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; ++ struct drm_crtc *crtc = crtc_state->base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + u32 plane_ctl, stride_div, stride; +@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_p + crtc_w--; + crtc_h--; + ++ if (wm->dirty_pipes & drm_crtc_mask(crtc)) ++ skl_write_plane_wm(intel_crtc, wm, plane); ++ + if (key->flags) { + I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); + I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch new file mode 100644 index 00000000..53219119 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch @@ -0,0 +1,61 @@ +From ca5732c53bf66ad755284786897e0dd10330de87 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 3 Oct 2016 13:45:15 +0100 +Subject: drm/i915: Unalias obj->phys_handle and obj->userptr + +From: Chris Wilson + +commit ca5732c53bf66ad755284786897e0dd10330de87 upstream. + +We use obj->phys_handle to choose the pread/pwrite path, but as +obj->phys_handle is a union with obj->userptr, we then mistakenly use +the phys_handle path for userptr objects within pread/pwrite. + +Testcase: igt/gem_userptr_blits/forbidden-operations +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97519 +Signed-off-by: Chris Wilson +Reviewed-by: Joonas Lahtinen +Link: http://patchwork.freedesktop.org/patch/msgid/20161003124516.12388-2-chris@chris-wilson.co.uk +(cherry picked from commit 5f12b80a0b42da253691ca03828033014bb786eb) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.h | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2282,21 +2282,19 @@ struct drm_i915_gem_object { + /** Record of address bit 17 of each page at last unbind. */ + unsigned long *bit_17; + +- union { +- /** for phy allocated objects */ +- struct drm_dma_handle *phys_handle; +- +- struct i915_gem_userptr { +- uintptr_t ptr; +- unsigned read_only :1; +- unsigned workers :4; ++ struct i915_gem_userptr { ++ uintptr_t ptr; ++ unsigned read_only :1; ++ unsigned workers :4; + #define I915_GEM_USERPTR_MAX_WORKERS 15 + +- struct i915_mm_struct *mm; +- struct i915_mmu_object *mmu_object; +- struct work_struct *work; +- } userptr; +- }; ++ struct i915_mm_struct *mm; ++ struct i915_mmu_object *mmu_object; ++ struct work_struct *work; ++ } userptr; ++ ++ /** for phys allocated objects */ ++ struct drm_dma_handle *phys_handle; + }; + #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) + diff --git a/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch b/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch new file mode 100644 index 00000000..242e1f81 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch @@ -0,0 +1,78 @@ +From 56a76c0123d6cb034975901c80fce2627338ef9e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 5 Oct 2016 13:21:43 +0100 +Subject: drm/prime: Pass the right module owner through to dma_buf_export() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chris Wilson + +commit 56a76c0123d6cb034975901c80fce2627338ef9e upstream. + +dma_buf_export() adds a reference to the owning module to the dmabuf (to +prevent the driver from being unloaded whilst a third party still refers +to the dmabuf). However, drm_gem_prime_export() was passing its own +THIS_MODULE (i.e. drm.ko) rather than the driver. Extract the right +owner from the device->fops instead. + +v2: Use C99 initializers to zero out unset elements of +dma_buf_export_info +v3: Extract the right module from dev->fops. + +Testcase: igt/vgem_basic/unload +Reported-by: Petri Latvala +Signed-off-by: Chris Wilson +Cc: Petri Latvala +Cc: Christian König +Tested-by: Petri Latvala +Reviewed-by: Petri Latvala +Reviewed-by: Christian König +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/20161005122145.1507-1-chris@chris-wilson.co.uk +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_prime.c | 17 ++++++++++------- + include/drm/drmP.h | 3 ++- + 2 files changed, 12 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -335,14 +335,17 @@ static const struct dma_buf_ops drm_gem_ + * using the PRIME helpers. + */ + struct dma_buf *drm_gem_prime_export(struct drm_device *dev, +- struct drm_gem_object *obj, int flags) ++ struct drm_gem_object *obj, ++ int flags) + { +- DEFINE_DMA_BUF_EXPORT_INFO(exp_info); +- +- exp_info.ops = &drm_gem_prime_dmabuf_ops; +- exp_info.size = obj->size; +- exp_info.flags = flags; +- exp_info.priv = obj; ++ struct dma_buf_export_info exp_info = { ++ .exp_name = KBUILD_MODNAME, /* white lie for debug */ ++ .owner = dev->driver->fops->owner, ++ .ops = &drm_gem_prime_dmabuf_ops, ++ .size = obj->size, ++ .flags = flags, ++ .priv = obj, ++ }; + + if (dev->driver->gem_prime_res_obj) + exp_info.resv = dev->driver->gem_prime_res_obj(obj); +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -938,7 +938,8 @@ static inline int drm_debugfs_remove_fil + #endif + + extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, +- struct drm_gem_object *obj, int flags); ++ struct drm_gem_object *obj, ++ int flags); + extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, uint32_t flags, + int *prime_fd); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch new file mode 100644 index 00000000..aae96954 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch @@ -0,0 +1,48 @@ +From 02cfb5fccb0f9f968f0e208d89d9769aa16267bc Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 12 Oct 2016 15:28:55 -0400 +Subject: drm/radeon: change vblank_time's calculation method to reduce computational error. + +From: Alex Deucher + +commit 02cfb5fccb0f9f968f0e208d89d9769aa16267bc upstream. + +Ported from Rex's amdgpu change. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/r600_dpm.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/radeon/r600_dpm.c ++++ b/drivers/gpu/drm/radeon/r600_dpm.c +@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct rade + struct drm_device *dev = rdev->ddev; + struct drm_crtc *crtc; + struct radeon_crtc *radeon_crtc; +- u32 line_time_us, vblank_lines; ++ u32 vblank_in_pixels; + u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ + + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { +- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / +- radeon_crtc->hw_mode.clock; +- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - +- radeon_crtc->hw_mode.crtc_vdisplay + +- (radeon_crtc->v_border * 2); +- vblank_time_us = vblank_lines * line_time_us; ++ vblank_in_pixels = ++ radeon_crtc->hw_mode.crtc_htotal * ++ (radeon_crtc->hw_mode.crtc_vblank_end - ++ radeon_crtc->hw_mode.crtc_vdisplay + ++ (radeon_crtc->v_border * 2)); ++ ++ vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock; + break; + } + } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch new file mode 100644 index 00000000..0574fb0f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch @@ -0,0 +1,33 @@ +From 884031f0aacf57dad1575f96714efc80de9b19cc Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 19 Sep 2016 12:35:22 -0400 +Subject: drm/radeon: narrow asic_init for virtualization + +From: Alex Deucher + +commit 884031f0aacf57dad1575f96714efc80de9b19cc upstream. + +Only needed on CIK+ due to the way pci reset is handled +by the GPU. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_device.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -661,8 +661,9 @@ bool radeon_card_posted(struct radeon_de + { + uint32_t reg; + +- /* for pass through, always force asic_init */ +- if (radeon_device_is_virtual()) ++ /* for pass through, always force asic_init for CI */ ++ if (rdev->family >= CHIP_BONAIRE && ++ radeon_device_is_virtual()) + return false; + + /* required for EFI mode on macbook2,1 which uses an r5xx asic */ diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch new file mode 100644 index 00000000..26bc118e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch @@ -0,0 +1,40 @@ +From 427920292b00474d978d632bc03a8e4e50029af3 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 27 Sep 2016 14:51:53 -0400 +Subject: drm/radeon/si/dpm: fix phase shedding setup + +From: Alex Deucher + +commit 427920292b00474d978d632bc03a8e4e50029af3 upstream. + +Used the wrong index to setup the phase shedding mask. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/si_dpm.c | 2 +- + drivers/gpu/drm/radeon/sislands_smc.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -4112,7 +4112,7 @@ static int si_populate_smc_voltage_table + &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) { + si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table); + +- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = ++ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] = + cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low); + + si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay, +--- a/drivers/gpu/drm/radeon/sislands_smc.h ++++ b/drivers/gpu/drm/radeon/sislands_smc.h +@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISL + #define SISLANDS_SMC_VOLTAGEMASK_VDDC 0 + #define SISLANDS_SMC_VOLTAGEMASK_MVDD 1 + #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2 ++#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 + #define SISLANDS_SMC_VOLTAGEMASK_MAX 4 + + struct SISLANDS_SMC_VOLTAGEMASKTABLE diff --git a/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch b/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch new file mode 100644 index 00000000..a4734007 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch @@ -0,0 +1,225 @@ +From 7edabee06a5622190d59689a64f5e17d1c343cc3 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 27 Sep 2016 09:03:13 -0700 +Subject: drm/vc4: Fix races when the CS reads from render targets. + +From: Eric Anholt + +commit 7edabee06a5622190d59689a64f5e17d1c343cc3 upstream. + +With the introduction of bin/render pipelining, the previous job may +not be completed when we start binning the next one. If the previous +job wrote our VBO, IB, or CS textures, then the binning stage might +get stale or uninitialized results. + +Fixes the major rendering failure in glmark2 -b terrain. + +Signed-off-by: Eric Anholt +Fixes: ca26d28bbaa3 ("drm/vc4: improve throughput by pipelining binning and rendering jobs") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vc4/vc4_drv.h | 19 ++++++++++++++++++- + drivers/gpu/drm/vc4/vc4_gem.c | 13 +++++++++++++ + drivers/gpu/drm/vc4/vc4_render_cl.c | 21 +++++++++++++++++---- + drivers/gpu/drm/vc4/vc4_validate.c | 17 ++++++++++++++--- + 4 files changed, 62 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev) + struct vc4_bo { + struct drm_gem_cma_object base; + +- /* seqno of the last job to render to this BO. */ ++ /* seqno of the last job to render using this BO. */ + uint64_t seqno; + ++ /* seqno of the last job to use the RCL to write to this BO. ++ * ++ * Note that this doesn't include binner overflow memory ++ * writes. ++ */ ++ uint64_t write_seqno; ++ + /* List entry for the BO's position in either + * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list + */ +@@ -216,6 +223,9 @@ struct vc4_exec_info { + /* Sequence number for this bin/render job. */ + uint64_t seqno; + ++ /* Latest write_seqno of any BO that binning depends on. */ ++ uint64_t bin_dep_seqno; ++ + /* Last current addresses the hardware was processing when the + * hangcheck timer checked on us. + */ +@@ -230,6 +240,13 @@ struct vc4_exec_info { + struct drm_gem_cma_object **bo; + uint32_t bo_count; + ++ /* List of BOs that are being written by the RCL. Other than ++ * the binner temporary storage, this is all the BOs written ++ * by the job. ++ */ ++ struct drm_gem_cma_object *rcl_write_bo[4]; ++ uint32_t rcl_write_bo_count; ++ + /* Pointers for our position in vc4->job_list */ + struct list_head head; + +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_inf + list_for_each_entry(bo, &exec->unref_list, unref_head) { + bo->seqno = seqno; + } ++ ++ for (i = 0; i < exec->rcl_write_bo_count; i++) { ++ bo = to_vc4_bo(&exec->rcl_write_bo[i]->base); ++ bo->write_seqno = seqno; ++ } + } + + /* Queues a struct vc4_exec_info for execution. If no job is +@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, stru + goto fail; + + ret = vc4_validate_shader_recs(dev, exec); ++ if (ret) ++ goto fail; ++ ++ /* Block waiting on any previous rendering into the CS's VBO, ++ * IB, or textures, so that pixels are actually written by the ++ * time we try to read them. ++ */ ++ ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true); + + fail: + drm_free_large(temp); +--- a/drivers/gpu/drm/vc4/vc4_render_cl.c ++++ b/drivers/gpu/drm/vc4/vc4_render_cl.c +@@ -45,6 +45,8 @@ struct vc4_rcl_setup { + + struct drm_gem_cma_object *rcl; + u32 next_offset; ++ ++ u32 next_write_bo_index; + }; + + static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) +@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(st + if (!*obj) + return -EINVAL; + ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (surf->offset & 0xf) { + DRM_ERROR("MSAA write must be 16b aligned.\n"); + return -EINVAL; +@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(st + + static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, + struct drm_gem_cma_object **obj, +- struct drm_vc4_submit_rcl_surface *surf) ++ struct drm_vc4_submit_rcl_surface *surf, ++ bool is_write) + { + uint8_t tiling = VC4_GET_FIELD(surf->bits, + VC4_LOADSTORE_TILE_BUFFER_TILING); +@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct + if (!*obj) + return -EINVAL; + ++ if (is_write) ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { + if (surf == &exec->args->zs_write) { + DRM_ERROR("general zs write may not be a full-res.\n"); +@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(stru + if (!*obj) + return -EINVAL; + ++ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; ++ + if (tiling > VC4_TILING_FORMAT_LT) { + DRM_ERROR("Bad tiling format\n"); + return -EINVAL; +@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); ++ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read, ++ false); + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); ++ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read, ++ false); + if (ret) + return ret; + +- ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); ++ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write, ++ true); + if (ret) + return ret; + +--- a/drivers/gpu/drm/vc4/vc4_validate.c ++++ b/drivers/gpu/drm/vc4/vc4_validate.c +@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS + if (!ib) + return -EINVAL; + ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&ib->base)->write_seqno); ++ + if (offset > ib->base.size || + (ib->base.size - offset) / index_size < length) { + DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", +@@ -555,8 +558,7 @@ static bool + reloc_tex(struct vc4_exec_info *exec, + void *uniform_data_u, + struct vc4_texture_sample_info *sample, +- uint32_t texture_handle_index) +- ++ uint32_t texture_handle_index, bool is_cs) + { + struct drm_gem_cma_object *tex; + uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); +@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec, + + *validated_p0 = tex->paddr + p0; + ++ if (is_cs) { ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&tex->base)->write_seqno); ++ } ++ + return true; + fail: + DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); +@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device + if (!reloc_tex(exec, + uniform_data_u, + &validated_shader->texture_samples[tex], +- texture_handles_u[tex])) { ++ texture_handles_u[tex], ++ i == 2)) { + return -EINVAL; + } + } +@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device + uint32_t stride = *(uint8_t *)(pkt_u + o + 5); + uint32_t max_index; + ++ exec->bin_dep_seqno = max(exec->bin_dep_seqno, ++ to_vc4_bo(&vbo->base)->write_seqno); ++ + if (state->addr & 0x8) + stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; + diff --git a/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch b/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch new file mode 100644 index 00000000..c3ae1473 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch @@ -0,0 +1,42 @@ +From 51ab70bed997f64f091a639dbe22b629725a7faf Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Mon, 10 Oct 2016 10:51:24 -0700 +Subject: drm/vmwgfx: Limit the user-space command buffer size + +From: Thomas Hellstrom + +commit 51ab70bed997f64f091a639dbe22b629725a7faf upstream. + +With older hardware versions, the user could specify arbitrarily large +command buffer sizes, causing a vmalloc / vmap space exhaustion. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Brian Paul +Reviewed-by: Sinclair Yeh +Signed-off-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -3848,14 +3848,14 @@ static void *vmw_execbuf_cmdbuf(struct v + int ret; + + *header = NULL; +- if (!dev_priv->cman || kernel_commands) +- return kernel_commands; +- + if (command_size > SVGA_CB_MAX_SIZE) { + DRM_ERROR("Command buffer is too large.\n"); + return ERR_PTR(-EINVAL); + } + ++ if (!dev_priv->cman || kernel_commands) ++ return kernel_commands; ++ + /* If possible, add a little space for fencing. */ + cmdbuf_size = command_size + 512; + cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE); diff --git a/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch b/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch new file mode 100644 index 00000000..9505a731 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch @@ -0,0 +1,68 @@ +From ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 Mon Sep 17 00:00:00 2001 +From: Sebastian Frias +Date: Mon, 1 Aug 2016 16:27:38 +0200 +Subject: genirq/generic_chip: Add irq_unmap callback + +From: Sebastian Frias + +commit ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 upstream. + +Without this patch irq_domain_disassociate() cannot properly release the +interrupt. In fact, irq_map_generic_chip() checks a bit on 'gc->installed' +but said bit is never cleared, only set. + +Commit 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support") +added irq_map_generic_chip() function and also stated "This lacks a removal +function for now". + +This commit provides an implementation of an unmap function that can be +called by irq_domain_disassociate(). + +[ tglx: Made the function static and removed the export as we have neither + a prototype nor a modular user. ] + +Fixes: 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support") +Signed-off-by: Sebastian Frias +Cc: Marc Zyngier +Cc: Mason +Cc: Jason Cooper +Link: http://lkml.kernel.org/r/579F5C5A.2070507@laposte.net +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/irq/generic-chip.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/kernel/irq/generic-chip.c ++++ b/kernel/irq/generic-chip.c +@@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_doma + } + EXPORT_SYMBOL_GPL(irq_map_generic_chip); + ++static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq) ++{ ++ struct irq_data *data = irq_domain_get_irq_data(d, virq); ++ struct irq_domain_chip_generic *dgc = d->gc; ++ unsigned int hw_irq = data->hwirq; ++ struct irq_chip_generic *gc; ++ int irq_idx; ++ ++ gc = irq_get_domain_generic_chip(d, hw_irq); ++ if (!gc) ++ return; ++ ++ irq_idx = hw_irq % dgc->irqs_per_chip; ++ ++ clear_bit(irq_idx, &gc->installed); ++ irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL, ++ NULL); ++ ++} ++ + struct irq_domain_ops irq_generic_chip_ops = { + .map = irq_map_generic_chip, ++ .unmap = irq_unmap_generic_chip, + .xlate = irq_domain_xlate_onetwocell, + }; + EXPORT_SYMBOL_GPL(irq_generic_chip_ops); diff --git a/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch b/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch new file mode 100644 index 00000000..487050c3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch @@ -0,0 +1,50 @@ +From 4973ca9a01e2354b159acedec1b9b8eb8de02ab7 Mon Sep 17 00:00:00 2001 +From: "Steinar H. Gunderson" +Date: Sun, 9 Oct 2016 14:21:50 +0200 +Subject: HID: add quirk for Akai MIDImix. + +From: Steinar H. Gunderson + +commit 4973ca9a01e2354b159acedec1b9b8eb8de02ab7 upstream. + +The Akai MIDImix (09e8:0031) is a MIDI fader controller that speaks +regular MIDI and works well with Linux. However, initialization gets +delayed due to reports timeout: + + [3643645.631124] hid-generic 0003:09E8:0031.0020: timeout initializing reports + [3643645.632416] hid-generic 0003:09E8:0031.0020: hiddev0: USB HID v1.11 Device [AKAI MIDI Mix] on usb-0000:00:14.0-2/input0 + +Adding "usbhid.quirks=0x09e8:0x0031:0x20000000" on the kernel +command line makes the issues go away. + +Signed-off-by: Steinar H. Gunderson +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-ids.h | 3 +++ + drivers/hid/usbhid/hid-quirks.c | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -64,6 +64,9 @@ + #define USB_VENDOR_ID_AKAI 0x2011 + #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 + ++#define USB_VENDOR_ID_AKAI_09E8 0x09E8 ++#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031 ++ + #define USB_VENDOR_ID_ALCOR 0x058f + #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 + +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -56,6 +56,7 @@ static const struct hid_blacklist { + + { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, ++ { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, diff --git a/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch b/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch new file mode 100644 index 00000000..0b54b3d5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch @@ -0,0 +1,44 @@ +From ad8529fde9e3601180a839867a8ab041109aebb5 Mon Sep 17 00:00:00 2001 +From: Dave Gerlach +Date: Tue, 20 Sep 2016 10:25:40 -0500 +Subject: hwrng: omap - Only fail if pm_runtime_get_sync returns < 0 + +From: Dave Gerlach + +commit ad8529fde9e3601180a839867a8ab041109aebb5 upstream. + +Currently omap-rng checks the return value of pm_runtime_get_sync and +reports failure if anything is returned, however it should be checking +if ret < 0 as pm_runtime_get_sync return 0 on success but also can return +1 if the device was already active which is not a failure case. Only +values < 0 are actual failures. + +Fixes: 61dc0a446e5d ("hwrng: omap - Fix assumption that runtime_get_sync will always succeed") +Signed-off-by: Dave Gerlach +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/hw_random/omap-rng.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/char/hw_random/omap-rng.c ++++ b/drivers/char/hw_random/omap-rng.c +@@ -385,7 +385,7 @@ static int omap_rng_probe(struct platfor + + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); +- if (ret) { ++ if (ret < 0) { + dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(&pdev->dev); + goto err_ioremap; +@@ -443,7 +443,7 @@ static int __maybe_unused omap_rng_resum + int ret; + + ret = pm_runtime_get_sync(dev); +- if (ret) { ++ if (ret < 0) { + dev_err(dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(dev); + return ret; diff --git a/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch b/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch new file mode 100644 index 00000000..d74fe900 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch @@ -0,0 +1,155 @@ +From 776b2e15f8af7900409456292efd45af6de97172 Mon Sep 17 00:00:00 2001 +From: Jacob Keller +Date: Tue, 19 Jul 2016 16:23:30 -0700 +Subject: i40e: fix broken i40e_config_rss_aq function + +From: Jacob Keller + +commit 776b2e15f8af7900409456292efd45af6de97172 upstream. + +X722 hardware requires using the admin queue to configure RSS. This +function was previously re-written in commit e69ff813af35 ("i40e: rework +the functions to configure RSS with similar parameters"). +However, the previous refactor did not work correctly for a few reasons + +(a) it does not check whether seed is NULL before using it, resulting in +a NULL pointer dereference + +[ 402.954721] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 402.955568] IP: [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] +[ 402.956402] PGD ad610067 PUD accc0067 PMD 0 +[ 402.957235] Oops: 0000 [#1] SMP +[ 402.958064] Modules linked in: ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_filter ebtable_ +broute bridge stp llc ebtable_nat ebtables ip6table_mangle ip6table_raw ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv +6 ip6table_security ip6table_filter ip6_tables iptable_mangle iptable_raw iptable_nat nf_conntrack_ipv4_ nf_defrag_ipv4_ nf_nat_ip +v4_ nf_nat nf_conntrack iptable_security intel_rapl i86_kg_temp_thermal coretemp kvm_intel kvm irqbypass crct10dif_clMl crc32_ +pclMl ghash_clMlni_intel iTCO_wdt iTCO_vendor_support shpchp sb_edac dcdbas pcspkr joydev ipmi_devintf wmi edac_core ipmi_ssif + acpi_ad acpi_ower_meter ipmi_si ipmi_msghandler mei_me nfsd lpc_ich mei ioatdma tpm_tis auth_rpcgss tpm nfs_acl lockd grace s +unrpc ifs nngag200 i2c_algo_bit drm_kms_helper ttm drm iigbe bnx2x i40e dca mdio ptp pps_core libcrc32c fjes crc32c_intel +[ 402.965563] CPU: 22 PID: 2461 Conm: ethtool Not tainted 4.6.0-rc7_1.2-ABNidQ+ #20 +[ 402.966719] Hardware name: Dell Inc. PowerEdge R720/0C4Y3R, BIOS 2.5.2 01/28/2015 +[ 402.967862] task: ffff880219b51dc0 ti: ffff8800b3408000 task.ti: ffff8800b3408000 +[ 402.969046] RIP: 0010:[] [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] +[ 402.970339] RSP: 0018:ffff8800b340ba90 EFLAGS: 00010246 +[ 402.971616] RAX: 0000000000000000 RBX: ffff88042ec14000 RCX: 0000000000000200 +[ 402.972961] RDX: ffff880428eb9200 RSI: 0000000000000000 RDI: ffff88042ec14000 +[ 402.974312] RBP: ffff8800b340baf8 R08: ffff880237ada8f0 R09: ffff880428eb9200 +[ 402.975709] R10: ffff880428eb9200 R11: 0000000000000000 R12: ffff88042ec2e000 +[ 402.977104] R13: ffff88042ec2e000 R14: ffff88042ec14000 R15: ffff88022ea00800 +[ 402.978541] FS: 00007f84fd054700(0000) GS:ffff880237ac0000(0000) knlGS:0000000000000000 +[ 402.980003] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 402.981508] CR2: 0000000000000000 CR3: 000000003289e000 CR4: 00000000000406e0 +[ 402.983028] Stack: +[ 402.984578] 0000000002000200 0000000000000000 ffff88023ffeda68 ffff88023ffef000 +[ 402.986187] 0000000000000268 ffff8800b340bbf8 ffff88023ffedd80 0000000088ce4f1d +[ 402.987844] ffff88042ec14000 ffff88022ea00800 ffff88042ec2e000 ffff88042ec14000 +[ 402.989509] Call Trace: +[ 402.991200] [] i40e_config_rss+0x11f/0x1c0 [i40e] +[ 402.992924] [] i40e_set_rifh+0ic0/0x130 [i40e] +[ 402.994684] [] ethtool_set_rifh+0x1f7/0x300 +[ 402.996446] [] ? cred_has_capability+0io6b/0x100 +[ 402.998203] [] ? selinux_capable+0x12/0x20 +[ 402.999968] [] ? security_capable+0x4b/0x70 +[ 403.001707] [] dev_ethtool+0x1423/0x2290 +[ 403.003461] [] dev_ioctl+0x191/0io630 +[ 403.005186] [] ? lru_cache_add+0x3a/0i80 +[ 403.006942] [] ? _raw_spin_unlock+0ie/0x20 +[ 403.008691] [] sock_do_ioctl+0x45/0i50 +[ 403.010421] [] sock_ioctl+0x209/0x2d0 +[ 403.012173] [] do_vfs_ioctl+0u4/0io6c0 +[ 403.013911] [] SyS_ioctl+0x79/0x90 +[ 403.015710] [] entry_SYSCALL_64_fastpath+0x1a/0u4 +[ 403.017500] Code: 90 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 89 fb 48 83 ec 40 4c 8b a7 e0 05 00 00 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 <48> 8b 06 41 0f b7 bc 24 f2 0f 00 00 48 89 45 9c 48 8b 46 08 48 +[ 403.021454] RIP [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] +[ 403.023395] RSP +[ 403.025271] CR2: 0000000000000000 +[ 403.027169] ---[ end trace 64561b528cf61cf0 ]--- + +(b) it does not even bother to use the passed in *lut parameter which +defines the requested lookup table. Instead it uses its own round robin +table. + +Fix these issues by re-writing it to be similar to i40e_config_rss_reg +and i40e_get_rss_aq. + +Fixes: e69ff813af35 ("i40e: rework the functions to configure RSS with similar parameters", 2015-10-21) +Signed-off-by: Jacob Keller +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 57 +++++++++++----------------- + 1 file changed, 23 insertions(+), 34 deletions(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -7990,45 +7990,34 @@ static int i40e_setup_misc_vector(struct + static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, + u8 *lut, u16 lut_size) + { +- struct i40e_aqc_get_set_rss_key_data rss_key; + struct i40e_pf *pf = vsi->back; + struct i40e_hw *hw = &pf->hw; +- bool pf_lut = false; +- u8 *rss_lut; +- int ret, i; ++ int ret = 0; + +- memcpy(&rss_key, seed, sizeof(rss_key)); +- +- rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL); +- if (!rss_lut) +- return -ENOMEM; +- +- /* Populate the LUT with max no. of queues in round robin fashion */ +- for (i = 0; i < vsi->rss_table_size; i++) +- rss_lut[i] = i % vsi->rss_size; +- +- ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key); +- if (ret) { +- dev_info(&pf->pdev->dev, +- "Cannot set RSS key, err %s aq_err %s\n", +- i40e_stat_str(&pf->hw, ret), +- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); +- goto config_rss_aq_out; ++ if (seed) { ++ struct i40e_aqc_get_set_rss_key_data *seed_dw = ++ (struct i40e_aqc_get_set_rss_key_data *)seed; ++ ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw); ++ if (ret) { ++ dev_info(&pf->pdev->dev, ++ "Cannot set RSS key, err %s aq_err %s\n", ++ i40e_stat_str(hw, ret), ++ i40e_aq_str(hw, hw->aq.asq_last_status)); ++ return ret; ++ } + } ++ if (lut) { ++ bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false; + +- if (vsi->type == I40E_VSI_MAIN) +- pf_lut = true; +- +- ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut, +- vsi->rss_table_size); +- if (ret) +- dev_info(&pf->pdev->dev, +- "Cannot set RSS lut, err %s aq_err %s\n", +- i40e_stat_str(&pf->hw, ret), +- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); +- +-config_rss_aq_out: +- kfree(rss_lut); ++ ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size); ++ if (ret) { ++ dev_info(&pf->pdev->dev, ++ "Cannot set RSS lut, err %s aq_err %s\n", ++ i40e_stat_str(hw, ret), ++ i40e_aq_str(hw, hw->aq.asq_last_status)); ++ return ret; ++ } ++ } + return ret; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch b/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch new file mode 100644 index 00000000..045b5d78 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch @@ -0,0 +1,32 @@ +From be0cb0a66a1d426f7cd9b170c008725044ae147a Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 3 Aug 2016 22:01:07 +0300 +Subject: i40e: remove a stray unlock + +From: Dan Carpenter + +commit be0cb0a66a1d426f7cd9b170c008725044ae147a upstream. + +We shifted the locking around a bit but forgot to delete this unlock so +now it can unlock twice. + +Fixes: cd3be169a5ff ('i40e: Move the mutex lock in i40e_client_unregister') +Signed-off-by: Dan Carpenter +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/i40e/i40e_client.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_client.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c +@@ -1009,7 +1009,6 @@ int i40e_unregister_client(struct i40e_c + if (!i40e_client_is_registered(client)) { + pr_info("i40e: Client %s has not been registered\n", + client->name); +- mutex_unlock(&i40e_client_mutex); + ret = -ENODEV; + goto out; + } diff --git a/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch b/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch new file mode 100644 index 00000000..f2d43851 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch @@ -0,0 +1,55 @@ +From 5a648dfad033bf5f945795c4e56ee7577f24f3e9 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 6 Sep 2016 04:36:53 -0700 +Subject: IB/hfi1: Move iowait_init() to priv allocate + +From: Mike Marciniszyn + +commit 5a648dfad033bf5f945795c4e56ee7577f24f3e9 upstream. + +The call is misplaced in the reset calldown function +and causes issues with lockdep assertions that are to +be added. + +Fixes: Commit a2c2d608957c ("staging/rdma/hfi1: Remove create_qp functionality") +Reviewed-by: Ira Weiny +Reviewed-by: Dennis Dalessandro +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/qp.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/infiniband/hw/hfi1/qp.c ++++ b/drivers/infiniband/hw/hfi1/qp.c +@@ -808,6 +808,13 @@ void *qp_priv_alloc(struct rvt_dev_info + kfree(priv); + return ERR_PTR(-ENOMEM); + } ++ iowait_init( ++ &priv->s_iowait, ++ 1, ++ _hfi1_do_send, ++ iowait_sleep, ++ iowait_wakeup, ++ iowait_sdma_drained); + setup_timer(&priv->s_rnr_timer, hfi1_rc_rnr_retry, (unsigned long)qp); + qp->s_timer.function = hfi1_rc_timeout; + return priv; +@@ -873,13 +880,6 @@ void notify_qp_reset(struct rvt_qp *qp) + { + struct hfi1_qp_priv *priv = qp->priv; + +- iowait_init( +- &priv->s_iowait, +- 1, +- _hfi1_do_send, +- iowait_sleep, +- iowait_wakeup, +- iowait_sdma_drained); + priv->r_adefered = 0; + clear_ahg(qp); + } diff --git a/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch b/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch new file mode 100644 index 00000000..5ef7c7a4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch @@ -0,0 +1,31 @@ +From 7055a29471eebf4b62687944694222635ed44b09 Mon Sep 17 00:00:00 2001 +From: Maor Gottlieb +Date: Sun, 28 Aug 2016 14:16:30 +0300 +Subject: IB/mlx5: Fix steering resource leak + +From: Maor Gottlieb + +commit 7055a29471eebf4b62687944694222635ed44b09 upstream. + +Fix multicast flow rule leak on adding unicast rule failure. + +Fixes: 038d2ef87572 ('IB/mlx5: Add flow steering support') +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -1843,6 +1843,7 @@ static struct mlx5_ib_flow_handler *crea + &leftovers_specs[LEFTOVERS_UC].flow_attr, + dst); + if (IS_ERR(handler_ucast)) { ++ mlx5_del_flow_rule(handler->rule); + kfree(handler); + handler = handler_ucast; + } else { diff --git a/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch b/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch new file mode 100644 index 00000000..9ecc8063 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch @@ -0,0 +1,89 @@ +From 84b3adc2430eafd2eb703570075c3c141ea0ff13 Mon Sep 17 00:00:00 2001 +From: Dennis Dalessandro +Date: Sun, 25 Sep 2016 07:41:05 -0700 +Subject: IB/qib: Remove qpt_mask global + +From: Dennis Dalessandro + +commit 84b3adc2430eafd2eb703570075c3c141ea0ff13 upstream. + +There is no need to have a global qpt_mask as that does not support the +multiple chip model which qib has. Instead rely on the value which +exists already in the device data (dd). + +Fixes: 898fa52b4ac3 "IB/qib: Remove qpn, qp tables and related variables from qib" +Reviewed-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib.h | 1 - + drivers/infiniband/hw/qib/qib_qp.c | 13 +++---------- + drivers/infiniband/hw/qib/qib_verbs.c | 2 -- + 3 files changed, 3 insertions(+), 13 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib.h ++++ b/drivers/infiniband/hw/qib/qib.h +@@ -1131,7 +1131,6 @@ extern spinlock_t qib_devs_lock; + extern struct qib_devdata *qib_lookup(int unit); + extern u32 qib_cpulist_count; + extern unsigned long *qib_cpulist; +-extern u16 qpt_mask; + extern unsigned qib_cc_table_size; + + int qib_init(struct qib_devdata *, int); +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -41,14 +41,6 @@ + + #include "qib.h" + +-/* +- * mask field which was present in now deleted qib_qpn_table +- * is not present in rvt_qpn_table. Defining the same field +- * as qpt_mask here instead of adding the mask field to +- * rvt_qpn_table. +- */ +-u16 qpt_mask; +- + static inline unsigned mk_qpn(struct rvt_qpn_table *qpt, + struct rvt_qpn_map *map, unsigned off) + { +@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt + + static inline unsigned find_next_offset(struct rvt_qpn_table *qpt, + struct rvt_qpn_map *map, unsigned off, +- unsigned n) ++ unsigned n, u16 qpt_mask) + { + if (qpt_mask) { + off++; +@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r + struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi); + struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata, + verbs_dev); ++ u16 qpt_mask = dd->qpn_mask; + + if (type == IB_QPT_SMI || type == IB_QPT_GSI) { + unsigned n; +@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r + goto bail; + } + offset = find_next_offset(qpt, map, offset, +- dd->n_krcv_queues); ++ dd->n_krcv_queues, qpt_mask); + qpn = mk_qpn(qpt, map, offset); + /* + * This test differs from alloc_pidmap(). +--- a/drivers/infiniband/hw/qib/qib_verbs.c ++++ b/drivers/infiniband/hw/qib/qib_verbs.c +@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_de + /* Only need to initialize non-zero fields. */ + setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev); + +- qpt_mask = dd->qpn_mask; +- + INIT_LIST_HEAD(&dev->piowait); + INIT_LIST_HEAD(&dev->dmawait); + INIT_LIST_HEAD(&dev->txwait); diff --git a/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch b/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch new file mode 100644 index 00000000..cb694653 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch @@ -0,0 +1,44 @@ +From eefa1d8961584c5b76afded94960ca4344bc638b Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 6 Sep 2016 04:36:33 -0700 +Subject: IB/rdmavt: Correct sparse annotation + +From: Mike Marciniszyn + +commit eefa1d8961584c5b76afded94960ca4344bc638b upstream. + +The __must_hold() is sufficent to correct the sparse +context imbalance inside a function. + +Per Documentation/sparse.txt: +__must_hold - The specified lock is held on function entry and exit. + +Fixes: Commit c0a67f6ba356 ("IB/rdmavt: Annotate rvt_reset_qp()") +Reviewed-by: Dennis Dalessandro +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rdmavt/qp.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/infiniband/sw/rdmavt/qp.c ++++ b/drivers/infiniband/sw/rdmavt/qp.c +@@ -501,12 +501,9 @@ static void rvt_remove_qp(struct rvt_dev + */ + static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type) +- __releases(&qp->s_lock) +- __releases(&qp->s_hlock) +- __releases(&qp->r_lock) +- __acquires(&qp->r_lock) +- __acquires(&qp->s_hlock) +- __acquires(&qp->s_lock) ++ __must_hold(&qp->r_lock) ++ __must_hold(&qp->s_hlock) ++ __must_hold(&qp->s_lock) + { + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; diff --git a/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch b/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch new file mode 100644 index 00000000..039a4f3a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch @@ -0,0 +1,35 @@ +From 9d47964bfd471f0dd4c89f28556aec68bffa0020 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 25 Jul 2016 23:40:01 +0100 +Subject: iio: ad5755: fix off-by-one on devnr limit check + +From: Colin Ian King + +commit 9d47964bfd471f0dd4c89f28556aec68bffa0020 upstream. + +The comparison for devnr limits is off-by-one, the current check +allows 0 to AD5755_NUM_CHANNELS and the limit should be in fact +0 to AD5755_NUM_CHANNELS - 1. This can lead to an out of bounds +write to pdata->dac[devnr]. Fix this by replacing > with >= on the +comparison. + +Signed-off-by: Colin Ian King +Fixes: c947459979c6 ("iio: ad5755: add support for dt bindings") +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/dac/ad5755.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/dac/ad5755.c ++++ b/drivers/iio/dac/ad5755.c +@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad57 + + devnr = 0; + for_each_child_of_node(np, pp) { +- if (devnr > AD5755_NUM_CHANNELS) { ++ if (devnr >= AD5755_NUM_CHANNELS) { + dev_err(dev, + "There is to many channels defined in DT\n"); + goto error_out; diff --git a/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch b/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch new file mode 100644 index 00000000..1187350f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch @@ -0,0 +1,33 @@ +From 281269f8a0b00f5c95de5158e8595ed51bdb4b0a Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Wed, 10 Aug 2016 07:18:16 +0200 +Subject: iio: light: us5182d: Add missing error code assignment before test + +From: Christophe JAILLET + +commit 281269f8a0b00f5c95de5158e8595ed51bdb4b0a upstream. + +It is likely that checking the result of 'pm_runtime_set_active' is +expected here. + +Fixes: f0e5f57d3ac2 ("iio: light: us8152d: Add power management support") + +Signed-off-by: Christophe JAILLET +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/light/us5182d.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/light/us5182d.c ++++ b/drivers/iio/light/us5182d.c +@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_clie + goto out_err; + + if (data->default_continuous) { +- pm_runtime_set_active(&client->dev); ++ ret = pm_runtime_set_active(&client->dev); + if (ret < 0) + goto out_err; + } diff --git a/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch b/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch new file mode 100644 index 00000000..b2dff957 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch @@ -0,0 +1,140 @@ +From 082d5b6b60e9f25e1511557fcfcb21eedd267446 Mon Sep 17 00:00:00 2001 +From: Gerald Schaefer +Date: Fri, 7 Oct 2016 17:01:10 -0700 +Subject: mm/hugetlb: check for reserved hugepages during memory offline + +From: Gerald Schaefer + +commit 082d5b6b60e9f25e1511557fcfcb21eedd267446 upstream. + +In dissolve_free_huge_pages(), free hugepages will be dissolved without +making sure that there are enough of them left to satisfy hugepage +reservations. + +Fix this by adding a return value to dissolve_free_huge_pages() and +checking h->free_huge_pages vs. h->resv_huge_pages. Note that this may +lead to the situation where dissolve_free_huge_page() returns an error +and all free hugepages that were dissolved before that error are lost, +while the memory block still cannot be set offline. + +Fixes: c8721bbb ("mm: memory-hotplug: enable memory hotplug to handle hugepage") +Link: http://lkml.kernel.org/r/20160926172811.94033-3-gerald.schaefer@de.ibm.com +Signed-off-by: Gerald Schaefer +Acked-by: Michal Hocko +Acked-by: Naoya Horiguchi +Cc: "Kirill A . Shutemov" +Cc: Vlastimil Babka +Cc: Mike Kravetz +Cc: "Aneesh Kumar K . V" +Cc: Martin Schwidefsky +Cc: Heiko Carstens +Cc: Rui Teng +Cc: Dave Hansen +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/hugetlb.h | 6 +++--- + mm/hugetlb.c | 26 +++++++++++++++++++++----- + mm/memory_hotplug.c | 4 +++- + 3 files changed, 27 insertions(+), 9 deletions(-) + +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -450,8 +450,8 @@ static inline pgoff_t basepage_index(str + return __basepage_index(page); + } + +-extern void dissolve_free_huge_pages(unsigned long start_pfn, +- unsigned long end_pfn); ++extern int dissolve_free_huge_pages(unsigned long start_pfn, ++ unsigned long end_pfn); + static inline bool hugepage_migration_supported(struct hstate *h) + { + #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION +@@ -518,7 +518,7 @@ static inline pgoff_t basepage_index(str + { + return page->index; + } +-#define dissolve_free_huge_pages(s, e) do {} while (0) ++#define dissolve_free_huge_pages(s, e) 0 + #define hugepage_migration_supported(h) false + + static inline spinlock_t *huge_pte_lockptr(struct hstate *h, +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1437,22 +1437,32 @@ static int free_pool_huge_page(struct hs + + /* + * Dissolve a given free hugepage into free buddy pages. This function does +- * nothing for in-use (including surplus) hugepages. ++ * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the ++ * number of free hugepages would be reduced below the number of reserved ++ * hugepages. + */ +-static void dissolve_free_huge_page(struct page *page) ++static int dissolve_free_huge_page(struct page *page) + { ++ int rc = 0; ++ + spin_lock(&hugetlb_lock); + if (PageHuge(page) && !page_count(page)) { + struct page *head = compound_head(page); + struct hstate *h = page_hstate(head); + int nid = page_to_nid(head); ++ if (h->free_huge_pages - h->resv_huge_pages == 0) { ++ rc = -EBUSY; ++ goto out; ++ } + list_del(&head->lru); + h->free_huge_pages--; + h->free_huge_pages_node[nid]--; + h->max_huge_pages--; + update_and_free_page(h, head); + } ++out: + spin_unlock(&hugetlb_lock); ++ return rc; + } + + /* +@@ -1460,16 +1470,22 @@ static void dissolve_free_huge_page(stru + * make specified memory blocks removable from the system. + * Note that this will dissolve a free gigantic hugepage completely, if any + * part of it lies within the given range. ++ * Also note that if dissolve_free_huge_page() returns with an error, all ++ * free hugepages that were dissolved before that error are lost. + */ +-void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) ++int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) + { + unsigned long pfn; ++ int rc = 0; + + if (!hugepages_supported()) +- return; ++ return rc; + + for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) +- dissolve_free_huge_page(pfn_to_page(pfn)); ++ if (rc = dissolve_free_huge_page(pfn_to_page(pfn))) ++ break; ++ ++ return rc; + } + + /* +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1945,7 +1945,9 @@ repeat: + * dissolve free hugepages in the memory block before doing offlining + * actually in order to make hugetlbfs's object counting consistent. + */ +- dissolve_free_huge_pages(start_pfn, end_pfn); ++ ret = dissolve_free_huge_pages(start_pfn, end_pfn); ++ if (ret) ++ goto failed_removal; + /* check again */ + offlined_pages = check_pages_isolated(start_pfn, end_pfn); + if (offlined_pages < 0) { diff --git a/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch b/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch new file mode 100644 index 00000000..cf253222 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch @@ -0,0 +1,36 @@ +From b64db1b252e9974a43a51ba083fa7d03e4716167 Mon Sep 17 00:00:00 2001 +From: Xinming Hu +Date: Tue, 9 Aug 2016 20:20:44 +0530 +Subject: mwifiex: correct aid value during tdls setup + +From: Xinming Hu + +commit b64db1b252e9974a43a51ba083fa7d03e4716167 upstream. + +AID gets updated during TDLS setup, but modified value isn't reflected +in "priv->assoc_rsp_buf". This causes TDLS setup failure. The problem is +fixed here. + +Fixes: 4aff53ef18e4a4 ("mwifiex: parsing aid while receiving..") +Signed-off-by: Xinming Hu +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/marvell/mwifiex/join.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/wireless/marvell/mwifiex/join.c ++++ b/drivers/net/wireless/marvell/mwifiex/join.c +@@ -669,9 +669,8 @@ int mwifiex_ret_802_11_associate(struct + priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, + sizeof(priv->assoc_rsp_buf)); + +- memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); +- + assoc_rsp->a_id = cpu_to_le16(aid); ++ memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); + + if (status_code) { + priv->adapter->dbg.num_cmd_assoc_failure++; diff --git a/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch b/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch new file mode 100644 index 00000000..4eafe773 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch @@ -0,0 +1,39 @@ +From c8ccf3ade7851054f82bf88f5fcd393a394038a3 Mon Sep 17 00:00:00 2001 +From: Amitkumar Karwar +Date: Mon, 25 Jul 2016 21:21:06 +0530 +Subject: mwifiex: fix failed to reconnect after interface disabled/enabled + +From: Amitkumar Karwar + +commit c8ccf3ade7851054f82bf88f5fcd393a394038a3 upstream. + +Recent patch "mwifiex: fix NULL pointer" skips extended scan event +handling when suspend is in progress. It created a problem for scan +after interface disabled/enabled case. + +This patch solves the problem by checking netif_running() status. + +Fixes:16d25da94f3d654 ("mwifiex: fix NULL pointer dereference during suspend") +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c ++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c +@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwi + + case EVENT_EXT_SCAN_REPORT: + mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); +- if (adapter->ext_scan && !priv->scan_aborting) ++ /* We intend to skip this event during suspend, but handle ++ * it in interface disabled case ++ */ ++ if (adapter->ext_scan && (!priv->scan_aborting || ++ !netif_running(priv->netdev))) + ret = mwifiex_handle_event_ext_scan_report(priv, + adapter->event_skb->data); + diff --git a/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch b/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch new file mode 100644 index 00000000..f5d12375 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch @@ -0,0 +1,408 @@ +From 073931017b49d9458aa351605b43a7e34598caef Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 19 Sep 2016 17:39:09 +0200 +Subject: posix_acl: Clear SGID bit when setting file permissions + +From: Jan Kara + +commit 073931017b49d9458aa351605b43a7e34598caef upstream. + +When file permissions are modified via chmod(2) and the user is not in +the owning group or capable of CAP_FSETID, the setgid bit is cleared in +inode_change_ok(). Setting a POSIX ACL via setxattr(2) sets the file +permissions as well as the new ACL, but doesn't clear the setgid bit in +a similar way; this allows to bypass the check in chmod(2). Fix that. + +References: CVE-2016-7097 +Reviewed-by: Christoph Hellwig +Reviewed-by: Jeff Layton +Signed-off-by: Jan Kara +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Juerg Haefliger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/9p/acl.c | 40 +++++++++++++++++----------------------- + fs/btrfs/acl.c | 6 ++---- + fs/ceph/acl.c | 6 ++---- + fs/ext2/acl.c | 12 ++++-------- + fs/ext4/acl.c | 12 ++++-------- + fs/f2fs/acl.c | 6 ++---- + fs/gfs2/acl.c | 12 +++--------- + fs/hfsplus/posix_acl.c | 4 ++-- + fs/jffs2/acl.c | 9 ++++----- + fs/jfs/acl.c | 6 ++---- + fs/ocfs2/acl.c | 10 ++++------ + fs/orangefs/acl.c | 15 +++++---------- + fs/posix_acl.c | 31 +++++++++++++++++++++++++++++++ + fs/reiserfs/xattr_acl.c | 8 ++------ + fs/xfs/xfs_acl.c | 13 ++++--------- + include/linux/posix_acl.h | 1 + + 16 files changed, 89 insertions(+), 102 deletions(-) + +--- a/fs/9p/acl.c ++++ b/fs/9p/acl.c +@@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const stru + switch (handler->flags) { + case ACL_TYPE_ACCESS: + if (acl) { +- umode_t mode = inode->i_mode; +- retval = posix_acl_equiv_mode(acl, &mode); +- if (retval < 0) ++ struct iattr iattr; ++ ++ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); ++ if (retval) + goto err_out; +- else { +- struct iattr iattr; +- if (retval == 0) { +- /* +- * ACL can be represented +- * by the mode bits. So don't +- * update ACL. +- */ +- acl = NULL; +- value = NULL; +- size = 0; +- } +- /* Updte the mode bits */ +- iattr.ia_mode = ((mode & S_IALLUGO) | +- (inode->i_mode & ~S_IALLUGO)); +- iattr.ia_valid = ATTR_MODE; +- /* FIXME should we update ctime ? +- * What is the following setxattr update the +- * mode ? ++ if (!acl) { ++ /* ++ * ACL can be represented ++ * by the mode bits. So don't ++ * update ACL. + */ +- v9fs_vfs_setattr_dotl(dentry, &iattr); ++ value = NULL; ++ size = 0; + } ++ iattr.ia_valid = ATTR_MODE; ++ /* FIXME should we update ctime ? ++ * What is the following setxattr update the ++ * mode ? ++ */ ++ v9fs_vfs_setattr_dotl(dentry, &iattr); + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/btrfs/acl.c ++++ b/fs/btrfs/acl.c +@@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_ + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- ret = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (ret < 0) ++ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (ret) + return ret; +- if (ret == 0) +- acl = NULL; + } + ret = 0; + break; +--- a/fs/ceph/acl.c ++++ b/fs/ceph/acl.c +@@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, st + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- ret = posix_acl_equiv_mode(acl, &new_mode); +- if (ret < 0) ++ ret = posix_acl_update_mode(inode, &new_mode, &acl); ++ if (ret) + goto out; +- if (ret == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/ext2/acl.c ++++ b/fs/ext2/acl.c +@@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct + case ACL_TYPE_ACCESS: + name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- inode->i_ctime = CURRENT_TIME_SEC; +- mark_inode_dirty(inode); +- if (error == 0) +- acl = NULL; +- } ++ inode->i_ctime = CURRENT_TIME_SEC; ++ mark_inode_dirty(inode); + } + break; + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct + case ACL_TYPE_ACCESS: + name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- inode->i_ctime = ext4_current_time(inode); +- ext4_mark_inode_dirty(handle, inode); +- if (error == 0) +- acl = NULL; +- } ++ inode->i_ctime = ext4_current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); + } + break; + +--- a/fs/f2fs/acl.c ++++ b/fs/f2fs/acl.c +@@ -210,12 +210,10 @@ static int __f2fs_set_acl(struct inode * + case ACL_TYPE_ACCESS: + name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; + set_acl_inode(inode, inode->i_mode); +- if (error == 0) +- acl = NULL; + } + break; + +--- a/fs/gfs2/acl.c ++++ b/fs/gfs2/acl.c +@@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode, + if (type == ACL_TYPE_ACCESS) { + umode_t mode = inode->i_mode; + +- error = posix_acl_equiv_mode(acl, &mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- +- if (error == 0) +- acl = NULL; +- +- if (mode != inode->i_mode) { +- inode->i_mode = mode; ++ if (mode != inode->i_mode) + mark_inode_dirty(inode); +- } + } + + if (acl) { +--- a/fs/hfsplus/posix_acl.c ++++ b/fs/hfsplus/posix_acl.c +@@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode * + case ACL_TYPE_ACCESS: + xattr_name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- err = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (err < 0) ++ err = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (err) + return err; + } + err = 0; +--- a/fs/jffs2/acl.c ++++ b/fs/jffs2/acl.c +@@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, s + case ACL_TYPE_ACCESS: + xprefix = JFFS2_XPREFIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- rc = posix_acl_equiv_mode(acl, &mode); +- if (rc < 0) ++ umode_t mode; ++ ++ rc = posix_acl_update_mode(inode, &mode, &acl); ++ if (rc) + return rc; + if (inode->i_mode != mode) { + struct iattr attr; +@@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, s + if (rc < 0) + return rc; + } +- if (rc == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/jfs/acl.c ++++ b/fs/jfs/acl.c +@@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, stru + case ACL_TYPE_ACCESS: + ea_name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- rc = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (rc < 0) ++ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (rc) + return rc; + inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(inode); +- if (rc == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/ocfs2/acl.c ++++ b/fs/ocfs2/acl.c +@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle, + case ACL_TYPE_ACCESS: + name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- ret = posix_acl_equiv_mode(acl, &mode); +- if (ret < 0) +- return ret; ++ umode_t mode; + +- if (ret == 0) +- acl = NULL; ++ ret = posix_acl_update_mode(inode, &mode, &acl); ++ if (ret) ++ return ret; + + ret = ocfs2_acl_set_mode(inode, di_bh, + handle, mode); +--- a/fs/orangefs/acl.c ++++ b/fs/orangefs/acl.c +@@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- umode_t mode = inode->i_mode; +- /* +- * can we represent this with the traditional file +- * mode permission bits? +- */ +- error = posix_acl_equiv_mode(acl, &mode); +- if (error < 0) { +- gossip_err("%s: posix_acl_equiv_mode err: %d\n", ++ umode_t mode; ++ ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) { ++ gossip_err("%s: posix_acl_update_mode err: %d\n", + __func__, + error); + return error; +@@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode + SetModeFlag(orangefs_inode); + inode->i_mode = mode; + mark_inode_dirty_sync(inode); +- if (error == 0) +- acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/posix_acl.c ++++ b/fs/posix_acl.c +@@ -626,6 +626,37 @@ no_mem: + } + EXPORT_SYMBOL_GPL(posix_acl_create); + ++/** ++ * posix_acl_update_mode - update mode in set_acl ++ * ++ * Update the file mode when setting an ACL: compute the new file permission ++ * bits based on the ACL. In addition, if the ACL is equivalent to the new ++ * file mode, set *acl to NULL to indicate that no ACL should be set. ++ * ++ * As with chmod, clear the setgit bit if the caller is not in the owning group ++ * or capable of CAP_FSETID (see inode_change_ok). ++ * ++ * Called from set_acl inode operations. ++ */ ++int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, ++ struct posix_acl **acl) ++{ ++ umode_t mode = inode->i_mode; ++ int error; ++ ++ error = posix_acl_equiv_mode(*acl, &mode); ++ if (error < 0) ++ return error; ++ if (error == 0) ++ *acl = NULL; ++ if (!in_group_p(inode->i_gid) && ++ !capable_wrt_inode_uidgid(inode, CAP_FSETID)) ++ mode &= ~S_ISGID; ++ *mode_p = mode; ++ return 0; ++} ++EXPORT_SYMBOL(posix_acl_update_mode); ++ + /* + * Fix up the uids and gids in posix acl extended attributes in place. + */ +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -242,13 +242,9 @@ __reiserfs_set_acl(struct reiserfs_trans + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_equiv_mode(acl, &inode->i_mode); +- if (error < 0) ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) + return error; +- else { +- if (error == 0) +- acl = NULL; +- } + } + break; + case ACL_TYPE_DEFAULT: +--- a/fs/xfs/xfs_acl.c ++++ b/fs/xfs/xfs_acl.c +@@ -257,16 +257,11 @@ xfs_set_acl(struct inode *inode, struct + return error; + + if (type == ACL_TYPE_ACCESS) { +- umode_t mode = inode->i_mode; +- error = posix_acl_equiv_mode(acl, &mode); +- +- if (error <= 0) { +- acl = NULL; +- +- if (error < 0) +- return error; +- } ++ umode_t mode; + ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) ++ return error; + error = xfs_set_mode(inode, mode); + if (error) + return error; +--- a/include/linux/posix_acl.h ++++ b/include/linux/posix_acl.h +@@ -93,6 +93,7 @@ extern int set_posix_acl(struct inode *, + extern int posix_acl_chmod(struct inode *, umode_t); + extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, + struct posix_acl **); ++extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); + + extern int simple_set_acl(struct inode *, struct posix_acl *, int); + extern int simple_acl_create(struct inode *, struct inode *); diff --git a/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch b/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch new file mode 100644 index 00000000..c02dec4e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch @@ -0,0 +1,55 @@ +From 0610735928ee47870e083d5901caa371089216f1 Mon Sep 17 00:00:00 2001 +From: Georges Savoundararadj +Date: Wed, 7 Sep 2016 18:38:15 -0700 +Subject: power: bq24257: Fix use of uninitialized pointer bq->charger + +From: Georges Savoundararadj + +commit 0610735928ee47870e083d5901caa371089216f1 upstream. + +bq->charger is initialized in bq24257_power_supply_init. +Therefore, bq24257_power_supply_init should be called before the +registration of the IRQ handler bq24257_irq_handler_thread that calls +power_supply_changed(bq->charger). + +Signed-off-by: Georges Savoundararadj +Cc: Aurelien Chanot +Cc: Andreas Dannenberg +Cc: Sebastian Reichel +Cc: David Woodhouse +Fixes: 2219a935963e ("power_supply: Add TI BQ24257 charger driver") +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/bq24257_charger.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/power/bq24257_charger.c ++++ b/drivers/power/bq24257_charger.c +@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_clie + return ret; + } + ++ ret = bq24257_power_supply_init(bq); ++ if (ret < 0) { ++ dev_err(dev, "Failed to register power supply\n"); ++ return ret; ++ } ++ + ret = devm_request_threaded_irq(dev, client->irq, NULL, + bq24257_irq_handler_thread, + IRQF_TRIGGER_FALLING | +@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_clie + return ret; + } + +- ret = bq24257_power_supply_init(bq); +- if (ret < 0) { +- dev_err(dev, "Failed to register power supply\n"); +- return ret; +- } +- + ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group); + if (ret < 0) { + dev_err(dev, "Can't create sysfs entries\n"); diff --git a/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch b/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch new file mode 100644 index 00000000..238b9566 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch @@ -0,0 +1,142 @@ +From 23f889bdf6ee5cfff012d8b09f6bec920c691696 Mon Sep 17 00:00:00 2001 +From: David Weinehall +Date: Wed, 17 Aug 2016 15:47:48 +0300 +Subject: Revert "drm/i915: Check live status before reading edid" + +From: David Weinehall + +commit 23f889bdf6ee5cfff012d8b09f6bec920c691696 upstream. + +This reverts commit 237ed86c693d8a8e4db476976aeb30df4deac74b. + +Our current implementation of live status check (repeat 9 times +with 10ms delays between each attempt as a workaround for +buggy displays) imposes a rather serious penalty, time wise, +on intel_hdmi_detect(). Since we we already skip live status +checks on platforms before gen 7, and since we seem to have +coped quite well before the live status check was introduced +for newer platforms too, the previous behaviour is probably +preferable, at least unless someone can point to a use-case +that the live status check improves (apart from "Bspec says so".) + +Signed-off-by: David Weinehall +Fixes: 237ed86c693d ("drm/i915: Check live status before reading edid") +Fixes: f8d03ea0053b ("drm/i915: increase the tries for HDMI hotplug live status checking") +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97139 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94014 +Acked-by: Chris Wilson +Signed-off-by: Jani Nikula +Link: http://patchwork.freedesktop.org/patch/msgid/20160817124748.31208-1-david.weinehall@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dp.c | 2 - + drivers/gpu/drm/i915/intel_drv.h | 2 - + drivers/gpu/drm/i915/intel_hdmi.c | 43 ++++++++------------------------------ + 3 files changed, 11 insertions(+), 36 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -4148,7 +4148,7 @@ static bool bxt_digital_port_connected(s + * + * Return %true if @port is connected, %false otherwise. + */ +-bool intel_digital_port_connected(struct drm_i915_private *dev_priv, ++static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) + { + if (HAS_PCH_IBX(dev_priv)) +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1388,8 +1388,6 @@ void intel_edp_drrs_disable(struct intel + void intel_edp_drrs_invalidate(struct drm_device *dev, + unsigned frontbuffer_bits); + void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +-bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +- struct intel_digital_port *port); + + void + intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -1422,24 +1422,22 @@ intel_hdmi_dp_dual_mode_detect(struct dr + } + + static bool +-intel_hdmi_set_edid(struct drm_connector *connector, bool force) ++intel_hdmi_set_edid(struct drm_connector *connector) + { + struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); +- struct edid *edid = NULL; ++ struct edid *edid; + bool connected = false; + +- if (force) { +- intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); ++ intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + +- edid = drm_get_edid(connector, +- intel_gmbus_get_adapter(dev_priv, +- intel_hdmi->ddc_bus)); ++ edid = drm_get_edid(connector, ++ intel_gmbus_get_adapter(dev_priv, ++ intel_hdmi->ddc_bus)); + +- intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); ++ intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); + +- intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); +- } ++ intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); + + to_intel_connector(connector)->detect_edid = edid; + if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { +@@ -1465,37 +1463,16 @@ static enum drm_connector_status + intel_hdmi_detect(struct drm_connector *connector, bool force) + { + enum drm_connector_status status; +- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + struct drm_i915_private *dev_priv = to_i915(connector->dev); +- bool live_status = false; +- unsigned int try; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + +- for (try = 0; !live_status && try < 9; try++) { +- if (try) +- msleep(10); +- live_status = intel_digital_port_connected(dev_priv, +- hdmi_to_dig_port(intel_hdmi)); +- } +- +- if (!live_status) { +- DRM_DEBUG_KMS("HDMI live status down\n"); +- /* +- * Live status register is not reliable on all intel platforms. +- * So consider live_status only for certain platforms, for +- * others, read EDID to determine presence of sink. +- */ +- if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv)) +- live_status = true; +- } +- + intel_hdmi_unset_edid(connector); + +- if (intel_hdmi_set_edid(connector, live_status)) { ++ if (intel_hdmi_set_edid(connector)) { + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; +@@ -1521,7 +1498,7 @@ intel_hdmi_force(struct drm_connector *c + if (connector->status != connector_status_connected) + return; + +- intel_hdmi_set_edid(connector, true); ++ intel_hdmi_set_edid(connector); + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + } + diff --git a/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch b/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch new file mode 100644 index 00000000..620b2a7a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch @@ -0,0 +1,37 @@ +From 410280bac6224e066f4cf0b87db08f0418a135b6 Mon Sep 17 00:00:00 2001 +From: Christophe Jaillet +Date: Thu, 11 Aug 2016 16:38:54 +0200 +Subject: rt2x00usb: Fix error return code + +From: Christophe Jaillet + +commit 410280bac6224e066f4cf0b87db08f0418a135b6 upstream. + +We know that 'retval = 0' because it has been tested a few lines above. +So, if 'devm_kmalloc' fails, 0 will be returned instead of an error code. +Return -ENOMEM instead. + +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Christophe JAILLET +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -831,8 +831,10 @@ int rt2x00usb_probe(struct usb_interface + rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, + sizeof(struct usb_anchor), + GFP_KERNEL); +- if (!rt2x00dev->anchor) ++ if (!rt2x00dev->anchor) { ++ retval = -ENOMEM; + goto exit_free_reg; ++ } + + init_usb_anchor(rt2x00dev->anchor); + return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch b/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch new file mode 100644 index 00000000..a29bf7cc --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch @@ -0,0 +1,80 @@ +From babf985d1e1b0677cb264acd01319d2b9c8f4327 Mon Sep 17 00:00:00 2001 +From: Uma Krishnan +Date: Fri, 2 Sep 2016 15:39:16 -0500 +Subject: scsi: cxlflash: Remove the device cleanly in the system shutdown path + +From: Uma Krishnan + +commit babf985d1e1b0677cb264acd01319d2b9c8f4327 upstream. + +Commit 704c4b0ddc03 ("cxlflash: Shutdown notify support for CXL Flash +cards") was recently introduced to notify the AFU when a system is going +down. Due to the position of the cxlflash driver in the device stack, +cxlflash devices are _always_ removed during a reboot/shutdown. This can +lead to a crash if the cxlflash shutdown hook is invoked _after_ the +shutdown hook for the owning virtual PHB. Furthermore, the current +implementation of shutdown/remove hooks for cxlflash are not tolerant to +being invoked when the device is not enabled. This can also lead to a +crash in situations where the remove hook is invoked after the device +has been removed via the vPHBs shutdown hook. An example of this +scenario would be an EEH reset failure while a reboot/shutdown is in +progress. + +To solve both problems, the shutdown hook for cxlflash is updated to +simply remove the device. This path already includes the AFU +notification and thus this solution will continue to perform the +original intent. At the same time, the remove hook is updated to protect +against being called when the device is not enabled. + +Fixes: 704c4b0ddc03 ("cxlflash: Shutdown notify support for CXL Flash +cards") +Signed-off-by: Uma Krishnan +Acked-by: Matthew R. Ochs +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/cxlflash/main.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/scsi/cxlflash/main.c ++++ b/drivers/scsi/cxlflash/main.c +@@ -823,17 +823,6 @@ static void notify_shutdown(struct cxlfl + } + + /** +- * cxlflash_shutdown() - shutdown handler +- * @pdev: PCI device associated with the host. +- */ +-static void cxlflash_shutdown(struct pci_dev *pdev) +-{ +- struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); +- +- notify_shutdown(cfg, false); +-} +- +-/** + * cxlflash_remove() - PCI entry point to tear down host + * @pdev: PCI device associated with the host. + * +@@ -844,6 +833,11 @@ static void cxlflash_remove(struct pci_d + struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); + ulong lock_flags; + ++ if (!pci_is_enabled(pdev)) { ++ pr_debug("%s: Device is disabled\n", __func__); ++ return; ++ } ++ + /* If a Task Management Function is active, wait for it to complete + * before continuing with remove. + */ +@@ -2685,7 +2679,7 @@ static struct pci_driver cxlflash_driver + .id_table = cxlflash_pci_table, + .probe = cxlflash_probe, + .remove = cxlflash_remove, +- .shutdown = cxlflash_shutdown, ++ .shutdown = cxlflash_remove, + .err_handler = &cxlflash_err_handler, + }; + diff --git a/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch b/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch new file mode 100644 index 00000000..342c96ec --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch @@ -0,0 +1,33 @@ +From 6999aeabbb703a81a204cb6f9f8f151759a99ac4 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 20 Aug 2016 15:25:32 +0000 +Subject: spi: spi-fsl-dspi: Drop extra spi_master_put in device remove function + +From: Wei Yongjun + +commit 6999aeabbb703a81a204cb6f9f8f151759a99ac4 upstream. + +The call sequence spi_alloc_master/spi_register_master/spi_unregister_master +is complete; it reduces the device reference count to zero, which and results +in device memory being freed. The subsequent call to spi_master_put is +unnecessary and results in an access to free memory. Drop it. + +Fixes: 9298bc727385 ("spi: spi-fsl-dspi: Remove spi-bitbang") +Signed-off-by: Wei Yongjun +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-fsl-dspi.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/spi/spi-fsl-dspi.c ++++ b/drivers/spi/spi-fsl-dspi.c +@@ -760,7 +760,6 @@ static int dspi_remove(struct platform_d + /* Disconnect from the SPI framework */ + clk_disable_unprepare(dspi->clk); + spi_unregister_master(dspi->master); +- spi_master_put(dspi->master); + + return 0; + } diff --git a/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch b/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch new file mode 100644 index 00000000..2e5bc67f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch @@ -0,0 +1,40 @@ +From 4a236d01b5e0d7e6f4ee9e6c4056fce10b38e8ad Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 15 Sep 2016 17:57:40 +0200 +Subject: staging: android ion/hisi: fix dependencies + +From: Arnd Bergmann + +commit 4a236d01b5e0d7e6f4ee9e6c4056fce10b38e8ad upstream. + +The newly added Hi6220 Ion code fails to build when the ION_OF helpers +are not present: + +drivers/staging/android/ion/hisilicon/hi6220_ion.o: In function `hi6220_ion_remove': +hi6220_ion.c:(.text.hi6220_ion_remove+0x4c): undefined reference to `ion_destroy_platform_data' +drivers/staging/android/ion/hisilicon/hi6220_ion.o: In function `hi6220_ion_probe': +hi6220_ion.c:(.text.hi6220_ion_probe+0x5c): undefined reference to `ion_parse_dt' +hi6220_ion.c:(.text.hi6220_ion_probe+0xf8): undefined reference to `ion_destroy_platform_data' + +This selects the symbol when needed. + +Fixes: 2b40182a19bc ("staging: android: ion: Add ion driver for Hi6220 SoC platform") +Signed-off-by: Arnd Bergmann +Acked-by: Laura Abbott +Reviewed-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/android/ion/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/staging/android/ion/Kconfig ++++ b/drivers/staging/android/ion/Kconfig +@@ -36,6 +36,7 @@ config ION_TEGRA + config ION_HISI + tristate "Ion for Hisilicon" + depends on ARCH_HISI && ION ++ select ION_OF + help + Choose this option if you wish to use ion on Hisilicon Platform. + diff --git a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch new file mode 100644 index 00000000..d7b8117a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch @@ -0,0 +1,41 @@ +From 9afe11e956766eaac4643adaaf49f223dd536c92 Mon Sep 17 00:00:00 2001 +From: Nicholas Mc Guire +Date: Mon, 25 Jul 2016 21:22:27 +0200 +Subject: staging: ks7010: declare private functions static + +From: Nicholas Mc Guire + +commit 9afe11e956766eaac4643adaaf49f223dd536c92 upstream. + +Private functions in ks_hostif.c can be declared static. + +Fixes: 13a9930d15b4 ("staging: ks7010: add driver from Nanonote extra-repository") + +Signed-off-by: Nicholas Mc Guire +Reviewed-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/ks7010/ks_hostif.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/ks7010/ks_hostif.c ++++ b/drivers/staging/ks7010/ks_hostif.c +@@ -69,7 +69,7 @@ inline u32 get_DWORD(struct ks_wlan_priv + return data; + } + +-void ks_wlan_hw_wakeup_task(struct work_struct *work) ++static void ks_wlan_hw_wakeup_task(struct work_struct *work) + { + struct ks_wlan_private *priv = + container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task); +@@ -1509,7 +1509,7 @@ void hostif_infrastructure_set_request(s + ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL); + } + +-void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) ++static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) + { + struct hostif_infrastructure_set2_request_t *pp; + uint16_t capability; diff --git a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch new file mode 100644 index 00000000..9cdf0a7d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch @@ -0,0 +1,44 @@ +From 9d29f14db1095f52ca00b8162b242d6fce07d19f Mon Sep 17 00:00:00 2001 +From: Nicholas Mc Guire +Date: Mon, 25 Jul 2016 21:21:50 +0200 +Subject: staging: ks7010: fix wait_for_completion_interruptible_timeout return handling + +From: Nicholas Mc Guire + +commit 9d29f14db1095f52ca00b8162b242d6fce07d19f upstream. + +wait_for_completion_interruptible_timeout return 0 on timeout and +-ERESTARTSYS if interrupted. The check for +!wait_for_completion_interruptible_timeout() would report an interrupt +as timeout. Further, while HZ/50 will work most of the time it could +fail for HZ < 50, so this is switched to msecs_to_jiffies(20). + +Fixes: 13a9930d15b4 ("staging: ks7010: add driver from Nanonote extra-repository") + +Signed-off-by: Nicholas Mc Guire +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/ks7010/ks_hostif.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/staging/ks7010/ks_hostif.c ++++ b/drivers/staging/ks7010/ks_hostif.c +@@ -74,11 +74,15 @@ void ks_wlan_hw_wakeup_task(struct work_ + struct ks_wlan_private *priv = + container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task); + int ps_status = atomic_read(&priv->psstatus.status); ++ long time_left; + + if (ps_status == PS_SNOOZE) { + ks_wlan_hw_wakeup_request(priv); +- if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) { /* 20ms timeout */ +- DPRINTK(1, "wake up timeout !!!\n"); ++ time_left = wait_for_completion_interruptible_timeout( ++ &priv->psstatus.wakeup_wait, ++ msecs_to_jiffies(20)); ++ if (time_left <= 0) { ++ DPRINTK(1, "wake up timeout or interrupted !!!\n"); + schedule_work(&priv->ks_wlan_wakeup_task); + return; + } diff --git a/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch b/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch new file mode 100644 index 00000000..ab357ae2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch @@ -0,0 +1,45 @@ +From 1335a9516d3d52f157ad87456efdd8dc9ae1747b Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Sun, 5 Jun 2016 14:11:19 -0500 +Subject: staging: r8188eu: Fix scheduling while atomic splat + +From: Larry Finger + +commit 1335a9516d3d52f157ad87456efdd8dc9ae1747b upstream. + +Commit fadbe0cd5292851608e2e01b91d9295fa287b9fe ("staging: rtl8188eu: +Remove rtw_zmalloc(), wrapper for kzalloc()") changed all allocation +calls to be GFP_KERNEL even though the original wrapper was testing +to determine if the caller was in atomic mode. Most of the mistakes +were corrected with commit 33dc85c3c667209c930b2dac5ccbc2a365e06b7a +("staging: r8188eu: Fix scheduling while atomic error introduced in +commit fadbe0cd"); however, two kzalloc calls were missed as the +call only happens when the driver is shutting down. + +Fixes: fadbe0cd5292851608e2e01b91d9295fa287b9fe ("staging: rtl8188eu: Remove rtw_zmalloc(), wrapper for kzalloc()") +Signed-off-by: Larry Finger +Cc: navin patidar +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8188eu/core/rtw_cmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c ++++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c +@@ -670,13 +670,13 @@ u8 rtw_addbareq_cmd(struct adapter *pada + u8 res = _SUCCESS; + + +- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); + if (!ph2c) { + res = _FAIL; + goto exit; + } + +- paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL); ++ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC); + if (!paddbareq_parm) { + kfree(ph2c); + res = _FAIL; diff --git a/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch b/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch new file mode 100644 index 00000000..630a49f1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch @@ -0,0 +1,33 @@ +From 992f961480d23e9ef9e686e512a419efef723523 Mon Sep 17 00:00:00 2001 +From: Phil Turnbull +Date: Fri, 2 Sep 2016 15:35:31 -0400 +Subject: staging: sm750fb: Correctly set CLOCK_PHASE bit of display controller. + +From: Phil Turnbull + +commit 992f961480d23e9ef9e686e512a419efef723523 upstream. + +Commit 6fba39cf32a3 ("staging: sm750fb: use BIT macro for +PANEL_DISPLAY_CTRL single-bit fields") accidentally changed the +CLOCK_PHASE logic from '|=' to '=' which clears all the previously set +bits. + +Fixes: 6fba39cf32a3 ("staging: sm750fb: use BIT macro for PANEL_DISPLAY_CTRL single-bit fields") +Signed-off-by: Phil Turnbull +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/sm750fb/ddk750_mode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/sm750fb/ddk750_mode.c ++++ b/drivers/staging/sm750fb/ddk750_mode.c +@@ -63,7 +63,7 @@ static unsigned long displayControlAdjus + dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT); + + /* Set bit 14 of display controller */ +- dispControl = DISPLAY_CTRL_CLOCK_PHASE; ++ dispControl |= DISPLAY_CTRL_CLOCK_PHASE; + + POKE32(CRT_DISPLAY_CTRL, dispControl); + diff --git a/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch b/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch new file mode 100644 index 00000000..9f33eed3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch @@ -0,0 +1,36 @@ +From 4d31a2588ae37a5d0f61f4d956454e9504846aeb Mon Sep 17 00:00:00 2001 +From: Jan Viktorin +Date: Tue, 17 May 2016 11:22:17 +0200 +Subject: uio: fix dmem_region_start computation + +From: Jan Viktorin + +commit 4d31a2588ae37a5d0f61f4d956454e9504846aeb upstream. + +The variable i contains a total number of resources (including +IORESOURCE_IRQ). However, we want the dmem_region_start to point +after the last resource of type IORESOURCE_MEM. The original behaviour +leads (very likely) to skipping several UIO mapping regions and makes +them useless. Fix this by computing dmem_region_start from the uiomem +which points to the last used UIO mapping. + +Fixes: 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation") + +Signed-off-by: Jan Viktorin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/uio/uio_dmem_genirq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/uio/uio_dmem_genirq.c ++++ b/drivers/uio/uio_dmem_genirq.c +@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct + ++uiomem; + } + +- priv->dmem_region_start = i; ++ priv->dmem_region_start = uiomem - &uioinfo->mem[0]; + priv->num_dmem_regions = pdata->num_dynamic_regions; + + for (i = 0; i < pdata->num_dynamic_regions; ++i) { diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 09eda125..55a7b2e9 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,9 +28,89 @@ - patches/linux/patch-4.8.4.xz - + patches/linux/patch-4.8.5.xz + + patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch + patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch + patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch + patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch + patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch + patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch + patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch + patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch + patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch + patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch + patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch + patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch + patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch + patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch + patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch + patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch + patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch + patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch + patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch + patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch + patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch + patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch + patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch + patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch + patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch + patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch + patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch + patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch + patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch + patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch + patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch + patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch + patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch + patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch + patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch + patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch + patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch + patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch + patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch + patches/mageia/stable-rt2x00usb-fix-error-return-code.patch + patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch + patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch + patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch + patches/mageia/stable-uio-fix-dmem_region_start-computation.patch + patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch + patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch + patches/mageia/stable-i40e-remove-a-stray-unlock.patch + patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch + patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch + patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch + patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch + patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch + patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch + patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch + patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch + patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch + patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch + patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch + patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch + patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch + patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch + patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch + patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch + patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch + patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch + patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch + patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch + patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch + patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch + patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch + patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch + patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch + patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch + patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch + patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch + patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch + patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch + patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch + patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch + patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch @@ -40,7 +120,7 @@ patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch - patches/mageia/kernel-sched-fair-Fix-incorrect-task-group-load_avg.patch + patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch patches/mageia/pci-quirks-drop-devinit-exit.patch patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch @@ -86,8 +166,7 @@ patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch patches/mageia/gpu-drm-mach64-3.17-buildfix.patch patches/mageia/gpu-drm-mach64-3.18-buildfix.patch - patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch - patches/mageia/skl_uncondition_memory_bandwitdth_WA_n_adjusted_mode_in_SAGV_check_on_a7fac751ddba.patch + patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -196,8 +275,8 @@ - 2016-10-28 - 4.8.4 + 2016-10-30 + 4.8.5 Version Bump. security From 536cf65dcf50dc3f302d0ff4ed4321ffd6c7b27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Tue, 1 Nov 2016 13:15:32 +0200 Subject: [PATCH 08/11] 4_8_6, perhabs old aufs tree cause problem? --- .../kernel/files/patches/linux/patch-4.3.2.xz | Bin 39640 -> 0 bytes .../kernel/files/patches/linux/patch-4.4.1.xz | Bin 23612 -> 0 bytes .../kernel/files/patches/linux/patch-4.4.2.xz | Bin 60144 -> 0 bytes .../kernel/files/patches/linux/patch-4.4.4.xz | Bin 200972 -> 0 bytes .../kernel/files/patches/linux/patch-4.4.8.xz | Bin 331620 -> 0 bytes .../kernel/files/patches/linux/patch-4.6.3.xz | Bin 103616 -> 0 bytes .../kernel/files/patches/linux/patch-4.8.6.xz | Bin 0 -> 120040 bytes ...-raid-fix-compat_features-validation.patch | 39 + ...-partitioning-for-multi-screen-cases.patch | 35 - .../patches/mageia/fs-aufs-4.7-ver-fix.patch | 16 - ...odular.patch => fs-aufs-4.8-modular.patch} | 102 +- .../{fs-aufs-4.7.patch => fs-aufs-4.8.patch} | 1314 +++++++++++------ ...-partitioning-for-multi-screen-cases.patch | 75 + .../net-add-recursion-limit-to-GRO.patch | 85 +- ...ession-caused-by-commit-d86e64768859.patch | 47 +- kernel/kernel/files/patches/mageia/series | 94 +- ...-arm-clk-imx35-fix-name-for-ckil-clk.patch | 37 - ...ol-creation-for-output-driver-widget.patch | 41 - ...d-variable-in-snd_soc_dapm_get_volsw.patch | 42 - ...or-_enum_double-mux-s-second-channel.patch | 35 - ...fix-obsoleted-initializers-for-array.patch | 85 -- ...fix-obsoleted-initializers-for-array.patch | 96 -- ...-code-in-soc_tplg_dapm_widget_create.patch | 31 - ...riodic_chan_stat_support-wmi-service.patch | 58 - ...0k-fix-reporting-channel-survey-data.patch | 37 - ...in-management-path-in-push-txq-logic.patch | 81 - ...hput-regression-in-multi-client-mode.patch | 54 - ...neous-dma_free_coherent-in-tmc_probe.patch | 37 - ...h-ce-add-missing-async-import-export.patch | 64 - ...alue-check-in-ccp_dmaengine_register.patch | 33 - ...-iv-buffer-size-in-crypto_gcm_setkey.patch | 35 - ...ult-creq-state-during-initialization.patch | 80 - ...mation-context-for-each-dequeued-req.patch | 40 - ...ne-ipu-remove-bogus-no_irq-reference.patch | 56 - ...g-back-after-multi-head-was-disabled.patch | 46 - ...method-to-reduce-computational-error.patch | 53 - ...pu-dce10-disable-hpd-on-local-panels.patch | 62 - ...missing-drm_mode_config_cleanup-call.patch | 31 - ...pu-dce11-disable-hpd-on-local-panels.patch | 62 - ...gpu-dce8-disable-hpd-on-local-panels.patch | 87 -- ...-drm-amdgpu-fix-ib-alignment-for-uvd.patch | 30 - ...ext-reset_counter-in-amdgpu_ctx_init.patch | 37 - ...ssue-when-using-clk_register_divider.patch | 50 - ...ze-when-determining-865g-stolen-base.patch | 118 -- ...e-drm-i915-allow-dp-to-work-w-o-edid.patch | 111 -- ...g-regardless-of-dpll_sdvo_high_speed.patch | 76 - ...-cache-pwm-alternate-increment-value.patch | 79 - ...ernate-increment-on-backlight-enable.patch | 70 - ..._per_line-on-watermarks-calculations.patch | 111 -- ...9-fix-the-watermark-res_blocks-value.patch | 75 - ...wawmmemoryreadlatency-implementation.patch | 91 -- ...scanlines-for-y-tile-is-not-always-4.patch | 133 -- ...nes-actually-affected-by-ddb-changes.patch | 92 -- ...le-drm-i915-introduce-intel_has_sagv.patch | 103 -- ...e-mmiodebug-before-a-register-access.patch | 43 - ...-kbl-also-needs-to-run-the-sagv-code.patch | 64 - ...-in-atomic_commit-into-it-s-own-hook.patch | 162 -- ...g-hpd-handling-into-the-hotplug-work.patch | 102 -- ...-not-skl-only-so-rename-a-few-things.patch | 179 --- ...e-watermarks-if-they-haven-t-changed.patch | 79 - ...h-changed-wms-get-added-to-the-state.patch | 43 - ...lues-atomically-with-wms-plane-attrs.patch | 479 ------ ...arks-atomically-during-plane-updates.patch | 335 ----- ...lias-obj-phys_handle-and-obj-userptr.patch | 61 - ...dule-owner-through-to-dma_buf_export.patch | 78 - ...method-to-reduce-computational-error.patch | 48 - ...-narrow-asic_init-for-virtualization.patch | 33 - ...deon-si-dpm-fix-phase-shedding-setup.patch | 40 - ...hen-the-cs-reads-from-render-targets.patch | 225 --- ...t-the-user-space-command-buffer-size.patch | 42 - ...-generic_chip-add-irq_unmap-callback.patch | 68 - ...table-hid-add-quirk-for-akai-midimix.patch | 50 - ...ail-if-pm_runtime_get_sync-returns-0.patch | 44 - ...x-broken-i40e_config_rss_aq-function.patch | 155 -- .../stable-i40e-remove-a-stray-unlock.patch | 32 - ...i1-move-iowait_init-to-priv-allocate.patch | 55 - ...e-ib-mlx5-fix-steering-resource-leak.patch | 31 - ...stable-ib-qib-remove-qpt_mask-global.patch | 89 -- ...-ib-rdmavt-correct-sparse-annotation.patch | 44 - ...-fix-off-by-one-on-devnr-limit-check.patch | 35 - ...ng-error-code-assignment-before-test.patch | 33 - ...rved-hugepages-during-memory-offline.patch | 140 -- ...-correct-aid-value-during-tdls-setup.patch | 36 - ...ect-after-interface-disabled-enabled.patch | 39 - ...id-bit-when-setting-file-permissions.patch | 408 ----- ...-of-uninitialized-pointer-bq-charger.patch | 55 - ...heck-live-status-before-reading-edid.patch | 142 -- ...able-rt2x00usb-fix-error-return-code.patch | 37 - ...-cleanly-in-the-system-shutdown-path.patch | 80 - ...master_put-in-device-remove-function.patch | 33 - ...ng-android-ion-hisi-fix-dependencies.patch | 40 - ...010-declare-private-functions-static.patch | 41 - ...nterruptible_timeout-return-handling.patch | 44 - ...eu-fix-scheduling-while-atomic-splat.patch | 45 - ...lock_phase-bit-of-display-controller.patch | 33 - ...io-fix-dmem_region_start-computation.patch | 36 - ...pboot-Init-apic-mapping-before-usage.patch | 61 + kernel/kernel/pspec.xml | 99 +- 98 files changed, 1205 insertions(+), 7079 deletions(-) delete mode 100644 kernel/kernel/files/patches/linux/patch-4.3.2.xz delete mode 100644 kernel/kernel/files/patches/linux/patch-4.4.1.xz delete mode 100644 kernel/kernel/files/patches/linux/patch-4.4.2.xz delete mode 100644 kernel/kernel/files/patches/linux/patch-4.4.4.xz delete mode 100644 kernel/kernel/files/patches/linux/patch-4.4.8.xz delete mode 100644 kernel/kernel/files/patches/linux/patch-4.6.3.xz create mode 100644 kernel/kernel/files/patches/linux/patch-4.8.6.xz create mode 100644 kernel/kernel/files/patches/mageia/dm-raid-fix-compat_features-validation.patch delete mode 100644 kernel/kernel/files/patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch delete mode 100644 kernel/kernel/files/patches/mageia/fs-aufs-4.7-ver-fix.patch rename kernel/kernel/files/patches/mageia/{fs-aufs-4.7-modular.patch => fs-aufs-4.8-modular.patch} (71%) rename kernel/kernel/files/patches/mageia/{fs-aufs-4.7.patch => fs-aufs-4.8.patch} (96%) create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch delete mode 100644 kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch diff --git a/kernel/kernel/files/patches/linux/patch-4.3.2.xz b/kernel/kernel/files/patches/linux/patch-4.3.2.xz deleted file mode 100644 index 32f9f186341e8c23e9fe2fb4ff56772fa9f3b1a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39640 zcmV(fK>EM^H+ooF000E$*0e?f03iV!0000G&sfajMYWojT>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$p4y*yrKEu+nE=5mrU8s@oT4;ZCWV>l=eF;2yjHfQ1}E%XAFHF| zYE#Vu$6gs4az`Hz^q8^jT?2J0P##?wZxxUvrnkRU>9XSP|GwDLKj=@ZQjzd;F=t45 zR$?#UER8y^)XTfYyhTO%=wYnwy2;(maHg{S`4Bb*7kI_;3^2o)rk?fjSiO7D?r<5ClR*#3x_CTbNT-d;0LD3fovX|CK+v$(lK$%96Y^s$Txtqvgn5t&Ud`8z92=?h5pvizD$~C)8C$Tzu=N;y|6@LxmeSnLULc+ z)J7%u#$#KlGNezarSP!lBxY3+ev-UpIk{f{8*7AYF}K5?+BMaRS3H zvyRuqFSP5anD@m>|9AW#_orsqKX9KazcsGt7|*AeT&#G6TF(Er2KQ(&X0FFp=sp

x@YzJ+AJq3S;;%;Iy*27j$$bw-xB1 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 diff --git a/kernel/kernel/files/patches/linux/patch-4.4.1.xz b/kernel/kernel/files/patches/linux/patch-4.4.1.xz deleted file mode 100644 index 7a414d5bcbf33d52a2c51d4ed3aaa609e8777c8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23612 zcmV(rK<>Z&H+ooF000E$*0e?f03iV!0000G&sfaiRZd&_T>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$p4WOUgooq0_Vv0rFG*P91JyUm^8QPe@R=`8@V>}kdP%LjYk}Y@ z3Aj=Jqr9%ju_6QT8TqHhoj;x!)U;kzw-2)w6(AOjXeo^*lLLSjBte`*z1k%)`|T%( zUfWt06qL832-WD({99!}FFF_+p7?FBn8x#zLNdE8${e4XoW*hOwZ|d*K1q4sjI+^r z(LniuLFt;^YgQ6L&Exl{Gah}6v&N0~4UioE2uV`x(Co9?OTqfob))wgj&3-xSSj);s{y@2~do11(r9y>JFOpP0mB%QAjegFUm_?!j||V6{W$ zX`U(3P$R~bL~PKln`Za>Rd7aBn}S`at^MwT1w(1y?rP;eB>qj&5DoqQI-dQ!fG``! zNh6VuO~U`C;Gb4t>eUTZNT$eH;D^Mi;TJ8?jC!1`^uz3>F{(1M)kAzw{hBnntLK$paFR1xlP!G$5fMGWO0ZtHT<(?pH(4G88n_cqdVq zs*Z7GD3EWqR;1Q3VghF`ZX7xCfmj5RsMeaIAX)0|JiG~wg>21F9U->BR$YF!L?&tm zj;#G-0vRD5_BfeTCS>1MOSBBCgN3uLU6-xlqAC^36K-3bd#5AfP>Wi04h+vgSZV7p zF!`GQaFwkA|M*C(!3Fs2TeF7rHI-0mU=twjWPBK?!E}q^gg~Kkl_8KTwDxapdGbI-TlnBFu75$!>}vm#SPFY`IF1S)F0yy%aA zB@*xPvg> z3tX|ZU$HR$3L;wH^9uM&4IjY8|1^Pjg!mMRoJ9a2mDknmiM7J!`_b9RS1L-@urjK0 zh0C7kgh5HOm!?y&9XG?#($p4=9Ynbpx@gsON>STvY_5K`zPAs8oi`r^zoiprM%0>J zC6YU@dS|2v(bv@=xymc=Ew zU%`0Rru?6%K>M0bNn4Ns_sWEre$;L9G8nQZ!XROYKTiEpIed-fb=XZpi=x0yot53R z1dA_vh5WCO2S{`EU~It#4=hlCJG~vjJ~He_FoFgpPYx-o zrl8T)*UUVUJ3yQl4baO^$?nGLo51i=v!tT&h z?Q-4u)vU%qhGAgWmvsxyd1z{zln*{Px?*WX1A+PTKc>& z@vM0czheGLRMLm!tl6ZQkDx0h=MPX0D0n5mq|s|fJKEi>v0Xs&Nvgm2p8?GLUdX|M z6G+eb<-(K=>^n&_=0;Y7uT{L-{+56gS{g_gT01x}>f$d2$=vzf>wWO@Ol@T(lF?8HwGOo}WEslqkV4ZlZo{a+%_d_4uQyqmrlK0w;7Qc^JlbDLyXO z9hD~Q2FyJtI20Z+pDrVxkP8t5Rh$0};7k6Gk=HmX7@`c!q@!+-a?RET@Xn1gSmGhA zZEKuQ?Q=BJ-a(=mUgDUOVyAfBf)Ijl8@|Dgir229tRgc&RaFvl$Rb96OmS-{zPu+rT|p_6#SF*aOCFXqg`9Tj%@f{Gs2OEGvF&*{}*q z9}9g_5H08E(RU@e$!Ln~16}v-?QROmK3OuACZt2Q0BE{iP2{WEI#*igPq%?DNPHNF zHk5Xt8%hX5WkS2>>aJWKC&)?O+%9a>TieoZwmXRF^l`i+jMuk*ddG7iVTX~OWCskN zuRV$DO7a6g69-wtpm_3g%!Bhl&-Kh3v3twSh34OHt4(&riYD^j{2HT(%I*TrNrxk( zgcr3e?^HD|Y-*+VYu6TPLhP)tHlw@Q()j=E7>+7Csnw~yB&N98=kNmh9%=dGJ%b5d zjZMy2lv1Fm{3=>Tgmo)`4Zt~iNNApwV-xP5r~hlKpJ--5S-u7GS*M_eQc1Zdpeb^M zVwIpdzR>5Sd*v^xKX7HFax}eg&QidUI;{&P{7nTX$rJn!&X7?{7xX51OR->azlr2& zxGRoQmAU!v4%1EQfK+Mu9FT3{JtfbIb=;dh%^7L|dKYv=nVFaq$f5WD0M{Jwe{}T} zadc*HO77C||L}+hb)j4T+P<-3dHFVkntJj`o5N!`Cc1{}F&kNo%#IXuX|q|Ep@$8x zn-f{rTuE(WEDu%h)dkVx)Y5HDg z%W7G=uEygr;4>rzu;k9SImhkKgLlBZ&bVE0K91gMj7MKOOI0yWtik~HW9DLC3yS?7 zB=Q+HBCBR^1+~ueean~yP9zq=3P%n?duiI%?w%bPRn!hxJT{A-F5rmz6u~k+mtegX zs?tlHyV5~=Hbp`eOeswSg`@ zY$-_*gl=dI6p2D=B48G8UB1Ao88G&rLH&llZjE0|X&G(gDZDCsA?&&J2g)u)X=Tue9FV6~N zI-=^@iS|@Ztd#qUJmuwXECvcZfk7?pl7A$%>Hr$AbJO7YM$Mn6?joc8da-jOi&Acq zV9|;+Dah>(LoSFWva|n3`r-AuWJ1%%X}e4D!0iP-;x>!2y_+t| zp;_U;T2e=&fZ0j>=Hq|rJLCBg5@^v%&9YWx{%OS6JKv>=7{W)ck;iNDuZ}eP-@;vP z0+)2&R=*wQ;Y~uJrZDX;{#3DUD6W)v(4$AsNXG*I)nfU z%gR*<=J5&623LZ|>zD2lxbc+oKTdToPc0CU>o`HIf_SP3P~D?z`g|b;@&Qd1X?{!- zCX`Bk<*SNF%H_At$G;`eqX*m}fhYY%K=8>|+jec-l0}|nP@u>j_rjB4w(83x&^beE zYgFSAz5DRjH+_6?G$$FBB5}5N1E^~`8C)Z(C=Fq`*74OA*3`?|BC+T4G|Qk+nNofO zzmNO>y&6w%_$jzl+kF7i|AI$J^k|B)00z^xTrE~E)GZ#8f)i_(wMAr1bW^bSSc?!WtgPh*t}sra%KUAAiAx^Ks77!=GR(t`R*0 zVdh7t_S=@1I|+b_Q#baJ@dLM_!pdR2hrnNvOG)i`ZeUnt?+0G>nY?LgbQ&d0O;6+ExH%@_URAabdcyo$eq} z1>TIRH}1v%F$6klNaR~i#Rrye9f*nMqwSV&4DYU^ilE+QBM*Q>Duc6S&OIwfUeDwP zalaYF=PEPTnp2zI4ADAt8LBKc-W^rsW=Wvv-<)+1NxxYN?}5}N{j~qKsGL{H$)&9p zo_Y)4*fLkh!iYM$Yl7U>)$+7s?jSMzBpEJ3yTwx1fLSal_X;Wx&j5!|YTnME4FmK4 z4YJP1oC$G8f70&7p8C|>0W7%I_^3{@)=u{#buW|jij&7n1qv;LoaaNuCl6H$Uvm_* z%UDIKQ^T4>i}+u(9tIz2jhyG*YSAAGa+g9tAG^Ac}-l}{;9^$W;eEkad-&Dp*pnb;M`j|gD<9B8r zh9%s-j6Z~%+|$4z84!1Bh3vR7sRrdQV^J3mG|*6F^K%KblR%anCU-%tftu${?|*>! z(cn?Jz)f}VLhf(Z0|Olqc^J%cJ?)O#W_~a8%+60aUVUTlf*{LeyOD6i;2)^@Nykd& zXLio(J6>~k)#6sF_bVub8(eV#}vo4=qN_BNiA}cP=^;f*Z2{Rmke2-DWhuuRTHnpIBD@X;g;{LIJM73)QqI zi^6F1%8PVn+-s;P_5PH|VGd7Mpy-OeL#kew1dZ_a!?HQ7 zh5`c%@~_Q}6S2XKMTk$7HKwfaqZgc>lb-+>oZ^2-vTQg?h_0mjj-`exAI&(A@_|Wg zwKbhe%FPnsidHa${lW1Ngy15D9WgVzv4;vdi>*FJJPf=j){QP_YI`l0ViP`xBc z0~Q+z%sz!Qq@%?29kmt`R)A-KjyOsn*;8p}Avr4bujR{)C4%9;2{6#SzWw;W+%t53 zEFz$s(Hzvshu{=2(hl$JDKj7=gw+95-vOXkp^-H&5F1<>+4Hg4KzbOrsS=^J;}N%y z)WI2H19$+QNyBRM{ofqzn0-aM;fQA=0sv1*ydfMcw%gD>cK7htE#Zrg?Req1aV3@^ zwFARPoN$){dwwR>V8s8a@nx=Q%`TloP#P&;;9TNh$kct!a)?YM-qQw;nu0a9C}%_H zCLL30S>h{fzv|;+p-aTP+~yL*FR1E7#gty!{!;>K$rA=;|D978H;Q4*%4ak{Wt}$ zhv1k<8=l4JFT9hHRxl{m%QxMh8T_RMiY-a>D-P%39i_M~ z)?zx?3OyY?gOcB9jhR9|qEp9xPAX`Myg!gv?jc<288GbS&_b5Q`Ofa$;bzTAsQKP_ zJOne+&;z~i)saL|ar{ar5BYj=p6-O28YLbcg^1TWB^i&dXA#V@s3FHK(JTVwD-S&>j<@}@^=R!cmT=0R4eZTNq-t_ST#I;3d1N zt;`bSuS8V(ei6c}B$=j{lqK+h_Ht;e!vkI@2;B0lyeOH^ellHt8H2mkmt$o*^Zyd( zJZIOa*R3&)#albbK<*qu?9rXt5?qiMLNf&%B}-%cVB{sX4uNMgt@HSoN#Ps&ikm2P z2F~O=O$}U4oO}7EB%BxK$#`SlY4G|k*yH_LQAo+9`y$1hB)l56ksJH!<2Ah7(S+wC4E;)JNb@cK<5T^wJjwpB z*-&4if^Q6%k%jx_`Xc+2Zw1*OnW#Qw%d7RP;NOp^(5oKB-^|?65%nVCAI%tM#(tcZ zI4q|ksy4LnH2zl$H-frUKW;j<(XQVaG=w@LX+p7gnvTB=8`1ZO*+c*vq1D_p+JQlE z-~MXV?VH4l&a=~j*-J$pFVUl)s>fVa3g`*+&)f;C9&+jkb$e)FJTwIeTj->V_qLj3 zyM(9NHDxvnMc5z5&e@fOHXJ~{pTu& z0+vXpJv~-`-B!X6`k%}9n-oJc9WpoRapoB*=L+Pj+&WV(U0hf=Y$zz7Ejq}!Wrf+$$ zc2DGSPd^cj|4ll)4h1%g+Ol@C2-A?P)se#9opHXsNuF&Z2zwspn*_Utz=Eo?i)Woj zK?>e#S^;C5>zNwL+zEumpt1 zK`5-|+lOsJUDRJ7n{dOoYG>>ixRp$VZ26QnC-VgvNaSZ#ScR>_VIQW9KxKq6iZE5E znK(&9cbJ1V+A+?;zMwzNZj}B{O=k+641qti+#Q=Mr9g?y(GgF*l}Dv+0#@+qEhr@5%??{oJg6AV{D=^2 zwe|3#8mL3=%6k2LHe_BDc$N0SOW|j#KZuse6N@8-+YiJA$v3uaix1@A`E}|GtIAEf zWMhQfjy?N^TvBA>T2ojKOXs!H5hc0wP7j?{9q%Vlr|D8APgfT@7X!O&)2pJ0CYPat zaNk=XWA1PqBPBaA5)Cc~)WP%fc8`|b=E(Xlt#>r(0KYx_bn>t8wy-Dy`4rZ(4QnT| zAQbc09+xbID?-$wGKUS75GQY9Pp!% zR!|OR7%P6iRjAlYI7a+gNi1^1sa4iQ_TT2M+nk?7Gzp5$bQMHkj>h>@PTvv^&v#~E zMVfWm{>u7}o4{f)EVhejgD1KF%<~ysiiiPhE}Vb+5w0RnIi%z&O>2Q``%J@7WC4%? z%}h)8C2w<5rX0UieB;Y5V9b2gak?j=-7tv1-UN}RUcvUF>^KlbtVjW=D$dy%)-Rm} zYt1nFS(YTiR%`(H=G@X9t>yps_5jC|!F<#WIw?__EWZB(noFD0veFMLcti?o@-{on zh;RuP{U&_Kj%xDxeINX>jQJvQRdc6q6DX=hg-&NG4tLG`oK001sWu&-vWi}b6dB`6 zc{M9FLdu|ePnWs9X@ZoxO6-q9Tsw%Ns?^w)Q|_pyGZ>rr$XqdIxg1k54l`cz_fZzD_e>7+CH_k{n_pA`xiha=*f;!h>+1DI zx-~2(L1odYS%oe7%vf0wo_T*7cB$#w_QAL3(uY#Tm*c~9K7yGW@A?y%FxCj@J}f}{ zY^#eo9#_W9TrWt6VoWDJm%+Mw9bp8e)UEI#Y?AC>Pe zR82~kk;cf4^(m)eE#@No@LR-~*ay74GPTb7;TYM~VLtep|8Wbdm3&~Ora+Wci5$U( zl}Tv1o_HQS;J30WjAXAoFYuyRaI$MMD8|i?B@=4cLh|pQZ=842=${Mqh$}N=F4xvN zhPvKxeNDIDMtqV+MaNlTFe(Wsrk_xRQ+&cYHx{KI%SwGKna+1B{Gk4J>JkIicMHQ# zB~8&ifZwBPFLP8-V`lNzCkQo=S_pZ(O%o&aA>YRL93w#&LU;TmG48%9tZd> zL(?JC@!LdKt5g_q1IgU6opBV8eFJCE7i!l8q9K~~-ar2q1o+UPUy_bfK?7+Wbv>NS zYo@T*nc`pL)hvzsXIxT9___O)=q^0QB(C-RdmZ@>7=G1xo(Nyrv^f0~lk7H5XNHrt z{8&FV)GbOUZSFDC1-KM>T+i<*OTbvZ0j1Z=yy#|$@I4=Ub}f%9_3p6(bbJR$C{Ah} zjHeARu6a=nDl^r*X*ZJ`hfCEr*K3#J*YxnT4r{`So|hr1J>rV^Rlh3JS)xoHDmTl zw|Xtbn9SkJ&l5*tL1X@x)vE=IxJXO~aTR9f^oiGX67nG?1Dzmwf7>hPGC2A*!jhS5 zQXp4u#xW`W>)N!4#Et>ZyIHPI1Sf&@y}pI^Vz-Z53r(AA)M`XOnGRo~ z=&%jl$ZrYtm(H_^W?keh_=ryN=N>NF#R^h~(RX|Fv>2DTLi1a#J1fqB`D>F`L`IFC zHzI^fTxZ!v^*uv`Ww6>|MSSE?KThS|C?mD=q9csW8DpaO-c1XKE}+tGnWAGL)GIjv+|C`k5FeEiswQPa4-7{fqKX_k(5_HS4UT42DH|Sl z!M&`ka*TDTs1lmhB!3~OK>`b;a&uOL#ZZ1}VFp5)!Ua-T@=9(5pqF!5?9-aM%V75s zE%cfSZEk&A+%L6!>9I0)Q}(|>UF`I>XAr2aW)!2@&tu@eSWujX5SJz&QXr@*+(SDp&1F94|H4AvwUdPDN4MVRImdWX82vn5#{|Tns$7C_KXzCqAB0LDvi=_ zgkWdQIR*Jp*~;qFUBzn9ck1hOdAgVhGi3}V*BxSsE>e3NU=l||1b;1kTFMb1XwHHS zd&zZqA4f^cY}d(3&WOSII#^k&$q0WeoID#=sq+v4V00ez;9V3n^nAa;1)FZHa4nq|o=N}vR;{5!Lt}qwXxdZ2pV^fsW^vSlO(C2o^I*6=Y}A`5t<9 zZeTDJHQ6p|!GyqHa`0`{o(~ef8NWz4`oL1&C|lvu*a)%9S1>az&kCb4;X>EJ1zNO|zGMG5H z#s~ni4GD*ZmP#bz<)vDHVa(v&ZJbCuvgV9kVXOxS0@D>z2xTNAtn6mLb4AJxM^~P{g(-^f&F>3WdFQ7YZA~9PAbureQyLh zd*NA&1gg(?9fVItzZaO+dM>wZ8+}$Sw(X()R;%)nH2J%k3VyoNhMuW4ANhIXT}s5% z9cAb^DU}l00!Z_H=8`JdUZ^ye{{x-AdR@;=ChU2G&xn_tA8(?w0+(lb9c1!o9NQHV##-g_1! zq$rr3|6AQ&9%vmz(;J`!leD(L@_9d?$yKvo@Ii3`KULeNBf{*rOZf2RaFx8#^2*xgI9fzb3>F?eNxnO)Uyu*Cin*87UF0kV4+Ne4mIMsANF)9cKf-yeoseMe*) zB+`m4nRvoY>lkY@eY);K;Dx%7Cfh!!X{_2Nunn6K zkr(7}s2s2S$x3KVaspeueFu{OdBXBq3+8X5f<$aQsmvt4qMXY|^G0&E>&3lMYRg5a zuJR1-?rqgV*~mKBFk_+DayM6gEQtSOJp;upkqV*p&`_Rgl5NXy!Co<&PZDtGG+BoM z`)3`<{Y2v(PcSr@t!w^sO#5c+nT6{>hLG_iF~?b&CV?Xa{GX{xBr}q{j%jq%D9b`* zw#+;TnJX`O_dDl^IQTCZ;tblY&lV@pR2&1GRt*SR3KS#nB%n4pw<#p!OtKU(08utH z7VZY!=qBKHsBxc7(a?Npd0ilC@smSZcra}b=Sjywh_k)Zk47Ni%5?)M);#o+HT7!G z4Ew4!14RMX3SRT?nS-x+IVOZXg)=j`DPA&rHD&k**_9CJn9MZrBqtm#t+PhO*uXGD z?e5w49z@LFzX0$`5O9u+lNvh|)Le*>ukBKMfe?3&_57n%BPPxZFIu;v{Clc|enk4l zM#t>nyL^E;Q8l8CRN5K84ora+mcY?=V)=xOtmX@QhZU3RDvnkJ!6_Uv(Nop=H^*K> zoVHS`-#Z6>FyFeT_CKh(BrQy-szbBkF})EQoLSvdH%N7jYPKwd`Q6s5@uN`_8@? z1uJl5+ogTTM}674_aI~RMr=p9`QX|6Bv=}K3*DC5v*xvT&>fz3;ek_;@v)mBfE%g_ zU*oi!dT+gXS*1&C^-%$5tBh%*+aJk^O%KhxDy6_Fv&Cls7G-S_Nh8Gr_y!K+GiDvO zRJZl9;>2CY7OsIx#oJseL4*-*t3J@EGT}dO%4p=rq9Ei3xRe~cW^G}N;bJnZ8N`*KPE9Q^(`yO`5f#&MppMr zl;VIm)e3)xd45Ibr|#VuwtK2s zv`?D`Q-cYw#wG)y0Hw9T=WFC*l9+*QZu#(6@n$yqm0T}iF9z)ylOaM4aN1UQv=MCK zS)}&VQ}k9|PDeA1KvH()g0dsopSn5i0R_ z=0oGE6z`QWwreho_@9s3=m2pJ$LS2fB8aIysT|%f^Op97m|PQ1Bdn~e5iiR&r_Lgm ziNhKj(I+f59jxTHM5MW5b<>$((XcoX(x4f!C|dZls}UkP+e4(|#uyNB=p~(Ms*e=L zXXS$F6Uz+hKC&yXUd>rL+CI>vJ~&r&i+~WlsP)F@-1bXDWS0Cjd#1vuM~|wG&6Bew zZnlXBvbG(jHNh=MEVa`RenBCMK6#NR^>7pj_oDptaE3w=E$<>of+8Rt0-k35bU;qw zaw2<}mJL4Ny1Ap?#u9tXXL$FhR+^n!F%8tTVwg`^1F@r1+b}c>9M}$X+I@-4VZ7P9 zPPNY-SVkbebHEH9g&PSMhdocV)8=f1MY_rqOK2{6IWx+R7Yy0l5Kzrm8guEt`9hLi zW!&;VC^D$-5SVRR}%d_ez$NxxY#>2aXJ;Xz`uc}!u)whXH8Fd$-L z1VhXo66prl$kg!e)o_6E`c1DMpzgJ@fp49j_;b_~>~ugv8P-?WVE`qy4DM3THP(o8 zwWo@j6@kxiGBa=d3^h5g;uGk`H6!W$aLLV8e7d$pr{{Ay<_Uh@N#iod@XL#4h{FIZ z{BBZ1oF0oEETySr;)6Ku=rm(&S^A_b>DcU`sxaWD6|R&uw%++jGks#OQv38EsEpDJ zbg-2c6{+shSdEsvZgEWn>{7{gz=d$u({nUnwR{MAEV*jQ<{o^!4GLz2Q5ol3njza% zTGD{YOceZxjU>0ptetD6ix6T~+|AG5LzhAf3H)R9P)Ug97rBF-1nv_-XV-(wq&an1 zS|f9N)u7M5_+-wGo?FTgtJUCi|1V5j z_kY-QhG;A)(M;wt7GUTA+DC`ZgZ|`nfrq4sr3?++;N*xbulK1;2Zop6o$9j_V`~>z zaTH+OVpUiH_pv{_Lwv}l9-ZO1d2U+zc45VOZkALF)*&NsWNY^vC|W0SBv(Rs?oK~` zd5`JZB>3>0OBIl3?-cVqTf32u%f%mU`|FP zHl}%o>oBT<6PQfm$MyOfPId?rRJ%a@m%e^25nk}rJ3;|arQOa6eerFy1%vx_h<))VUGCrrQ5W$ zj4W_#snwZp>eNEt2q&gh3)uDUxZre?{Uq})Q0z3>0hgx7*)9Ei$Na(=aDvq>OiDH8 zU_aJ2;5R4D(}5ahFHh0$zVy5k=sZHWRe&=lePr|N?0c#a84Bhcc)NPJXhKXjJ=iK3 zQ{&>C+7cqqrcAK<7nVffZQ){Os0^boWu=v^Zs70keM+%r;4bLQ;}T zX>OSJWJs{9fiFJ-Qgkb_>ooS_QJ-s$BOs=ek9f*a`(83$?X54ru{){CLgSt`ft6cAdnXrNG3)qO!9D)_r~2`A>!+N~2l$%b+wvs8V*h zn}Ad+3A`Av?0}Cj9%H~A6YiCxAcqxbf9hKMbH2>yNeTRTrEe=F2(3pXy%Qn^vQ`CQ zU?N#Y6@ER^C-!kGpF)9H=UNXGmB%J5hUT`q@Doq8J?zX*@eDU^>CUTyY4%RiWv_Z| z$(?~AzITeJ1ZQhEDiTE9k&Fe82sUZIiYidz?sZvFHO(V-kGXiPu}RmmMb16B?w#J4 zetJM(bUQ%;HG+kILh0AB0vjHuWx#IO7}SQ-&zV<#n*H-${ysf!>>cXeEXqWzT+!;3 zJ-xDCPr|C^=(foxZXv81G~;CYUox@fijQfUS{1DlfYE;!9>xEr;I_igP`E>ZhM3R! zEpQ5Fm-euROT>{WslW#uKP|M zQH782xkLmqBXXWA9;!aLL)Si@P@AAYhs`6SVTXyKg^xoPpP{ns3GY{1$xdVGst!u| zDSSh36HJ#kWP%hUVT0Z=YKcaz7Dt?2vD+8hxneg^{avElbCJ7@#pl(U?*hI4s1AMP zaJo|_?l6&kC*Nb;b{hjL?4|$k_N_3 z7osXs$aU%a2>to)o9^FtMCu}JFq*<=lw&gM8#xI%%i^FJWLG78kkJc>Ul0p&k^QG| zjLmm!!aEcu7o8bUnhr06GJvYgkpaySHIGOu&prnTagd%#f(Ir|0t!xpuDy0H89{uC zHf-G^6dXq{ZzM1cF+oX)!h}|{rw|Uk{X5@$y~(*66H-hcK9N^Iwl4%N4TQfEr8+rwU0>+HZ3m}n;r|9q2GXM?z2KwpH<69j{BQ6!4?6%IX zje_YZ{%Z-C8S)T2!9{^ejg*+)KHzpYhj6s1<60jkauf4o7l zmW%FOg}qQV6t}R`YvWYvJbtYcSE^P8H5&qA7goUBx@(#zytsXOk&jVRiHUcFsR z(CR{?cHlADJVTcv@fI(EICE;J2!?KudzY({KR3Dmw+!E@`tdiJxiGl$U9kM&=4T#+ z0t6hkBZ7Xvi}M)@%PFluVxpNE@VOW9la{$?JCQ)zW0mzOS4XYlV0mPlz?ledAnX>m zkjHEf2Sa(FA;t5>hn=q9VQZZsu>XxIOm%%JZcU5CFOxHGr->A=7|1 z*h1=%Q3RxPZ9N8Et2Wc=v|JS13^XGr_I8>cFNNHKX`r%;;r|cDN zCcctI$ydMh2S6JCl$#f+P_dY5Q6#0soShqTZ^djdCrsMU;G@WMAc$XL?0a*!1I@;! zRA5IO=|jCRsfP@BMAxtEMw$d_9qW$^`J1KAs$qraqk{)vksUlhINyQYkFQS{?sH)6 ztbB~rtO^i`)PTZVtw(y?LH&Ha6N?8aHF2^4$Pz?++p3A)U2x92*n9`sl@q(7&S~WQ zm*_Ic2DjVp`)euY+$2(^ZohshpspB2(~}F`=V9E?NIE=TwTflIe&+@jHYNaE6b~l@ zV%wT_^`xbfwLrD+mZWP#vNg$n&UZyGky`o-dat? z#W#z|ROmu_D>UT!h{*XhBao?}z5^{|?0`h?Zn%U^3+4Nbp1^4qxu((BhgQ-BjL6dr z3LR=(kMJWBfw@NiL^^!x3eWApD*ab0FZ+d%bC*O{ptYLZcnk=U2F=nG511<*3v#;~ zbKT@;>+t28tA8i#@CU*3Z;Y^7et`OL|FkXjQ2>%Yk$1{W_9sjJ`wEbbwU2Y3bL70; z5ZBPihnSV7EOKg&oIUwG59RY!ZrYdrAh(3lsCFegO6M#O{_Z6RK&i(=(MFar5||Uw zu+b+(ztp8b5A2MiK1aCY%Bm|M6S?@h4Hzfk|E3Ywl8B+jc$d&J7|J16_d5=nGte*Y zx8~n)*CNO?k(sAQa%6>vUZ!Mp{wQ4pK2$^yL3aUDTFpn$si&3eSrwvZNBlc!J|A~g zPm1ft_)L8(m%z6%;YVn1+{G_?x=$WA);N>@Zt}mn4oftMQ2}uLmM8gL2{mNC-=a)- zl0RXhv(}YLIWjAaOsvljN6Ku3CG-t^pnMUvwY~l2NWqi!gHJRvU^s3&WYnq%yqY6e z%o{A9>HhwtQ~EO(#>%cvSIA%6oPLX_Y)g>$Sq*H%EnLCx|C?NhuItK7{7rvHo-g+pgBk##WqU04>EstTsk|eDZvk1 zCjT5a4h((Z85<^kQH=o-!9`Q_D8Hk!HG&JBiHw`)(i|Ee1?Fzl-yusMCR~N%BJm%v zo&7gn9_4IgXoFW)O2JXMaMn#!4f8+}UUZf4I8qvRSCUrtW~$}MnhhW2OgrPKKQUmN zV%4|$kJq1rOUV=33&Gv;*<&-%0)0zC5hDy$Q4>p${$=AHySRf-vw8DQ{M`=48-F0K z{2WW#GpQ)p5&b^P-V}yDk{T-wX2AiY16NU?W7#rKBKy#Qgixcr6EK;3@-!Fl*@fDayK+`dVt$FD_0dZ&8R))|RYI(lF3Y?Q$vl zqki7e9p`H6z|W4_Mg3D*wt06>nxENvV(&NiZfzi($$OfMGNn7{@i0bVa$veNPE%$b z^u?>hn=wFdAdRA%91aA3#7y(W5IP^()&(r%-)>vLiU}!S;-`L&hCYX(a5Wk?DZ>Vc z-?@Xt<=*UkcW`t+o-MdG;$kfusgQO zV~%XClpeIIedXgS1q!Rv93uY-<^;BSqAR~jGCRR-ITa$^5pF0xOmm=H?E!&vG(n>_ zCtwO2m?HYuSV=~+DA|u4t6oe}Qvl56 z(Atsl*~rdyyx`Ljv)Z|d80G7;@viy>MTrt9lBp5gDJJ*+N5g3KDa-PVkQud4RP;zi zDtO4P&lMDH)%CqLJ0LE=g%@HCRGD-g4lT^gXY%y?dVc8{5AypnY#t2Gm&i`MuGtT_ z#x}m2vF)#kaTw#H?7h50%+I8S8<3np1uxe%l2cRs%ZDc9!%q7iHmZQ^jdr7!P$8}I zE{&bi>D&o52XD>?Gbw+;$R?Wldq&jcy@1;Q&BS2Ta4z^!Sp;Sh$Z~d*gf+)^15%EY zsjNNf_=NkW=RY<#@`4EgKo^$xs<+{J^~J9CJF-K=h~SJwdabb;glSH@J=nt%_v*(#1`n~`WFTpj?XOXZ@J-WZ z9@@dNrFf1rRyj91RUBuARNQj(lVK-6I>CE{RN!f z?g@AXP%)PK9!IGmY{|R6GQ8Q7KjfDw0(;Ue`2v=&0L&c8kuD;Xb8f3XPQy z+bu4Lzjr_6RUTYm*_fGcn*yzN8JrZv#1@81)olC}2w9x8C(9Clz(Dm&bnLB87mx{2 zunivAU2}ri1#3!4_H`9}q;mTq`hj9T5HB7+KUYIxeL@Sh(Fk>GxqMD&S5$ATF)sS{ga$xw}kYDBpfA@FRBz1zOutQ>u(4=pzyI(2gC4L66BMn^4lE@q$VyL&b z?^Dh`EO_p>2i^^eu1XZFg!=c@`{`>m zf*%uMUw*w3VgpM{N^Uctkzr$l&sY;@iiYT1HWVZd9ThKzT0H3E1#SUJu^OHAn`o<` zQR`n+USM+*q^E`$kU8U^p>S%M#wc^2UuOF|0V^ET=K?e7<0?}nu^A*SVr4D;sv$HgPrk_-R`%EzkF)uc{J!J_dw<}uQ&*^j_E;rZBt z)ch=`3bVJQa9z1HOF(pB@n>rQTJ5>Ggzd#7M#l4rl@$R_i=w|j0lzVw8@MXy*Xi$(`R zZjpI@@ANi=hmcT9H7lqJL;x|Nfcj@!cbp*=d38I1y2UUSwrq(1?5mqUBb@L7PxQP@xLZ0QhBEs;3l?1j! z_mV;b{z-+8BQ`P>SUv$-p8S$!_d55eBvNP#_HRc?Vey=8dmLFm+8`0Ek=8rZ?f|&; z2-za3APJuGYeN&?SD+2Az@)d1i{oupPC4bJ64$gVNF~qLM4$7k2BsF8LPK}ol$S?F z4=1jzUy@X&cSm3ew5!DpRUFn}4=naRWCPcfP=??g7K<5XLxxZbhbt3lcF?t-rIfTt}3`mGBN_*{p25h%EoKb2@U0MO+f&7EvtsZi zV?Xe`syYwTkNxVIm9-PSzI+CJZ(*u*>Cv?Pz&&}-1+IYjsyoP}zE~ypT!o;DVv_eE zfsY)~vTFcs{rCTkY19YgOY2~nV8CfpOn0=RvYI0hUu9Ch0)XgL zuqm;(20p_D>uVO)IBYFk19R5=F_oH1)vKG|a`0ivu1qX5kr$B$#lG$3vaq!YRJk$v z{+#_KqY#L{ytDDIUT3Cg)AU(Z0>#QccF5piFEf~L?YDfR!sG=;dX~X#>xbrF?WE&5xd9W1ey?1416%^qnCy&+D6-y3OvAYL_e#B*8^xFvn3A#ZN+ zSHFJ*v@pW+1ybHYLGb;|B;cPjc2ig$`1&r!35A-d5BFzUx*E~35&!pjj1YGUOWZrw z#*clvI&$wll+lOw;EuoU3win2V!brWWd>BtApJ*+`ELdF_)VI`8E(lbb(;8CV>4_D z*94D~1^WXNdsv2<5>;!u9=Bk1+|1_zQ~gxBOb$ zEN70UNLvx<%u^V>iRt|E_U$nNijLS02cOs}~E{~x5)Wfwn~VDkE8&-?L{#`qV| z$@J9r$K5j-Dsh!UqLx6&0HkLSG*}9uA47zRhMCiJ%kNwKtga$hjXJU!*`-yI8-uDF<4=K=eh%f+uQxfZ893k`jIn{$A>Ww|OZh z(-iuae#^a+L61J1Z}<2Rzvs)<()8w9q8kZ3Wu80usyV|pA}j=+qv91T`2oF)h@r99 zU^YDyT~1!1se62DUb*gVDxCq2Rc@zBh&K++lpIUqNXD={3hGp65lMt$Ik$QKt5Wa# zj6=;$d#zPOtk}NdjkixdM_?NsdNJ*AU!L$-w9_Vn>!^lxqYtt8R&@F>r;_=Sa_yvi(Ak;RpnQ}>-ZfMeQ;yS6HSbT@&b{+Xw|w3eR7Jf_ae zn&5$HXhr;DWT7LXxSZlEpck~yO;#_AuGQ8uErGcm&jb?G=ew)g`zK0IwneKqH3Q{W7`Ra8qXh@bGye(a>z{ zYOIwpc%Pe4(m52*1^$wV-T|FBJa3RHw^s!B(MX^YUSOy-Hq4ra0O9qkte&vGJ&R>n zo0-wON0_<~TWgL{?1KiM==9tVt=D3Vo-v7Ga%`Mhrx{NymMGoa;50@Iktj8P%xx7` zH)>@V`vt9nYj}-2-dSt6aw<{njg2I z;Iqt%7DYzh2eXA~Z0JM)-z=4ln9G;J5oO)Xp|RfbhOBApyE~fW68ctlGzZ=r3HG&l z4%9#7I70Rlbk6cp1z}Y~J*zvHO=^$wCQj*m@H%n&WOG+KWsyYEto@b_YJ!3OS&M}L zfcOQb!W}SI?Zc1a7;n$G^G3dK!%yVUx!y~wyE!9SS%r2NZ_-rK0A6PQz$bfC`CxbtFqY>G+EQ+s@Ua*G^?c9xGa`K!q(ELH|C( z349gPh<`J1dYl$zVI)8;l}sRTO$UX~^cc_NgQ|gB83a@^<$~HCgy@R~VCKtHae&u1 zOdN+8@x_{+!^C*^_202l3-+TL`}Vh)i))WZHDEIqUL*%D8+nxP=WO7?0!eK3T+Z4#2CMXT zD+26IvPT?AwJd!7&M0MS1#l~j_1p=14Noss+X=8Pw^e;ztP1L&#Qh48o!~vB2rHSb zTFAAxH%Q;w8z`*5<6npXT>!Ll|9Hpny^^HomFf{y4>t)x%&ayqw?9u^pQXOp`Lr19 zrd`;ZwFl29%)e;&u(^ufWZ&=6DNg(QZ5Hw=&ZPz4_v3_(^#$YJz0KG)mLqbXi}fL= zCGGwY^P=g-Rw|f!N}()cB+5YIQtM8Y8g*jMYhYPh#rDif_vufDtN3v*nS7Q?a+7%A zCVtzX`u79&D356t!z`rZP0VDhEpQlFvb_+%|?dlnVQQ4;7w!vyki#0VHOPe zYwo*+?vJ0N{KawSAsrgjU$9zWK<34{;3ftLeab+y3#K_n^}jsQuMEPzte+afrt)!P z=qhdsf)fASfEiV=bm!OHRS|0mP=F;mD4Zqb3aAWs48}4R4=Y~+Y6}-m6EYL3C^R*r zPyjDfNZbXaog&lpB0MC6BUs;JrT38%tAd)gw+Kr4o@qa)4afvM3Jja@aJ33cKNGnK zD{H-gO(vUuN}F}(`p7PzlPgqU@BVR{MfMtUA+LnP<)I{dg!n$97?Co^^sFlA%3(w5 z%B}XbzQpFY1K25c-_8 zo@1v-&AG$9Z7Q(pzADt1(CM*qh*y~Uw$TMvQGBzn=nbo-9uEV@&Km(5AX^}h4THu( zSDNShMxiiB)E#-BW!{vi6+s9^+N}4;Ym%~NLC((qzpVPwV9|PCKdAE}tRQoEWo;IE za}^B3Jjb`20sI#|CZ3V-`EXmv0+LT?L03-bT5V>+pWHFt#jX$ z%an-zGK_>);~-!04@G+6oYr3lQ$0FNgv4=>cRG5|qGdLAp+)fCHl^ppB0><-!MjRz z7>?=0dqEYBrj}6<5Ah6!MjeZ>V4fw%*_tqD-9w~)^UxX9Az#06Cco&MHO8=zP+cxS z@Y6E#CVE~A=}(FU;!S2603jAO>$O()F}XS`S~!|Enu3JoW!nhFmjL1XTb#i6ZoyQh z+koZked6G-EUcFrjnrmAcStgUQB3Eym>xZ^Jac{VJWiU@XN)Tig=K!D=sv?Ad+Xe0 zhtk$8W^l5VA~MGkH8Wb)n2D_+j>YI>?J0m2616dqg9HQakU?t?)wErsS+(0IQWvEvW7&{lSs6rfoxv;*dgq+@MD)-_~*`yQ;>r3=;@&u zw2lmTyo7-oAuuJ=;rX>#N^Za@LX<0>)$r4CE@f#q2#R<)gS)5^=%EQa^75k72c)}# zBk{6}#G$Z{ehq&DKz~Zi4_;UiD`dWJiftrCxaW9w^!TkcsMZw9u9o&@Dj0g_M4b$C znw>a;DZ@q1MPe~vu_Q4B^6MXFja>ykE}W!dSSVRlXojbSTxmFxGY3>qbRbbW-8t*Y zKYoK!fP-j+3m&m5B8xGKFYB?<@RGx7q)gPxF{=OpnKz3-s5(-kl{6cEWDGMS=2$tg z46fLX#f*z0tCU+pNZ)ZQ7#;!T@FUma-bRrs8{0oeL76t6*S3w!0DRw{m~!-WYdW(P z!*25a>}6B|1+K<)?Q%NdBMtjV+J(^!HP{z1@wo(M4DKv!6Tqjd)xCXCQ`2@6-xVP) z$y~e+5Cf2)vh?k0j@&aJ=Hn?(*G=btXrsBLH*G9iq4Hi37|qxoUrGfLblsj`>)=N+ za16RdA3(STd8?w;m`v)fK?h!j)SIg6;L{3^xv8%ZCw6P|i5K~|4aK0UFbX2^%(7jJ zyn(D>8sGV z>}k5{Wv}IbU}#)7G455~1(tt)_gC zwUfQQ$R1|&yHL_z#BR082c1P^i^Ho(!)yDuJ{B##b2;a>|9~)U{&=ZuXY847TWaa9 zil3`F@VY65SsZ znk+|+H2_z*mEkV~=Z7(fHqDy(FIzvUf=*&*2ha-#JQ58;JMgpU0IA%I@lPZGmr)dQ!|W>s;AMwQg)67<5h_X)Jl&|O8+lb6cfNW zh4&=6`|wPjFyxW{p^7Og+&;@7CJr}*rx0|D7E-X&xSjn`as$wyTY!2X%a(lf9fH*W z!5Y6!(!vCX!7DZWO5UaM%~!zV2YX#X@gq~nxXHQo{5w{B_k|>?t@IGy8-B&-X+VK3 znG}ICIbI0iouHyFU1!pDm|{uT1mc6(tArujPVyfe_f8>3n>)QbY*tUrxj?Ox;kB0A zu=aFfPoc|T zi4BlWey!F9nT^*bnz6Lr(x(1cu68@mS$1pKCy5G#9)BoongKBCU! zk`mc8ieOpzepzQ&fd++o{#40`1fjEl)OwAnno_9V8yXBbat5(aPFpnXGd@lO)f#>n zq=8@x&a_@+2@YD~(%(%zT1zU&b8ElMFmb%jSKp{rva9DUza;&g@h9X>_)5$BjO01~ zfdGX?Fp*a!LRerJ7hnrVUTyV$d6H7)o&DlJW-veSQ4$v9&B@W z1EE)y@}EC-Z-ef|``N7(nhWYU5u1ZNOTXhDC48VY?@e5Ai`0XI52za0Hy2B$!#+6UC$Pmut1DH$j7}l6(6jd8-IRRSU3De z1bWEktx~Z(!uGJjt>Zf8`Jc4Bb<8<^_CU`XeU(i1%aSj&3u8#!FEFiEL*_mrcf3Jn z<`_(54fcIBB&Nb}!uy(5$UxwUuYJ;y-yx^UVdWDT3s zjsz)`yPSw?H~N&9PbRiFkk#L(o=x+um7=2+CXp$f7X5B{00I%foMTT}mLqf9L{rtZYbx&EM zVk3Z*C2xr4okQ|Ia6#`_hBG_ICl((Ewa@-0aTbg7&?|e2(z0XU;$)y*Kn@D44RfxaEqG)gtOb1i_8A@Km z*u$Y6Na*$+RFcF8=RZgpbFW|iUa zVXOU=;_lH>&7h6hYg80Xh&D53XIUx|>L1-q6i!~0XVkjKHjv#s0yS>jn?Kg8=#3mM zD5EC4s)Ao}TyJQM+gOo7V4&>#2b^SFAJ{UIi|YlIcli=A|1mey!D+jAr^Uhkv9KpP z!%ZM4098wD3W$UW`yE^-1@pnYdHmVhkfHs0QDr<-VZFU7;#)xMAtR6yB=&1tZMfMw z?NnXn=>lc3pS{}lGfWYu9~NpaXv!R01q(yQ#$E^k_%I46mT?C8^4?`2dzK6Zx$`80 z^ce^{tsh|eIw`PieJ@W@XkJkyBY{3wueJjIj2b;-kgfc7Jnl{b_Uk*~q5E)uO->Cz zslRi8gW>YZ_yDj~`pX~aN`J)B`?re*S5@~knwakI`mPKt=>(>xa00EY`0ne%h TqI3{0vBYQl0ssI200dcDlouY% diff --git a/kernel/kernel/files/patches/linux/patch-4.4.2.xz b/kernel/kernel/files/patches/linux/patch-4.4.2.xz deleted file mode 100644 index b2133065372be371500d244810a6be679eacbe9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60144 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 FSz7R|12_Nx diff --git a/kernel/kernel/files/patches/linux/patch-4.4.4.xz b/kernel/kernel/files/patches/linux/patch-4.4.4.xz deleted file mode 100644 index f8dad41478a481cb1cea5f43fba73f8f86673ce6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200972 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 K000001X)^QXV_5y diff --git a/kernel/kernel/files/patches/linux/patch-4.4.8.xz b/kernel/kernel/files/patches/linux/patch-4.4.8.xz deleted file mode 100644 index 95b5d26458e7f09b3eca0a14a0e249048df5337b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331620 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

wz#8d{oCAsAtGu4PRQr&Wj_?&U>ewuL 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%0D37Tu& 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 aQ2k*e4wT}8MHOx=S?&(4hD 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%0AUOiY)>ceVTh7J{{_D?_@p>|w> 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

BSfF+ap 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 W;Ne$0DNsqV#Ao{g000001X)^6XvGHr diff --git a/kernel/kernel/files/patches/linux/patch-4.6.3.xz b/kernel/kernel/files/patches/linux/patch-4.6.3.xz deleted file mode 100644 index ea360870849e96739899e675a1126e830fbdf35b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103616 zcmV(lK=i-;H+ooF000E$*0e?f03iV!0000G&sfak#~APcT>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$x*VEvLF<#vA5JV#^YUrax_bEA%p2vvz?b8DA`>XcuK!h)AfIsu z64ca!K+UXdiC5;n+rwQSBbYtbQbe?muh&-FCn%Hhsdrgv1=KjASfZRmsQ{KcGOyxu z2XjPru#O099*;O8dP|k@*|2-YQ0{-m%+(jO5{UOb0^C#v57b%(C5%`)Z_{0b){9tG za>O%rdPoEVK6KdET*45CqNRcsx~}5 zcw~jSR>Uvm%PS|>UJxc<3fAbpS%6nn+4V+$lM8Cj^*_5bUXt#^4|MgJAV7YFWrb5mFj?~c?i65irZY2~Xr%Je?WcBWwEdbhp~se^ZMa%r z7ShJ812odSYuEBP|3xnFY{6lM28+p(7(g@7Te_?G#v1gsuE~2VgEN1HjsBDx_d&@q zMUB&5<`_^bsKIV*`31>v*J^XIJE5CyHV|*nmScToB2YJjdh;1IYoyMON$6|oR<;;~ z!NjvtJtW(Oy2%4f2QAu5CSKlC>;oUz20i}b#LH&vMVe91qR%C?{Ya&Op^iHfb^Glpv}Q zY6W{q5Mkv%f^`p9Dk2RQ`6Qa1APq-Q{bF+&z4HKAENg+h5hCjwUKiJ*zC_r#6g4-A zm1g_lWgPfoS=M(S+y*DI9nXQEkuYNM+PkRoCLPRmv3Cj*!680<3FLKpsaJ2QiTX^qxr@D1?AI$hD{GK23l6vDu|}5p z9}Y*jC>%vXW)tFWDRMOZM?*vbs18GrCaIck5^a^{YdpyIXhP&gw;LTBJ{23Y30ufc zJxl)0AGgyiaxSNcJ&^^RH-uF_f4;%QshwwhNCC2l9_b0l+HBvJ%;rf0JI5+a7nG9I znV7kcD!`BZGzdO-Apa>32YPb1>%IENW+qtuqP{B0$x&-b(#jQmnl%H_zV2^5r~Gdf zP7NV4?=CRNfsO{2=Z~QnTa!4+?o&P@0a6J>gEr>mrIV5YbT-+;9PLeA>bo4^w0ZD? z^lyj?w<2Q>bH+*Elsz7HAXCg`so;-dA--uwZ3&5^)?Z*0G`5<^B z12|&!^VpiGj^G7;qX@!Y9WPaJ=l6&4j_cW$``E>;%D9hMc;C5f2$LVOROqSpOKwwD zM%4>^E%xA|_`B<{XDK8i4>Ciy(i3W4^hlEdH%K;05=-L+w;!sXlIa(*JeS>(Wq`6( zV2+2t*;Z;_JA{=_YNDvU;rCWJ5?Hj6g{+#4G}S3RZQpcT?*)M~RbLt;6|gV|xOlbZ zfJs;%%so%+<-r=Y+Bnxj!Q^1UMz|864H>5=5wGrb&0FD)*1``idj+K(natcg{k>C( z>LwD)eAh+VTDjXL`Pk_4Rc4xgI?l`6o?^s2(EK5flstsfUAOYx<0gmIbck_#V&o|1 z=j@#LSfU6_V9y2}v&0=RxsS{Zf zf{;|d&TY;=QDfVHiaB={C(O3jr6PR_Isn>fFX9D*)C?Nx{UpA;R!q$+lN__~>ZHuR zsqC!Ek`#UJc!FFw_j&$gtOTlGm+F(?r6tLBrwX_xdtF%SvZ_%_Z@iQ+&LB^u(k7#-m zMbCQvjTj^^++%02YWc)9ErTgZO0Hk%!L$SR8w|ei8%{P_(2i#eN4(GX0JDas-DKga8N8RpSD~2X0Ix zTSGwToPz`2ki{b-16-35W`Z#}eFo9-c0ONer^HqP{O7#Y=fq9nWy|2LR3>V<%qx;P zCL3iE9_0$hlAq4cJ9PfI`!IA8N_B2Wy_}o~GJy{DD>vZcJAW7iwzC{>sPtm3kzb~m zT?|#~{L4}a5)~s^TK}M3T_@jeGUtgwjcvCX>WlIiQ_^prA}5Y zcQ~Vz_~FptZ3h4U!}vv);~n?O!x_SDI}o;;I0V7Z)ll^?oFfK^{vMdG$BR!PtGa*5 z*>Xs7?7k@aF5p)K4q&`Q?|I4eUZYvTo*U}ChmwV*S(Wf$jM)dON2>e#oK9*0>J#R4 zM1L6v=h)_pz1Ny*De#7tCe|AFYKq)1oQYg`#q1^6B>GJzspQi+z}vckci26xAn__n zb$2Di**X>5jpoAz1UaNGjRUrJ__7;;iIa2FQuRDkX>U1@r0pkv-itp4=V&~xQ&lgc z@_MSYYUm_TPg0SH0D1X6%|31D`>zKsT2duEmH7~kV=$I`6m<1nmdha5)^COxhw5U^ z>iP`42=TQ2I=xBZAm7%^MA)8K5fTyvFRZ5q#HKI*-?c8PAnTfo-567xVO{b!=zEJ{ z*85dVlWLyRBz}mXqJ?~E{kAR!X)SuzM42{L|c=0Rs9(;Sd_)KHw`- zJ#IH}fr%O<$Ab$FCumT-bDkD2K4yjcEbt!P?9d!ahhqB)%RrIf$bwA50ZwoBI)$); zQc>-m#X+@dx{iJ-s{eJqDpsLjUy)#-?|;j7FDg;hv&9rAUf7ahDWy7GOujRv&n>bD zlWY}tk-?PzQ52bprP%)Ed8Iu(s#pVK_{Yf-6*6b(g58yPOf8UOHdH}X=+>7Mh2ACJV*!6iq05eDEVB6Fy+suQ(X6t zkdJ8TDR_jbrG)cJt}08a?CnaG)bR*%i*9qEOq0EyLZ007qMkeb>3Ff6G9!HMH0O4X z!_fU|_z>SEc}->PCG3;<%jW+<6A#ZI5(ZG7!A)th>Z_r9DaA!C^QC%Gqr4e=>~5B& zka26JNjAU;f3C>LCka*qIlQ;g8zI)sR3rPb84`Y;KSa|;eYQBdXc%*(7L1}pV#$mS zu3*;W0gG0D+n*L-cXw432u1=f@V{}B-s!)^M{@DsvJGFnkMpm}ttItfWmJK0kC5Y) zb$pr89p7VSU-{4+oF&mBAZ`y#Y;}M2vdml@p$zrYoPg-2`gOQd!sj0!%1TnnI?T|8 zu00S@Z_wr2N#*SKf{2?I2&ftK>hV}zDopQ!-wf+s!f5<1`^XES&yW8O>Z!}U;7;)A z{RIow1PAr8>?a&mioQe5g0}OWYRjLkt(T#X>`h;5?a136O1|oxRfCaFP|uae0!DNk zfA09_@C5)-TZ%u-$h9}73;aJuzVB`IW(xvYw_3vGs!OY5#P@$IkHX(9vFtEy`t{v!LDoG|8@JXy%a`$FQboc zk=R~HeS)pho=ZX3?f&-$4K#>2vLEKoY2&3k@nXn@YQlk7E>3u4?|f-=q}(By3FV(3 z_7>MPT=6VxiQ{E`-taH=E60)>8}9s$+06(HCxO7pazDcI`%_YiXFbJ;?oYVX+3+@t zWxb+akS__rhM_pn^DK;H(Hh!MNhl^og7ywHSC3_PL&@b;(81%^6$0l=ppSYy37Wcb z@>Xp9=gAMidBe+Tqv(otH)jSpL?^TWVZzM~C4r5;BQ$u4!eI~Q7G!T5XtM9=E1tp0*NKl?H+xrg{$w(7=^KVuU+>DjqguC7sW zO^|v>Ent|pDajQi#Q&pF^z&@^$30W6c_(Gq@(L=#1=JHG$98p!L)0ALNFKT=@ej)s zF=C35^icf(yFfnjj^QrSv8~z4 zD9?yt-amIVN^A4SZsm}v-mmMSLqVSZ|7hhmelZ+J1@HNduo=8HzGb&=%TUWpYWedrnu}wd*}7}D%K3qGgNF9xi!C6WG@EMj z09^{35E_)M=D?+p=t|Zns`_lK0BJd`_JEB!ut>dWvD#CrQkp|)hOJa0yCGc>0c052 zmj$F=7@)7=329{Ff>O5STSt_8Y8-Q_4kGU(X2{HG5H`V^FIkF3m1;Okz$dqmr{nDtRA^t}y z2R1#$G|+`H7zO~KEZ%dg^nJzfqKnk!=x^N`pV5H+{j#f19DJ7rLn7FnUp0#uOtP6`OZAY?R^@9wgws~mlQwZml6U%K{5HS!cA z-!g`9ZTGRv692gkdd~7-2AZ4B-!?3!Q>Aic`pLVzS+tHvz2}#t#3IRzKaN=~yhkY@ z47_r)Xt0p~fvpxj9vy@!0jfs4bg7hkI?@*5w36QQ2M|Z$fw5E4CYi$K_m|D?r5eB> z)A#G)O*RyBSB0nAe0=hq(n43iS1!xz3gskNiPLOQazj(JJzjJDd@-XS^IYN zzh_0GrgI5xDz$+9CV-bJ>U9+%PyUKUdU4-tcmt;NKNl9Co_gS);?`_*RlX#t=4y;z z(xk2=ps_Ayqoiy=B-Dz195XlD-)zmX0SLMEWik6`ps~r~zvBbV7yCD0|K^FvYZCZj zxUT|445tG*hl(ASYLuSBM7p@j40zcK_Q-b(2b!2UmiFfk=TDcs=6##HkK$&@hV3HI_(*181~Xjg8QNoL zPrOi5aGzO)eBZgg$v$VKtMwpJ@$zUy7X}g132Nu-e7=pP)LbgYW+F4FCJ_9@xpLh+ z8-{Z??!A*7tsM-bh|q5lrV1qCfBtSoQR|1iVJx@z+0%7D=&}>{PCN>u%Gwc_6t)g; zv0ycHrAARObfvhbGlu^~{`NK8oeRVdaHKZ}IbLON7{e3F{K6O>8iv2`Im-&+#1yD zL|N-N`lLf*(!t%;he*%R(+npBP8L zJvrtrM=E7SL{=GAm9%)wR#H292uvduS|za}boxc{B7xf1nUmn5=(7O1)-PyEK$$Et z3o7)4ghbtK=lN&LJ?!1toD_wXFYw2vjb$ayZ=GuHmpWMM%4t4AL4LJ|_NW4pt`U@1RizHIPwImA$s1^szyh zTdQ>6lkaj=yjm#_fB)4;@_T-b?hWQj(>jWz!yy#6O_fc zAI|fdf?wmQ|86zhH0@qOi4wr=*^!;r$H@Q1IA3dMWAf1MeyX{PUOTFh5yJDa$nV5Q z&INj{1@W?TTDPVJenV0d#-jG9Ne(Ciuj}R3-Vt2>VerZb4TdFA*Uk50z)d+|rq^pAxu%;hO}{I1%03nXM(L;R3kIz? zl8aHvK-9%f=y0*=j@4BLQRkx@^};{9hTiF(eBPuGB%HEsSFRQc5#T-Sl)Rj|d|Fg# zvQTid*kT2Tuut$bt3SrL5-;XoP)Jwo)PrJUt+`(J-n-Lz08Z{0)w88dhZci#q=1qRKnk|TUZL3c)F zhT0})R!2Wilijx7&~8di#m>k=G92xiSfBDf>SSqIW(AktH&=E~)c|kn&CqKT;UM>y zcn(fdCkW(cjw4mX(ee!?xF(B0KyE(l3-UZUFl|C&;#ZH2yBo9%r3xB;M3|K+AHy=S zr|ne{EPiT3c8&bMn2MX;19y=$>3pHl>4LEFGhJI+kA(y4tVv);%A~EIhzc5?i)-mF z7fX;ViG55*c9X*EB=hoH+^B@LQ8M!v^q2yf{(xt+43}!iQ2=nRnyEKixmM{HV1I|N zaTcOsEOZNFim0V%e}8j!BagVNpn-scD3zPWEEeq5r4PBtV;O0Ow2}GsItNUhQV}ml z#)YXLK&Es0{c0U(bl#H=;M3&OMH3Zi!M=I=K#hoaneV?bwyelc1)SxbMS`se)wwIuMDO;W?)M;uwDA zdKxmwMq8NqdOdRn%rXz=UTQD6)zx~X%;EyuT`J})1y2hUDd$ScvC%w{X4XQyH{&p$X9wx1N2|dbCnIEoq$P*6xA1zRQw2>N4d1OqKe+k41%lTe% z+l)#5potm?Kg1yh5BC1Xzfc8HXw;ALyhG(}Fz9P7tK&&0UxR?FZ-okzP!JrB>9lT8 zv;xhb$0yh8qU0la{VWZpLX_>;k44nme`WvPD~t(u0h3BD(xfwhbuMZa5k#-(@<>f* z6!v}ewBx;UF#JRq^7Wk8tsgNFmkEY|QTrqgX11N#F)XasZCIsR{4gM-LS}jOW8R_r z>9N}gLu$D`iOl?ThjbE^lzJ-P_Ys7DD}+%%9KkqoIbp9^lb`ZB4;1K164`ickdkY= zoaz~pl^11}$XMonxw@|YyV4=v*VO0|^zDX|13TmWL?3RxY1P9l?EBrR(tL<*6NLM9 zu$b1__p3CC_N0&f6H6GVygLU~mK*u2f%9B6&;1|FUaQi_AdX-=2#;Anlsq@S(W85H zdyaln+8{h}`m8LW+H8;)CdAX2Ig1p1!)=(vD+*wx=duhFScIrIJ8gx&lvX1|ia4+i zWVK8fkwW-mBFPdJb*_fd=l|c~AB>YD7SR-?BGif0oS^n=SJ`2i2W3Z>nczzR``As{ zhx>~Zn=l3kYn1N&1}^>7tu-J0hSd)09pi!y;w<8wDy?icU`>sjWDr|A&U-{@fOA+r znHgO9C7}@Y`-?j8D)?hJ%%mcoBVlqVnQ8;_|Cq36@`Er)Oe(Rb;ss zUCXF$_IZaPwkd4SbZVO_0CWVK69Viz{Ue)22eKhbLJdRL)|A-@g5ioxhVnnMVytADUfAXCfvFt@TH>M(OANM z>%QCkQLJ{}E%{Tve$|hE&sVGssG#L^1BImxe-z1zq7}yDgx*(bkKy+;vm z0HL3%j}`4nkx_lP<93!+#c`6WjCJKLf@Cx=FwH-ph1Sk$M?6xkr_qXK;UTkeNQ=K! z#&SkwQQ#okDpUm6`R8Sd$DQt!;G=x;&|Y%yDx#1tkYJdR$`{O4<)|?5WJMQaFoW(z zJxstV&L2qd4~HEIKkK07oZhI}9gp)t0|cB(XGnI=e?O?E79c|M4Tq7cluCYj_YlT; z$#e+t+ClYfk)QOK1k;SiuxuXEd)5#8FXHS(Bk*hGaXpan5-V`L7HkmbHgIlFw)nCy z&qUPGYM_!%S+?cX`^Z|+(F#VAi%rjM+UzNZp>#w*aC1fpel~9>bS$+cB-gB6Zkm09 zlJ>wLDwH+lfR2#^uPnE zOLSQVhWQhNJzc9*!awS3&hO3Na9Qn3*1L8P+Xwe{K~Ye5Ph?5iAM(pk$iN`kc;b>^|(f?yBcKh8s$g;q@m zMK`~LyReZJLp|^8QsTQw)l0Wlw(cM?7%_s0DN5 zFlRnJgzQ|`^haaH+hJn9JAd-wbhM$X&Tq>9OWK+p*2H?QSIAwykAp6yh(9O!tSS}k$kqY2ob z^nPRyP_-gfs++9pTTI*n@D)X_pFYl1y?dg-IDxe6)`=2jL-{*Is~HWs;A;WY8igwF zLc*uXdQ4eWk&9NK-kT&9aZ?ffj(*j`8)5Oltdh2C6cn*neLHXE>&yq!I*+4m5I5%E zg0)aCu&JV;N(`O(Ld}}@+QzzJd@rpI8Z8p6xXFon$_o}`DaBUe_G!?I>pC#Q$R~+Y zrVVx)0LUG`ugn(9^aemmN!*id+Vw-J23+7u6vFJW`?fK>u}nau&qdhl@q^EVQg2~B z0GN3G5(%|OOOJO!Z~>IRwuS%Yaa7(sNPMea%vldJtyKIGNnfHHS+$PfPW{2E}1`Z#?0 ze_J={-Sl!_$gc$_e{=kX1zTwJN@BNvk(4^c6Y1%au-OQ+yFj&vM0;Q&pmMHP0zZ)P z-V#bb$U`M2fJPYk$w7OrWK8}439jFi%^hRaYz2!|LM z4n}$NH2B}&XLHlEhwVM8-}_UzmxxQytEX%`quTObO#Pmvf&t0oO2u*1+tz1XY@W0% zchw3LS6PNxWhS)S>GDzU`b7zKOEyeW?-{b_iW0Ro1BFzZXE4J#)R}v%9B*sutA4!G z;de3sZKQxkYY91PfRL0=xwwp8gQ)>5^KomEg?g(~PH#)Yqi+vM^+c^3Ji@mmn!8UJ zjf*(Rshtg#Id0bz)E8eM%J=-Z7LN&rsxUeSsIsFe<3g-3a<&*!6Q4`0K4SHk$CA$c?9nYyda_pVt%vFoN15kS zf0uQ<2eomKISPR-TR4WGIZTPLtGr+_Wlxmh z80ZT}NjREN*@3*&OY|N$I1XFqj#Q0K75jU4lKtbmTs4iH#EjAmIjuQTEi2jgc>pDv z1R30@iq@WRIdwuiAN0ekV6b88){dN*k_Q&lcZ0Jr2Lo;#EG%qdD_yYF4R+&iy-!KS z8)(>UxH^eguin97@?-)+n{V&wk+n7J?b{2zU`qK#isxso>DT|Iet|JCymRf35jsPJ z$i`^C|M9%Srd;{%IxN-nxQsd689NvEIju=K05TC?BhL9i`48a4^lN}4Y8Ib;<%XhI zt{VUeaYO5Hi4`nbw4GOgqHXq7*`vjwBZff_|4ex2R?9<9wgMywIiw)2iBov3gI4#}djj0)EvL z6vyJ}w9{EXDJxc**tZtc3$Sks5{-EG4tzmYy3M)t#kFT3q#>@jd;=y-!8q(1E5r5X zSLQ=-m&6B$rB9iOzprt>AiB6BiG<~0@Rnn0{KzYn@!BvF@xNW(`Vh?e@E>q+=AKG+ z3s=9K1k<6;d6I4A=LdN^M>}q@bh<&Z08m-`&;54KKb08hoyTLZriLq26GEr6b7%N8 z4%Cn&8MZ(Ka9e3f{tXmyuTdR1+_qiLv|xIZ`GOpRt7u_K+gnVzTcxFB;d9Oc`u~_1 zM(*kFZ*!p9u(@QaH&k7o`NDW$0-Qq$2@OyftiA@s3qhLP;*LF=wOUN15pS(Oq^>nm ztjhGt@rs9QV}8$wnm=njgM>m zg_4_)p|H4|lX>6@A~GZL4P4^ZyE=kj%?U%X9hJb9O9#=VKJ{LO1K=x}5E+Ac4cf>B zfSAigL=DlTPO4c-?KLK1FmgDA@6aHHLM6>}dJelTq2qE%29c}lj#)5N#ztw6 z9_Z3${R7dB3htL-Y%s@n!hcaBbZt_UZlsc$Eg{TfFmYCK%mDvb>j#z5odrviut%HLlfn@g&t?iDMS@=ItpjM=)-*rP;MXTjs*TevNqA)LclVi9Ah7((D zxhP(1?la5BitXQ1B252TycWX0cv}I?JR2jlWLvI}9z0p{IA{v+g5Kw7fM%;5|) z(CV0kQj(ZG^KTuIC9PmN+!|YLZoJ&| z&?6DqO;s`ba^q2GJ2IG?d(y478v9KnY7*^!;_5pj^{4C>I9YYS?-0SnjDJL71NwDC z#yZtNcxP+|#d}hC?Y82T`V^WPR-X}woFqj5&i@Jdt4#Ofrx(KO>wM%4ByO!+rq$6z zXExp{6Ve7Jg|q!{d%z|u4jzkcj>%AU;_WnWpXRlZ3La+4a*`4eK=nRUYn{oR*y7Yl z90KIQ&P@7~xR^}Z+XziS6UN@=EROObBjd#eYLfTgz~WVq;r)nHg7)2Jy8ebIy#LxG zQR@GHQYc`>gN+M7^55i~#D9UYJt)(Lia!Pi)=AMXuE028y79g{w8q`+#uFb~UagOS#Q!R}Sc12s zI%%J+Yy`+B>Ae{h+8~|Eafy`*(ed;DhL<0d&dkwM)FA2m)11rk1==PjU0AINH*&LJ zQtT@W1IO5!`S<|=kF`*Bp}I<eo;l1e$m53BUMrFAG*JYFQL+)#lRm#}ea%M0Kegsg+;i!n%!t*X{bI7&2V>b(*Q`HwYNNSMwB79cxud`BoYq8 z!1&pMD^*5XAvBpxc^FPLK({i6k+`HlaMa!b)YMPn51B<|R*5Ii-=jnW{C)8Vu;sDw zvKd)iD(3je@q{Lp>Z@fFtOo-t3zFnO#OmyuEZ>PJS5)Utwxxs0WQ2%#ErH(>pg}qW z!Gy>TQ&yMnopv=9lysm{3S2S4^9Gzh=$-zp-&(M+_=+1Zxc>91PGUl6XV^v!tw3rz zF*k3^D!C5HqOCxv6w_(8o{W^X#nPHQgQdgVgZ@dZ))HsB$!#n3x4}ywhNdU}>N=Nl zJJ+Yc?{kK*!jkuvy4}lNWk!*=IZio0dq+W|D<-o@kTi7Lo5c-G9mkl=qlgP_41Nlx z?&`G2WC}q22S0~(J)7=uLg&pd@Pj(3>s|FeLc~w7K<@h0tFaZYF;{-XX=&(X)ghvq zKa;PsqQc^8&9?o%!vPV-FOO}i6_Xcz8ObY?*e&IL(KPLwd8J1Dis>mDOKRT@A0b9P zE*j=QXYNsl(}>LV(6D2{th=5LF#|HvwpGFBT+ORAlPH_fJOxl;&*GgH^b`$UbeW-5-%GH-Rm3K$WKwW7it9UOLAZgGtUAxE=gfLlhVIz)5QIeMe`hj3g#Z%~;!qKslP z!b1Aj7GPq=#k%Ut)9ih3nShb(KpCV2C$IM6I&)b3jso(HWLBl8-%l=CS(S>FNc=;2iMSdU|;CO*C z7F8w=rbTTi3A_~dyyt-$AZ_`~3R55tm0%rtc19I_LM{3pt_A%iob}uX#OmMR61cV!Hs%-EsR0fIm6t*J@03zz z^Sb=6hVXR7-`92Zltl#zL~a#ua8Q1Ej1)@dP1Y9^CRM?3g<>^WG%d@vHTs)=>Ru0#^Yb`$I9Y^i!! z2C~CAve8FW!9^;{d5p98NVc?|M``@PqkWXgI`MBtP8)rw%#{u3*@VOL{$IDk+@{uI zAVZ3c{CP7Z&b#_WGfzc25cE}>X^}dKFxWHg%$iZyIjmtNm!x~g$#`|OoBGQ`(GRDH zy!#;>1hMpcIW}IhnlP@_@m5tP>FSu_*h~KrJPsq-GgYLMGB}n*wT`if$^65k)a21r zJa&~=foai{E-+0fbhH8=o-*b~VwJ;?%7z*oiy~GiJG=54X`WyI zb`GJJhKpaS7&URfa8Xzs`k<+h=tV?65%J8GEy{4EQE461^|Dj>+$ygr@)f1=>MGwN z!_lA8#8F$+*GL$k0keGeUB1AeIc}=!@UdS^jyyn!tgb*%X~};fY^^5Dl>2G0IisJX zl@BnDjK3TT9@U)O z6y4_0NOxDeEQNUCOo4HDPn@b8^Z+Ts1x&FC;Yp_APCCX<_zJY2J?5`}u7utXmG&cK z+$TD(wQgL*cym4$DEWg&e`k}~jIDb83wpSaW*BjYd1VLFqS0RmJBe7hVnf&HHaJHT zrnt~gbG@F^(kYM`MNbttQbCZRl0z`F#YtG{opjK6yP)KT1r;h}`XT)tZW%QL5O`5| zSkwngR>04@o3lQDqIEIXCXJIdGCR9}o2J1=_u3D??a(44ebr9))4E`VfyM03Wf!#0 z=qK(4ySg(x-szhkOC)!OMN`fIpH<*bMzZkg*U6v%WS(o**0K`&)&ykCK-CKhdVld& ztvV&)(J;bz`{!OkcPLnx%hf{JfEJcr#~aM?DXXg^=_KdB$Y_7BNti*)$LBlLyQSn6 zdU0Z6H@H%0bE3ZXwsWSL2va;odv^XXCNNzA(L%{e=GH8wW_kfE-^#-Uxm9%gX--j@ zZS0A}N0@0KPwfxibQUJRr2w7}_&gx5{wlnO^7{2q1s|zwPi!K)(Q7XZE(B<#DP?GMkH-DaHR`Q>sJR?o@L}%Y(BM=LE?G2i4O`{*f+zuniz;&EN*CW(2P|=Q_xWbhZ2{m768)Y^^kw^OSjRv| z8yu=+t3) z=s83&V)4&!i`(m#`0`wJD3KXE((~U1nav4msEbkni&v!F7v>%%Dv#4&O$^dZr;*C>6 zzDQyTs(5X(QyLg9ngp{{CgtbEm09+*$iPeZHNi8}BnUetO#va*4A$UIE2JYsQ#Vk~ zFWinMgIJFzAj8c8qOQzFwwl7f$<`0)s#l{7X@Rka^zy6y9MCaW;i|+@VV~y(`BUJd zeHaxP*MRMOf)B<~L*X8kM3F#N4X?G2sbAfndxXsLxd}b0=3j1Z3aXRWsLO+UU9~+%ZQm$b>iup zelbI@o@PvrjNLbPAIerIoSL46!QX7Sh;a|pJk$suwf;=>ekkB^gHJ(w6j{0yJg2Jf zzmu;{P^--hM%?jHf#@j^AOp_x^6hAGQ2bc_f$xw#Sj1`7rL3frrh)(Ww+I8wzw0Q{ zCCNYKTL@Z}m3dorMf{br^@JVcy#V|2V`sw@BH|x|s97#9B~UX{oR$CtcyMY)09Zg; z?VwHec9)!}16mtxJW9@WN}gLVt0#={tPQ7pyM&x?Xv)ZG)!o`iA>nYoN0<_gyHjTqPjO_+qTMv^Il<%XC~Zc^X#BWZYJqgOctPO-0WwJ}AaXiz!8htT z=@*-ktETTou!t=vp1yq(>q|zT#NEptu!B^sPKi;*BObr1fw-E*a?1)K`WpnZ^tT(g z_)XF=#S%l~_H%%bzH>%b0(zRUy0R@CqP{rW+$DNjaz5Kt+FT0=6#N2euog? zxkGe=FYsl29JFmM#h7H?g!MqPCr=`K{SU&@URMbG!) zBy)TmwT?Ph3Lae|@GYgMbhvdt-c;_ejKl#YnTf){Nk;?keGQPraKF0!uh4Y5Pb21Xd2O zoNBPuiu$3J=tNamm!57Am|fPXg?rwPIZgR<^X1IaC^R!rRc~fMsDflR9;;CaNyMh#=gk_i34}5vjR<<1)9AZ2I@?hb>hARv@ z)n#p9xij&Zg>!SBe--$`vUHuVn5W-wIYbDjbu}o~F`4d4jia=M8*nE#34%oa=yo^O zvbC3pfTj};tSOk}zcw)pMWa1$2oU1`FY=&69=m*3T|Lnh^+In(J@KHIp>dj~Vn*iT*vy#${5RxUj zm1NiJJIii(S82+^Dw{|Od=J1j`mYI|_nv`4wV<~It+kvW@$C(A#rv8itZIN*Uj zEXw!9sOuAI)c;M*B0Z>J~_n6eD$FlreX9_>4}N#{vu zf;0}7QR@QiJetzJQPeo&w^Ke^-tJ&VN=8^qtTr)7Cn@;+-_8)XA(tA! zU3omWow5Q-mfsop%}3PIYZ)Yu5dar$q(lMkz7&(yP7x8$gt}UP1lTIJO%cjG{m(d) zC=gKDXWBURgjQ%5xy&RIYLcQ29J8m;Gr;gEhmc@XV5S0APo z6uk8&@b)ih9=JsWeI_f*m_~&zecm7pH5FG;lcT^llI2_G&z36*o?!;*C=yDBkxKV|lZSD;S8Cil7XZ#nj2pShhV0rmRhrYfw!mG7Ubtz^X3x{|ZGIr>>#)VT((kJex1k&D71mhBDLkm7JQUx<6XrvbTxCzZ9)yqtX6w18PxKGBfbB?lv zZF}#I6o=()P6d!2(r%ikK7SL8i7s!F;66ZB0@F`DBwtdUPHyEX9 z;1NxpFTZCozX!z!sjUQ5n|k1u$-UC;Mqd?MP*;@%k0vW_beRp*HNlH(4x>>ol6SLJ zl^xxtJxSbKqFc+DVxk2pr*8E3y>LaKbK-?)3U5c)N|}}thboiH=gPCEumnv?Pl8=j zNs-x+Sk)?1@j?`aF%x+5ybLM_`hvl`P7Fl)Pm1^d@&M$7@P2k%_$)PdwVaOh*9p(9 zyBmEINUL325ho|)u^*y@7fC(*FWk} zXPTO}FOomYeLdRG6zEBQc==?*?%*n)MOAK^(EJ7e-`qyJGbB?(bz~gS+h)3`vE0tv7X=UMS$r;ICG<==Q zKisYW9HowgXq>pS3ya)V%z2cBWmWzp2?#z!lJOK_g?R*Gs0fRQ%*25S#{$ae2boi&|8*kB*G10^|14!BR;7l7%qOMlCY6=Hqti zWe>|LpxTgP#vp-AhE*fkmYguKD`SBnBzbCk-S3ARG_d4Yp*6FRm_XM5UiiaTh--Y$ zRe8?|)BLD*5^nU3(FPL=X3Y%LwE!>n77EF1Y^@=>w`{9(;3?h2DJ)O?En!@7Rx0g?0F7;<`U&`#vw=D4FW8sucp_bVkF?_HnPYZxZ zx^cY9lv%bds25Gp2k!L!4p(8i>uEg$Op+9ig)@_~`}KK?h!3q8Eo~$$2I~8Sba>?1 zW_U`LP7i|PFINw@%p6+|M(Lj|*eBFD~ zuNCK3f4Tr#7JFSEgQyCITLIKg+=-2AG131Eg|;p&d#6&krkiPwTCIV+8uRZGH6h=0>c7gju*3NbhcC2XffT!)c{<&{>>`m;Eqfn4j$^uRx&aybmK!ky*8{^jGbQSw8aCdj*up112+s@=&W_wil{Vfc=`EszOY zf_b!LH3^^S3)}`K`ti_Zm1wJRWzwO%US5FrzklfP2c@b@?tli$@Ku!L=|#3%iw@yw z>F~F5dO8*uOTDH|%B3oZWzzt39Nz)mqjt6IGdCuMI^+7<)c3YWQifB2{9(WmW~l)o zbJLy;)(w55n772085+YghbV^)AIoB>&CL7P9HT-cIiL8yrrT4;H@03LRQhJ|Ihq%1 z0MOb*^NyWSoOi!KkjOqBLcxh8YTbq1=LH!C>crvANh%mai>@gt=>TYU8H@iirASR? zB;PUSJOebtVYK300V4@(;Aq?gvGef5t5tTnBiPOi@IpP!de$Q@nSP%cZ_ZrJX_x#D z&iCr1_@UMAN;%o#t7bN;Bnc5o+pWOW{hk;TdMAYeT3dPq!Xk(~CSToA4C;+Hv9cX+ zzcI;9TO61O%)jvJEq-~RT7IEw=CB+&i@HFn@(fLe!~x10%-8_3ryq4pP+*I(VVQd^ z*Q>)I8iyJksZkB&{JJxe2iM(50iqy`2&Wla|AjbVJVSyNy~QJ1^Ma2boI+)we}Ek{ zUl}ehd9$XgnpjR;;whb^@C4EW7a`u_K@OFF$C0HtmwCr(p75+)kT)ShgFA=OkV#)5%&J`dMM=l47(`4W6B8w*k z%^M+UlnopsU-drj(JElC?!LihF*MRA`&wCLHBKR@R1TStWV)8sQ)Yq_q5FZ!#TpQA zms=wXA9YBb1NwDCB>?7h8gbDN5$u`8St?LX@(eqBx*1nCSJav4ERX6+E=acR8x$Wx z1zqYoA+;zU5mGuuVEM(fxCNppDY9ZYoyI&cVn^T3fY%^%gJ-D59(x$5oz*=EvvREB zgIq1b!H%%neLf((Tfxnf(phj@TY-bDF$ZbpIGEE4aIf^{6sT9-ac@xLGu~lFC5A8V z6V(QxH_XA77!@=VUqag4rP1}4O!WZSUe?;xcVP03pWyLW47Cw+_fZocdWM&6MLF8i zYw^|3`8_O{dD!&xvWZ)xCPPB>ZXI17ZjTs>HrK%_r$~*-0t7YM7P&1^=ZhI)kF!ek z@?|#^m}bjJD@GL3<-ddc9NfK%Xfr(~O!9$)$&9bA7Oj3@_BC0VDG(f_oJST~>r{K2 z9$Oee6_$ZLUMkg8Rr)>c)>FSuF#K%l-<%8Qz21-!v6jFKpZ(e_SF0pyr(XsBBU@fTkEuz%;h6!DyGcCdNN`Lm=WW4$0JC+nKE z-$o}iEyV|M`PC*egi2n}5V{V0knU+rZI=~8nDhKHc{ZU@gjyRE=pEF3A>AC4!Wh*F z#Z7((P`k{0hjj*L|fp{(%96ustK`iQ#Rb1BTqu_yON3V22J=2bI5RSiViK!&pWBzQ-AY~ zd;Ya&5YwYsr-uDn>8+^N#}@xL%@1RBnPPQwmdpTJVcEN zW)MgaAHvNl?zxuU$@KQpPaE7V(_{bXjoB{BRs9|P697i~e@P1r$VW>w>d_8r-_;h;`)tLDuGw#|$I^0qN?e)Q z*A>8K9EJdpdI%Fi*}YAf9I-A#1%6^cU9gPvy{p)YE1soBB++Isw|2OHEi6KY-R{@bPD zY#?ng7k4$YRGn2*nQ}CZs{ZH39UnH~OU&X}DbAmU$C#9C_R(o!@Kb2L7`m=PjiXct;bZMRu;!Znzd< zWFF!G3)3G>+V;FU65XSLyE8|?4u)lGj1^-__O;G|d8+dKSB6Y{ig`FMDg8yI<;T2P ziow%mBtdZwxrilHDcJMsLDDIdoEcx|b1_mfey@9=7ad+a%WJqzZSzRsrgc4iJ9nd( z6p`gCS-)$={q10dDgdNLAq}JbNTCRttuc}8byI?-R5ldHH44c6kcOfF0Z>bli(K&u zC3*Zch;&CSYi_hm+`*L02sA#Qnj2nqP&JswD5P|ENtmcY>91VzUpipI>XPTuvu_Fd zB`dBKfsnJtVK%%5+1|)$1nwgCmVdz#!zH8BXoo7&DgOgCRB#f_1c#8?_U=au7q&_ zfnyVPf&S~E;hNaT-7G%pf_Dj%CP8>T>)Q506a+g3CinGQ?|xWShkJYWvjm5->%bb% zg5?bTrIG3joj`9DAoN)7Rf$rh@7OZU-U^(-KGf7=wRxNQv42Wnd`E_`CYL;^pf~Uk+35^zX#|McCuKaP}b3* zXahDi2EhIWdh0`dg7uiTXd}Qw(xmcSzxQUeo!kfd>rII6BALuoK2!OaQ5vEpolguw z25xI@x{CfilK>78ozbo2g1B6Bm6Sc>6L5KlXRLn zGD09bZTgD5R#ZHZYIRL<7}pKpCZWhyo)b>2!ZH`P4fRwb(7#C_lZ%4bARF!TFafmX z#=)-_S_2F2>CuGA-|pUH9%KN2iJk_5Gjg*0B5s(*wbf5MpRUrp?v>Z zahXo`neYa)cMGj5va<=vtvabmZ6Yx0A6?O=<#2K5`kKDQnj7~&o#$PiS?PYB!ZbnR zo)LrIasjpVh+oof)pB$Zq?YBR^Y$M7(i4B;!VWkWnE>=90^Wr_{9(*3-qoO+oHA)5 zCSdBYI2`lh^b4VSU0OeE@wo0HGnB0x>AznIS)|3xW-W^u;ONC??KdrJBYW;LDnYcG z1kYl4`{YhcigU+)-qRuh5$tXH_ULvm;5W5yiz+AN)$VRdbottS8LY6O-ejAt{!iQU z5xKAy&DMiJIIvYx^G9w%BBBw@$RmmIwgPa!nwI?00@`g(-gumGbHuE0M)iExeTqI_ zME=KaCy&&7k3t~Ro*k~BlWIzjLVV}29?j&R;VRr^)4n62yy974R3XJCc`sO-OSpw- ztfcVP3&jI1T$2b$AQcJd%Of33gOGRjb%|Cvb#lKxuZvmMKpl1#tW7r~ zJ1o#D8PF~}JqJV@48LzdH6;N6xnsJx&N49)2e6%l>bw)Fal1ps(@aI;O$umpqXXh} z^Wopg^9-Z_x#C7(kJ8t}ZJ_j%Y-;l|1#Z0rHlF5$X{+7#3_AjR!Ru{6QjM3X!S0_D zLe=GB@=j_!Dfnk#Ik2?b^(KZ7mRqS53%VKk$a}1Ou{w$( z)rY_mGjuj(l0&!X*Q~m8SP+sHH_fQj9>59voe~1iHV)$h=tlS%`#j3doA;g8gsL!|>urT#wOuJkhk zAtAh~;H@Y({2HFsL{t{eqnGoO%cN$i9p^v?r)~i1zOxc@Re(X2txNJ5ktu?06d`!+s@H5Gus6f)4aAg z>vE(TIHvig&=m^Ombey^tN5%?SJ)EjVu6e^3dT(GEk9v;?DwS4q72Y#6Vr1G{`gj2 z8K|fd`o;RoIv(5}M2jLPR#W-7ggBnD5RY-?-^PR~dz-NN0GjbD9imID>-O98k}7@p z$vq@xcl>G83S-JH@H4o^GJ;4xTutW`nv*v)w+k-f-W%?B_?=}s4sOCR$a9-HV5CD| zNL_n3&{Uz;O<1%SKEb=Lp>7O$bqZS$D70^xxF%#$e<)79^SXym({RnND>TA8gnh3b zJ~-XPDqaf&pZ+xDGdQI{U)S1KfDMN(LK^u|-E{?OAlWOxV&2)p)go6$MCCaB6Mc|n z6~z*DU47mtRGPTB-KQ{(l;B@b)Q4|?J`Qn$VGbvRfstvuHg9N&qQ2Sh&RcsLNuO6m z1$?*#NV{!)%~cLt7ch}a$DNo4R7PTXY<~d25!aS#@_Wdg)${J{C3Jd{;%Z~<#0hxF z-S&k3&!?hz8nfItU~wu}Pa6#bEi^$ubi*n@Z^QOoJKO z86N%#)zafUz@>!Y{8nWLUs8ZaRVI%QvD%ArYAbri;)%r_qM0Qu-<=P;Dk z6y^S9(pXm#L(yaktTs1^+SxvS+*3etTRB{zGer#_j#~~)A>yc%TqpQ?aFxf!g_HIr zF5D3?X(zm@n{C8#$VH;VvT?o~e2SO)jY_=5pkR0^AjobS4-*H6i%vhrOLj~@+-RE( z_-5SVnn?8D4R5#KOFOQe<+dAjgyFwUVx(1iE1*8LIUXxaK5f2Pf@)~|tiTjA(3WJ~ zsJi`e8NlvjN9>_@Y5({n8_uGC;*XHLWaTcp;!}5vXjDPwR^!`OZz0r+w^q{P?}^4l zWyr=J$|buy3*mqB%P3m6bF6PxkVrd}!&RgmWh3Y!%MT%*Bh3kRmkW}25>o-*VHM2X z3jQ8VpD&YyU?1zHa1Y1{Q#%kyB@3OwMRvoysSnZ9{)ugka$!wfxxQ|&0<1m^7xS~< z@p;@0XAC!C6b(ZS9mdaAK20NYZv9|Nz#(r_)^8MMaef!8sKlaMVLbK8E9_3Jh$sPC zBE~NK#aY+ivipAATy=bZlQ1aa%%UJ--PNETYZv(ON3>$RGr`jOGv3n>9( zgM80d)>!(*Xp^(~VoT(nAuR?nDB?Bi$Jw| z3hJPkOyurbByN?lAe-uHEr5QY^=5#nf++7m6yOE9OZg_f+Q>TNn5W4ruIE7nc_t~% zy;S8%njWV=e#vsm8HTY*9{z3iE3A0NhO-8CXZp7^h<{9mvL=r8sWhL2SadLZbIGv2 z1FL#`aGw*Br@p+kvX067&_sRGItFYUp~R9`uOq4mq0L~ubvp8vA?!(;M4wZM68oKe z$`?d@-9^G(1|Y$78Z_K;1%Uccd)Qx(j>h0fb@bymBQ#2oI=X!GxJ23VVIvd78#hD? z5!0tseNj`4n}YCokhxtavr~{!8z@roL@l=|=ClxMHK3_GVFMl4*(EX~|Z^oNV2ty{ZI>j2P2L|$nK+NVt^?h{Rd3$VtS z2>P*wo9yZNgI+co8DE46{f5`SdBPfnXV$fETu%bk_Fu?E#0XN?bL*v>IzOO7(AvI~ zTrMMA&DW(g^DX3`WN1Zv z_J7p273wOlxNf0MfO)K_{M@wSspyN3PJv^ON^LHrpJtEWNsW0lD3dncK^9IVi$U75 zNfxo*wQ~|xi^-q05)IwgZA`fW2lxl@+uT1&|5XD;cv2&TF=oI6*T-$xzGk8K?gPOWPs`UeV|rz0~nD{ z@D$I=xZEFYuK6<$o=Qd9pWqT(vOnzbNP=(?!KiUpW{JV#44Yk#+aM|1bVi3!R1dMcf6zL>Q4JcF;!M{G$rh{Ht6VlO0kDYP4%__ z&}%FX0T&{wn2@gi8?%jjvD#do$7r^&5-JpE(uGWw%?P827D*QO=pKWhcL-++bT5^B z>sr^f94S7<24Rp0TR~-UBGma8 z!VFc92~j$6vpes-Ovx+ z8O(4Rsp}2=WL7y2nIMJbU!z*Sb9@h-9Fm=9$3hLlOwGRY01tc}CY3rNAGc z;}TgHr5ht@;#Sm9GtOz?a4NxB#P2tf-5I5jcpg!xg3H2e7ar76UDz^Ws;bW(vCmYl zXC@l?WCTs3iT0$<^r^ym|22U^ZfAw&tpNgpP^(=QD$p!{dylIcr7Dcldhp_PSD*aX z1TthX9ZhV!@)gd~x!9cs2s{oQyh%OG#2`Pv?h#Ad0~S@~{>cS$j9|8n`U4HECtj|a zI21tP=mz zhf5RpxThm)#~l&yb<*f(^HY98)~2zhr?&{_9aw`7pL@ti^d{6`=CQ=87GQHJiTzBd zb@y>Wp>mWG zb=e4n$`Ai>LCLLl2Yp8)^z~3lfQQf#)9u;Bmh0hc`zLIqrmsGkfTmSKg)j8N023X0 z>|2!9Y3lcLJiH2J8?1G;9X4Fmzm6k>nw9C|mWf&2EzUNqXNG1a1nnbT!g4{=xv);U z7qVWs?QG}anjfbdcWoI#lK^XdJg~ErvnfW~9JLeC_H48>a>FT-Na2W5&kdRNnF&>%e|3|Yz58KKyq+r_CI5e8x5 zU~+Pq;Ais&a?0^O98@qS?b6bu(ZAJsQ&#j_D79PI(eB+t1BP;c&Iw=u)t|Dn6ia!1 zy#Rh9sCC5bWSpmh)-R`0gTlbn@`~()#Sb;PJpKT$C^`{};42Q~NopWJ$#F^{L4sjZ z2I#@EYqDj1lszvMg*Blqwd-qRx0am_UUR8+jl@Hsvb3UXmdpB3f=u|S2X$aap!=Ym zl8&?1Bx@~Hn#^+aaiKIPY@w>_@2I!FfG%`H-Pfy+2aU@{xEa>yD!?B-p)Dwd2)0qb zaj*iNfuCc-NOLkN?H1-585bks|3h(g+;@b^#l;6_5n#SFcw4k?%W)~^@c$Oz7QdR( z+pBT^xDF{M_i9nGH4>u4uyi;VGkVs`Lb=kMB2++6T5f$T(0)V3 zHt6p`pl1A$EZWM)z;HtpBkN0J4>|Kku$gn`3(zwiCn!D_ z8T6|z|+w}NKzUr)}gv(zri{PgJoU~$?+*o-d0aW<$>8`*N~)F95bOx>Q6QKtCF z&HVQbLa(T`tfj7|xH#feP9Cv@H4`u}aNjYMvpMBJ<5DrPD8gv=1urZd7#IpmB{*MW zFKP>&auj-5q=ajEK?j2sgUH&r`TNs`>i0`tx)juknl9obe$0$VOeRie9R`{0FIEx! zAD9c$!*9O&J&UAmUcy?FG#b;y^$P*MfA$J-nPei<5Qw^uY-IaSCj$(72x)E}xeo~8 zh4~z6Z-Q&;dPQ?nf3|jV+PmlNbI)+ZJ+`ik4Goocy@+sIga^~;fXeuSj;MY$Oq2EG zpv)uwd0ugzsndw-DJdkb+Ak1>%NG^C^eGr=`)9fSS@Izvs=k0;tUMzRHr0G4R3!%4 zS2KO&8^230ZsJt~G|4Q^E)9y(l>ta=V3+B!cHU5X;1Wcj72W=%0{cky$Ewxi#9C=P zuGvS#P!Z&bG#jym-#ZzSbN7*6`|p8w&hPI`}Zx_oOmKFyMmFv0%DHCbfuZ? zw^-5VKEB0(QQEn=#1H?(48)dU{@g68RPmt+6;7~~gumddl)rGwd#=y)!Z)rmbK@4> zve?@z^f6}@WD0CD2rNfdbZFGxXp6Oc8kh%T^e0UVwR@>jjo;}u`*y8;m`kB$}?9LrO=oAht5j8LWnSZZ0d3hMnYE$E*wl`j%Faq*#Rjt`x^Zv+6tkHR(R$UjcDOai@Tvaj<&sC zE!(f4{^~-!0dMeWMj>hlrG4(3r$l);ni)+Yj@vOS(l@g8Or0V$ffY5&4#z+59t`&q z7r_%x9<%41kalNz?bMkly|+vW{@+~jx)-3c9ueF$Bap9Zo>L@sW*Q3nHd)H*+@Vb_ zVtP%MekgyiFTH4X6})*}MXY5;&&4y@Hm^!YW+7E)U)(5?4#7bQAvzkE&Ip}|cgY(75ZyzuIEN;`APd!S7Dl2OZ?}(@^*0q-+vP`;K$Vm)bD33+}?C?M;Bmc6oW}2Wuw&kmSzDE%#vq&HzSaRPb=6 zbmJs%Ua+3>>-fc*c1~H*6@C6are;fw#Gep>KRY-Yw779$4K041-lNI#>@^jIK`PDb zFRAink9ID=!*o9l9R(>Vye%>CxE;Sf=@>n7*2?D_o9#%B04W>W<9DDU8j zzA;900o$Pxnm)*!vB(0Y#(VLEAvB2bA&P_$6rmq0n1KaC6s$>aJ7$Y3?j;Uv#{~q8 zv|I2&Dv5R?N|q9rfss~l)eOuANYA@VVC+@NDjKr@#89Z%B%6{=x=WFBehN z#IG{CV4gbI-ZwvwbIWyFKHHc~y|AayI!4X{)T1-U6A?O;Heer-iyHqe7hvdrsT2_@*^kT7Ib ziYORBpya`Dh!}l_6>-j8N5k8`)DFn+7jz~tt<@daETk`2&mJ5|#7NrrY%iv)3)Z^K zB$;llHgk1QhtX!gi-Ai<3Y>eJEA;p>u5@rKI+|*l^ z_BWM&4K{Zti8mk{jtee^6f#-l2+@5j%H=inB_>V@NHck)@Kk5IVy%JlaW+e~96qLg zfonQi7~VMyxK~2__QO&s2UjO95d?Cf-FQ#!aixw7+n42^>Sq2S=Mp`hWa`rdBn`t; z;~2Cq@cT3En(LUM5ul8DFIbv_=;-JS!Wecsz;;a}>b7k03g{dS-pT1el}oY#b_B(r zU7AwF3U+GqO+9#uz8q$CAfsB`%d;HUUi# z6$8cWw(+q#L)^XZ1vIGeb&R0Emn|Z#nP=={@U{0@{PMaVGC&hRSR|n<;}&u1qdBs? zjE)^}pkaYXgV>jiU!cHLBthvF?b#cZB)=fMt_UU-e9MGq7V|_p&0%{K-ti;CY!Ldla2>}jfBM>}6uD^meoyWmVraFN1q$C)(yP9X;iY#?G=Ymn6cx*HC z8MS_Ygz+R!gNdpZmiB!&Zo}91Ow-vQYFG7C06|f_{nvIWpo$)TWc16*OE!9wezT?L zxIdkd*5Sn^G~Iw(SF%YgvsLN8k(f2GA|1E4iha?Ak^I*(M2-YunZq|+d8R4QLP2u| znANS3>5@Y`rI?mynOJa&S&Aqxz#yYC@xs^%nS!60pF!AD{Dj6$B$>9}Awf7u$|a?= zB{7K7DdyGi!iJgdL#}O5Jy;=uZH<3;>O3;x2V)y2U8M^2k=`0W)5XyU+f@-@+^YWp zliW)9cnVD;3_z}>4=<$$*464FJ~QUI(U{p@&`KnlIQ{G#Ecz`YgFdJl#a+KJDm4d| z-GJuzWoW(iIi#T3P=$dk5FeJ2vM<|%VN{;ZVc|&-s^q9H(3X!cYSHwiQ^~>ZcZ=I( z3uLT`Dceyq`Jvc66*CF|>>7im6TS2G+Iu1thX!xg&)nKEs(Je0V22~uGPcj%g?CC3 z2?XL+0j{qY1FGOakWS1)87xUd3=2#QOznd}`XE^ztI^(hkWD2ir|BoN3M3)d4vu2& zK9Szi2ZBnh6~o`|R(PNm2v;XwjuDkltQqyF@#~BefbMkv9zs9o2yR8$iZ-6{GH)P5#D^#@muG(|0yyN5wRG9@lL+TKyGI8sCB zM^(_fB)nl};{MM*j#b5?sbdSwb04zRL1RtLGxLgFlnu<*?8d$gMFwLa8E`L;PLGx>FiMhdfE}%PBB4480WxZ=T zQB9paC4s!+E)CO#vf))svv)XOiC+eOfbgat|D>-G=;8o@KsS$wmqvrGZ)p|*Ne+&{ z)IEPNkwTc8CAydIwdYNLg`LI?YLp2^DhkmKmYNAJ9)EQ|eoZg+Ck!45tgqzpR+@A= zlo_3$<8XbyW}Bax?c5~MGCeU~lJRRnTD`+P#okm@^=88(!y1o>B|d)McA^;5N4_yc z9%$zi3mG!?_?Bd<_YuWnxaVq)p{GEoy|W7n7lKe>A)UGZt^-K$c75ZXoRbwKCdfe~ zkQ;^+cJxm~E*NZ*AlD4F*X*%v+GcGVnwJKqS?~)o;P8`-ZU%58VzY!-sme{GA`ZpnE^6n$wL{Rx;cjrtvqVaZ?OG#2A6_Z0 z?M*+&xnzPeTwUvAIcgdI!1B5i1Bc(L6f(EXKst;8j|f!GZ40emZLePmG&GM_da?#j z+GO|m*Fm}4V=;DDVfr^EDYPoNKzQEV8&Q;ujJkXzF;hV|q!?ZBc$BW%+eFphx~DJH zDm8u43j|ak^W%i4uln~3z>(lnVeW5zxggVEQ){W%u1cNfyg0`Cr;VQkp%vn+eiBHLBA6cfvp^zDFs8i2(JHbL!51tyX;+C|6Q%( zPiB|BP!G}n0N>rx;dp25c}xcz4HYH3)0?tJR8SI~jB|SRqgsw!`G-{VSPlw+0WP~l z2GYl9l~snzj3kTGJBWbNhrJ^&ccfRr9)Y^sMOjlls}m)K<;)N%;_r0qNrsV@5P2q@ zUX3JPcY9`Qy!lt-yE`O3#ZfsBS`zR)Y7Urt2FwQVajihvs;~A9JtrRHb~ZSa&a#is z3bVlTGndp8eI}Wp1d`%T54`R(mTgSxh7KL@BPO5g;pJ=y=mYcRyRI2MVyEacfnP$2 zRSJ)b1f&7>rs7I;`U3oj?S~&L3oZAC*;7w&b`;|BaxNGB+&or%%ofvkYgMrQS!a&A zQ7Hav`b4CRufmTJXD#p_UU-WqI7b$b>Ks>g5`S%E&uA4mO$bABXNI=fNfEwlGabW8 zrj}W1Tejo1iw_iXVy7a?^t)%y0k^F{AqLV;3ZQZ}U!Rz7_dF28_HwD0mZ~c_(Aw=!BAB&v9QU6_AMK9bXEC}2ZJT)dWo1N`686^U&AsU zXTQS19wtExW(B7?2iqPuBo##@_^G33 zzMi>lXiL+E(h16%W6<=PcL=}5WfiX`4M^_E+Y_TSXh2hq%Fc^S5o>n~;^H->ZROyG zHQrV&7>L2Cc4h#8)X@c%-ZdR%R!*%0M4T1)?gKUnnMU;PMhgVSG1N-|-$gr4bUC8s z#0!c-msd*b@3$8};h=+B_}#{xcS9;b3fp$>h50`!n&@&zc&3?G7)(+FhWq_~eMS}I zjW@J5Dv#Yp?qI&d1p>&DF28ev2o-4Xg?;tYomR5FHXnF6y6SHmwCvc3(8(ia5Q8es z%f*2vbg9@)U~HJy%eA~Lwkub*029tN;H5eW5Ba<4npH_Eo~YFTHWhuTO?%`#%0_5R zPtB=Gn#WPiGBxk^SkO2>Sen*%pt#=Eo1d|_azkJ_4Bw}s_}5cNskQtcn7sjOqLZp2 zP$6v-2;dHX8_lkvek3xErHV{psJRw6aS^bd1&9TI;eQP z(IxW>OE~pqbdxSX>zFWwIm#B_RF}v%#O@~H)Uu;ryWiT@)wEa^ zUoSXQ0O{@q%HyA3Ueb!F5hr37Jsxg&TU0sgN39yfj+IWzQr`b?E;iC}Dqivdd>`EJ zma!NV+}T`*yr{J&6?)b8ww~?+rCf9Els0^PJx@GPpSw5-wy z$4kSO@RbgMX*nptcg_?=%xa7x#L@FRsoIZLWmPR`c6#`XonuL1TSqvi9DKZ`nuNGo zRGavZBlgp0thK=-th^k>~&&3~Sv;Ot&b;iA#xMY7i25_u2 zWB`L@ekFw&c!9G2iAN6gK+7s9p=32l=@9R;lLpN3YG2>bKn0@FfHQ1eUEQiGt8DTF z#8}Wx&UuR?j5koaTB`vWFS)KKwD*Mf+;he7$B=uQb-T}X^dFdBl+TGy}Ro^eE2A|5)CPT zMTDktzM*(>JH{p_Rt0HDLC6V+?@`hgYp&%8Icp$ZdzcSD)+(U6;q#X7cA9yhjpG%Z zGvNo_BulQHMLFA0pB_eg^*6}F*m8VLxnDOu^zr3i%>GX5OR~O;u>`oT}MHM;^PUw*tG) z@An7%adVGu4Nw;X0NU!kc~NvHdr+zxYaw8r@P$4xJW4T|B5q%8Q0DM0LSC@o9>-bc%&WgUx`Jzn z9-TX9+xMSDSZDy|>SZ3W+wZ$kRaw`x24OTC@TqN6_f9lZ+h0@!=_^nIf5s#GP;lb% zfIpY8xu0BR40j}rcpfqYQO@f$g`;f(8)htB#=cyUk#E7h*!VIC1$5Gk;et3DS1kBc_HY zT=!-hV92n2GyZc1V$Xo{B-hdJv#$vV{FrTlH77tD&{BzaOKm&9+<|7}M>+T&`)Ndz zF9cjn@^m6>-`dU7L+`|O%HcQ8$~`Q-o2}YzEx%LWaPB9I+himmUw2cphPv%wpKM#o zoeefdK4n*oqijntBCn}xa!6f5Fj0N&xp+-#^>P?F0$d*g66wU|FMM+DNpUra`S1{T z#Gr5iMm!K|VGw=dNS;M-RxGvTee`zX+|L&e7cRC@TUL@LJlt6k-eAM=>nFqhVZb;r zp~!*10SR?b_qK19K?sUIq{VbB5(3Up_(2>v7S{||0u^Gb{?LFMP3xhn83##EEQ~)> zYB1h55EKMx7P6JDcM_e|VuJ2I^Vb2)CmeFD6WExU3zYNd_CN%uBd2apKbq2hN)Cu( zL`9kv*QL1GqX{{~GHCm?d4HZc=fy9EK!8KOtuA^CiY~h*%Tm$`lc}dqnWIc?{-t#p72g7>LSu2iLJ0;TnVe2bAKn?=H$ zqw&|Gz|2+SB17Qj%Vr>0KwNT(WS1+hvN~T%`DiPXPEy)2;UHCGhGgknk@6)Ve%0Zt7(M=Li$>>IOU==0HkSrb# zAUeLO^G{D{{NacXZ|t7el-_}Pz^a(RbGSBA(tp@FVk#uq7F6O#bjAzQ-SIU2fuoot z7pBX8)64i8a?R$>#`PWU(y_KrKOsVw4V9^6udO3q%urx!m|U@_rjT&RKcfS!x#IgP zFRaph!8KhbNd!@mUCbLsT_Vfc1oxvQsJ+&%VvN5lL=7@^-DS2k!`Y>}5qJ;nT?}Is zlI7r0)Yd#u>VNj4g+Q-u>161@>};O|wXEZe>OCOvf~ODsEp-vX{ZKaczj2tQYu8v} zAkGO)&nd%Lv$rxaZ(!W?52-8-6>-ccqcr-35>V`s&RyD#>3v;ChD_8_bLsvezKeQ4eqK)iMU+4rP@E z&JX@As}uI_BoTFa*Ml%m;bBQsug{zdhY(GcqO*d;wk^~S&T6D z`-?z16l;`#HVsft(8f1QA8L;d@7Ph|&l%I&^l9Qlv(smS_juu>PE^R}t6kyiIQ&_A z^tX8`sgZ7`I64)-%_D#wrZiuDEpT73+G7hJ$(tJRkF`qzBKmBlq-XuZ&Uc^!rl|w} zNeL_dB_fC`HoQxEeE`ioTqb6~L*@LxT!C@={TqvNKK2u=t&FkXWE|J=puVPUl%1MD z`|J9rYK{~=HEXNI8k%ug0J?f0Q^qy{b363?>pV|(T0iR)S8x=M+Q7?NIveqi+gDEA zt{WCkSKaBgtl6(81;{<8fS)ihhvJ4vV>I5)t2=ueYuIV#q4jc}4Dh#mEU1>rpD%gs z1oB0^Pl1U!Yd1GUwCD_u62-8P6SNS69_~ zw4D^pmO#gYN?aM?1X@y};KKYJtX*%y+QMr)Jz`X;V- z*xkE;3qF?J!I^NJrZW7p-NJUFw?>i54{%TyH*iIoS2OkBpf;ZNcC)_FeC`^3>$b;~Pa{D?z ztOul@!)OyGQ1-=>@+(hxd8LF%ZJQ!Hy_plXKIUz+yj@u@db_a%%-%a#jXOM`W$`7y zj`_a`h*U%dEI%Ef(0QKD(6x>b$N8~}7yv~;y1#a=NzD$!H52{3$isfE8}@oTtvWy2 z3zy<-IRoSF!#?GAHSl$HbitWXYIjI#hY%=lX3lAXnkGS^MOt1b#477ccv8tlmO!4~ zLxZho=F}&4`2!+>r_~^l~#o9D^r72bSVE4P9;KS)0h$SyGyZ()E#6GGg2FJeA z=|lR%ixTwV`trc5f^k(r;#)w-o7TwZ9hIa5h2|;n*!*BUK}@I zd0kl*y^1H#0eS$A3#f1<8quK>D{A=sMo?;$hbM`us2|nL2=poL!*y_o`+`h>wmdCw znb);fNkd=H6O~!wx`BQ&aGE%}q>t4CxG1`pfGll~b@T=KLSBNPRj=E?m`>A45xp&( z1BiCvT&_iRqAYkmUpg-+p9%z|&zg?mlQuK`YVNz_o)FBWBSd}o5QU07DgAGKuUgtGSGO{EO z#o)tC!)6>q4p*v*ssQt$YHM1C0?E@lY?^Ub--mL`lTcX{@1q<@_Qs6~-WiWI(5Gv7 zu3*m|Kp&y|7?wZuiJZR-OGz(wd@C<@>A%v=Rew*T;3@VuM6b>WYuzY}Fkan)2)K2!E)n-^KefKA5Kc*3FosEyZ)Y6(*sJb<-H<^@Z z93(IN{l*HzTQR4pJfaX;pGh`}OLs1jjdF_@pk-MS;LLtJjv<|^FCy6+`QIrNS%~%P zayT=b#= z@MF}NsNcpGc;BWZE<~81`9+%f|EDiQ__GPGML*ioVDzQ7SbFPEyIk#&EOkrXG zL^AdW^-3Fw>zaDnD|r#2Tex|KD9-@Uhi?+x2j9r+}cT~UYv=mjHp9V z-trr3jFoM&aPS8FBed2rxLp2CyHhK07Hxo|pYKHewnu#*QBp#dXsBjMzzpQn!`i zQX1VfOj}N86=i;k=>Cn$={GKY0@1Dn^7%hvpMaM(WN+9MnnvE*&H&h-0JM zL;F8+oCQEoWi~kC8h|tor65Pcmq|K1X`Jg84#9snaN)x9gE+8Bvm>wW3@3L2F@F%V zb(q-qO{U3AUL*vuGWRTsb!?1J%Tj)LL(Zf5!7|*@f;MQ^9Dpai&~9AnTlj!0D&=c! zebgig0bMF>qU+_;jjSM!dy$1_$kIFz6N>Bk(sv-(V^Ijw;K#HHhn()wuac(RxH%g4 zU~Fu%jPS`*abs>59WRZ*r0lpZsiIK-70=J^oO3!@1;&wS&v0(u>(3k@kz>@e6nDr$ zvXo(<*k49lDce{LU%I}!p|D5R?959v{kEJ98h=SYD0YsT84w!nXf#I&4(1?BO%lS7 z-%~NJfN!AJ_N@G+T-Nqeq~Rm1dqA+;y_rZc(K66E-&rr9dFc)0P#pMEM0b(#tTdxS zO{7}lVURTl=32$gOSt~k(ouhAr!xKY7+uQ%p)cTj!B@-%*^feayUmH z$XC5{%bDGYdCYRkEgAGh_cuE*d+{M23w$(`rJWCFdlD;fHv(_n7|nN>A;MEC$dFWX zeQ=ROWSQFi48FT$`>mc5BhU(=gaZ{kqY6MQ(TC?GX5%+Cyu4r&HW#Z4dM%o@_GFGB z@N|~$R!ulD`>+0qG^_Khc`{h}&7mMx7cyrM!}%_;B1YuNVDFwcB@?dz?elYyjyKwT zZt-=&0s;Wk959Jbm6=opP78jWOV-W%C}<@m^z=fGX*biE$|RmLm<3bvAm~DKJ7`~X z6xWZasUQevcHtQ=obG0QyrfAR@mzGWZN}$SEodM0t%eJ#!efs zi?SX<8xjdE&?fCH>7A|#g|<{x;Nq*u0AX!$Ub5;kshaH+D-%Zxs%=*om&#zECLcoO-CO#S55DGPNU<&Ig zDGSxLk2k@Ve9vq$XWJf9sEw#%kd`qRWa`MVO3^UT5a}Q)U8Fpo z1^G4(WBxO-owZ?hbREjWIMLwUFs{B|D1}lcNxbT1t*&_LDu5%BkAsCQYkNr*NfCN7*$hv6Nl1-LOghT;aC0VVTB2(7=oMsTGXCU==ovHov|I=!qTgD@-XHnRb%j%^&$`>KVd(kczTk>RsYFq*UYoiG^Z_&4l-V1U!H>2pRI4qhRDQb_LSe>|wF4rE$tq)R_ zVNXo%*sQdbPziAr*C#?1heaHL%#J;g@Ytrd3y4~UTM0YI>*x~T${{PT+&?Ae;~K!0iK9^6VrDrz|`**(^4I805E9`T%6byH`)dK)J-_P9{$)c`xoZ zA8iMDjjhs5V$5RdFSFN}Yq$vd2&&P-qTiEzzBQA2#M$$!gZ9`@^O3K5xtEehR4pjW zgt;;nsA^dWdyHY%#{m<85SxnPr8-iZ!p5SO6gx^ZOJGS*#spRaH(!&*n0eLUX&o6&YiIwXTFJm5mka~`p!L%gF5OyQ)KBG2Zug;uML zR(DB$XqTm=+u)3UnA`Co<5gz~FKQ6gaEnIC)UCpo=8{7g)R1oYSq0KFZVGFVU;8J~=?_wb( z_ci|`+eZ^Kws3{GQ|!ELGO$y0aNL3OLkdp=Kor*UWYP$p{`d3tBDrm+;60k+H(i2!N5Q%`6JBk|K?i_OzmTeSRZDkr>YpU4 z`Bp{Cz#vBq{q98J+z`IT*Q%3(txo3SPw_cT1};D)!4P;U1WOseMM8EHfO9-g!$F4BA_ATyr7L)dBE zYBmFFfv*_fk6spzzW5)>$Na&qF@1UCE9cusLF}vyq}Qc2yR5++ZQf12Moo3gCmryI zCyOc0^+e@l^mE8~((=B2&tMR=dpC|FNolz-CT!D8)kTmc-vc(pt74d{YzkO^1orpg zb6m-@z*}axLJ}byc5rkNF>O0&cadBUHP$A|ojDr_8L+KD)%3^Z4Fhu^b1Fe`RS)BI zGw#a6lUU>q*LZ(eG=NZWD^bulw_>4{ncBr}OU^I=YsI`Xp-U4%#PA@%O)llt?2!LZ zX1pzV#mZyPL*(zhb?)4nS-(FUmk}tJ8u}+`0D)Z*mUa zI`j{)jLCt2h=^f4;=)$BBJ=yfiDvI{lYv@%7M|_B<08&f1)7iJe8hvYOvB+?Wdz~i zY?y>Ua&rmlf^-1R54<5vVVs^eLp+|*NG9rbXkX*j=HBeZ&cT~o_dP$(Y=}sV8+=C-ZH6+^juD7Xm!d8mxt>_4^%y2=N=oGo_RUJLVRA ztvI!`u7cA|W)pe?(9>Yd4+sWAu{$Pn1@`J)Q?$jCMxK};$s1!KI-uSy%Xw(xcY8IAUpN0k)@`G+ooQO4?7M3-wN;N5{x%cgxVQg&jp-G3@n+ zq4Zk~4E9ql_@&%X$VK9cGmwpC`K;(xec^B7yb3S`36+We^cRBX(Ery?^r!vNX3BjN z=};j4oK-ipl+I_%*MHD_`X!2MOAwd@FEx;hIo2+j0EZCILgyj{ob#4Bd$Zj-epkT5 z582L8yMXmXgx0k<@h#e-YZsqD=|o@(wUa)Nh#E7zAg@tFQVV9StjfZVmHQ?OsMqu6 zua5_JajaJ&JQ;zx#FqAjd(uVXAsiiIVX;wcB5PN=jA8p7V#I}@weW1t2q75pQ-Rtt z)cEFiY3UYx%g4m4N@;K(q6v4B$(OTcWN zsZ647;%Aw|u)Uqr`uEMuaE_QK3;`Ws8;yC(w4+nc4D_B$C9;S zCq|n!CG&|i)1%{rq;FCHEc`Z;dqPw*bUE%EGqf%9;o#ze^8g?WuvmUBj(&~KL+Q?g zXLY;#3!UsF#CH6j`VQmTH)Ta>H;Pt@J$b9vV!|A*oB!$RX-JqcK%`g`Y6^!KxYmiu_rU_S;DNZazDll zl~NgWAYHUjaBz9S{A(yF*vYD7H5{VqQe!Wj4kGH>U}A4}L+}*U4IN1$H&n|d&!4}~ zL*-c{p9u~dH%4#afQkAIQ!H9O{B3h!WLI)h=~<9gE@4yP$2?K13=zI<;B{TbpXyG& z^A9l#PsX0o*CTYz$n&7hvzoE>4Ky*&#+f_rKyYQvpOQJQ)l*HQpBnsO{os?=vNLpp z^FEI7e=e-~2u`=G0KjRuxm>U?H7b$CbV8o7`=yMdFPpq@f8h4@>}{@Oe^I;Trc#A1 z4Zvpb^gd5SP!vN|5*4GLB7uTxZ9-AhFvY%y55fW&XB0vIiB7AEq-QYUi96;Bcf=$4 zt{1u>pRL=h_``=`m+bmG2aaVGNijwJes=MPP;Ca|`U+kI*RJk7^NeoZ(8yonr)&| z*ywFH?YY=Wn*DrWcxO$Geb2PO)76C|7pZpxa6sNlYOm^v^tF{oCQ~;`L`#!8c4U~Q z^EHlvb*t}_QQ4d|T9$zgR~17JwoiML6cAYXAE)jvWw5(Z9HnkIyrvxLpKpmp@9P)nWt# zS!{QEY2-*&7SJA}tmTo9{;@8$;NJtBmd|hizV0M4f^mFUKsY|?fJ@N1x6YIfS@f8V zgsNE1yo_BKS*+cQ za~z%L%Ma|_y%ajD`V^xDzv>2OFL{fXv6qP7OMOO*SFA2OAm~{-Q4d@~`|S~M9zDi5 z9Rw1L;&cST#5U=|@sy>XL=lp;WQOEg6Y*AzYOC%N!S%qs}C-#05&;>CW*guMTD@~ZSI_;P^t zwGa{$q}euE4*a;k$ly;yNGq4;&XlpflCC8cZRjlfy4GnS5lb9$BJ1frl|Ln1Vg=Qr zyzZ48?IHVIKXFITRkGVeI0{NHSlTm6X0q1&fd=y}5wCT1HXd<8zw6e>WTEA;?*4<- z6{8_4kgDn7h5;bqC|aBq8XgeDGXqJS;}uH&8}>9LKG%gnXNeabNPHGwMpRwN$n^>~ zD{eTSW|N7@Xsn<7s0x*%AgRa0_2f6zy{}C8O#0EZB;uP6mD2#;Ung{)HUK!C%O0>n*Z#{dYbb#TP&U7)R*@q-`*Pv>cmgO)!lRHBz`)8=%gJxNiEo7Z7brh6E0pTPZ;{> zKw2lajs77v?E40M7(<}KqrT4QZYj|CNp2F<@I3ltg54*&v+Z*8fv~Pd9fTU2JPV2^ z_E(l=4lCD~h+~e9#{7>B$)6Sg(TodFFsy-Oby7CTM!>dKb**^~`ed>H4E~vXBT_5U z^|uH+d5aPgMcR6|jgmryV-q3gDHeEt(>qc-tSI{XO)tVWBiR9Jt(vmmI2)L)Vq^q=+I za}Iu4hqvDoDfrpbc`Gvu>_ZPudUTApR1Y= zz#b~^veG8l%~im?L61hbn0D5l*T|^2&FRVCkX4e3@0xuZli0UDoR7k>CQ!b#(9_b; zfsOOK8)OOsB&j)RIQr~teljFBR5O=`A(^|u=RN`IMuQIs7Vvm#b6F6K2~A)v zvwX3r#Wh2jA633FBHvi(BPTZzmtxh%Ta?W;DBy1Jdz#}SD6WujtT=PF_2)jH^O17E;j4-_8zIPaKOx(YHGLA%_6L*qR0a3DwQIXUJSTl-JE-1t%L&#SYmOI zsoaB;OAjW*mB)G>Q8c$+XifTY z)c>WVj!32u>`88XYt`F4VxXk_HZdbgZAY5sMZAcMM5Ow$V%prL{xOeoos%8NfL>EQc;NV zx1-J2D!0q1>3ktxi)kPB;?CuECg*7>R?YoB2Ha|u-P5`z-GIp0&J5Q7=?gc8MTB*$ zI@5{TA8FpN@bAVjPG5thiNK1{3he)-V4<0rok9Vcx&JZH`Al|Jhi;dbQp+HRc|Fz@<88suA<_`*vuD&4&qt z-`kT~S7j7L7tmsc7fNB!N!8S8hE-$i`Vzfcwqio@`S`msRj^@6z$moTlt)Lzw04L^ z`zHwf#cwfwKr?Kdm7x2gvawpCDBHP+cz|$>i3ul8ovR+Z(sohSw#1C;oiLIqzZ`%k z&oU|vc%m8s?6dT;+Xb#AeJgjSnZNWK$a?UE;Vq+Fe4#E zEH0f|6**77+Ope*NzdPUY2#D^tK~gAh!$kVY1wf{x|s{gp7^p0ytA4zG~)u@$RHCY z-#H#)!{fPv%L0(7- zyFeio8UzFMqNZ|XlSFw8Ow@$wgaGtICFAnTMi&Y=a*W5bWY6@nS)>Iss+up>+VPQMf$wC84l>nphW(Q0!k~U;(}@-JqS& z%dQr0s7C=>NL~x@A&!t95no+z<4edJ>=v};@HIQ#Yb$fe=cD&rCW(v?ih{4BWmE3r z1&&o!XMXf5Y|rLKFurN(ANiv_XW~>`m+<~wAv2$k4Yr0pyb6}qZhF}CWDKXEM~2)y zuQ(TpsUwj{D53~Gt+!V6d9((NU4_qnWAUtVDrJF+GS-f%wIu{NGN;3B>|n?PkuO*poEcTGAK_m$=kzeRYcWi5{ zD;)?bZmvLE#rYTsTYd@6RNJ&9!XxJ=o0g$q1JDt9WB2MIsPz)gVu3}P>=B?-eE?0X zMqGy4bBco7hQa^oD?6RjMVyT37yF%nv~|M@8HMIR+^~IZy~?is74oO$Kn4+75T9`Wwk_Aah)qdui8b53aBh9*^fWs{x`$X>4a1s}S;6 z@YCoOjs&LMFgECL^$%dvFSe-=X{0gM$2#aS6UA6Mi{KWHxX)XySIQ$@df=w=LptVB zSJ)GD*J#)8Kjra8trq64z8@DLLQQ1XWs_p!Gc#eMR7sw*vBj7h zSF@#Q8708lo?jb9grE24_)nFFoH>M=Xn`rL`aP%ZdMdWm*5|}^kwc*Pv0AYo>ovvu zS~lJFdKhJ{#JA`cUS0stsHb{oEko!Nra8vO7_%PoMoV?#-2b!PfQZ5!LDKCmYv~d_ z_m%<>U(B9UHtYay;${dcDWIzR;$tG~=GJZ?C*21eI7r4GAA1Y^D2xJD6PXxK!p$ zsGqAQ+#e{a4eoP8q7TG*E|~rZi|(zaH!&giBE%2ShUz9-lYVKa!To<&0z=$psg#&* zjllbvdjT}Pk_i6T0qP^|!Qm+7Rik*C`lly&KmYnj6D_cMB*?#w2chxdezZOq^uMjd z3hB4woZcC^A4?hC<1<0n{}hquOdp^7g5crVhFWTQOptnu-VEn(MjWX2W%xvJbOMnxCgRAKTYcJrG1#iuiFCdFgV>5;v^}b z)*D>QlOYj5Gkk$g=HLnzka^jXzGu=i{BD`osx~8SiCC6*nZtO_JZJEQ=XD-h1HuD- zInRJ^X&O!wfjWXk((oJg6Et&c#nVCr@sRr#hmM%gy%wam0q%EnprMuf*m(I+20Fbbrt4+nyJ%&(Nsq%Pi>a~_3-B#9p+D|)XHZBz_yyx^J+9m zKLB{G1z(7J&hhfUw#3WsBIEyF){TRRZuC5nntE&kn7bQ6J0pC*?q+ z^g?FJ!XIHZi^HZ(%F_6u1(DmPE&5GsZXp6R^IB9mWUS(%V09pv^67N?uY8|pLwWUx zF(!dLVGu}m=AUb((;)dwQH4PW9SFNVSc^6{TB#`e(k1s)y>s+xarggd_hbUbj?bmK z`sk(Yz*e5O!v*LM0=E&Urf^US&}~@tB+Qv;@4BfMlj-fUff&my7-9i$e|;J6)C92Y z#TZI%8JgQ8LwZ*1`8vV1BvGjY#dfz5Fc1Zn??c@&m|1Gq!U&G(nM%*GelBwrzbW(P zp2I*`5UBvXkIObNz`{tZWv8pZFKpjx5lJAy9w=hAqzT`c`; z+X9wRAI|t%38x@clkM|&!jIhwZhmlvOEz$i3XA4Bc&i>}#6eY(T&MRGx`o1YpD@mR zeoo!dju76jPA?EUj9~8vCmn50>CAO%LC+RX6$baJ8#1i?tdOM9f%3$cE)QJw@Z{#? z{8fd-_X^901A+Kb8F#mh2kQva122j;D(?EnLybJ+uT5t1s>0AhGZYc8Q9}b9PRpIn z6CYrhrLbUtVVt2sMukv3kU}u_ib1CTizTW!3wdn&W6$7+oryxq`sXI5c|1*fDc!M( z>rDwfLSRCuNdkdw%e8yrW`)slkP7BX4(4tBQ>6;kav@4D^F1|mM-yby6Lr>z+;a+7 zO<9157=^H;zloE&pzxVWFa?NZWss0nM{qdH^6I{ ztB;Ablvy63*jhRI+JSdsC`heybo3toki9zLuqv~@I==*VJQ=F*AS6Uu{2<^GW8xx- zg^4R^Z#OA7;64=+lqN`9&RPGwZs1e~%=^$Odzn*e?yxhjihlX>3Oa=pHMgQ37}J62 z{%@julx}%-3ijvFO`t^4~vqcrmQS@>&iXXmzTYbx)By;`R(R1`hP>p z_>@-}OzFBr>QOe0{*uRM(d8Btt+oqT%UEX2QhJaBX-c&A4ykP#P34Dqe7W9D1usB@ zDR3X|W#6hUSWYq0$hUJ#eZrowAUAJ8^90ecI)5BdNYn44%@{FDzJCa*i3prbM6eR) z7-cStlNMB_%Sk0$E06y04GK(gLu5f)7%!el+k+tbZZQ7c{3*hk0EYz(;unfRfSb1n zhgDZ+F;-+?7u|lgM?!6^>|AfH6N)|=2k=xK)@}EDqjT~1!(A!J-Cd(^q z2FZ^T!FQO*3!5B8Y_hqf9q_U4dYpLh}nm^+i5%5$g#ZxCdc!66i~luHnqEL8hubBgrEg z8~X*Y0~v}SrvZ!7yAdnuS@onHt}#*q-l&Ma*X2MmDnz(XCt`praZbrd(_qo*z6Q*a z>GC*EoO-g27cl8Wo8XMn97{&ZR!cKvGcse> zsSOWMt_^dm18suGLnz+6{FYmVzncSP7@FnrdZn3viY4HKw7HNSj9RGYd2u$6fB2yU z(i^o1pdQ_Sh=2o$SVH6(cB5x73ceL0uZW5ia;~3@Q)6RZNNf& zS(?0Ea@(0kl5$$g`LfwW{hENIMBer;HLqmi&iDi+Sfq%HyZ~eKJyf=4@=nOLJ(!l4 zrn~ucLW4dDXx{eb)qzWYwjTy8j#+z#=Eq0PG$fXTJCFO+#!~(uXy%ZSRU!XKnW$|u zUSVX}*?x3Vk9XwA^f3oi&C9TN;ppH{Y36F|O=KGB3m503zyB-WxL%XH!|oir*Eu|K zr^T*LV{1NhoE5@vMe!dTG%S~M-TZR5L3oRf&LDoiYkMPbpfZIEVHZM8pCHx=yYf-a z35ViL(DA7Vkn()?*K+kzLW4&cpzNnKjd!-L-x${JrtI_6h zpM=_m^8pNz(6hoHXMh33Z?%)WO7Bh<(o|ieBW`AByR(sF6The40M5uUOK&+m)7)w7 zAwSTDf&m4k42uX4=w#PzlNEvtU5>%9_^g(_`OtP7Yw~X2*%yMSJVdiw__>&M52g?B z<0;4m1jGCIsABLtTtvaR5lT%xQXQ9DfNQUv@us@DJT76Ew3RGcn{lIi_{Uqes$i*F zy?M1~u_%mgCt`+bQ=4`k6ddz$j+qfl(gj+zcq`9^CxB;PjY}1MkLsth!(xZpyS+cM zass*Bt`Ww=S(vuc?FZi0`=X~D2%jUxD^#SaOcHB;`b$i{vHXZ9Vn|bPvcTF0$B+5* zmI1G_HXVm{32N?Ew+KtZfnERl@ilG=hB}B2CX}ncGLN&r0pX#euCBsJ1G;MKG5t^d2Cd>K zal_T~Sf|a7B#~PTEgBV1Wc*}I@NGfD#ijvSQ9|Gw`1w; zt6G9%2H7X^8|y5N17S5dwlEw*_Fyei6U}C!q0!)dIJYL<9@c<1h#NxoGR3~ ziId76t=TKr_B{;SO-LM}I_%)(@=@|$hJGzX_yS;WMX({=S%a0mqE*Ckyr#NT23Ax> zO0RAaU&+ielvYZs!4#%nP2xRe^5iX-xe3_Iih2#OBX*>vZj|yVa8rQA=aVKNhd>0R zUU4#G$2g5(-nTzvt+XwYk0LvdM@6Z}GAAIqq&R#v5KrO&SG%;@v4qz3_90Dp+_L1R zN&CN@KTcV7j?^B`5fp)={}*r5C4vPNH;#a22066zwdlcG8RFDx{&T7LN~zVHikw7W z0~?S@Vwgn@+rgaPlrfdIkeEK=7&8Z`^$#;Isy0K|Xr-fkncG#uInr+ow7ID?N&yRy z#NzQ?^6nr8p+Q+XP}bU$)?|1w6jktJJtzJ@Fk5o0o_vYf33#qoCH^P z6hfN-wXKMMzY*eB8S0fYdFADF{%=VPP!rinsM)j)NTY%tqDfnG0+pMy9XR;sa8D?V zHg=5-to$X6!D#s44mgn1fXVD#Xa^V*GtVC_Aisg<;~{Mn1>&}tX1BUsJ^-KwFm3*N`CThJgiFWb$YvpHK(CFr@r%<7Z_ZEGLeBD7u8&+$8xj8bNq)A0wtLeSG(taB>wu-O; zmt`M?XX6xe#N31(suI;PpOGf-E%8ZHrxYU#JN%GH#U+_|$nE)=eMW-3carwI?kR!+ zx_OetFZZuCDsnS<=6(SX)<}2oduAZ_!sJr5h4(LE^W3Z#hW#IW>LCwP(Iw@MvZ7u| z;?hq$x5lEVdx1)Yoh41TYP)$M*TZ@`M!kXn>a2a#i=EHv6FFz6VRKZsBe7kcpQ@Y| zun4W{eG*JH-7|?X<$z%_OYV0$3QzJ~fAg%xtFuPWMvSr5MVu9y@JlN(H<@#4>c7C- zYgEhb9NjWV2XY{q54u!Zg#sogI>z=iV*s^BW#LxiZ1rD?a8%*MgC3^_I-*5C5>NSk zpc6)McXG;qa)K6GFp~S%1pyEsf4T{!&@Mg3q8KA~O&vyRj`Y zqv1k2AZV3h<#ESGh8_*?C03N7F3<{RiqZj#&@$N6!)0&+QTngEyX{*8{rFaPl?$&9 zA%Q_^Z6g6$c@~KJ)#hj4aVfG+Kmy-#M(8?4xi7n)fm?sL?c%aCAfu8D*K{qQ(Ec|0 zW}PH19ewK_;J|R$1p)Le?NN3&p}{V2QIS?|VEi;b^1k`&W_CT zYy^n)R97)O`UJEKB5Y^}EO*eKyXq2dIe$WF_ZD$P7L@zSkLCq3Nn zx9g5~6zm?akz*sr2I;ymRw;RHi{}oIGSdRWZf9*@cUNQ2Bc0)=K|1<%nKlZn3$PEm;3ASHY9seQ2!>{`iJEEpN|vPMs{C$mCAMaSG&~ zy(#C}GJ4%%+9d6r!W`E&j)T{HqWXSO7xHhcPe5Hl$)yU$^E{v*agKGJqtgy8{McpH z=CA4+W#)J0o;!3H%*E1rv;q8#!H{1X6@}!oXh|$|YDv#g-=wUitx4|yas$%|Lt4-e zZFEd>MLMT62I?)UWw=C#dh8b{q`uaWv`=VvYEF^_{brnwWL1@sXm0HS|MGIwGhZR!is|%6B&7K zkw5qJK#sw_S*U}i_mS}CzpYi9M};x#$m6mQx+bmMIBQoAB`o{D{j^z}kFN`kn5}_7 ze=;xc8a>I>sEk92;*4B&dkb++7-N)fc@_C9IyG~@+U084GP~#m5|A1VMu5hrwsno) zLryyFEv9(FK73Dar`|3a;@3&~E`@5vOrVoX$BAwEV|Am0RE3zix|O86+OAgOpf?uV67_1F8gMOZLb3oR=O?Mp%C zSDyE<)ng03T-SOE!3CqtuCXWfy{$vTTzE&qE+V(Z+RL|SY5*C>^#*QNK*8sddS;&u$HhAXbME$l$X0F2n@!GCVL+Xa3wUygB(}Nk^N-(un@_Z*NE#O zP<+yJyYx%QVSg|}Rx7h)f*+pkO0FO&r0ge#omNmSLLvq$Gom>OZz_ zv5M}GGZ4Q+&i}@rnmyNe6+}JC`|lXCb-}y&)#Xl$aYzJ78zHs-6_Ynk75sa^2J!q`4&=t=1XMFfa#Kx5e%v#q zd~P?03}^x>G)w7XZUhZf#t)REJ(0YjjP|m@ajM!ne50dh-% zc>h;KG6Oy8Qun4%pDce8j0ut)chA!mtyeCuk}+o!a5?ia%BC%FC8Vsu!7~KuE(w?b zg4we&x?v#ZDldb)gyGOGq_NztzUs~8*O!_EVw&ew0jo;sMeFh}&2SpXOpCX5z_HY? zN+yPsnNW;URtS#f5=@X`AigQSEtZVz> z9gnl#NPW@NyTguI**^{A!A6;|kJW~VnI3>@PydkI-eHFLJCbaX405RJo=*0lQuTV1 z2zrT8D$?7G%e?u?Nw)@s0v$vKceNkl4KNy|L<%m@krchW=T??T#5Ha2Hn`H#wYUk?EZ0&(~+ViH(dxto~z=?7qN2MpnTUz&#_S8+9`ONel$ z&lIK`x<5`tlJuxEM;3MJ3I4>!>$(KcR&@auA*YDd7g3R7`9jz<}=}2}w}J*Q2B65Q+%4)tDl2A{Q1**uf~ws>{y5 z`=J~B<2VnuLdUJe-R{!+X|nH+vmW%`#nW!9Lb3XdS9*Uv-G6+Dkl{eOSAV^;<+zIw zAdP#L!vbx=K#vM1J>djBJ*Tbu={`IJq>$22qw&~G35NjfF|0Pl+58*>ZH(!Onks5| zi}evpI$a;$iBnb(Ry;jMV|zdLHXT1o(T{diTI%G{ymvckTZ-|05}8V0z=O?C!JZ_h zw6LjB8!%PztlLav9sV^1JCp{@5Hq%SFo=M&vFt6VEHv{_duSi2j7#-vq3M9SUHI~1$0K{N zq6VDZu8}=uPlEGDvOd*bvoOI`T54&zzod95@)&pDmFl77Y|qeGi#OFPgDwCcNNo}r z6L_2t*!teUD6=K5r6tx03c!~&Fc5|9B2kwY&t4Bmcv{6Oh^gZAGn0#{Ve0Kfkh?MA zVLJQkYMI`WAVCcDGfx@2(*LV58hQDCQ?m>#!?4>BA|sPGD4RccJIZ(rg9>(J_np4;9(JV;H!Ez;(>!|nZ`S1&%~1Lza1UlO}0yaTSyy7yMp(hzg9^Khe!rWj~*WCvQBa0)qOQ1zf_bp^3$ zj?LZ|%bVN9j}rT=`1nsLKuWDl!Omy-Z{bYnq^i5oG^vS=z?Im)^_Uw1>uF|GD+Dfy zM(AyYQ(#KH?Mc2dYn7mmoDjMO$s!qQMikC9-wC}3iV}LV?Qkbz1bDJ;iXSF!8@Db^ zpTrgDvFy`0_kJiJyal@hrEsIc4;fl}aBuyyrv9WS9+Ph^0clT`Rq%W}G(fyyL&D8d z)8^4{T7i}7ahvVg2x58VdH0-&XW>V0SD0`3BQVsgD4fGnQjTGGhW^gGq`UR2Ratv8 zgMyMBrN9tRK-;pO#H*j0uW!Rr4m!5q42-KyL{ITgwi;;}b`BvM;yDZERC|*UM^@_V zBD%3rahHC!$aFOJNz#&#sIYFXh^D&CiyxMP^pt-rqCR{ApHWE!voEf?2^;$gD?aa# z?pBeriz-rxL`pEigpVWLLLq?ue*PyuCgZQU?j1R^P%PH=b5w@BMt>#yC4)*ez5aMk z{AEeS5))j=MCrUL(ElXU+sd1;;xgl{_U~caNBCJPcM!T2&C+|xkk8A_pVKdrjK>J^ zWZQKX(7PzuL12u@?b?I4VA==mD6GU`sYS5qXA+GBepC|tL>)-a%_39mW zirjVhJryql;KYb9o-@h?51fvoE3$FM1!j?%XIi}06>k+_J)@&IPXAkD$xS-cuA z4_P62p(P{puL?+FCZs^B5DIo&{04h? zK85>-;_(G`kC12Kf|1KgkAtLL=J>9jb2hC}rx}j36M!~_Lu!vF`v<+bVvqu;KMslE z+M2H8!vKRbE5^ikxGKWHhYe`18i&rcFj*$nxuL7t7q@9=R-1goR-7T9<~eNa(TUl^ z1$|l`&2@yLy7K*G!?IID3@OJ`+vWrcE%#nW93Xic6sQG5Pf+Q0%RQAoKf`6lWIsUJ zCM>x8DJuCq;Hnm`lNqO;-GfV2hMhXCbDg-kiF+5Lj z_VS$QEu5EF_fn5Doe>Y%!%l}zsH;zryFWd(xa9P7d$!~Fv2ESDdT$%Cncv*UZ7(ID?E-pEsU8YxnLeb&cVvd zalu@~-&uYp($QHqCvyonZL2~rDGBn?Qul_eJ1;YTD+5%IuR^Bw4^+wV%M=~?UW+^} zOvBS2PR;tGs<<3_KK}xW;p|=ryeN^zoTb}I!3gb|v^fu84W6M<(Io(%byz^XUwCwNWmw5LhGS{W=Dp*b zvLE-*2sv4<+8;rC7xdbQqZQx-UYa_3?Le^-m;-FzNNx=eFQreq*3RIy{uL44NQ}%3 z;x`X&eEQ>^;kvjI;o~Nud%79#IU$Ikk(YVaq}&th0++^Jc)FQ_PYG2htYrxAE)OkO z$pdd@%qcroF|^3u33@KwjO^Z;8)_2kxC@w17wO~Mbi*m&bh^ZYhKPN_wYN&|F>?1W zHDKWXDZxoHXY1&g=Eg1g(R+4!zSJ(d)eMHfbNBzd??e){f!Ueon!RzNHwDmm*ek<| z1Se1fYz@oy9fO*R5JJZanX!0S_i9m5i8v5$zAR60*&Ni&#V(9|-WGeGEOD**Dxukyi%P$N1MwZn>Yn9jO9-?#aJ9wo=ZZ_)P16hWNjjo*9p8g1_) zRMK%!cVTwOQh%(gjTP?2aqNnY&G%?%=9z7^6c}q%DpozXua5aOIR-QI!1jV|#0^N1 zk27fFKYRt!1GSt5H*#esv0{1skBmX0Ku5l75F1yu+?|x(F1a|>L;2~*((r?T-c_9z z7OTBgS2z|VNYL>c$mYv6(OOg@ohH&XuIEeAVd%6KIP}L`->f2V37#pUlwiFa)va7U zDusX?z1RjNR~?I&C9m=$@B-KzLu$rsU4`=r>8*6!b8Gv#tz%*;eB?rQ%dM&P_%|pX z-IN!f3g!A-Qw_YVnf4&ROZ&WF{{UG2ALJM3>GF9po!t2#wnA;;7uVp&daie&|wsEr&8eRH86EJKNf2y7ITJ{Z;fxLFuaBK zqgI34^XN6bfNEt59#S`P$9T$Db)@e0O+a^>lAm2#Ov!B6!a|F9M8Xh2%~$Embsb;6 z)kv<(a(KJd%jgq8(`MwDTH| zONj}0%l`$3^I>in#xp+gwOEZN7by$5X4H^cNUb!d`*-5~wLz~Afs+_VthEt*cY3!2 zV)c3@Rt%HBzp?{qj#WypnCRoix7QD0&s*Yfg`<1bb^P?mwtU~xkwkxh^5cA<78Ogn1E zbm_FJb$k4=XL{xll512^K~b6x?*%+9s9+QELA6x8=X3j_TQeIGI{i;o3IXu2G0PNO zgZa-enTeQ<7c?EAuaJp&9GE~=Sjcl^+=OZ{>3L$$R#7VenIx3{C4Yg47CSP=NJQ*sFPKw zi;Iw-Y(6FneB3Eds0hhhjUAOv?xeP?u#s!uu%Q$k5hXmIG<=Ps1eOdTQGZYsmYUgtqaY@M;J3QB}NXH z2H;y^`m^PH!+B`X5F8&)BY0RezMtpLr+6ATDC6%6J1PQ6rbB(R{Ef%D7J<%UE%sx)pnlp`Vz-RcyYZ+?V!FLfja5W@T*{mgv4~o=N^tR13+YS1Q^grKFg$_WDP@e`6CfibC~8kNA)j{fUS9 zIT8I1;nBnX%hSlubS3*?N79rnOYMtq>k!A8QyWqBp98lB+^^;}>bLgO9$!hD>a$K` zL#@kz)~H{puklpjh8-`JorQsaMsMj61heO8TDdsU1%;41c#wq|rF6q#1for7hm^Fs zg#SWkikT;(0H$^P~9T42ON>%@PFcDjI8Xut%Oc%h<#)((o-oPyZ zMdbCdBeSRgl5;V^*EdI}U(lk7afP2$m64CK{_~1@B@`@?yq54fb!y3%D~r$-Dv=lJ z$wVUX^8$xr9#1hhkGASG+3OP>O`bA@4!;;lDTkK#uXoXk_IKOQ#%i|x%vtX8)Wj31 zuWJBK8qo`4btb0}BoGI=`Wwe9w6l1olid7vgKF6RD*JCkWMaa^o58k zST9G1R_ra2v~XeBAI{4|pr4FwT36^2V@aV)kU9szop6k)^pOg-vy-)LbGpIhy%Q-7 zn@ke1wD*m#rWhu%*5=zBMv||xeM`1coE3^50j+AK*DE%Bsf);}0ugk-kA9ON(^1f) zVkLwCb(<~|O~r)o&2?WyzLQ+#H47}~Y^9~&1=xaVY8Zl(5p+MN9f1>@e$wAJP!+(W zS}vty56c69zbOeI`0!B56uSrt1Q>K@h$2uxZfF4#{gR1Ty@VsoV-D=#3RoKG?xRj6Q>Vw_f z30}w$Yl$|Qj0L|bS5@|8g?_*Ox!fQ($OK5cvnS-O+>B1aUnzx{CHS|JEKam|xD|{- zP#3}V7U8+62rdX(H!AqCWQOdVH45LYtow85qi!D$O=9I3<0;gKaP`gsBJPXqz0pl$ zGMX>OV45Dd#awJcE9|EnUJcYp2~NI{$iUV_8|m=Uh_-}oTjRdY@|aiumiXtJOTtLf zchlX3iO(GpsP7Cpfnu?ryk?%u`08rS`#Ov*==<`_LMu20pMswnft~Lxl7!bn$A@eY zIcePB9^>LqkNe0fiq`VtY}K_I_3|@-aa58b#YMas?t?wAiQ-X69M)MLy3Q0MI+N7I zyTu(TA;Hn`Hjm#yv=-UC7173Y5yAc{JuJStj2^@_O?rdTl4iGTpvBiHZA|Symn>>H zl>%$>3F4Qp!=laYQ@!2$wG)_;Ks-}}w8Mkz#*LTzH?F;OLw_YOO>BsEx#r9YF!_G3 ztIz?O!5rmRXxd-&l)Q1I=3#aSOiq+~lX8JvLX(o^N4CF>Kfz|Q$I#-Cx!n@WLYI?o zg% zhl+_ul#~`JcH3lP{|x)}UwJd-LfVa4_3RQ*dfmpQIT+oyp#({(%4*TWRU1^&6(;I@ zd@`4(smFfMU&7_-dz?I6o@Qo%*gvC^gZ+asM;o(%1nXjfH{sJ`mFZ^v4}uZO41Bn; zVtXP*E6PTvVNC#UQ}eH^PYQ4-v(*%;=EUe8fcj}*XHKK7Q6DesMdF%Yp;@4qkCHUb=D!BTci_wIbE8aE}htBeZjg^{e*`afeJ>JcG&hWg1MLw%Qf0ngS< zO8R5L8eb7P+#3!j>i`pp2;)nE)y{&w!6-Sre8Af4!bf!gjfiO+n_grXl`om9w&R zrct*T`rbdk3dGUeY@6AShIi4N$S1k8u+sVKOrjTPhBLelhj&gF_^rLZliK&)JR za$Owull;=eS#YU=>eStb3aH-W<6AmH)wk!zaEF`mwA;QWv|_$I{H$g?hdz=Tsh2D* z$zlcN|CX(6w8o_rAEJ4mA)NGM+u&sFdg>mz7G#)^F#&E?G?W-%UJb)H&YfHqk zQ*1wtdNRH4o#U7GHMYhhRE&F4jHJ}o9(l^V1rrCnk*eKBl`YVUtXt;+b0t=o1S2;H zpcI%59!vl>q8ps4?q()A5pGvt`fLV<=4;kW9(8uzn~$e^W=B*9ybbYdvk1vhS0!I* zo3+g|g^VjsyqOq-4-ha5OQ=E4QuCoGSzS%oG~fTqP@C#FDm2`XtcAe7;psO1SZw=B zk&gB=P9a=Zz@}?9dsBc}2vFL{AUpGmTrm!dm;o>5$HG+Ej#_F+T42ahazK~<)}n{v z!jzdqelv$7X5vMjk8!*ArxqDV9_T4cO+WOG{FYczp5s+}24BmnGdhmSz?0t#eyb6` z-C@A}+ynW>5*V4os;#DzqC3i1W?rPtz6^!DS^sOS~vY zI3{W;B><3{F)ol19c+6zZFgo|f;c*~zYQF}ff^TAq?$>k#;8?IV@9qzHtR2f-cBTs z!wQ&}EeF!;AsZ^D`ezJwg`VefbGFFzOH3V>{>3QcMIZE!fi^qJO>nL4<5;BPi(FO> zUd-se*T|Wslfn0Kgk_FZ64}W2kMS;JGIsZ4BQJ7bS*)h=%3Lf2%I|R$&x;K6^p)Mm zaiq%GIdhGEABY2$W^-|4Y_I}aSwWkuehK^@H9$Prn}%@zzV5Hmu+>gYZ$~=Hp>nSn zcZzD7Se($8%MrlL$nzrz0bRIRE+llt1P9qU!~9*=gtDe6(@MOD3TT??}qV#u`VHG;l`xpJ0n?<@lR000#lw@Ew77zBTiZ%}K3>3Gi5 z`iLF8T6Pl_4h+us0>fT~vcTA;gVDC~d)UilUCCGG1h>`b#C7hfG|&yWuTLDY=DX^~soj$Egf|(N5E!0o z5sNKK#_ZyD8jmHhZ-pKW+6A%vvk;X;fmI0=_J6;d#pn$l9VpuocAhEKjS{_5!&gRt zchc_a$2RmcgHzw&Y%F&PJbH#6{}WlDeqk7N;UJ>r1N%H=w4^}%9V~*D;gi=kzf*?J zr*|EroYEagemLHXZEK`60sa2Y9M3qj4?a{5ivW@YjF4i#EXB*O2rPktAo0(dVRiIJ z(i$RIyHf?8H18z6N+L2dS|Bdbd&%<9Z_6ZNdh4M+4U3)~HqS?o0F_+c$e0usz*xqO zti3%~V)tZO?Uje~Te{m7#jI1iRl$p)Vs1+dgmSgtFuyoHUz?Gp8Cv%04q#~$pPbV; zj@_f;D^w(VWhW_4_TSw>rrwIZ(u~B6waA!CMEAVSBi5BJ!Vv9m%M;gYAlWu#dr1`; z-}29f(u!-)m&qTu0e>qV=dkB@+) z;eR4rw?R0eJ<{Rz*m^OimR0cNIX^zEanE!b0_()7;}oenX2#%TGJL3?!7FMxF;fdo ze^_~pm4gqz+Db2K{^%~iJm!gyc$Z3d5cb&REs(AWjqW!NexUQKLZ})#+9MjRrX{%= zJO5N1@|D5gk z>*_sxlRCicgY#W_?{(24*`vzE5)C4~$U?$SSv}%N35e z4l^NVfH>C9KB{?ez!w}wmGwD>)F?Ccmv61}+cN8#x!CHPcg%TruC3j-#ii(2FfxNE zE3*e&NEAZq$L*hgKY94=>!Tjbc%hx<3YJzg_`m^7D7MBUe+gE=SfasQ3e3#m>?_)^ z^C>Cl`dO74jwG$|Krmh3{-+==35Qn*U{No6UbV2Y1Ror{9?i>0opCIXa;5}~*q2JK zT$l_OFR*P4SF2b0CnYk3l=A4upgIrJ(Uaq~&2nk6h#BvRn>}jBF_$F}o0~&|WKqAD zbdry(6xah^Ar@MDB@lZ>%@RmS4qU9~>4%P#Gd~xZ>3i@s{Odrxs%NUP-}hPT{QSR^ z%V}UHGCU~X3U;aUz;|_pdQ~q;629IpzA#AwBkYTo>t=>MyOMd}=p*E;a8Zy?6YOKx z(zGnsfaTWlZYop^{G_ztWVe1fll!0h^c|EK9>?eTk!2bzYgNkvaf%f4&Lw$1xbX{59`$~@E>_vIVf^8o8_7Ju-rtGSU}VkiBXV*W+#BCIvm-M74xa-B1}%xKdW^P%E_Ga?BYrRAqnSYGD$b!)09_mp%>5i72?p7`g7FT)2CHjw2#CP?aE8(btLh7JEBd}wsrS7836}w}KH^~ix7G)uVN0U3)de|O|9zkN z0mM34;8iv;QL~(N?kMZ=ruAkvZQei?9p&lak!N08jyf~w3U45@cwtsmZk+^g!surQ zu^su~*p?%n9KT5%}_{|uw6*bzTB{>=(eKc&)zHl6L5A?YtFg1i~Fia zc#^Fy)T@LC|E8o#nO^tO_TQQo9CaCh`_R;2knB~l3CnZ&yYGI9V(gYWBnj0q>H zJBn23Uk6i{lH$hUQ7X>BKsVHMHw^~2xq|PEtJ_?%-w27G8})zo6Q2pCA09Oid#3$; z_S6M*8@V=hrV!AdgJES^P#i;uIQfx~86c&_0DHh_1Vl9#$0zS6$jsto;d9@2TmlaU zbY*XMy)8vg67PH;l2)i@=H3BFG4LMo>{uc!Zrg0EfXFic9qq~<1>v{Xk{G2r0AnY+ z<|XGtqI+KG$&8tOe{qT!lBxn^hwc_&>w{8CNnL@f)|4`mDsmAO2xpbP#{cbLjGmE|M!)$0K7x68;! zYe6;NpfRvaRRul~GqT5Y=+Mj+(-&GkwT0O%2D$tCRS0~SF5tR)qd~!&+Y>!Js5Az{ zBH-pI)}kc39zgDk_#1JY*3fD+bAq@b!zyncL@9ozwP#YMPjH$hV@Lz7Ird9PxS>0Z zk$Xo?F_3gg6(Vp+ssrr%{qvQWhGt;wmt>_k+5wN@D}mQBP|<^H-g5YO`ISh;hUBff z^lZ}mbkdq5;$F;l-gw^R$BcqmKuV(_4FwxoRJP~B zYox3Xvd#em3VS+B?`lecLm5B~nbw*EoR#a<=F*!)`-V|kfIqO4C6`!Q>4!@1{^yHF zHcm+Sbw47>3TwDhvg#*n1q8zYJA64qDJ?{R=o20AwqOJDsF1s2_kl7=(YU2`8XrJ% zWDwP%U9()uA)!xqmFha)<@OnD^V{S2jV3>?R)CY;gR(|<%HA7Y)TwUiRt)+MQWD$^ z&FYRKy#e!ku)NNZC3CXWh^c1ykyacGPdommefk7nt7+wIVZE&yUmySA`;Z+%?k%(~ z!0$8VPnp;XJTodsu%I{C1tCIM4miFr=HWlw=i0dUFxJR%GMWTPNAe#}jHs05xy+`4ca&Vd8zVb%$>Dfgd|9Y!Q&w$zAEfYP zpKC1<3SD|CMivPecyu!tUw}H{Wa-2P&I$lnugC3Nb1zO7B1h&qC<#lhDpR#X zCu9q)8aM)Vc=NK;mhY6)^%QqBG;KGsCU{4YqZ#VNKFjC>%o@20;3}O^XO|*2kAuuv z26Da1VXn~(E6p2mwRrfT2|?Z7-I%--*L&02{)Q`LG^OdB8oM-X77HDTqMc_J@M!qvlbOo9xmAdXis|cI zRedOeOFcaF0->LkdzjB0+&&Qt`pBIoI5^Jjs+;a>44#gXN;*f|1yeUo!94T-BQZi} z+vEu|I2lHGD9B^RN=7=XqqlZ!8)?{lV##b@)3=q=??Uw#+JwEr;LJ9ZOl4`HugU^I z6$xU|jPrDkb<8e|)&Q#{O>LE`#+L2+{?Dujrow<+(mLoqHN%mMZnF&!_!URgi>d5~ zNZDxkG*fDD-`(9sAz{IYr2gkYR+IgQ}w-=3*<-sk(nX zga2@_&cN&H-6EW>A5*S;BO#Raxn1|X_pMY@BJMFDFW)HW8$}u;d5!pUs0^4Mr2gB z&Lth2wXmZN2-=6%B2eijL0ZzM&<8m{%yTBxA$W|MsoDP1H}KK3>5`UKP? ztaqkVObW$LvjM`RqK>?HH|vcCJF$)w9?O+(tfYpa+*+%H8#zZSUzr~Xv+y7tw~6&@ z%eS#{bL|12Qy>(}S$pVd38`+~i;UgYkdYAQ;heDTrXS{+Es+Q<&vz%an2|ot514?5?K>}%(A_D zUlPM^bh4FEb+HW^qe_G4tA3dmQZi3&9D4jj=CI;Ak-M-^9a1VQ4J<;lZlp^M_h~tG zLGz3>W*q1MoLlD`)QCjhru1y5RW^g zz^j=SRsO)I@9$9b7?g}og)(=w<|iW;%PE(d!z<1PfLsY9I|T6$I_%ls|67Zs_IcyN zeRaK=ECh9$hBpjy1VMzSRFl;D&Oq_30IxAhPaAS*d1L?i^N8S&zDd|j-+#|HdJ)&l@XrW)eU-B?_WS+K88p55|4uS}5*ct!T`if1}c7eZh&>mHNPFkkUoeQcL!>K$D zMLe+RZ7J6JA3NjzCZ%c4QGi5lj7_qc=J*J}E-ns8$ORYVb?ZQM%DYK0lj;Rb4nFGU zt&+jJk&U$Ej2zepoQd2yFdZnyoAg7SKGv^v4B@(;PjJ1uMp^<#%?phmtx@-lD% zw%lI!&QhYHLS5v#TU>%D2Hcx-ADySrx8W3*=}w2DOa_8@pu{*Wv8RmEJ};<&vgG|? z@rLq!T>+XL7iL3YwAur~_~CXS7c%fVqxNoygFo0xl*VZWJX_x!l3?|`YXyMK^ya{oM+}_qan2AM*KTZaqx`bP zmJZ%HDKNlQswsHQ$}?U;YJk$hTm5z*{}L*elIPP{%Tnmce+^`yAZt7qg^MXm1{^PUSj7^Oj zTi>dWfG9V{2^#C#!l)RzjgE^=1FC&3A28kB7sT#L1JU~$ds zUaH|g01gLv#RpOzj|!>v=FjSWk!5{TL*4}?zX}|+4Pm!Fo5xG2s#0Q482j0!&}0pY zZ(U}m`~cYY+e+J|&V~hbI;t_wv#oaNRPGU4EV8bD9 z)|pLGvP23678K#7Z!{;5zxoD;fnLT9ibfHH)Z;_R_8Sytp3dx!BEX?|0iLcDq7ppa zAO*`VgMP5hx73IPdr@t7=Xf2g6CV6UtD<)TGESZ+ZueiPc%sCedIi{?NRn>`oXIf7 z9ZeTvEK9HNO_$8-y`Q;U<`ZMEd9N6Nb1Xid&DO-RtYLA4X0^TT9k}U!(+e=>ToOhS)o9@*Fuyb#b*RecDMZ8l#&B$hd z)YWZ-((Z>gw8nUZVSQm{M#mCqYj5&ZN(|uE$w5Pgc@4#UxFhUEj}EUEWG7BnJkbv>+h) zP2qD}56qLerSvP{uzMRhk<*DD#NNUxp!0U&&!gX?F`3MYwcZE6gR0IRSzM~P4P#X{ z(pX7pSgTVk4qSSk(&Ty37QyjD|insz@on}FVN3cP^V|g|0sXd&#a74XH7a8a}m6%X1KE_vknqbRc#y)5<{Y1d!3>%zVoOz zP1l_*D$gX?SWN90;Ruyjqz9uf4SsW7NF>Wm@6gR%Eh`^nvL~+RMj~5HU6u8z z-snH3e8Uo}Hdjpy0l#o{zO=DZD7u+n{SZh^WnFwv9RSZ>sdafLqGT%WtQN)|1)m1B zK3N19ib}&H2({_1kG_}k1}BA99wn_fX-)61$Co-}wJ6|{#=?WMV13z+n`Gguv%Dd4}RN5&A;t5tOzbt)Pnq;~*4xCaG>A8i8{KbcsH-ZZ{evJ|5L zdkVN@_7{9|)-86wQM{gT=}E=0DwQQxf8F`HUlqS-+YsWQsw*6^D_{>wa&ME6qzEGA zF^K&NAC{c9xSu%;X6$ml@>P!kn7KYsy-la=0E0Geq^FXZsl+u0r92E*T4f_j9X_EtkLqSF*dAGd+vwyzk*MRRLSk<~{! z7J_N7;knz6tFchL==2otSUA%tuR@y78_5re<5??vyboR)%+Ux=AAK6ui?)cHU1jv^ z=jEnvH}66P$bSWa97*m?TsoTvo!$Bi7Lh>T{L&gWIKYg&gma`>i_563iz28hR9u8j zAm6L>E8xC|`_$NW>Cw)@(o^H^JC5K$)Tp`lKb{K{O7y5+G1stqW?b+|Ep_nL4CG*NZw|>47Xb@yKRw(o9FM5BSa!f}NJ1 zsUDC-WCV9u_MMcfZaX#hGM;&kO`8)t3;`dDg(^J1xio2a=z}6#=PmFm9a# z>`+)OFF-`T$0A#_nxdB{J}+O9Q4nqc2D`%|bqhZIZo+XQ9-9Ix8po`#_j^WE2<%CG z$3AK1x8zY953@^Y`%DMlz%b4s?3?mKD{ao}AOy2;mCl1tPX+3j` zYb826Wjaq-I%~-)+TT=OO&-UwzMAn`UF}_1vkZT2yz+fPp8MaMlr{o)j!n<;*GlQh zMG_Bpjh$0wt74LwAJ=hOMlq(k_N5uI?j;4U>I7D=iY+ z2=FdW(U|qyE4VIo2jY>-stutyWc1)skfUlsl8VPf>ZvAY*2%8ZZ91LI)<8Zs#uQ-K zikeNfD-U415!5LsZ))t-UAaVuVV@}K2749tWZ;=J!|Ys>wt(@FxokW6LEADipVH=6 zZ|43L_6*j6&tZ9&j791iX_&9^GUd=8fir5YhbN=$FES%vs2ZNVF(ip6Dj6%+L)n1K z8&iNp6sV?itlApmHd2nxV+)t}VfWRB11A`wk<{oy!mN@_$VpT5E__rAok7q`(2k8< z-ANY75eREV^il`6h5DW7pY1E(R|TLvxBS)Nf@hYKM;#NB<-6w}WYfy`5fArlO?GVV zvT#Q}uw$Mb0^(Wp<6(TY@MOCi%3kXY12p(-H5=7t%8OwyO2}vucHCINOlTzjl`*oi zwjoJhRGklLNQC;VB{x`TRg%cM#@Z6(9FlDs#P3i65k+hs|HT|nO;OAMHF}y5K`HTj zDA|5!PTmks13Oc&i{%15o*c*;et^-TKcg#Aoyy)VdWfAGA{T*6j>(55iB%g{BIw}m zQBlOC(Es!6PdtmVh~eL7wx8h>ZAQd%La z9lw9BjFi){5<1TH8uMc*XeTSw$G9pt5lxkIzgdpu$0_S?fL|4E zyzDfYjV=G_tQP4jXUHBvhj=}xljc|eLy?>tbxLR>&Rb8w zvdVHDTKU*LvB z?h0PoJAQC%<>*C`EOt7ABB2)D_<$&aqcCSnKJkdUrIY(ZrCL3-{hTL6un!5T*_#`9 z#FLw|%oLr#K+Q^g!-HFUSU6Q89j7xS!9+_hHQD2PulHW63AJ_^k_zmV0VkgTwZA&F zXIBp>hKZC8uC;_5C_(#EoHgF--nl_j$Pykh8`x`%%r>GzchHU080@Qo)UZHU=vT9g zPv&oCa=!S=5t(=QUB}Dh%iCHV$$l0~gRl8N^2MNV&8clwr>2{*UGO>d-5SKHA~fQS zwHYVgz1kA8rc4`zJ*pZli#FnqF(R$+EH))9DJAFX_3v-XVTeTx<}kS^gymtm^&7RpkYlCan=F; zRWn=rUr0kvsaJ?+W-07tb6-h{fOn*5s!ZVmU1^y`|CPtD-+?j`2g5!-!p?;ht>l6) zn*hpyQ?8Qil{|6Y@~=9ZLJN7uIhDc{6I*J;aQXN#oc*VQdP_N8Da~0Oat;j-?VOI#=^wPtaP3q0qrB?1c4P`uG{?Yot905dt zhS-&qSieD;+u1FC5z)U0bn@y2dPtM{vhBOW8^-8#Ysbft>8Qpdt|Rb{$Tbygg%iil zHS&)V7t=+L6$x5MsgV={&6sR_BEd!%3Szj zpwSX%PH+ln*+mo?%ONU5!?1PZ+dtX3@Mrn2nbxCYEDx>)oiQ*s?v6!#X?~ya zM2F~3ZW=bob>%Cn_SpUpt-LZDBqYi@k}QyPS^T9)ShusE=KUWx7bjq^9oqwp<0dve zc0pGYoVysKgJhB!Or69ipdHHVgTC~EvzrXxxX%ZIJ2_24rn=h)k1a+@aOC|8|USx%{t$>HkLnmGfNN)9ZUq`JmHU6ok(eWzs$>AfTDafVQzyqFPFAm0!DA!f2vgZ^@3Hb={vplc<-kJbZ7I6(jAQ6zWfL+ z%9Yqr^51kVjh5#s4d_TzNLLEl7+_M~%p>EqDh7je(P&xO%IO3RiJlIzYSFY5Py@|} z@|A!ij2fN!>$F%q)@cTuc>b3eT=|18-BF0>Z&VdeSYO`4Wr#_-{ZXPGz!POu5qWq@ zf9+cTZTBs0z(KSw@?``_oJa$@&ENb*WzFqrfl`=9O7jz{w-p997Tq*f5w8E?ozXjO zB56@SfuDlO0ru`Saub_a{yXE&Qg?OFQkV7GX2TwU3iKdtICTkp zhUsOk19M;JCGShZ`e=rD;!b=j-X7>@L7r*?DN(7}JrC~EaPvG?p#{^0T-0MBrx^?p z;=O$3`YiB=6HmeM{QrgfI~I?;f{CI4c}y)EUTM~1J2v&ockJ6%E3#mShq+XU5H6KT z&u!yGx6Ku|(OtmmLV0Q<R>Fk}Dyu9mc#zlXe=bOr% zVn{J;y~@OGPFJ%sc7cB7TZe__X?5J97SJefc`QKmfKjp!X_hkJiV-17QBX_rU_dzE zM$VHR|()!^L|wA45*gn3Pe)S2!N(r`?Ft3@y7WRBz@cV+|k72?htO3D#_$D7e<_b zTxABz-5xVf1q70Eqtw=FaXHHZ{}i3_e?>3$FRd_%35*4R`jB?L@E4jP+(8tsakKb4 zxfsVRDG&p`lFr^24{3XZqowdMY}h-EucLOLx?CN?x>7m9L(xT8VUe+kUw`cmc|2Ha znrjHp2{-vDb2K{Y6)wOdcA zOnP&#sZ!dx-nuqFNx4(V)-ovj+psi4Mv$J4rHPy}jU!yy;$7g=z+YzX5@F;~xiAZ4 zEV5i^hRR_+b-m0sj47(XeJ8!h|07PkrfCU^f(<40F|MYSB_t`mk>Pn<~Y#(}0!z8~|jh zN>8e78mu%|cL=dNZ$rNISh9OgZ7zm<(XQ(Rp2&3%0P=*SXTxLC2g`hbjdxNG?e*kQ zpD3C1@TMSL*V)>jrMUMuyYgQ&8+zhP9sXMt0F9as7{QnGYfxkfqUG85h_~s}r@ToL zd~~lx9NQ8q^vb0Jofsdcm;5YINwQCz3Ho}y>gch4wl+M8jr3La?3Zh@lz27#Pd~Uv zVs(^!j{0^LMVh;X*4G$QwymA}z_HqYKN9H&uJcQ?xmS^Ldx9C!6#_V(Nvmpdp_Kg4 zLGZP}oj0k<0{}}vw7(}yGHpF$ZM5djjFso!dfWm%LWd9-PmMsz?D+QtL34ws%&-ti zhW02JlNgrj+MD0ktC8$jw0(3+*VF;Ab8TKSD-S!=oO@$;7OmcpOTa=KEfcw2PVS0R z@#oy*u;{iSb^48u<0I+gOI`4mZhwD>YwdKC^@kYBaTF^B(r8EQKTqZD@w~?0KgcW2 z2#}7tOH6YwW>zI`bR5MRrO+zc?jM4pVKh73@qwF()Z3N@ziX%r6oTdi|F6y19Qj|_F_+UD9O@+Dy8G}BB- zx)_2d$?dwCdg%>8aXHP|ZUFmP=gqucNIYa!CyEK9>ooyu9ldkc@f#DgB??EJo~d+< zlKZVX_KK08W?>e#AD-{S^KJXWVUyn6sPHF?V9Z!|QAivtma8+PrefawN^K)!-RH=X zyBCGqk!ei!y@Nxj)$h!+SjccSvSQm-?~Z*Y#-4u4mjCO!@--y7DbUJa^NNNop z?f)HQ9)x_G3OZX>M7dz!iSO;32P#ubT*fln$%qcl00BSQrn88X0jv2GHH1G7C9RK0#V}_)@^8RS>kPXMvG{3$-shj%`v= zARjOjw0WqS#M1OaI8obV1k;7|BSPb3eU3t*stG9l@Y6POdHb-fo@xsuQ z|00v+wIU{iB&=n64qtR>NI-yveP}mO(rqf@$O{-f8=F~q?Zkr3*&Ru$a{ z>428yXpvK*f)R&eaK7(AZ6Y2ZKjrNE{!IR4sxhsl^dm)Go`aD)&#h=Q-jr%46}{(m zekN5`E(~3X+5<%51?Z+$cV9n|_{fEkD4<0PA%CWHcYQQ)Ip}m@v?3{1mxEH1-UgfO z;>1~jEceC_l0tC6fNU1zt%0UlOY{ECMiT1{)RsGen;R3@%cNrHP}N^vjPB(wT{$2V z%+XHE-_Wykuk)|$2ODh4MfzYXQj7AhVFBrd*l}%N0`bi*5~HYJS_Fe5p-X`(BGn1$ zhO}Z@G=NPz++}l6kdz8_V6xTR#1-3UAb#`dYy){qm}urtVwue(5L_e+jH~CJ&svs+ ze&YB`U5iZ`oJi=~PI`*ghE&_yAp>x7nJ*99rDw8GR3KjKx_HPXKYpT6b1Ul2w+Qrr z+X4T(EK$h#W96?=1X^?qlCO?H$O170%@+|yiXxhz-S8hgQ^zi>0edj7nWNMltD%18 zi)4I{X{b+Ija12Wd!XT{U=O@fMM(#iLW|LywA=@sFF8@xgDzIv&$YV_mG05?MZ*7T zyiNaid9~r7OEr@l)v0AoFojT!H7iQTZbGXPDt>`YsCiVsQ<$LTT?bFSnG_sUE9XI2A`Adqh4g8r`QfD){`>Sf@g-qIKXr;I8dU6}*fK znvHaOM@#pE(Fn}IShE?P&z56lr;v^r;oiqMLpFD#Ai`YBataC!8RKE9lGxU@XgmRg z@l7Ac|LxfA*UGd|Q#1a4=8s)D$IP!!uEdwBRq4s?mlEB;oSuaZ+~k2bm<2&a%TI}s zM--{4pquI=kwzKSn4rmiTy7knyGXgjs=AC=NM}L%>*L-A%`VJ$i-bv)t$sa&4LjzW zkP!B|1hRT7igz7RSU($SvB@qZipBWfq@u?xsn@CWNc?+m@WF~`IIhb$!f-y?C(z2F z7X)iBAAG#Pos_o>%dKU2biuS?FiXIF&j*j9NEH@0eL4GIeNd6tq8Dc2M-`vmwFulO1S;` z(vAIa*X6xqt6u)@rWer94b~C z6d`#|(NG-x+S_@Z{u_ZZ+Aj-cm$;O*A2aTQF%o3Z{S@y0kt0|=7_Onh(8g?hW? z1~y2J3D&rIwd$bS?S_tA%@ZA^QP8-ix1?@+xm}!|ReY9rryZ&fx z{ZxcL%=5;V{RhIfZpH=R?0UUawLA>P;g@sKpOvcaID-zOk@61v80;~4?p$7FLC`1> z3>w4wn4=5`2hA9j&*vZE6hcJmYa~wv>W+jFHjQ>avHiedh*RgCBUO)vRU%k}?8aR9 zxQG~=jur(v?BS%GqER-Y9itr1SK&K>?%$Q5%=zL^jKq^NB75lESf+6ssbZFpP%BUw z{lbaZ$(Dxr{ldyfItN!%p7wo1wVi5LCJTQB4#q3`63=M$GC;B<5{OfDognB3Db?Y1 z!$AfpY9IBaVvr?TXLV{){+gK2p`P>y>n2#1AUlVrK2ftARfhbU=giavZAY> zwak~vd4o{GTMc^Tp`3D8q#rmHd&xhMQq$n9=e>s>yt-sP2Xuj2BTT`r4hUhd z#0ihlDQQ(XnfV&G+h2dmgo>j9v#Sv5+vc0eS-Z5G0>@2P^v%TKQK}?Q7Gr!mRy<$@ z$F3OTI@S?`GK$))BXA7vItE`kyBBEb#!y>fsQQ3?OJ$@=B)_2#TS*Tma%dAe{x6zM z({n;xvGnoI#P%2&NH?p$n;Gw@Al0J&^>v;^>wdN!FyDwI$1*I>UasEgRLQIR>~mC9=v+&>!`t_)V(@BKe<>6Qe<} z8JdgAAPJerm7IEj`CCedj>B&PX&NF&uBupxp=geVj1&&viyTY8PR0N9cHi$5fL!)+ zSd!d&Ek#UKyT$FfF`Yb9o-&p}{xPis(f0YB6@<_WXsu$}PG*&o<3xY=pp^>!<%wt* z_^3SYn=Sw=i~p+k?SBtZ-KHVUs-)Z9UQrtV<;qMyy_&0C7hdlfgpFzmX!0zIALs5$ zu~iZl^iY+&$X)-UqpAuFza@#{@7+mwHo|sn_t8y>bBidhzw3F>Kt(Zv1Ndf&LxZ$2n zy(m^O0r^oRY;vwf*x9p-&*f)jSZViZ1G)@fTEn|pgaJ9CQ;Jd`r20;Jfm0t-WVa2$ zEfeUd_p)?Oj=Bf&p7-Kkpm8~euiVAqSuaZgUGOGe8HiQ@9i90NDkr?nQ+#Q*v~zq_ zwgS7z(NhTRcyEjbNqks+vgm3Vh-m>m@=EJAhh>KOvl3*;k>J`sETvSe&}IN-?3)Cr zYiTzrb^PrE+wO{;D2y1Z?&cr~7)_)&MV%LQki96LT5N6t zrb3u9|yLtB&s z%zUKitznvlyP`V-IrEcU+LYReNq>$0=n4}D0UxiH`N1rI_&PqzwdMrQ9`w)5we;U@ zJHxwY@Vgx09?Y1b*)iy9wg8JKd_ zpjE>EcdE6N$5}C+avfAd(tKfHy;jVrYohLN`wUr1S^2&ZC`yc(0wyKuV&irfRlMt{lH zD^_>l!n@H%ket^A7$-_C)7PD3<KPvi9@u#8W#MWzMG_k;V?( zMh6zdQN4DC1NNeH9S_;g=f?1#Q$8_;EyuAQYfHtF6sE@KN~hLrJPij{>v=CgS(p_D ziAeOs63u|4j%lH!3wq_y!4YUs6O?$aOiqUs?Op0~1W z;qW(H)uM=>GDnK>gG(*aOe|+Sv~?;`AmR+eJ<~Ke8srA^Pd`{qvOSJ@U#tQiJcOlg zM7br>I=MLXIS7$)Lgon-d9VM%M2`XFC?`{43|)gbMH+$5K~Jo^z?P|M)7>n1@H;P!2p#|P9%0>6anfJ}9?y2dlJl-t$_ z00RoPEf7U49w>zD{_jK-3`btMlx9OQ3ynG9U=)*#OT(+vwNX3#hi)t&*#-mOSqW6L z-V!}6c0B|dHbsv?m^_7#IEdwjL*1tvXg@t82s|A|>XF62#b0^2#80(IC_m#Nwd$n0 z!;!Wi^`ZUg_9JvLP_J@N38~}-cTMae57+_`zGLlt0jL934!C&D2Z4feh^Ax|+=fXMD8C zV_)D(K|T$fkvs5$-4v$?RkI45#{M{R0zsLixAiM}sEV>R76e`c6@9H;Q5PS*I}vz% z?DPL%>|t~_B;RM?t(2o4^82{=31 zLkG4UGKB2ID-6J5WeWWET{1!QZkKBmYsiwjKMYNM*yivsA#R@ zwE||MWnJQVZHO00vBKpwUkQnv?iL5V7~7Cq)rJk6Q-kaq-2R0V@0D(=KEt~vwpa`A z&jYXLMP&_+97v>UA_z*1qE=Ge%+g-w(og-i=vnDU;Hz|dXOd$5fKkm#oc$JuT1B!2 zTh&O%Hca>F^S@yME?7-2u@lhEu#QWjA-?R_8rnvT^@Oj%-1X5MT(hXm1`SJ)vQIEg zWF_-R-|=Cb&jn755*IrouSYIsEKF*MbOpAUrqRb#k!pv0@Xt``7=p*cer`+MrM{5o^ESGy3v5TrX>oo2%`Jj2KICUcRjV$-g zW=JU_G8%VNRPyL2*s7!?cI8I3A;ht^)n!?&9vZf>UjT$X>J_1hlDrDR&RW5;T7FoM zz{PVg=n9N_*wNrRK1J_p7fF(Y6bo&q3tpAN=vx*oP<$H80d&k$T}wV|8?$2iSbc|s z3JjF!XPXA=af#VRdU2A70Sd{@jcAwFDPK>fGlj<95%PmKmRD!?#lPRm4ab?(nXJY= z!{!x*w+wG5R+(CAoUTl>Md9bR`e~1C!*Ft=ex0g7nzkWej5Al$gv1FVYgvADK0bhu zdQc@m-mpH2c=NIR9}Fgth-)OWr`H+U`D)Bwz8PgT(Zt`1vecQrTq;JC(IO>~a{$1+ za=PQ`-K|l@aXOEXZ%#AnJW@4VLykQb^U-ZsLOW!gj%4iQ+F zs4j+J{c&HLkM<+2+6mdHTP2R7|9SVUMP@n`L~gpa)~5Pkk+30&_&h3#kTm;9^Qydu zF{bGZa2mqCGeUQj zzVFi}+wVRw<_8@BY+y4b(C(%r`hrQ0Dn4wt$%>oP`QE;z9mJcjl`#r33+k5c^jkB# z%ncP$d)`O7T2Nd*%=+oN;vu-n{5V`Ne6Ix{#NvWYFQWM3BU@l{!4bv_5Z$i08K^w+ zS(P|cEN)@n`{Qsaab)FWs)w))9ytc(L6-&%DM*c~PvIsQo%AW!xHoX=_M)tj-WH8atd7KiP1N&2JAvOcovlE{P2XCBm zJS{dl>uJ~;3BLFo>d;B~bbAP@_o#_9-R)Q$Ia`Xyu+$+yJ%I#Scn=>B-+EZC)Ts?AL6HfHY5&O4XUd7k0>uv|6y*Ni_hiru6gy5uA9w|yp( zB+DziPD5ULieFc;gy}-m_2;T$u7(L83LzENL&7$gW()B=UG_o?`0Ld@f)KsDR zejV;7iViI2n&lM%Y-5)>hidctuU%^{DnwAbz`dB%-Tz1vg>iC2&5)Hv7|Z-jXalER z4OvK|<4yj%Y97o>O>fHuGaX-F7lm_Ms=dD2}^28$D-8O09rnSW<&MNe^TO!Mxa^BFW_CdmCYsz4`a_GANb z#*OfD3ZC?kRQcb*W-v8N>u`t?X94=*gYszq8Gn^?q2d2Qk8YBL^`u0TvQB_3W!w}# z@U!91XHlzjD6oP~Ed=dL-^kT1oJ6{qLl!5*Lj622nY; zXA*=ljj0F&QJ)Qz<$MJz#EqcU2v*|<428`kOhxDuA=T?6(Qh?Ji~|Go$2AurFwl+)v9zm*o(&M{2U?2rd$Egk8R^TUUAT{aIcZ8a!c#X z5&726&jJ>(?w-n*nIk;x9tPmK$8>GX!Ym*G2Prqbz54 z)J711I=B|)>|=dm)VWN7lIvHoR#jAJ{T;U{*ue9T(D6X_^9nNm0<`D8x=OoRb1N8s z$_~b;*WhGcA?pM$=0xd<;n}5EI$*}W4%P9)qPB&YvN+xZc1`h<`9*c0DzWfQ95tmEoPjSbv1t*NONx3T}cz?1fV^J;h zrt@W91rfCJ;-l|Np>u)GV%$j=PM&q4Ja24$Xe{~V;qgFxP`-3VLhI@uj}Bf@75 z{}S^?c1^_ECTR^?0P4M`pZ?`=-3z|9!@a0e?oo^Xx^X13M*)XyAwY~BmwzbD2mv_W zWi~E97<$M(TP0)!U3}42c1&vPUvdtRkrix;7*z&9H{QX9nCz&BJRcM$DhWamDuj9s zT?{52Ja}rq49YZ+zJ$|n$)N0-{NEv*EJ^_5+Q&gU;m`|m(vb;@5b;lP{hmfwV=%%` zeGN6m(??xh`W7~lXl!1~4BTTEs{*`BL#5*rkjWVWqbw>GY*K=oZ=9ua>zE-o&wTAR zP*kvb_-l)Rk0qNz{}a=2tM%vDaOG5Sv``?Aw+9>ihz2 z+DE~Y2*F2mc!zV8M5csalsC}*$ZMpR*KjO?PJE)}c#ZmM#G+OrsLEkWoj1m@1=Vwv z3sx8kohWIl4ZoY}`~AFPl;UcL9%(j{zs%kq3wSb0gGnu_NR>WqpRjtRas2#X8H2>E z*~Ai&>x|vHs{_hq_=qg@li=Fs;d~gM(K_~sZLq_7wxQyFX`Y#uXpg_h1_Yo+0x}*G zSs>;TvulR@*&|21q`<3+I|bgn7xkBgSjlOj5TBtzJ6nAHB1fjqfl-ICUZ}=pVZ3sw zbI0LrEj>Aj)x;EwBK21Pt`A&i``o-^dSkXtd@+I3j%p%W>_ZBHE9c_fvL`mN7}$( zA(f#X=LInB_IwdqnAunn!gQAtQ7t#agt|qvvNrlvueEX~?!Y#C`q!{Fr?KL@NSB=b zspOcaIu`WPK+(VNkV~W zfF_U!pQZ9y7oR`>YO*})l~r777#j0O zgEicB`l#msp;@=2e@La|mH*9CBiIB@Y0qF0sKnww?{%AC`uE+-*z&VP3hQ8S_9{Lm z&~9Rk3xOs9MSF>skpXgASpQz<{BA{)pi|G3tbxn?v)ZFVC_HTTQ&i1ZVX@aHQ!7Tg z=}St{elkjxLgU8N)yf#pnO?9{Lp_o+roxaW|(;ZW8Qazt#r({s(Xxw7XrtjWGo0qKxz*m$j`#?M%01L zdrusn98}D2?3{uk0X4aJb=Dsjj8)2UigPG1on5+xMNMIqh4GL*EG6;Q&z*yzU>grc zgqXbH+?o}|1*<-WSm#v)Wm$+u#Ayc1*9VfP++*lJxQe4B{+t})j z{^a7oX%{ai<=wHT)=(fiXW{x_;eh-@0!yoKBWOhNaJqB(qBM{sbi@8-4I$B(`f;no z*FJZN*snJL4d|}<6p@|~bEjPqYG~#Sy$t(8yU}y5sTrb_Vb%i=_I)|5nMuQc1Z7!g1 z)rh~IJr1ZU7%kjwp*a6rlzBP+Co>@$R@P21(uFQ#REB~cvOMN`W9|8v!f)8~_S3P~ z_YSvs9Ub2Gxh%=JuS4^5D1oEjrEjgm@xsrxRzMMpnI(qZB7T+9JF!z#5#4DMID-Ny z%gWn{C715{P*AMW9#$jC+vx3XIoC0QW{Q_IPWc&Rj?F^mi4f=lf4|8#F${1VxF{18 z=LXNb5sdd&bZKOCNDfH~JuxWPXzxNL4B^Keh5W13Cc(G{ zTMdEazDL@@0nxlk%Cj{;&pH@369}*c{OEAp+c;AIoGiWKM;H+)%i+3gpm?37v_KSj zx0ZabZFJ<)JJ{0}@@?I<{3i1#`IGJ?tUj%?tHo?#lP&UZY7|O!O|HHu<&%kfen>U^ z4cVq@)_&XZc@J{C*JgVdFj>;Bq1n)xtvYC5^LcjsUn%Ysp+T{`gPa28<+kgFnwIVG z>O@n$DbXM;Z=RavM8uVxTE9LC0A5Zh;)tN?$07SBqpoYTwP+#`O~IF5n58Q_kjTs! zb{D@lWLL6FxDrJ-{kw$WNM|R_hItqIn(^D3mb?c&cV8WGKXS|>k)i4X8FZ_9I zKFcfGf5VC1KqO|f)oN>~3igj)Ejqp)(?@ODC)BAJIQgQH~c3rN*FPz-Q8afi)SKgMAqSjnc~V?@f`X&ijA zkc#I7+q$~XaB;t=7P*pBl;Z+Q@rZNr;z$A2rk?M=)c7iT#OOA-O&(;;mwp=%=Rqwt z?viiL`X&p6G%vzIn?cbhYZ_wz_YJ;r67mXO0WiEh%fJ=UffdsrtIWq{r8_tu2*4F= zhdph0Jj}?uaS<1Gpn#@a`k>9WYI`T1UT}#l9T4@^VeaAHBIWbDi_7}7WnGDylEQVk zZ@Ls091TKl3xl&eK9rMUg333l`DmlsIvka;4G;xjqAgd0&C!8*!`|NcfEKbdx8BsW z7*}m-xgh-9x{@F*dlk7Y?Fhblk#7TmB4b?ULC8aE;c}Oj&0O~+AQR02B}{!9;Fy=W z5=IgKlTkTH;KaxUK3C$J6fzSa4_enT@UqCqjM|hD&+IYeS+tD&4)kFtm~b(voTK8~ zQaNze0Urs!(jv!E7>(KD2q0tLBD1=GKJtpl&B?sJF#_WYPAF3xM_bp9tOl2*e~+jb{ja#rFJ5k7f! z3hz(hi+wlLMpTldPi(;)}Xo?R@^u%&XcQvRT9J0ck}~H z<^YsE>qVL-an?d5GX!Exy+ur;ndY4}yP5O};BzAdejr`ix)IEKw$xfE)CHQ-(>L$B=*U5HR2MeMT<%<$)^?J6E@6!UkgCg zwW?(b=cV}kU*sQ@2O`}uIfD4{m?{F``wYFEgZG8MdWAzPowkKiOpV$ugDPw~IS_tc zn^~;MFEo&6lwaCcZMR10cMV?~<4i<6M6)3-Fkjq9J9A2YSfk!kaJ8~u47hi3Nxd)G z?TUl+Z>4OEkXwF+7ZtJgg<5ult3(0; zXebZg=oky$^7Avur4%%>Zf>U$=={I;^rRCztj*rOTXuP(&8?!y13mHI^(ySc8KJ>Armf0PZr}iTDg5H2$vY< z90tc}2xs58eL5kMNt0YKH+MjIFG(XLebe&@u)l=hBCCMzsm1VBA*)1x+e)TShZQcdV zEJ@y@31eoN+P@cC12R02^SB`8!+$W0j-BX00^~&T>~c|U=I+G6JUO#2oyzL0jr%t> zn9A{u-{7UPK7-dx@{sdL_;`duJVUM8+88)(zd~9tZ|a~-FExHrtCP*C#(xLuYLQ% z*wlSyff5%C+YOX3!4I?y1P0s$&BzM~`=x|k(s>V-L!6-CLVHpK3+7|b1&D^HX9)sn zqu3Hh6HJ)h^$;C#M7-S?zApP2-HOV@V%qn8tn2oi4eZ%4sHh!eNCzg!Ep%K{ha))V z2BL89=KU^7ODWJo1=VT)1DIn=fkisW|Ir{|$9rkgHnqR~<6tT9k5FTNY-aC7 zaGA`~l$F9W-6t}4PAX`QoA zvypRp9yLbM*_RBd#6N+-G3$y0Re|w3^7cd0H?Cyzx~OTkA+&+jQTnC|Y2BZMNYm>) zBe>Y3sF+<@TH7A8BZC=BUIc!L#BLcdJC4RXAvT?6{4b9NHf>|VRMOx)JKZYpwrjt? zPXY8W*cp65JQ<0AX(F49E{BVa)8-2au`SdKZP1?UZ_ouduz@ z%9x&Ul2pu)WLI_uO2n|vWb@oQU?^!BlSOTTaAIUZYPRT-t#DdaFyeCm0Vq1i-HK>m z(#MjRwLBK>@n<3h&>l+LFT^LFSm~@DYj`+=Mk|W~YF4b{I^*0O*0Lc(LgV;knxCmq zAA~_h;XLt1sLOWo#A#u4V2i|}$yS~ISP2UdW z*ijWQW4Smova>YTFhl6)Yj1VUq``IM!qju|u4#i|M?Dt(&pkeq(_NPc`|^2B{pzu{ zU$*DgyaSFkDDmT0ZGic)CC`zH#jpm-uj$n)W$%ctWmdjl^3fQ?TuA7zv-SMtDSZw# zzJ;2yUP+qF>9@}%#~CUQs_FwV&ANj55?0nQr78KCh3j$l)F8YhY$^RHYaMg6gmKo2 zmRy#7fsyw?3Z9#V z)jt01Jeb%dd3@cg?!v}k74tTc~iKnhiTS zu^sy5X2clwMdX@35}^Y^(US$)o`zqCUc3uuI->}{-0EKyO$YgUW%|6B8Bk!!($ zz}f@F3i8>6IAi{vRJX^=+jIN;_P*({Ux;0fYk84GaN|s`kie2Gi9|o|hQ1$6Y1Nrv zpz0$#`w;iSC5gDrsG6SO$(*`^8%Mdnjy5K`Vij@ds@D}8j%~*hb^yE`20!&b zLHoQVu}%PeQ?}Hsn3gAPV0ATFi&C+k7CiUwQs`6#{N^mcCq(f@bFVRu3}Gxth!nEV zG-ByU68vb3;1K^JJtd=sKED-elCPo?bBIgW{4OB2j%}t}bremhAJWJN#h6*t$W@qP zF#$BuuPAE@J$hmQLk~IGHj>w3b6aQ!z3PV$QI~%a%`OyI7D)Hzn$g=oZ_Rb0uZfS4 z$D)yw_6utN{6|hPuCb!nK${4S+j)&A{ud{d)u~Mm&5bSPS8TFdyg+Z;3v2hZQb6l% z^vN7HmCyJMTJ#xY*nm0#wp)+GTTn-bCHl{@{5z|$KS@;{paz2kG^$Ib;a2-Z@Q*2I z+)0*p5667gTp|r2cn8RwOC&pP(^JbT@9Jt^oRiSd6+j4mJvCz~SjDuN-5rZi>JKMe z-RWr)9Dv_N!|Lz<&3g21Wqib+bVA37`PmR}4GS3?dbjTn-5|j-=hRD*lL5j;q?~;9 z57gvfd8a}e$)F`<6*Kg#!%hI7&(M;>e&Vhe48^IwpieMhUv-y-(-+fk+Q|YaQtWe_ zl$TVYiC|FBlI^aRDD5jG^w-K{*wEBOQ* zu-3H!`2eMBcZ+GqS|^nX*mb2TUeWBG5<2>gv<9<9bFv{u2Sl$Cj-`kRHh83eXG%KU z--G?0Jsb(@Pq z7pqm?`XY1bNuYMJ_u^IiL~$^ltBygKYFJ1{Wu_+UtmtBfxi?p`SXRrGU1{4Iz3!X& z3bvea5?~bOG*Oy8yV=A2lN=qH$$lLLoIvQ+h0-1Dr+XhQQ;JiUpifiZa;@`w5QsTr z1Y6CEr9MLyc!zVB;|T{;Mhh6#o8*wFIkL2e`^G{@T`49vq1y6rHB^on#-QOs=4+Gu zBkYUd=9G4OaBCD>!`8Ta=tK69g&}h}IA9xWG{eMO=?DRm?guNBqiw7$6?G$1wheT( zM%?)x8TC&Ui_7sBH1}g4X;OR@JRddY z{yPJKkh49eJD%iORg)G&Y0en*oPuDhAwl`&^*UH_JtKmcBJ!P`-H#Mc06LF7wUH3A ze&kGJApcczRb!0HIzZ|K3|?fbjtOK8Mr4F87+N(ogwE{lrsK?9{=%w52ojs+aY0ge zgzK(mxjg?2>g?Ynhv+=-(P={5_(FrJE`b&jC22e2+X=>n=OE)m5g)NqXR`RFzhDwFc8Qb9c{6!h4<6{3a?TXQ{n^>v);@kGeTqB->W?# z_SH<1P{2XZ9-#XS=rJo&JcMVci?Eur-xqktx1ru=6@ifc9iEwdrUMto-fidM+|rWg1~FCkJ#$Z(Eu<{sVTdUCat7zyZ;2?qFfl7@_>NtOwGG%%o{@v6U4~#`o zUYOt}+>C|IzM6INIO0$eO82l~Y$d4zediH*;jcLjpLuDaNmkqh5_d?87=cw_3+L}~ z=lnE4|4$$E%F9 zkE|?x(M+(#EK`mwz3BLj!&glxb=vdnwfT4OolD&D#M zQ8w|=;QvYrX-{&cym$xWUHSszujJcD^pm)CrxCcjNcFkm3c6WMoAG~* z)~<2j4}(<4{-0BD?HV!)ikZ zQ{na&`8$uqI{a~j>Ms3WGTx?(++Z`@^kI5eIE$k8Lsm|auOjnCf6D!$zK$*K4ju9X z#Y<9?=Gxs3?>`&F>naziCMLZ^(dXkm`L;T8K<=;A@1a2+rN!gza`w15OZ`Y=Kgi9 zA6)}hJJJ;M>F?kS_;jg4gYVTTapGd-O44N%P=8szD>hBFd~m*|tj+c%Hc=BTg7ygM z^^$jum=6`l1vW4(8kV=V8Z)Ig5m-;=%@K>PgA=p7k@y7OO>^HqlZ3|C1D57;!Uoga zk#-^YS&nxSEq`}KcC)8(uE}Toc6t3Yz84MSCSR<51g;Uaxh9ge25Oxm?Fn6E5(3j7bHxyWc^`Xobq)et1jM&xjQ9>g zqmIF#KB2nY5<>w0Ot8&1ns(SJ***cRT5#@!JFEHan?k!^!U@L$>|=-=mv!Id_cZS& z2E5h5BZh**?ZV>XHP~2fa!^(4Bn0^t>6y#!%fVtR83A5X`8t#44o`1&^ZMDQ$;+?v z=(ec4aLY3}E@vigV73$t;Y;d>bXrK-EFJQ9qwH3UBr|5Zurma?ZRLM;P+nc?YNJN` zW$d95)Y^XEgzP(N7PZ*uP_D-_D0sv02FbnbIJa7BD&#EIS5z4Nu8sP9YyYyIGTA=z zOznUs638cf)fU^ZLPX$rJ!7TRPaCR)+DK)vRB7JcLR}4Ms8}Mz^^b^BW4??yU||Rr zUg^$&d(bfY1ieVxQ{rDzK>QRZ*Z0^caB_#3sW=P!{pV3BKPx(}W8A6&E*S9_M{VGA zYpE!bN+id;>+OVuPY_Q8SS`V_FSdx^UW;QC7&|XjoRPISq?WV>7<6cN+Nd ztBt!5)m9UF7|zHC8$w1k(b-<{Dfp^f`N^=??6g5K(OG9=H;udSfU9`adt0Vikrxmh zxK>lvpt0S!WX!>GMej?heQ z`4lvGsTYk!vM));uc$Yj!$qTR+F?o zf~=ZXCCC8PAl85FrpfK9S;TKug5CX2?Io5cor&kb3{BDK?%^#@ec5ThHu1kG)}nT` za!(GpGtm?a#{{=*Tdh)X=g#~`op=qYw*PWIDs2UeN;dv-BO`Rp=v#f5eL#SW0SNfd-iskV(p^&J1*nPKjm!46+P1 zP+kKy)$`b4ageY2$VZNM2+vZu!a2rAeH{`cRICo{rnnLYrdYEQGOwhyoo7pb*M7`c z=T%kk!oOO>6Nxe{_wJoE*d3f#qV$wQ`e)>-H>d^i1)+M2z(Z5J6qdE{T9^(qRpvUV zQy$Nk=P}z+z08$HZJ`Nr*Q#7=#HEHrjR_v*lWFVr?J zPm?flXMz$X(^=Ws)kt;z-A~5NDpqna<4i|)()wFG<;ngnDt>dJ%hqo<7qnl2DC@=Z zyvFYyh|*7$3&* zgf#bck`c)i%{S4HxvvUaw!FToZh85Gqa(~drND=S(nIJ%wMZ$TUzv0^E`|6t0ykAe z0`N2>&t}UfgTJAyUPU;N>}6ZQ1STY3X*h{`8T<0jq|btQ9gxf}nKHhPMoq3#C%k$m zrtq6L+qPfKWB*7uQm5|f9uogHR98HI5}tH-*yWOp4+M-LpVq;}<(G;PzfJoO#1509(Nl_JEdc9383@}i_)Y^H!ztW(R;dL@;{d8Jz5m)qF9 zV-fB0uM`9m7g_2ywsl2!!w7}_p_-!=WKrq>?lmNHk%@H;=; zix^PeHlDgi!u)50ufbf}7m8aS^TKtEpn4<5`u82m(Hbl2YKY4zWGZbXbnovk4#rjlVigs)eW9c+qp$V40HU5n}E zY(5m{$QZ`_ixXT0`-HcCd-zDin-YGofJNYID#J493?4ZnY@$08hzLBUKVvq9!S@+L zKJnS!4rxE43GdxF#4vwlld?4&q@(rr1~D@ayR@GaL}6XAqKsc6Yhz5qKw#J?`NiT&pw zcIywR7g^k=s1OR>mF*O$S#8K1i{e2g>~8jI8+I1|dwjevL`F|ph@IKS%XL#R)_pm1 zal3Zf-0{?3gyEr@JVAh^uq7KNJlxmW_jqm5%W`NJSPMQYV~^UASQQ>PS7F|TUla99 z-rfX|Z4;2z*)0(sz^-e@43WHoqQ0+#mFA#$P;UFE7C7{}L7L4GM9m!=nk;K(E5tpZ z@2Up(`daAC^d21ahZd$e?+g7!9o*dJSR0UY1i?x<_f%hG3PRtW7AN;ySB;LG=VRtv`)+_ zuGwH=P6q$LK;KZ5^eydbgPM;wvb@>u!I3_Ep%mhEgkq|f)QToXEwyl;@9&34Lj7;! zbkCI!!9KYoO|D)H_$`wjIF8OG`WbUeG0WsaPh9f&R}>DftRgy~ZC;$pQ-t-#d*(6u zXoF^Q&qWzCo6atE+CI3f>50>iRSprSugx)G`W-_Gjbad}M^ufoCrx(u-3ue?fyHQh z%nT0V0W41&16WMSV8-?$X>C0_T0Wvd&o$p0v;!O!d-&_GdB(O)07rc#^lOK1Eb_ay_US_2y?=BXUd!>En9N$?eAOuV8`k5=@h1xwf7DUzAWQz$tqvw2DLX z^T=<+`Cu~Q9y0G2qI0phhRp*R)4y&2l9^g0%!ybp17hK zn2K-rIrF6%!OjKaJT9|7rWk%D672l17dsMY#b*b0uC{M^iAxDqw8!=E*wo_L5@)}d z>w)G4Zt5H(cCoF4 zAotK&yyp{T=qpmO;#4R0bnh|?h+^Ds59Jb{F#4|2C2 z=;6qAOCP60{}aA0*rJ9*{hFlEf53y_+jFD%Ur<4-+de`pEx1xiqA(&^p9}*Sq)1VG z`uG2T854`oG2LGbR7=ZwRgGbo_=8ua_v1XsS&V5MQ0$_zVYb=)V5 z=Os(4VDkf|qj5#5zRLkk{;IGJs=tX4vn?$4#OhM;@u{atJl4_kab5ZxSA1pU475VxZPM3j=Jx{a0n8li;IVw)r@d`rl8=@#$}Y!(N#+Ah^1EEoWqX0!0R+C z)hM8_4N)9=`@R0D_g;HJx`Sy+(NsZ?ZlOEX9Sm~%ItUVRm6zC zxO5z{qOJPTJ3t)nRR|mJDLceN9tkz(Ks?lT>CbD)nWkmJ4q?zB{xpg z-0jfp)~~&LvdGi3o z(oybRh~aB#vjWts>bx=}9oXniO=J#eA4T47Cd< zuYpI95+u2yFyE)S1PSdao;E%LMzEIbDv|_EGDUXYd!D%UIK`N zJSl3iT}3*8A0H=)s{KkFfY4ej#T>^}gL1r}s+hE}Y!4-2xs&$Z%-OPpJYH`Gqw~b* z6B6$P$Ow5V%rL`e_s=n8mbVvclnLKj@BqBIs#o7RSye9ld|Y8N5Q3ynAYB+a9-Y>c z1VB*StFwVuam1XZmq>>-?T1ejVzt^UVqBszq^H(M8C>K@G=9twAT8T{1H9Y~bCc4) zv(|CDq!{dICg20rUzGi&=k3?JXT!Sm9|N6jH3K0{2_~hiTy8Vy(wg|FcWe2q!m2Fz{h?%> zQ(k+chf%R*af>^VXBZk*PjAkaKZoxc!JP~CCK$io9cr9Yzt2u$+wxg%U%9hCoE<+LLNG+kM582*f zKr3TUB=GGRg!=!5yS_sGT12PIA6(KEjkLC5pUoM&_((O!u+NdW%}8%`{exE<*k=-( zBUp)jJ9CUK-djH;Ws=&Qe~><&_g_DxU%xQI}=^$pe7|*Z=u|;;1EP^s-gk7bbjA{ucs~Is40@S$ukN40tpLZ>E zmxv0aNQLHASsC>p--R+#`2&XmvrQ~R<=7Ib16ry5E!ci0DUJq61Y>H3anVP9KQe=& zfKH)|YF!`1z?OdbK|UxA_hHqOFCXrTqtlKw5;tgvIV#1KeeikThQTIoYss^}aRN=O zyHzKjjLsV2V0_@z(f1q|;f-~8C%lh=a(gT_^3i((Kq4Vh@AQ19xO!h1wsjdfpwHIn zafWTq{^-$>Rs234P=O&Rohn;DU2mJE8Pqp-iX^;!9R`jap?YXgVWO!`@7PY&WMT}E zm>ycp8e{mqzw2R0EhdspZ^<#k$lLH1FN~oJ6FcwT!4H`BO$h?Z6&=#0Qok<163J1? z5n(}1vA)VBa6W-*1y}HPSMH;EVX-+8?1$778$J!5V05MibM-7Md#Wf1F?ro|Bv!oL z^*GjvsEllPeAwt@a(SsT|3?)t6W@~jZ9g?$z=&(ip1oM;@NHOI$FQfhYvV+?@E5ua zuC+joN?{xBVgA!eJ+2o5rYQ(QAs>FKc!q%EFLdAl?o1EkaX~>wHWx`Y&X#ogAZ>?aR5g?o^EdH?J{}CvgwI=aoUWyHylxI5MGc&g< zoN~%iCEOU@F}$ZcuP)@b4b>W*Yx%h|O6R6cj5-}}u?ELJq$mi5b9ELKh4*&w}*f`FPcZHR(QmF9&F8-+lRv;o$hyTuM7I2;hDLsg|#ZC zXfcj0HwGnoLOTKwfpwsnMq9e7M2ystY$;&8eA~ZMa7K32Q~GHf$DpA79h4DGIs29H~N&WA$c&Ay-FnWx7!_NNJf+W&Zl@h`Ixm`&?A zapoD!+ZZzuU00Sm>j*?JsuUy)3_2GP8{5aK3oS)1pQgKN5rd*>r;d}nuy2%Mk|tS#UY9GCeP4@E3TKi&`df_}{HdTe>+5g^#V3u*M8 z;Cb?+Pn`sxZ8jaMuZZe*fN?6t!fa~x80FaO??E#N?(|4~BiXq6ezSG!JK5OGsE-Y; z-2tj27Hcu-gR#F019%xY$G&&+M1o4m38*ia!HI2@He@RJB@9ZE1fFFOl_<}se>Z4w zQB$npAaeVx$XM|A`~j;EMs6=}u#O&Pk>eO{G7sh~C#-XVz+(Q=~jju;4>#GX&LKE@k?EK)r56V8Y9C-(Dx@nEG0inz4-DUP|mu zm9agw39!_i^S)`^%OLW~f1;DhwL7UqAp73awhTHQwv;Tsm=s)CQp#3Adf$==w)>Y% z`n@29{7z7dPag4g#+0x0lptExx7xFz_nbi-i-o9l7c9Ud`IUm8G5&Oo0#FGDWyvgR zKr8&;A}74xgMeJi877)fC111;iE?VG2D;hy&`bo2C}zH|QSPMb377jfgdsa3zSa+! z#l5x7al^i!kr-EwD>FtA)IbU24zU)FSo|2(UT%-dvMNxFjN!PMZvod9jvsk@;_;;y z5h$IWkWn~kL(rP=g-TqLiH+I@irJ$JOxQ&WAgh2*FpwNC_6w|{%lB_`%lCbxz1&XBapP-8V!IdvWCg>7N6V8xG4y^s$><=H;>43ycd$xHW2oNo?B!vS^l> z6^Pp~J6v}A(eM)y15yELyBZTCQ$fK3bU5!NEd;s>8gBkR>{1{;sRsurnx;O=(hDw zG%mLQ@q2p>eT-68$MPZ}vsb80u6K47OA)z~ZJ(J!q_6*=;NX~U^~lbxv(T)9u=??V z$mo#(4|#p?C7}ArY`XzPA`sykRR$Ag?-IZ`+x=TvXWbOFHgv3R;IOnVGw)S(nWuQNckR zudxP?=RPW~pEp=T%dOxES{`#I`(<~qF%lhL`fS=2pvx+tJD+>ZD@P!mUUV*6! z$X3A#uLAwT5X(#D2Ecj$*BlVZQJto5 zAZ^RLc*z40H}THER~XYb;vl)J+H%AtmUqdx@>iR}DWIUKry$#Nnw}_>i&f{V507gs z|0qXLjFLPD_XWnlKNHcb`O{v#jG6i~{!e~Qs#;Zfd=Yv;{=>!98<~9n*!7HJGD3y= zKDNm+FP+g>A)vvM38lFtzW>I6xD`W&MN!*)j>;>B#F6(ySAt+{>xM=~DSso!pT8`W zMwJUa26ku#_?m{2G%j$kZ|irDNFoK2ht1aZLK<&9ym6XgbZ8YQ^ooJ=ZWYd?ixSuF zOo4w9i8BF>BkX+JNfkz0xD5m`U9S;wx*-Y)Ttmo_;86S7sjO;T?lciaWS)|& z)&R0(IkZ(())DwG>>VbqTxPi8-_%I}%H=0CBCA#r+fs>b03d{?557D0p@VPX>cNO` zJ^2OtX;?Kr7^jyKyM2==5=EWX%kMYJC?0EzL?ME*X_od&I7#SqE*MEmQW8i*yd^_U10w-U9fS>>q_IDUJUWX>PF+|^F zbna((e|~UO*7>VX*ZasluAS=~cfanxJ#LODxjbsIl`_x|>x0$hQs|~as7Shz$6uzk ze8dVy7H-3tC5khWW}Ln?S;H^@+pFbRsOFXGrC|1$A^le?sRg&o;&XIrP3Uh!2&99f zb@LN7!mrW2MtWUi za*<$SnCIlQ|Q4YNLE8fXyXHkeQZJN*+`Fl3Q1eO`S0x8Qi~3){x*b*fr?{ zB}>!BpbA&NGk97sAEe^p6TbwkY65&UHTcfwALbWMWrsxV{yFD;wII#y3f@x`86J-g zCFdH!Fe5~V4YCS{E0kSvWBRT@6d&=3CsPRcZiUY#su$_fY)`-0Tr9*=Bq~jrv7~VY zPpoW?50iABQN0gM-ANI*Vs~?ZmS0@l~x|YfZTpo$+Sjy=toaXGdG;@*P5XVrThHXq1 zk>hrG@!Xqr?G3=C*S_}8ZI*kSjuIkzp--q7clTmO*v-m`bH2mlL-1{jqHCg`fEoR&3^}H0K(-iVUtiGu4%=&S?KF ze&kBznXV(qlIefFDd6aK5exSq{2Wc?ynOL3DAf>8qGD?U77&P31aj=xF$keMoov~Z zZp7N(gLHEE4UP$rvJ78M+skwNE_J}xsHz~392x$00-QpJ%B_b&ZtqSY69i}ih@w#m zbaL7=Dri04I(KX1nzK)f=}kNzqw(9LZR(ao1jA(dV0pRaqIa|2_bJ2tei8C<+&z3=XG?BA8dv9ur#>H zT(_bOq;x&h&|??zpl%U^vxI8qs>~TIH&Mxdd6LY7Kj$JJi%(Y55_vq(T#?7-U152$ zh9$UN$C?l2s5f5I5g=i{)l60mP0N+jQRNqtkF4}9^qe+ny&<%utvleEzOrjD?IjIV zOr$jR#Iufb5oeL98BI;$PpqfU3$g{pALRID5jOj8=`iy3e%%x!{boF^4T~DGk=PHK1(6zapUt=HFaA(t?r?K{1jb1Q z$Y$X{UZG__)Hrb-XeyqT;x+z=(@kT8e(Soe7$A1@*QN*WX$MglXzDs;dg`GN;g=0 z0=C5fF;4^^vGa>;8@^5m?lJZ6D*A45vwU-WY0!c@e>mTlaamxYKIzMc?c&i3bWt$p&9RUt z?OtIb^2A#Fl}=5IS~isej8RA=%S@me+|5x0heve2$~MX;oxN4$Cj2>xe1ug?=_Bn< zf=8}o`3Z(z$e~cr&KwQ=vkJ#wuep%_$|VEzMZr-7rJ^Qo= zRIb%N=21?{=2X|GzowJN|Sg$-0)z(&{$NaS*;!drdm3` z(F8g%UP}>-w=MmqiArgZihV7hE<0y$j{t|~gw=n1TD41^lc>FtcBO(O%p%PZ;ywU1 zwz`t;2bB{1-xL&{%%)S~q0%PofY7d^{m6`Q$@O4cET7|Ua#3&WD|sXrH-IaJ6}9OU zEE@PlEFP`B4iC#Gxmbj}cm>2DI-QQnn3}sPf0j@d_Ohmm(iIa^)ci$ks(N}z7>Nf1GEZP4* zH&dR{3x=`~(|bV5B85ZlsmH|a#K;!auFSZ!g3IK}66GKeNxTP)FIYTgLK-=$3r&3T z>jx&!Oq11S%jCJghL=GxprAeUOBeX$X0vY0&$^EXl+u;u`DBfO-nwgRa6ah^0jx4T zwGx|k&KFpT%lWd4n%awXI#Wn;D|mFaXJgA|MP8(p8Ow2{*lFi84Bhkpv&VOlO#ysf z>|b;U-k@XgQZ{g3bdU-x5BY;8`J#;M2oP$%B^k0S4{l`{I-Hj-LjG zgn)$}XBB#_YUBUrb)J3ZbwQB+F%F%{iK9hwRr`3u$8%C za>;RKy213D#x2$2abA=Ql+Anvw{K~t zZeQuU4 z6Mo{a9gY}J`Zl5oN-XWsje>Aox+@yQTM zm)vw4n(o4LT-PqLQkPy%P}_6AAs0(;n+FMIA(G8IN9p%_8oNY{?O)(QZpy5i1~ek{^J#vz6> z1}gz-T_|DtK}^pWygar+Oic;=K;YIIsd9|(w3TQ~&|&a(b=N~zn#Zd|iK9IcrtLg% zK)6(iYqiB^^#>|^0I7E+@0thoFQX1zIWS3k#*Ao0SA!NvJRTkJ4S>I<)>+X2P~&JI z{D8ufXNSwV5?AhYlfquEFV*RC5dd0I6R3~Z0_+3S>cK2&-w?# zHR(P&WE;z>?ty&3KcFDK?ppL&BgV~K-GQqw1NS3`ghPwTJ)vz28v3OnN7~_Em11x< zB`#b*8PKK+*ax5(kc+@={?3CKoWV{YLjFjnM2JK;_p#SS9~3@KOC{Hqv*^NSqL zR(;GFO5}0p>KTkhBQ2U(4d%-qN6c}u^t+Q(1T8)r{V7BgMOYQxDsZL4d?yg}7eukH z?8=b7AcB28+DenEWjdd8C217h5}a8Olt<647sNU}cF}-NK?}QNS4BzpdF6u{y>D4(k*)8(a99XVSCZ#5Hk(@XFUUW!g+$*_ z1s+7CW=oB}=_Cl0yLg9~S%D))Kt1D5tNCR29q1k^tOgT2#;u2{n<>HI7PCTaJuzyC z!cxx=BsN5-ZBxsx>mx08+1g!7A?H$xVTJ{HolbmRPO?2&Y!|3u_2U_Pjcog>T;+cK z;@t?wIx(HnQK`+R^%w>Z?g^JM`+lYw{z?FZDAoqC1R5eow1*wcZB_h?-3Y@4L=0WG zNqXJ-3*4mB`4#Z=HgA9{2y;ZXfpLS^0p?&NPUEKz?yuR-0;u%w6oXtQYr;s=*)e6AJ!np)X2o6p6||6b?zV4g zClvh9OF3CyA6e{HGQAtUnW6D>Bh4^A{6?De#GA$eI{4t5OX3^2#!scQ({j3!8r72Ere-K%>;6o{xiI~iILOqx zRnCYGQxph|TDo+JP&*`snYTWUR(H1kVAOseFTwxQ<_&XfA7Lw5Q;0wH?D1$E|IbR`Eo9xy3na}tWqTPcz7k%=PWxhPy|pYA#6SfG zQ)H6XU(|%ZDunU?U;P+jkDY8AD97WCs?}z`30N%(d2%3d>Kcs3D}dHi>HgG@-vVA8 z{to*e+VNa3wk5?{zg` zDd)6M?@}UKB z(ZBG;qrqnZg&Jblzz6;H!W082!t!tvWH5~x`iPTI6@{|(WA5a15;K9Vv+0TCydTI(};cAN29E+IrPaDFbA)U#MIJk*>!#XhJx|1Ruhr>w9pl%$JyM_wPr7}ML*;c1li_N z1`e({^R;ly2%JH)gbe&Bxtr^Ovyxm0xkZdZ=*3?Zw)Dafe}fC>1{jK62J#QURx;P| z9zX6YEjhCI6crppOoKNY4!k@^z5yL(EfV>oFV%Yr<)r1W`Uch;p^llbTp#YbPHwQ6 zM062Ejyo$@mdq*ZP2}uNp+4w+iR)+tpij3LL^P*f1|i;fX8#ix2+=G-4VV{ZTL!xv z>A-Civ9)YMm-or)*_?f{d@X#2L_%(*AEdg1VX`# zxvy-et7J6sq_dMIRNdhZHOtIb^I+f{#ftX<{T7{n(e83P`i?wm&x0?k97KGZ|8RKbl z3%Q_;_FHPq&5hD7>$5t_%j-V&ubs?(mAck*#@G~biQzgG{75QmpsQeWHUb}2!mzdX zsc!Xe!_YUYlt7*pLq6V)O_bQfF@#t9yLGtswAf2zmFfK>rSvmF=7N^-*{!u_2N~*? zmCLi_F4s5jiLP}H^*sNyv?TgRN02JaIN$VS-y73>?^b05<)xgp9-Tk)y08rcs{Sf5 zSZi#r?ktQWU{_=LhS5yH6Xxw!Jc+;2fB+k?gb}6(y_K%{pPX=nYdWEo%w#U6{h%Aq z!1NsI(w_o>e)}hADtRHTl+LUZYMu@`yyexs>8x^^&lR`2@B9MugVf@C4U*%wQ6xno zvL5kWH)pXF$b;$JAz>Jr7=-n6Z9uKI#)5xbk0+3Emoy5YQz!ZZn)xvL->tR}ldDYA zp%VRG1F>`QL>pS|*PY5{T_!HwiC4z1`v5R~I^Swv(=A?g{B; zvf3yMKN!1R6E*wVhsAb}kZy;JyB01PJOt-4F?|$8Xg6B49yD3qxcrO)C0Squ+Zyge zV36IrvY5UoqaP(dVf>o>SdwK5U9uO(E0P$Sbrbb*xJtM9Z>kx$v^vp*IqJXepjjON zR0x&jGKtFvO0?K?Cg~?BDlE^p zdTryml+KM&3mjZCpGGrY#JxRiNzV^VjWukTPx>GLquy(Vu_EO-MhTJFHLXE87vRw& zX(FWh$d_~LvHWPS5!C8_>;vL6-+md&4qtCER$<5A^IF&0dZy823`V2`1g#pmVI5ajb+Ic}Rj&bS) z4`+HsqZP?^GlB-351&`@iPj1&55L5$UP!(=fl|(}7C9^&*mY2>M(FnfXLvB|uj>9r<0~0N5Fr4eS7^ zvMQtT^+$SVH!ozUq(%oLw1=$cVk@N-2a0rl3-(sB>*~HVTo!aLS}~qvJAbhADA;q! z4~e#Iae&g zE@t%+bz&X6dFg8K2DwD8eHg#8#Ne_ulEpS94Ksr#mW&Rk?F#-0Gbc|o;DXn0suwAT z!*wn3Ug;pQh--71riyS4b;nA|$j)xo#6X0Uv|Wbbu>uF~hj0(3PZCwcucxBJBl;^0 z6L-5m)p^bQbkSVd6e7W|5%4aN->Xi{3y{lMfy) zD@6&+@SDDIn^o4W0mgrQWVz{j?B&pLYcht}WD`+95~d<4)}si@i{KG_1J&*D3aVD8 zFRWPW>pOwA|6U!X(26@jRsF;MQKm-kY=R&8?%mk#lKJ6wv!u-j@kjqY;L(zIx`7YY z5fo~fox<2U)pb0hYhmh*LpdbzxCF?*J)zQpBl)=Jew;d=bFG{fp-@nH` z47(sFwtavxJ*whUz!2H!1ZE2+9iHqtK3LWhgpl6WQpUmZ3vOXU#O0Nad^ff`;L$X- z+5XuOMh1`rtBJLiWHQtLzJ2v(j`j@959$J-h6yGPyF@$_s!mbp?j`RnBU_@ig=B+W zmYp|+lJX`rxg@Gk8ujV*OQp%q)2YpM40=kPRubrUcj0yiq7Vw{QUbkU$(1M9NHoib z71Ypuy$w7W01|J#TBrrA$LJkqD0iEokYe5iZvg~ES3o3zzP)$1^n8%NXp@AtNqaZ9 z%q^+Lv}09ob+%foAKB@Vu>QkZ0=o9cyXLdyw_xy*l4$U53EK*KEo)8OJv@Iy3wz)q z6`!Yv5x#ieXs?qJE?%?QgeL_%Wv<77GNnq94U~VB!>ad@N%wX_Z(()lhh%F4@y{vt zfrWo~>5rsEUVm0OG3=QH{J9#9iPx)JZD){*{o*jBui*&Q5up7cL*GC@D4d1fC zwh_#p4uCmK9QmzzKLMD{H)+O8*?V&OQ@?%v`z;}U*5Aart%|-+L7(S&M=wr@Z;nMs zXaf{C2?ZuFX+}nE2@$yJ7ffj*WMZa{lUbK#nshm;?_WS=8s4Y1m0)BnT zP%0S<4Y8RAwniM@-BDvfEqd2s^l07Q77KCG`3MybMDa|mO_CB?iaJF+UT*_ZeRN;wWBl(k+Nun8(yEF;77s| zszB5h4P?u+e2h?I&80FOupuoB4r;o`u%4wX`(M{^C1kdFyI*LU!1q4nlUZ4^X5AzW z7AI`DJB*2Mx+;d4fAkVlU+*9Zxa?`n`q^upOGW?vezuM$9*H15c3ag$F%IJgRu~KQ zFOz7)I%}`(Z>suiN(q+HcqkE*%9bu@+ZW4G@T;gsoB?f9)!{2Vu}&bE-10q0@vYuC zaqxu|F?m09M~D_(QsrSjT~58Ii~JGQHz=FKTE{7I)fq4^H=5>LH9dk_+Yi-uY(ryh zy|}?vYRv>va&TqB3>i2UFthdmX-V`S)qbJ}toW?>SEU}+4mI7XK?JTNbg$p2Aj;gF zCnsQmcI(Z+K}Gx|5G$U9S2u!y7nvx40nRLOzp#?Q(GXLUjIrI6ndi~(U=0X#_+;(= zcUWZ)kKETz8FE-(wvA;=LGXz*2YB$y{qHNX&==EF!FDrxBb;>H^qf5BhV~#F`Uaca z-7^$C-`HuzUiqXFK=!B$tdF_-J@EDPk~=%zH$|KavO!=9oyv|pTftr@Kb*o$Ysxwk zMPIU;TZRcKdW$axta4>q$`vgxkdG*H`AZwMzl*HVOnTizaP0 z2N+awtiqU?dg!nIaF2xFT*!c*2=y;n7E%MYeMuBKsFr@=GNnxhh@VpdH#rYYA%a#- zCKdF8E;MLjs#_pmb-)a2=f@N$I^0aguB2G^RH`XP348y_l{acvg3tJmm=zbQ2Izq< zTnyGRqA%G2W5kA_4|ty`03Eitk*~SepAS;gk1EQ%A~Bg0zEN6kI;&vbhbRkU9LbnK zkZ^933}YNMS^0>?>$F$ia^;93(0ZT)DP4lGM_oq^{owc`t7^&HQ!Nn(oP}zrHba7E zq(2l79*uK|B8vArz=1X@p6X)jm3Il7AzpblA6Ij7g!n!Tmb%`FxCu=Q<22*N-XmO6TDU%sRop4qf0AARfu z?&o-(8)|XrSr*CodZkCVRar2k0s=21v2f3E~-oS})fghYpoX#pP3mNzEG+No( z@Uwc5%n3-32J?rb8o~pkvqE9ju~=$lJr?qO2i6q(?hDb%-`XEvU8Gc zJssJnRcA@M>^y<<56E=Mg&iPsmo3}Y+;vc+=tN_(nG%Gh^rkI2*~OvfZ~y|;f-yG( z39LGg`e_D-0~MG^q4FZC--*&)T^&0uyvNRWz5xwjzjoO8Wk~soEDU1{YS1H^>A7-G zAM%NL5J7$-ZVN&?)@;psEM>L0o!8J*>^C>2@Is-w@R^RTOZc7+7`%aN$?sI-wwHGN zQ3+_B1$)+{7DpA!w1u$*j@M{%{fcyx5onL;NZwv9T*|iQ(2vC|fT8YD3G>?_feAnK z!Gi$IYcfxiW)vY5;RcCJOD4e2nlpv>!%@kUA1^do2zl^`z_jWYJi7{D0p1CM+W|r7 zpQ?a(xrq=>5d0tia)u#hdioes$?N4a%h*9=sI~gWA5l-i4UdVLAilgW(X!O{dn!`q z=rC>ldy=dTmzXNrPNa1ijhdf742M{BGmFrd@1(`pf*-y50kxJHI$v7z!#(`+fZ)ug zPnI^%#R<}sg#X;AUR%MN%TgS$vHeqkU2mg&Z@qEE93H7zGCg$;uO#(r8TH+UBeN;S zc4+Y8gPwExh_h3Ll}P5Xc$cjrgO+hcDCXKq+w-s!-E#Tq2MAn4HCsN1#ErgHIwJSErnIdw)A z`5{z+CZlw1WFmcxG2m2N z#zs!)XOeW~B}eidTZ*;f9xcYsLzJW`oXpsqK$j;+L&Y~2I1Uoj?If7Z4R=Rt_yi}K zM~`5gFo_zFJHvC_Neu0p7ZG9prDl!#aHz}x73;u9e8#Hbr@(ky_}@@nO~vPSOXEA2 z4V4@Q3rmYK8{AL-E#>P`1om#ycn+by>=~yLXpCzqyg{K7zEO~5U&~(WL{f8)0%kzF z09@@mI-Ors3Sq8D$S>%4a%EuhxvmIV4W<--=fK;C*QN_XNmmIS2)8y*FqmI?BKpu8 zE`R(UnJD@U`8VkSm#AZtjHH35k@&+W^iT#WmY7=;f$^L_3a45!7LqA-q*7ctI31t@ ze%^qHP?4F#vfD}SNn^%g7sQ1gNyXsjn*UIb=u{z7w)_j#P31wt$g-^t`k9VzGAW#_khYk&Km7G!9}ga1veR*H85l{EW>4M5%Ua6gIb z+;@5{RGu~T^+eI98aDW?Cntd$+HHwUtnriT6Ckrf&$U1XypH^A-Cd-JPA+`cb072< ze`Dbml>g(dVcQ}BL68@8Rdg_$vovuLa!`mD^&_tBM5Wm?2O!VprmWtjOwrNK@z*9K z#|md5=tWY0mTDIxN_}ti=!ps{TseGSUmPOo_5SLzX%xc$tK{(b zpf^5_ZdtT>d`v)dqVIN)uB;4KHOYc}=|cqQxVWf7s}(OuapHrY8_$ofBX8igbBMdllQwLR-S+vzp;pdSw5%e zE23yDCl>dFXEc}=iMu{4kyaK$wIMy$H;Lk5?7paA6()Iq(uK++r@;=VVG_H3^za;` zz6sh3Wj1*O*VC?5AR#mbCB99Ir`)ckamT0!z1vhDQx@$*qc{c^!@J(h4QC}}fhb=_ z9yIztl@HoKzUn8S!7Q8@3n{^inp2J4l=4b|=-4mO=_zfkMq&ow46NJuYq?~=u~+c8 zrlW3K4i;ZpHehWd0t93nuc^vC%pgzYTnvFFlF91TbZ@N!<)W&_G3{r%U@rkWKM2d1 zV!XF@EI*bo$UOGFDMvy}j}dlmc+Y; zOAPXM|ye&`Gwg+)X;@2)p5$N%X%L~IXPj^qFsTpHKqUb#?@rNoF$s07JP1D|dbZ{Dm!B~A_ zTPs}YK_s_ye$NeFWS_`ZF}=f{WRRyZuUQVov+m?Q{Cbn1<1rFV;~HF{e>V0oD9jx9 z?mZ&4Kx|Q6HrsM(L$`pD)~6C28D|i>!V<|o5b$b8nXdDKbXgx%P z5~ZgxKX1jM5I#k}oYLAM_Ykj~@dL(7dJspZ15xQwsTQ0P9#odxb#>vH@}+NGtyQU4 z4Dz1KOqPhnHVtC2UuqBjM1X%c9$|sqRG;xD2k=E zkG+1m9Y9pGLl1n&`uQc>>V5rSfMD^X2+;H{?Fas`Z$TmZ+KZcW2dh*PQV3946)aN5 znEm^Wg&Tu$Kg=MFVRa11p4`OyXAQ4ERgRuXBk^t0xB5s$-eix}9nT3|Ddtp?oxET5 zYak|&N~%@iVCcnV^XfP}h^PfAm9$a;T%HDNs*WX^nf)3t8Ae-VMbxJ=RWVY1n%&;| zCQzw4xBz)FE4mesQ|cU_RlLQ#-d% zqqcRYI4mguU)u*x^!-)k*_6yJci|Ey{YHGZluShi*w;iPkt>7klrwN>bfpA6 z&OJl~Q70YO$e}g&k|}o>kJWG1J>2gbK+3{Qd!8`|l;|O4Vk6B@8!Vt~fyKcd$kORE zy&o|-kg0k`t6~d?HXBx|V{^@tGz)MEr4sn1n*EMa47g_KI?V0_l(g(KtizK2cWes_ zcuR6W3NA~PP^YWG%%u{TM{+K4^n{fYcC1~zS&Y4R6WZI_Mmp<{YpUvg3(2NPh$otK z^m=0PPO7gEEY36*+Lz0exk|xKUl< z6t)K~4aO(}Qsptoi$eDBx(qcjBxszk>w5f7bLnHH><3Du(g!IsSM0t#)U2W@#E1K# zQ%n+&?Z`5gK*)ojAAoXNo*qs8j`e~|XP)$ASxU;mds7Q(iE-5>xg_*-Bg@(QRk&&; z>ZgN^2Mx<1GdH<4cG@aJ2k>WdVlGKC42V=?dZVfoc1&+TLr@|Roh2T4TdhE{LSfXG z#X&|~5?$xzAnbvNw`SvKLWBxMdY#u>wEZIlM8JeNl!`Sm{&_-D3?oP?3efL?tCX{g zQtXRES5ylOKlTr!=%^R|W)OiaAH7mxw(?-J5ze8$4TvGTE>V#iK5Lq1Id43J>-PD) z@c=}s)Q<}OAc2JO&GeJ3_$Bi(|8~SGt~FbIT{v0I5?O)ryWWL0K$%kq8`#u$F$%KN zTlJ|6yYs@a{L<)}I)yDkY~-+poAI%qQ2j>=i*cp_97#?GdPy5mST5l(1<=-bmP#%p zQYYvI1n0_)B`Z?Fn*J&lOeLrDNC^g~ihpP)Q0d$N6j218S$u4+^dAPt6rj}(* z0t`mhTHB|6XY%o;*RDxHON70LBk%z3n~qP&QBI+j{R z?i4WP;vK)ZUp;6Kbr1pQ6r3y^4fNWdo|q{!x}4>p3cm0W(!5K z?Hinqc=~2op?V@Y?uO?5}>b-v`eBgNqP96v6{ zImXkDv6E2ptw9eqpmf;bge7EjQQ@3*<2uXhe(QQM3Z40!Yhlsy9_C)JC-!0Gg7o&9 zvjZ{!3E*m~Xf%56vkq07v~K19xo6jFU<2TUc_Qf89;&s1ny1HAAG% z=~Ods zRE-`1-_g~h1OfiXL!fRz+5wqBFZwdl;wF{`f5(}1+z-j_X z-)tJ*ZI$RFb^{8VJ5T0NR_cH4m_VV6a`b>06SkD@R1aKRQOsqIOPzVQwab6$haKwojv^+XahTbm= zY-)w4yu=3bU4`RRlenZzfv}$Sdu$&2*6!0>NTJ&AiO?Ev6Nz09=r8CbIU9)qbN^h= zK@su@yT=qW+{*qBj$JwVaPp&ClFd`obzviNXx~UALy@zK&%cl00$Q)R6AF0yMnF=^ zbBjL4bJw`OEaAa-$F$G+Yz~AG%0EN6Qmxxz>44XLWK{e?ce|;)Od+_1-$=nQ9lcPM zqIw~)E$A;m&;j??#*2=+>IYz9^LN*rL=7L_kO1mZnKag>aPtddMj2ARImbiZr@EMQ z01l}Zv&rHyHM~fRn5;dai4j*a^N0=3^t2n8T}Qo_ zRZ?8R5*oby`zK|~H=BkmYB#~9wiQKGg?j^`!~#C=D;2(|D4Bg-00l|T z8H(3`GuSiBq;Kl>Ygh|$zioRBPj=rgfW6H~5`-Ns?CwYJ9K_-91FTjQOUl5p!+_l@ z-EhGBV`!PGbSmqYrPK9W^=<$b@&`W)R#L#KT&4U9_dR7)&9t}}EH%ZR3cdqZAzM#a z#xxJYbZ&8q=G7jUR&&J~8Rs}C=sH2Z*#l{R`A9K8w93q^4*1d|7gzXfv+96>YL4#Y>KS{*fSwQTWb?)SJ+E3eXFcx7qn~jOoq;q@DT4cSmA(O1jo5J47E_NJ9Y3X{XxBT z#K&2(BRnqV$u+o!j4MvN(pd_#HGnx@_Mxd(R=Rx&a#-jMk{yMg)_5lsQ#j~_9TK|m zagBDos}}>misVz|xDP(8AX~+i%`TpyJ-}7Vq3ZjCwX1O{r1iO*7y{ zP9!#>v*w5KZdp`LL$N;>lpV+tW*GI{t>U*I*+Vis)<`imX{R$)nDZc8~#?ccZfescgSE>pa zC+w(-&RDF|;2lGTqYnL#4Pexcj}MsXbup2dg5WK5<1SYU2Ak}`;S-6Wa$9Y$cgxK=ONK_ zY$Ji|n};24TIYOZ|37c9k&cN_z@{eDje0~(*PYkMz~+VE&tPiP+x@}fCWQkhJ~#_A zb;=R%!B3o_+sGbN6g_}koiwj7*tnz?6Q~e{-nc4KJ%XRywC6`ft$_+#D*{}b$%%TN zrSvTczrex;u8sMqfm|Bn`UAELFD;v||KURW-u|0Gbje9u33l7}PfXSaCDq$MkWbl7hs>9Q%{e!l7(e13u0DMl(w;Gt zX@__sv*R?{eyTP{+pO~QM$M*cY2boC)a?s10bMQ60r6D-aMQP?ejisW`Ic{(E#$>v zXwQ5T%45$K2>stwIP?~EIPc1=t^UF;CTX>Dsp7%F@~Lg`uSEG1#ZHj3h*2GwQPVqa zQh`j&ZtejRH}Rl=i6&u!dD~_TW2X?*L}v}nNomVxQ+I4LJTo6M@kf3<7-X1RV7@_DKpb;0c5|5PkkI< zY?_RFEIs9sXE$@YEsfQHS4Sbm%+C$uq6YB#D|ZyDYhlD{gUPUM7Y9=COZ(~T27YtY zK|D@M(;HkaVVM_ef8a77#c#@6W`*RgH!&n<(zPjI5Z13IQd*WSc6-Rk^Rd7&Nv@Wr zw(LnBNsE}MdTmYn)o;4PZg>^%2)M+mo*m679uVkA>1~R?&hL${J|c}I$J%Ph?6AiQ zJQ?E9he)aQuZorew((GGvhHuQDFfqLFX?M9xL5D&f-70fb=5P4CTdm243&%Qe`E^ec)JPu~e_mL7aZq~Zu?ng$eu3)b1l zRI%e>yGR>|PtP*V_}#}GGd*J}pn;+B!)J)P$}3nfQxZNKHpucO$Ic2ekfha4 zU5n4(tEtWM^lD7Nl~1gb25{E;o2JTmMp{=w0pYrm?dg6Eh5W-f(yB8T|GWLX?#^L} zrKXrhHCK?mc)ESP<a{Xe)5)p);srl7;wtM$B!ZOnG!tn0wq#%N9Pgj%tMqF(({s(x66m27s@*Rb6k8ALN8F z`HVaWCP)%m>#Q6f+5jltovj8qVlqX>WR-L2d>BzRAXpfDrzC#+Bb3x4`nQZEm*bxEV@9gq5fv3~)Iq>p8+JoO3Q)-;-erwbSv7 zIdaQ89S;x&vGO!v!E~L#72HnAim>Lmcli&Iqd5_x30A4@Ed(}SQm!*^Vf#iW6bY2J zu)b~XV}-JBQ-#x1tIA4-b4d-LIdL6iex%@ZEIQ3Y~|gYdYj z0<}t5QX8FSac-L})muC~Rw?>mu|RCV5L_MsPMIK>b&U-8o&+CYh9Ktumj{+xXIT)z zV~$2##MG_4v5HGmgzEbIu(6BHL-aDO!ujs1gK22sBZ}d7eMB$%bD9NiNq=tE8*`kY zFajl@e!#FOfJ=FNG1wH!e2d(@I2td^C}IzvnX4r`A@jBjQMyogHLLtBD%lma2QqJe zhXr;vq&P@3OdvhndS=#w5w-dzb0`SJaHZI=Ki{zL=mhyTrK4Z!ERO*VZ@v(dCa#bjzXyzb2bV$!rUh0LpEORuV}cK>z`qsRoGq U8+;q4W3j|%`vL#}000D8T0jD2!~g&Q diff --git a/kernel/kernel/files/patches/linux/patch-4.8.6.xz b/kernel/kernel/files/patches/linux/patch-4.8.6.xz new file mode 100644 index 0000000000000000000000000000000000000000..0438de2bc7116a225fc2bd96e74082abce822b06 GIT binary patch literal 120040 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 ENZ0YYp; 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 R|I4w&XZr#G00004Sz0VHUbz4O literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/mageia/dm-raid-fix-compat_features-validation.patch b/kernel/kernel/files/patches/mageia/dm-raid-fix-compat_features-validation.patch new file mode 100644 index 00000000..f2261039 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/dm-raid-fix-compat_features-validation.patch @@ -0,0 +1,39 @@ +From 5c33677c87cbe44ae04df69c4a29c1750a9ec4e5 Mon Sep 17 00:00:00 2001 +From: Andy Whitcroft +Date: Tue, 11 Oct 2016 15:16:57 +0100 +Subject: [PATCH] dm raid: fix compat_features validation + +In ecbfb9f118bce4 ("dm raid: add raid level takeover support") a new +compatible feature flag was added. Validation for these compat_features +was added but this only passes for new raid mappings with this feature +flag. This causes previously created raid mappings to be failed at +import. + +Check compat_features for the only valid combination. + +Fixes: ecbfb9f118bce4 ("dm raid: add raid level takeover support") +Cc: stable@vger.kernel.org # v4.8 +Signed-off-by: Andy Whitcroft +Signed-off-by: Heinz Mauelshagen +Signed-off-by: Mike Snitzer +--- + drivers/md/dm-raid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 8abde6b..2a39700 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -2258,7 +2258,8 @@ static int super_validate(struct raid_set *rs, struct md_rdev *rdev) + if (!mddev->events && super_init_validation(rs, rdev)) + return -EINVAL; + +- if (le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) { ++ if (le32_to_cpu(sb->compat_features) && ++ le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) { + rs->ti->error = "Unable to assemble array: Unknown flag(s) in compatible feature flags"; + return -EINVAL; + } +-- +2.10.1 + diff --git a/kernel/kernel/files/patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch b/kernel/kernel/files/patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch deleted file mode 100644 index d91513c1..00000000 --- a/kernel/kernel/files/patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c -index 425544b..0c2e252 100644 ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3362,13 +3362,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, - int num_active; - int id, i; - -+ /* Clear the partitioning for disabled planes. */ -+ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); -+ memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); -+ - if (WARN_ON(!state)) - return 0; - - if (!cstate->base.active) { - ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0; -- memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); -- memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); - return 0; - } - -@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state) - intel_state->wm_results.dirty_pipes = ~0; - } - -+ /* -+ * We're not recomputing for the pipes not included in the commit, so -+ * make sure we start with the current state. -+ */ -+ memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); -+ - for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { - struct intel_crtc_state *cstate; - diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-4.7-ver-fix.patch b/kernel/kernel/files/patches/mageia/fs-aufs-4.7-ver-fix.patch deleted file mode 100644 index 7ffd27e4..00000000 --- a/kernel/kernel/files/patches/mageia/fs-aufs-4.7-ver-fix.patch +++ /dev/null @@ -1,16 +0,0 @@ - -Mark as 4.7 so we can rebuild aufs tools with matching 4.7 check - -Signed-off-by: Thomas Backlund - ---- linux/include/uapi/linux/aufs_type.h.orig -+++ linux/include/uapi/linux/aufs_type.h -@@ -26,7 +26,7 @@ - - #include - --#define AUFS_VERSION "4.x-rcN" -+#define AUFS_VERSION "4.7" - - /* todo? move this to linux-2.6.19/include/magic.h */ - #define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-4.7-modular.patch b/kernel/kernel/files/patches/mageia/fs-aufs-4.8-modular.patch similarity index 71% rename from kernel/kernel/files/patches/mageia/fs-aufs-4.7-modular.patch rename to kernel/kernel/files/patches/mageia/fs-aufs-4.8-modular.patch index faedd6af..62a3b4f0 100644 --- a/kernel/kernel/files/patches/mageia/fs-aufs-4.7-modular.patch +++ b/kernel/kernel/files/patches/mageia/fs-aufs-4.8-modular.patch @@ -18,9 +18,9 @@ security/security.c | 10 ++++++++++ 17 files changed, 41 insertions(+), 1 deletion(-) -diff -Nurp linux-4.7-rc6-aufs/fs/aufs/Kconfig linux-4.7-rc6-aufs-mod/fs/aufs/Kconfig ---- linux-4.7-rc6-aufs/fs/aufs/Kconfig 2016-07-04 19:02:29.246286120 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/aufs/Kconfig 2016-07-04 19:03:53.653714965 +0300 +diff -Nurp linux-4.8-aufs/fs/aufs/Kconfig linux-4.8-aufs-mod/fs/aufs/Kconfig +--- linux-4.8-aufs/fs/aufs/Kconfig 2016-07-04 19:02:29.246286120 +0300 ++++ linux-4.8-aufs-mod/fs/aufs/Kconfig 2016-07-04 19:03:53.653714965 +0300 @@ -1,5 +1,5 @@ config AUFS_FS - bool "Aufs (Advanced multi layered unification filesystem) support" @@ -28,9 +28,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/aufs/Kconfig linux-4.7-rc6-aufs-mod/fs/aufs/Kco help Aufs is a stackable unification filesystem such as Unionfs, which unifies several directories and provides a merged single -diff -Nurp linux-4.7-rc6-aufs/fs/dcache.c linux-4.7-rc6-aufs-mod/fs/dcache.c ---- linux-4.7-rc6-aufs/fs/dcache.c 2016-07-04 19:02:29.260286196 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/dcache.c 2016-07-04 19:03:53.653714965 +0300 +diff -Nurp linux-4.8-aufs/fs/dcache.c linux-4.8-aufs-mod/fs/dcache.c +--- linux-4.8-aufs/fs/dcache.c 2016-07-04 19:02:29.260286196 +0300 ++++ linux-4.8-aufs-mod/fs/dcache.c 2016-07-04 19:03:53.653714965 +0300 @@ -1310,6 +1310,7 @@ rename_retry: seq = 1; goto again; @@ -39,9 +39,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/dcache.c linux-4.7-rc6-aufs-mod/fs/dcache.c /* * Search for at least 1 mount point in the dentry's subdirs. -diff -Nurp linux-4.7-rc6-aufs/fs/exec.c linux-4.7-rc6-aufs-mod/fs/exec.c ---- linux-4.7-rc6-aufs/fs/exec.c 2016-07-04 17:58:15.707773651 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/exec.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/exec.c linux-4.8-aufs-mod/fs/exec.c +--- linux-4.8-aufs/fs/exec.c 2016-07-04 17:58:15.707773651 +0300 ++++ linux-4.8-aufs-mod/fs/exec.c 2016-07-04 19:03:53.654714970 +0300 @@ -104,6 +104,7 @@ bool path_noexec(const struct path *path return (path->mnt->mnt_flags & MNT_NOEXEC) || (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); @@ -50,9 +50,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/exec.c linux-4.7-rc6-aufs-mod/fs/exec.c #ifdef CONFIG_USELIB /* -diff -Nurp linux-4.7-rc6-aufs/fs/fcntl.c linux-4.7-rc6-aufs-mod/fs/fcntl.c ---- linux-4.7-rc6-aufs/fs/fcntl.c 2016-07-04 19:02:29.260286196 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/fcntl.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/fcntl.c linux-4.8-aufs-mod/fs/fcntl.c +--- linux-4.8-aufs/fs/fcntl.c 2016-07-04 19:02:29.260286196 +0300 ++++ linux-4.8-aufs-mod/fs/fcntl.c 2016-07-04 19:03:53.654714970 +0300 @@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, un out: return error; @@ -61,9 +61,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/fcntl.c linux-4.7-rc6-aufs-mod/fs/fcntl.c static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, int force) -diff -Nurp linux-4.7-rc6-aufs/fs/file_table.c linux-4.7-rc6-aufs-mod/fs/file_table.c ---- linux-4.7-rc6-aufs/fs/file_table.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/file_table.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/file_table.c linux-4.8-aufs-mod/fs/file_table.c +--- linux-4.8-aufs/fs/file_table.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/fs/file_table.c 2016-07-04 19:03:53.654714970 +0300 @@ -147,6 +147,7 @@ over: } return ERR_PTR(-ENFILE); @@ -96,9 +96,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/file_table.c linux-4.7-rc6-aufs-mod/fs/file_tab void __init files_init(void) { -diff -Nurp linux-4.7-rc6-aufs/fs/inode.c linux-4.7-rc6-aufs-mod/fs/inode.c ---- linux-4.7-rc6-aufs/fs/inode.c 2016-07-04 19:02:29.261286202 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/inode.c 2016-07-04 20:51:39.805168596 +0300 +diff -Nurp linux-4.8-aufs/fs/inode.c linux-4.8-aufs-mod/fs/inode.c +--- linux-4.8-aufs/fs/inode.c 2016-07-04 19:02:29.261286202 +0300 ++++ linux-4.8-aufs-mod/fs/inode.c 2016-07-04 20:51:39.805168596 +0300 @@ -1600,6 +1600,7 @@ int update_time(struct inode *inode, str return update_time(inode, time, flags); @@ -107,9 +107,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/inode.c linux-4.7-rc6-aufs-mod/fs/inode.c /** * touch_atime - update the access time -diff -Nurp linux-4.7-rc6-aufs/fs/namespace.c linux-4.7-rc6-aufs-mod/fs/namespace.c ---- linux-4.7-rc6-aufs/fs/namespace.c 2016-07-04 17:58:15.729773645 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/namespace.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/namespace.c linux-4.8-aufs-mod/fs/namespace.c +--- linux-4.8-aufs/fs/namespace.c 2016-07-04 17:58:15.729773645 +0300 ++++ linux-4.8-aufs-mod/fs/namespace.c 2016-07-04 19:03:53.654714970 +0300 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *m mnt_dec_writers(real_mount(mnt)); preempt_enable(); @@ -126,9 +126,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/namespace.c linux-4.7-rc6-aufs-mod/fs/namespace static void cleanup_group_ids(struct mount *mnt, struct mount *end) { -diff -Nurp linux-4.7-rc6-aufs/fs/notify/group.c linux-4.7-rc6-aufs-mod/fs/notify/group.c ---- linux-4.7-rc6-aufs/fs/notify/group.c 2016-07-04 17:58:15.742773641 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/notify/group.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/notify/group.c linux-4.8-aufs-mod/fs/notify/group.c +--- linux-4.8-aufs/fs/notify/group.c 2016-07-04 17:58:15.742773641 +0300 ++++ linux-4.8-aufs-mod/fs/notify/group.c 2016-07-04 19:03:53.655714975 +0300 @@ -22,6 +22,7 @@ #include #include @@ -161,9 +161,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/notify/group.c linux-4.7-rc6-aufs-mod/fs/notify int fsnotify_fasync(int fd, struct file *file, int on) { -diff -Nurp linux-4.7-rc6-aufs/fs/notify/mark.c linux-4.7-rc6-aufs-mod/fs/notify/mark.c ---- linux-4.7-rc6-aufs/fs/notify/mark.c 2016-07-04 17:58:15.742773641 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/notify/mark.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/notify/mark.c linux-4.8-aufs-mod/fs/notify/mark.c +--- linux-4.8-aufs/fs/notify/mark.c 2016-07-04 17:58:15.742773641 +0300 ++++ linux-4.8-aufs-mod/fs/notify/mark.c 2016-07-04 19:03:53.655714975 +0300 @@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_m mark->free_mark(mark); } @@ -196,9 +196,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/notify/mark.c linux-4.7-rc6-aufs-mod/fs/notify/ /* * Nothing fancy, just initialize lists and locks and counters. -diff -Nurp linux-4.7-rc6-aufs/fs/open.c linux-4.7-rc6-aufs-mod/fs/open.c ---- linux-4.7-rc6-aufs/fs/open.c 2016-07-04 17:58:15.746773640 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/open.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/open.c linux-4.8-aufs-mod/fs/open.c +--- linux-4.8-aufs/fs/open.c 2016-07-04 17:58:15.746773640 +0300 ++++ linux-4.8-aufs-mod/fs/open.c 2016-07-04 19:03:53.655714975 +0300 @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l inode_unlock(dentry->d_inode); return ret; @@ -215,9 +215,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/open.c linux-4.7-rc6-aufs-mod/fs/open.c static int do_dentry_open(struct file *f, struct inode *inode, -diff -Nurp linux-4.7-rc6-aufs/fs/read_write.c linux-4.7-rc6-aufs-mod/fs/read_write.c ---- linux-4.7-rc6-aufs/fs/read_write.c 2016-07-04 19:02:29.262286207 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/read_write.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/read_write.c linux-4.8-aufs-mod/fs/read_write.c +--- linux-4.8-aufs/fs/read_write.c 2016-07-04 19:02:29.262286207 +0300 ++++ linux-4.8-aufs-mod/fs/read_write.c 2016-07-04 19:03:53.655714975 +0300 @@ -525,6 +525,7 @@ vfs_readf_t vfs_readf(struct file *file) return new_sync_read; return ERR_PTR(-ENOSYS); @@ -234,9 +234,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/read_write.c linux-4.7-rc6-aufs-mod/fs/read_wri ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { -diff -Nurp linux-4.7-rc6-aufs/fs/splice.c linux-4.7-rc6-aufs-mod/fs/splice.c ---- linux-4.7-rc6-aufs/fs/splice.c 2016-07-04 19:02:29.262286207 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/splice.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/fs/splice.c linux-4.8-aufs-mod/fs/splice.c +--- linux-4.8-aufs/fs/splice.c 2016-07-04 19:02:29.262286207 +0300 ++++ linux-4.8-aufs-mod/fs/splice.c 2016-07-04 19:03:53.656714979 +0300 @@ -1124,6 +1124,7 @@ long do_splice_from(struct pipe_inode_in return splice_write(pipe, out, ppos, len, flags); @@ -253,9 +253,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/splice.c linux-4.7-rc6-aufs-mod/fs/splice.c /** * splice_direct_to_actor - splices data directly between two non-pipes -diff -Nurp linux-4.7-rc6-aufs/fs/xattr.c linux-4.7-rc6-aufs-mod/fs/xattr.c ---- linux-4.7-rc6-aufs/fs/xattr.c 2016-07-04 17:58:15.754773638 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/xattr.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/fs/xattr.c linux-4.8-aufs-mod/fs/xattr.c +--- linux-4.8-aufs/fs/xattr.c 2016-07-04 17:58:15.754773638 +0300 ++++ linux-4.8-aufs-mod/fs/xattr.c 2016-07-04 19:03:53.656714979 +0300 @@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry *xattr_value = value; return error; @@ -264,17 +264,17 @@ diff -Nurp linux-4.7-rc6-aufs/fs/xattr.c linux-4.7-rc6-aufs-mod/fs/xattr.c ssize_t vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) -diff -Nurp linux-4.7-rc6-aufs/kernel/task_work.c linux-4.7-rc6-aufs-mod/kernel/task_work.c ---- linux-4.7-rc6-aufs/kernel/task_work.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/kernel/task_work.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/kernel/task_work.c linux-4.8-aufs-mod/kernel/task_work.c +--- linux-4.8-aufs/kernel/task_work.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/kernel/task_work.c 2016-07-04 19:03:53.656714979 +0300 @@ -118,3 +118,4 @@ void task_work_run(void) } while (work); } } +EXPORT_SYMBOL_GPL(task_work_run); -diff -Nurp linux-4.7-rc6-aufs/security/commoncap.c linux-4.7-rc6-aufs-mod/security/commoncap.c ---- linux-4.7-rc6-aufs/security/commoncap.c 2016-07-04 17:58:15.945773585 +0300 -+++ linux-4.7-rc6-aufs-mod/security/commoncap.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/security/commoncap.c linux-4.8-aufs-mod/security/commoncap.c +--- linux-4.8-aufs/security/commoncap.c 2016-07-04 17:58:15.945773585 +0300 ++++ linux-4.8-aufs-mod/security/commoncap.c 2016-07-04 19:03:53.656714979 +0300 @@ -1058,12 +1058,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; @@ -290,9 +290,9 @@ diff -Nurp linux-4.7-rc6-aufs/security/commoncap.c linux-4.7-rc6-aufs-mod/securi #ifdef CONFIG_SECURITY -diff -Nurp linux-4.7-rc6-aufs/security/device_cgroup.c linux-4.7-rc6-aufs-mod/security/device_cgroup.c ---- linux-4.7-rc6-aufs/security/device_cgroup.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/security/device_cgroup.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/security/device_cgroup.c linux-4.8-aufs-mod/security/device_cgroup.c +--- linux-4.8-aufs/security/device_cgroup.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/security/device_cgroup.c 2016-07-04 19:03:53.656714979 +0300 @@ -7,6 +7,7 @@ #include #include @@ -309,9 +309,9 @@ diff -Nurp linux-4.7-rc6-aufs/security/device_cgroup.c linux-4.7-rc6-aufs-mod/se int devcgroup_inode_mknod(int mode, dev_t dev) { -diff -Nurp linux-4.7-rc6-aufs/security/security.c linux-4.7-rc6-aufs-mod/security/security.c ---- linux-4.7-rc6-aufs/security/security.c 2016-07-04 17:58:15.948773584 +0300 -+++ linux-4.7-rc6-aufs-mod/security/security.c 2016-07-04 19:03:53.657714984 +0300 +diff -Nurp linux-4.8-aufs/security/security.c linux-4.8-aufs-mod/security/security.c +--- linux-4.8-aufs/security/security.c 2016-07-04 17:58:15.948773584 +0300 ++++ linux-4.8-aufs-mod/security/security.c 2016-07-04 19:03:53.657714984 +0300 @@ -434,6 +434,7 @@ int security_path_rmdir(const struct pat return 0; return call_int_hook(path_rmdir, 0, dir, dentry); diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-4.7.patch b/kernel/kernel/files/patches/mageia/fs-aufs-4.8.patch similarity index 96% rename from kernel/kernel/files/patches/mageia/fs-aufs-4.7.patch rename to kernel/kernel/files/patches/mageia/fs-aufs-4.8.patch index d2d09b83..1efb3528 100644 --- a/kernel/kernel/files/patches/mageia/fs-aufs-4.7.patch +++ b/kernel/kernel/files/patches/mageia/fs-aufs-4.8.patch @@ -1,4 +1,117 @@ + Documentation/ABI/testing/debugfs-aufs | 50 + Documentation/ABI/testing/sysfs-aufs | 31 + Documentation/filesystems/aufs/README | 392 +++ + Documentation/filesystems/aufs/design/01intro.txt | 157 + + Documentation/filesystems/aufs/design/02struct.txt | 245 ++ + Documentation/filesystems/aufs/design/03atomic_open.txt | 72 + Documentation/filesystems/aufs/design/03lookup.txt | 100 + Documentation/filesystems/aufs/design/04branch.txt | 61 + Documentation/filesystems/aufs/design/05wbr_policy.txt | 51 + Documentation/filesystems/aufs/design/06fhsm.txt | 105 + Documentation/filesystems/aufs/design/06mmap.txt | 59 + Documentation/filesystems/aufs/design/06xattr.txt | 81 + Documentation/filesystems/aufs/design/07export.txt | 45 + Documentation/filesystems/aufs/design/08shwh.txt | 39 + Documentation/filesystems/aufs/design/10dynop.txt | 34 + MAINTAINERS | 13 + drivers/block/loop.c | 18 + fs/Kconfig | 1 + fs/Makefile | 1 + fs/aufs/Kconfig | 185 + + fs/aufs/Makefile | 36 + fs/aufs/aufs.h | 46 + fs/aufs/branch.c | 1399 ++++++++++++ + fs/aufs/branch.h | 296 ++ + fs/aufs/cpup.c | 1378 +++++++++++ + fs/aufs/cpup.h | 81 + fs/aufs/dbgaufs.c | 425 +++ + fs/aufs/dbgaufs.h | 35 + fs/aufs/dcsub.c | 212 + + fs/aufs/dcsub.h | 123 + + fs/aufs/debug.c | 427 +++ + fs/aufs/debug.h | 212 + + fs/aufs/dentry.c | 1117 +++++++++ + fs/aufs/dentry.h | 242 ++ + fs/aufs/dinfo.c | 540 ++++ + fs/aufs/dir.c | 749 ++++++ + fs/aufs/dir.h | 124 + + fs/aufs/dynop.c | 358 +++ + fs/aufs/dynop.h | 61 + fs/aufs/export.c | 824 +++++++ + fs/aufs/f_op.c | 759 ++++++ + fs/aufs/fhsm.c | 412 +++ + fs/aufs/file.c | 844 +++++++ + fs/aufs/file.h | 281 ++ + fs/aufs/finfo.c | 138 + + fs/aufs/fstype.h | 387 +++ + fs/aufs/hfsnotify.c | 274 ++ + fs/aufs/hfsplus.c | 43 + fs/aufs/hnotify.c | 710 ++++++ + fs/aufs/i_op.c | 1438 ++++++++++++ + fs/aufs/i_op_add.c | 911 +++++++ + fs/aufs/i_op_del.c | 498 ++++ + fs/aufs/i_op_ren.c | 1002 ++++++++ + fs/aufs/iinfo.c | 272 ++ + fs/aufs/inode.c | 506 ++++ + fs/aufs/inode.h | 687 +++++ + fs/aufs/ioctl.c | 206 + + fs/aufs/loop.c | 134 + + fs/aufs/loop.h | 39 + fs/aufs/magic.mk | 30 + fs/aufs/module.c | 319 ++ + fs/aufs/module.h | 143 + + fs/aufs/mvdown.c | 691 +++++ + fs/aufs/opts.c | 1847 ++++++++++++++++ + fs/aufs/opts.h | 198 + + fs/aufs/plink.c | 501 ++++ + fs/aufs/poll.c | 39 + fs/aufs/posix_acl.c | 85 + fs/aufs/procfs.c | 156 + + fs/aufs/rdu.c | 368 +++ + fs/aufs/rwsem.h | 185 + + fs/aufs/sbinfo.c | 342 ++ + fs/aufs/spl.h | 100 + fs/aufs/super.c | 1025 ++++++++ + fs/aufs/super.h | 625 +++++ + fs/aufs/sysaufs.c | 91 + fs/aufs/sysaufs.h | 88 + fs/aufs/sysfs.c | 340 ++ + fs/aufs/sysrq.c | 144 + + fs/aufs/vdir.c | 887 +++++++ + fs/aufs/vfsub.c | 871 +++++++ + fs/aufs/vfsub.h | 303 ++ + fs/aufs/wbr_policy.c | 752 ++++++ + fs/aufs/whout.c | 1047 +++++++++ + fs/aufs/whout.h | 72 + fs/aufs/wkq.c | 200 + + fs/aufs/wkq.h | 80 + fs/aufs/xattr.c | 334 ++ + fs/aufs/xino.c | 1305 +++++++++++ + fs/dcache.c | 2 + fs/fcntl.c | 4 + fs/inode.c | 2 + fs/proc/base.c | 2 + fs/proc/nommu.c | 5 + fs/proc/task_mmu.c | 7 + fs/proc/task_nommu.c | 5 + fs/read_write.c | 22 + fs/splice.c | 10 + include/linux/file.h | 1 + include/linux/fs.h | 9 + include/linux/mm.h | 22 + include/linux/mm_types.h | 2 + include/linux/splice.h | 6 + include/uapi/linux/Kbuild | 1 + include/uapi/linux/aufs_type.h | 406 +++ + kernel/fork.c | 2 + mm/Makefile | 2 + mm/filemap.c | 2 + mm/memory.c | 2 + mm/mmap.c | 33 + mm/nommu.c | 10 + mm/prfile.c | 86 + 112 files changed, 33747 insertions(+), 30 deletions(-) Documentation/ABI/testing/debugfs-aufs | 50 + Documentation/ABI/testing/sysfs-aufs | 31 + Documentation/filesystems/aufs/README | 392 +++++ @@ -21,73 +134,73 @@ fs/aufs/Kconfig | 185 ++ fs/aufs/Makefile | 36 + fs/aufs/aufs.h | 46 + - fs/aufs/branch.c | 1393 +++++++++++++++ + fs/aufs/branch.c | 1399 +++++++++++++++ fs/aufs/branch.h | 296 ++++ - fs/aufs/cpup.c | 1370 +++++++++++++++ + fs/aufs/cpup.c | 1378 +++++++++++++++ fs/aufs/cpup.h | 81 + - fs/aufs/dbgaufs.c | 419 +++++ + fs/aufs/dbgaufs.c | 425 +++++ fs/aufs/dbgaufs.h | 35 + - fs/aufs/dcsub.c | 211 +++ + fs/aufs/dcsub.c | 212 +++ fs/aufs/dcsub.h | 123 ++ - fs/aufs/debug.c | 428 +++++ + fs/aufs/debug.c | 427 +++++ fs/aufs/debug.h | 212 +++ - fs/aufs/dentry.c | 1115 ++++++++++++ - fs/aufs/dentry.h | 239 +++ - fs/aufs/dinfo.c | 539 ++++++ - fs/aufs/dir.c | 743 ++++++++ - fs/aufs/dir.h | 118 ++ - fs/aufs/dynop.c | 356 ++++ + fs/aufs/dentry.c | 1117 ++++++++++++ + fs/aufs/dentry.h | 242 +++ + fs/aufs/dinfo.c | 540 ++++++ + fs/aufs/dir.c | 749 ++++++++ + fs/aufs/dir.h | 124 ++ + fs/aufs/dynop.c | 358 ++++ fs/aufs/dynop.h | 61 + fs/aufs/export.c | 824 +++++++++ - fs/aufs/f_op.c | 757 ++++++++ + fs/aufs/f_op.c | 759 ++++++++ fs/aufs/fhsm.c | 412 +++++ - fs/aufs/file.c | 830 +++++++++ - fs/aufs/file.h | 278 +++ - fs/aufs/finfo.c | 136 ++ + fs/aufs/file.c | 844 +++++++++ + fs/aufs/file.h | 281 +++ + fs/aufs/finfo.c | 138 ++ fs/aufs/fstype.h | 387 ++++ fs/aufs/hfsnotify.c | 274 +++ fs/aufs/hfsplus.c | 43 + - fs/aufs/hnotify.c | 697 ++++++++ - fs/aufs/i_op.c | 1401 +++++++++++++++ + fs/aufs/hnotify.c | 710 ++++++++ + fs/aufs/i_op.c | 1438 +++++++++++++++ fs/aufs/i_op_add.c | 911 ++++++++++ fs/aufs/i_op_del.c | 498 ++++++ fs/aufs/i_op_ren.c | 1002 +++++++++++ - fs/aufs/iinfo.c | 271 +++ - fs/aufs/inode.c | 504 ++++++ - fs/aufs/inode.h | 681 ++++++++ + fs/aufs/iinfo.c | 272 +++ + fs/aufs/inode.c | 506 ++++++ + fs/aufs/inode.h | 687 ++++++++ fs/aufs/ioctl.c | 206 +++ - fs/aufs/loop.c | 133 ++ + fs/aufs/loop.c | 134 ++ fs/aufs/loop.h | 39 + fs/aufs/magic.mk | 30 + - fs/aufs/module.c | 209 +++ - fs/aufs/module.h | 76 + + fs/aufs/module.c | 319 ++++ + fs/aufs/module.h | 143 ++ fs/aufs/mvdown.c | 691 ++++++++ - fs/aufs/opts.c | 1846 ++++++++++++++++++++ + fs/aufs/opts.c | 1847 ++++++++++++++++++++ fs/aufs/opts.h | 198 +++ - fs/aufs/plink.c | 489 ++++++ + fs/aufs/plink.c | 501 ++++++ fs/aufs/poll.c | 39 + fs/aufs/posix_acl.c | 85 + fs/aufs/procfs.c | 156 ++ fs/aufs/rdu.c | 368 ++++ fs/aufs/rwsem.h | 185 ++ - fs/aufs/sbinfo.c | 340 ++++ - fs/aufs/spl.h | 98 ++ - fs/aufs/super.c | 1026 +++++++++++ + fs/aufs/sbinfo.c | 342 ++++ + fs/aufs/spl.h | 100 ++ + fs/aufs/super.c | 1025 +++++++++++ fs/aufs/super.h | 625 +++++++ fs/aufs/sysaufs.c | 91 + fs/aufs/sysaufs.h | 88 + fs/aufs/sysfs.c | 340 ++++ fs/aufs/sysrq.c | 144 ++ - fs/aufs/vdir.c | 876 ++++++++++ + fs/aufs/vdir.c | 887 ++++++++++ fs/aufs/vfsub.c | 871 +++++++++ - fs/aufs/vfsub.h | 297 ++++ + fs/aufs/vfsub.h | 303 ++++ fs/aufs/wbr_policy.c | 752 ++++++++ fs/aufs/whout.c | 1047 +++++++++++ fs/aufs/whout.h | 72 + - fs/aufs/wkq.c | 205 +++ - fs/aufs/wkq.h | 82 + - fs/aufs/xattr.c | 332 ++++ - fs/aufs/xino.c | 1304 ++++++++++++++ + fs/aufs/wkq.c | 200 +++ + fs/aufs/wkq.h | 80 + + fs/aufs/xattr.c | 334 ++++ + fs/aufs/xino.c | 1305 ++++++++++++++ fs/dcache.c | 2 +- fs/fcntl.c | 4 +- fs/inode.c | 2 +- @@ -111,7 +224,7 @@ mm/mmap.c | 33 +- mm/nommu.c | 10 +- mm/prfile.c | 86 + - 112 files changed, 33420 insertions(+), 30 deletions(-) + 112 files changed, 33747 insertions(+), 30 deletions(-) diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs new file mode 100644 @@ -1726,10 +1839,10 @@ index 0000000..49afc58 +Currently this approach is applied to address_space_operations for +regular files only. diff --git a/MAINTAINERS b/MAINTAINERS -index 952fd2a..6a8f0f8 100644 +index f593300..8a17054 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2210,6 +2210,19 @@ F: include/linux/audit.h +@@ -2256,6 +2256,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -1750,10 +1863,10 @@ index 952fd2a..6a8f0f8 100644 M: Miguel Ojeda Sandonis W: http://miguelojeda.es/auxdisplay.htm diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 1fa8cc2..7339e65 100644 +index c9f2107..005e292 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -712,6 +712,24 @@ static inline int is_loop_device(struct file *file) +@@ -701,6 +701,24 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } @@ -1779,10 +1892,10 @@ index 1fa8cc2..7339e65 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/Kconfig b/fs/Kconfig -index b8fcb41..78adefb 100644 +index 2bc7ad7..3049386 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -236,6 +236,7 @@ source "fs/pstore/Kconfig" +@@ -245,6 +245,7 @@ source "fs/pstore/Kconfig" source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" @@ -1791,10 +1904,10 @@ index b8fcb41..78adefb 100644 endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile -index 85b6e13..e7bb164 100644 +index ed2b632..aa6d14b 100644 --- a/fs/Makefile +++ b/fs/Makefile -@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules +@@ -129,3 +129,4 @@ obj-y += exofs/ # Multiple modules obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ @@ -2086,10 +2199,10 @@ index 0000000..49f43b4 +#endif /* __AUFS_H__ */ diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c new file mode 100644 -index 0000000..baf786e +index 0000000..3bfbe5b --- /dev/null +++ b/fs/aufs/branch.c -@@ -0,0 +1,1393 @@ +@@ -0,0 +1,1399 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -2130,7 +2243,7 @@ index 0000000..baf786e + + if (br->br_fhsm) { + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_delayed_kfree(br->br_fhsm); + } + + key = br->br_dykey; @@ -2144,8 +2257,9 @@ index 0000000..baf786e + lockdep_off(); + path_put(&br->br_path); + lockdep_on(); -+ kfree(wbr); -+ kfree(br); ++ if (wbr) ++ au_delayed_kfree(wbr); ++ au_delayed_kfree(br); +} + +/* @@ -2232,22 +2346,23 @@ index 0000000..baf786e + goto out_wbr; + } + -+ err = au_sbr_realloc(au_sbi(sb), new_nbranch); ++ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0); + if (!err) -+ err = au_di_realloc(au_di(root), new_nbranch); ++ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0); + if (!err) { + inode = d_inode(root); -+ err = au_hinode_realloc(au_ii(inode), new_nbranch); ++ err = au_hinode_realloc(au_ii(inode), new_nbranch, /*may_shrink*/0); + } + if (!err) + return add_branch; /* success */ + +out_wbr: -+ kfree(add_branch->br_wbr); ++ if (add_branch->br_wbr) ++ au_delayed_kfree(add_branch->br_wbr); +out_hnotify: + au_hnotify_fin_br(add_branch); +out_br: -+ kfree(add_branch); ++ au_delayed_kfree(add_branch); +out: + return ERR_PTR(err); +} @@ -2413,7 +2528,7 @@ index 0000000..baf786e + br->br_perm = old_perm; + + if (!err && wbr && !au_br_writable(new_perm)) { -+ kfree(wbr); ++ au_delayed_kfree(wbr); + br->br_wbr = NULL; + } + @@ -2980,7 +3095,8 @@ index 0000000..baf786e + sbinfo->si_branch[0 + bbot] = NULL; + sbinfo->si_bbot--; + -+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + sbinfo->si_branch = p; + /* harmless error */ @@ -2999,7 +3115,8 @@ index 0000000..baf786e + /* au_h_dentry_init(au_hdentry(dinfo, bbot); */ + dinfo->di_bbot--; + -+ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + dinfo->di_hdentry = p; + /* harmless error */ @@ -3018,7 +3135,8 @@ index 0000000..baf786e + /* au_hinode_init(au_hinode(iinfo, bbot)); */ + iinfo->ii_bbot--; + -+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + iinfo->ii_hinode = p; + /* harmless error */ @@ -3436,7 +3554,7 @@ index 0000000..baf786e + if (br->br_wbr) { + err = au_wbr_init(br, sb, mod->perm); + if (unlikely(err)) { -+ kfree(br->br_wbr); ++ au_delayed_kfree(br->br_wbr); + br->br_wbr = NULL; + } + } @@ -3448,7 +3566,7 @@ index 0000000..baf786e + if (!au_br_fhsm(mod->perm)) { + /* fhsm --> non-fhsm */ + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_delayed_kfree(br->br_fhsm); + br->br_fhsm = NULL; + } + } else if (au_br_fhsm(mod->perm)) @@ -3460,7 +3578,8 @@ index 0000000..baf786e + goto out; /* success */ + +out_bf: -+ kfree(bf); ++ if (bf) ++ au_delayed_kfree(bf); +out: + AuTraceErr(err); + return err; @@ -3787,10 +3906,10 @@ index 0000000..32a4d8f +#endif /* __AUFS_BRANCH_H__ */ diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c new file mode 100644 -index 0000000..52f87de +index 0000000..598a4d6 --- /dev/null +++ b/fs/aufs/cpup.c -@@ -0,0 +1,1370 @@ +@@ -0,0 +1,1378 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -4137,9 +4256,9 @@ index 0000000..52f87de + dst->f_pos = 0; + err = au_do_copy_file(dst, src, len, buf, blksize); + if (do_kfree) -+ kfree(buf); ++ au_delayed_kfree(buf); + else -+ free_page((unsigned long)buf); ++ au_delayed_free_page((unsigned long)buf); + +out: + return err; @@ -4174,6 +4293,7 @@ index 0000000..52f87de + } + }; + struct super_block *sb; ++ struct inode *h_src_inode; + struct task_struct *tsk = current; + + /* bsrc branch can be ro/rw. */ @@ -4189,7 +4309,9 @@ index 0000000..52f87de + } + + /* try stopping to update while we copyup */ -+ IMustLock(d_inode(file[SRC].dentry)); ++ h_src_inode = d_inode(file[SRC].dentry); ++ if (!au_test_nfs(h_src_inode->i_sb)) ++ IMustLock(h_src_inode); + err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); + + /* i wonder if we had O_NO_DELAY_FPUT flag */ @@ -4249,8 +4371,13 @@ index 0000000..52f87de + goto out; + } + h_src_attr->valid = 1; -+ err = au_cp_regular(cpg); -+ inode_unlock(h_src_inode); ++ if (!au_test_nfs(h_src_inode->i_sb)) { ++ err = au_cp_regular(cpg); ++ inode_unlock(h_src_inode); ++ } else { ++ inode_unlock(h_src_inode); ++ err = au_cp_regular(cpg); ++ } + rerr = au_pin_hdir_relock(cpg->pin); + if (!err && rerr) + err = rerr; @@ -4299,7 +4426,7 @@ index 0000000..52f87de + sym.k[symlen] = 0; + err = vfsub_symlink(h_dir, h_path, sym.k); + } -+ free_page((unsigned long)sym.k); ++ au_delayed_free_page((unsigned long)sym.k); + +out: + return err; @@ -4670,7 +4797,7 @@ index 0000000..52f87de + } +out_parent: + dput(dst_parent); -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -5250,10 +5377,10 @@ index 0000000..ccba2c4 +#endif /* __AUFS_CPUP_H__ */ diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c new file mode 100644 -index 0000000..21ac773 +index 0000000..4db01e8 --- /dev/null +++ b/fs/aufs/dbgaufs.c -@@ -0,0 +1,419 @@ +@@ -0,0 +1,425 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -5284,7 +5411,7 @@ index 0000000..21ac773 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused, + struct file *file) +{ -+ kfree(file->private_data); ++ au_delayed_kfree(file->private_data); + return 0; +} + @@ -5346,7 +5473,7 @@ index 0000000..21ac773 +static int dbgaufs_plink_release(struct inode *inode __maybe_unused, + struct file *file) +{ -+ free_page((unsigned long)file->private_data); ++ au_delayed_free_page((unsigned long)file->private_data); + return 0; +} + @@ -5410,7 +5537,7 @@ index 0000000..21ac773 + goto out; /* success */ + +out_free: -+ free_page((unsigned long)p); ++ au_delayed_free_page((unsigned long)p); +out: + return err; +} @@ -5512,7 +5639,10 @@ index 0000000..21ac773 + for (; bindex <= bbot; bindex++) { + br = au_sbr(sb, bindex); + xi = &br->br_xino; ++ /* debugfs acquires the parent i_mutex */ ++ lockdep_off(); + debugfs_remove(xi->xi_dbgaufs); ++ lockdep_on(); + xi->xi_dbgaufs = NULL; + } +} @@ -5537,8 +5667,11 @@ index 0000000..21ac773 + br = au_sbr(sb, bindex); + xi = &br->br_xino; + AuDebugOn(xi->xi_dbgaufs); ++ /* debugfs acquires the parent i_mutex */ ++ lockdep_off(); + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, + sbinfo, &dbgaufs_xino_fop); ++ lockdep_on(); + /* ignore an error */ + if (unlikely(!xi->xi_dbgaufs)) + AuWarn1("failed %s under debugfs\n", name); @@ -5716,10 +5849,10 @@ index 0000000..81f272e +#endif /* __DBGAUFS_H__ */ diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c new file mode 100644 -index 0000000..e72acce +index 0000000..5d46398 --- /dev/null +++ b/fs/aufs/dcsub.c -@@ -0,0 +1,211 @@ +@@ -0,0 +1,212 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -5738,7 +5871,7 @@ index 0000000..e72acce + p = dpage->dentries; + for (i = 0; i < dpage->ndentry; i++) + dput(*p++); -+ free_page((unsigned long)dpage->dentries); ++ au_delayed_free_page((unsigned long)dpage->dentries); +} + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) @@ -5761,7 +5894,7 @@ index 0000000..e72acce + return 0; /* success */ + +out_dpages: -+ kfree(dpages->dpages); ++ au_delayed_kfree(dpages->dpages); +out: + return err; +} @@ -5774,7 +5907,7 @@ index 0000000..e72acce + p = dpages->dpages; + for (i = 0; i < dpages->ndpage; i++) + au_dpage_free(p++); -+ kfree(dpages->dpages); ++ au_delayed_kfree(dpages->dpages); +} + +static int au_dpages_append(struct au_dcsub_pages *dpages, @@ -5791,7 +5924,8 @@ index 0000000..e72acce + err = -ENOMEM; + sz = dpages->ndpage * sizeof(*dpages->dpages); + p = au_kzrealloc(dpages->dpages, sz, -+ sz + sizeof(*dpages->dpages), gfp); ++ sz + sizeof(*dpages->dpages), gfp, ++ /*may_shrink*/0); + if (unlikely(!p)) + goto out; + @@ -6062,10 +6196,10 @@ index 0000000..5d2cf66 +#endif /* __AUFS_DCSUB_H__ */ diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c new file mode 100644 -index 0000000..44bdb5f +index 0000000..443fee3 --- /dev/null +++ b/fs/aufs/debug.c -@@ -0,0 +1,428 @@ +@@ -0,0 +1,427 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -6391,7 +6525,7 @@ index 0000000..44bdb5f + au_br_count_init(&a->fake); + err = do_pri_br(-1, &a->fake); + au_br_count_fin(&a->fake); -+ kfree(a); ++ au_delayed_kfree(a); + dpri("dev 0x%x\n", sb->s_dev); + if (err || !au_test_aufs(sb)) + return; @@ -6399,9 +6533,8 @@ index 0000000..44bdb5f + sbinfo = au_sbi(sb); + if (!sbinfo) + return; -+ dpri("nw %lld, gen %u, kobj %d\n", -+ percpu_counter_sum(&sbinfo->si_nowait.nw_len), -+ sbinfo->si_generation, ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, + atomic_read(&sbinfo->si_kobj.kref.refcount)); + for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++) + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); @@ -6714,10 +6847,10 @@ index 0000000..0567f31 +#endif /* __AUFS_DEBUG_H__ */ diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c new file mode 100644 -index 0000000..4bb1530 +index 0000000..5eb4f36 --- /dev/null +++ b/fs/aufs/dentry.c -@@ -0,0 +1,1115 @@ +@@ -0,0 +1,1117 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -6756,7 +6889,7 @@ index 0000000..4bb1530 + br = au_sbr(dentry->d_sb, bindex); + wh_able = !!au_br_whable(br->br_perm); + if (wh_able) -+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0); ++ wh_found = au_wh_test(h_parent, wh_name, ignore_perm); + h_dentry = ERR_PTR(wh_found); + if (!wh_found) + goto real_lookup; @@ -6921,7 +7054,7 @@ index 0000000..4bb1530 + +out_parent: + dput(parent); -+ kfree(whname.name); ++ au_delayed_kfree(whname.name); +out: + return err; +} @@ -7421,7 +7554,7 @@ index 0000000..4bb1530 + +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) +{ -+ int err, ebrange; ++ int err, ebrange, nbr; + unsigned int sigen; + struct au_dinfo *dinfo, *tmp; + struct super_block *sb; @@ -7437,8 +7570,9 @@ index 0000000..4bb1530 + if (unlikely(err)) + goto out; + ++ nbr = au_sbbot(sb) + 1; + dinfo = au_di(dentry); -+ err = au_di_realloc(dinfo, au_sbbot(sb) + 1); ++ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + ebrange = au_dbrange_test(dentry); @@ -7481,6 +7615,7 @@ index 0000000..4bb1530 + au_dbg_verify_dinode(dentry); + AuTraceErr(err); + } ++ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */ + au_rw_write_unlock(&tmp->di_rwsem); + au_di_free(tmp); + if (unlikely(err)) @@ -7835,10 +7970,10 @@ index 0000000..4bb1530 +}; diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h new file mode 100644 -index 0000000..bdc1af6 +index 0000000..01211d2 --- /dev/null +++ b/fs/aufs/dentry.h -@@ -0,0 +1,239 @@ +@@ -0,0 +1,242 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -7866,7 +8001,10 @@ index 0000000..bdc1af6 + struct au_rwsem di_rwsem; + aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; + unsigned char di_tmpfile; /* to allow the different name */ -+ struct au_hdentry *di_hdentry; ++ union { ++ struct au_hdentry *di_hdentry; ++ struct llist_node di_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -7904,7 +8042,7 @@ index 0000000..bdc1af6 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); +int au_di_init(struct dentry *dentry); +void au_di_fin(struct dentry *dentry); -+int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink); + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc); +void di_read_unlock(struct dentry *d, int flags); @@ -8080,10 +8218,10 @@ index 0000000..bdc1af6 +#endif /* __AUFS_DENTRY_H__ */ diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c new file mode 100644 -index 0000000..43b5509 +index 0000000..2626c0c --- /dev/null +++ b/fs/aufs/dinfo.c -@@ -0,0 +1,539 @@ +@@ -0,0 +1,540 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -8126,7 +8264,7 @@ index 0000000..43b5509 + goto out; + } + -+ au_cache_free_dinfo(dinfo); ++ au_cache_dfree_dinfo(dinfo); + dinfo = NULL; + +out: @@ -8146,8 +8284,8 @@ index 0000000..43b5509 + while (bindex++ <= bbot) + au_hdput(p++); + } -+ kfree(dinfo->di_hdentry); -+ au_cache_free_dinfo(dinfo); ++ au_delayed_kfree(dinfo->di_hdentry); ++ au_cache_dfree_dinfo(dinfo); +} + +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) @@ -8215,7 +8353,7 @@ index 0000000..43b5509 + au_di_free(dinfo); +} + -+int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink) +{ + int err, sz; + struct au_hdentry *hdp; @@ -8226,7 +8364,8 @@ index 0000000..43b5509 + sz = sizeof(*hdp) * (dinfo->di_bbot + 1); + if (!sz) + sz = sizeof(*hdp); -+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS, ++ may_shrink); + if (hdp) { + dinfo->di_hdentry = hdp; + err = 0; @@ -8625,10 +8764,10 @@ index 0000000..43b5509 +} diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c new file mode 100644 -index 0000000..27bef0b +index 0000000..395563e --- /dev/null +++ b/fs/aufs/dir.c -@@ -0,0 +1,743 @@ +@@ -0,0 +1,749 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -8774,7 +8913,7 @@ index 0000000..27bef0b +out: + dput(a->dentry); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(arg); ++ au_delayed_kfree(arg); +} + +void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) @@ -8810,7 +8949,7 @@ index 0000000..27bef0b + if (unlikely(wkq_err)) { + pr_err("wkq %d\n", wkq_err); + dput(dentry); -+ kfree(arg); ++ au_delayed_kfree(arg); + } + +out: @@ -8929,7 +9068,7 @@ index 0000000..27bef0b + }; + err = au_do_open(file, &args); + if (unlikely(err)) -+ kfree(fidir); ++ au_delayed_kfree(fidir); + } + si_read_unlock(sb); + return err; @@ -8941,8 +9080,11 @@ index 0000000..27bef0b + struct au_vdir *vdir_cache; + struct au_finfo *finfo; + struct au_fidir *fidir; ++ struct au_hfile *hf; + aufs_bindex_t bindex, bbot; ++ int execed, delayed; + ++ delayed = (current->flags & PF_KTHREAD) || in_interrupt(); + finfo = au_fi(file); + fidir = finfo->fi_hdir; + if (fidir) { @@ -8950,22 +9092,25 @@ index 0000000..27bef0b + &au_sbi(file->f_path.dentry->d_sb)->si_files); + vdir_cache = fidir->fd_vdir_cache; /* lock-free */ + if (vdir_cache) -+ au_vdir_free(vdir_cache); ++ au_vdir_free(vdir_cache, delayed); + + bindex = finfo->fi_btop; + if (bindex >= 0) { ++ execed = vfsub_file_execed(file); ++ hf = fidir->fd_hfile + bindex; + /* + * calls fput() instead of filp_close(), + * since no dnotify or lock for the lower file. + */ + bbot = fidir->fd_bbot; -+ for (; bindex <= bbot; bindex++) -+ au_set_h_fptr(file, bindex, NULL); ++ for (; bindex <= bbot; bindex++, hf++) ++ if (hf->hf_file) ++ au_hfput(hf, execed); + } -+ kfree(fidir); ++ au_delayed_kfree(fidir); + finfo->fi_hdir = NULL; + } -+ au_finfo_fin(file); ++ au_finfo_fin(file, delayed); + return 0; +} + @@ -9374,10 +9519,10 @@ index 0000000..27bef0b +}; diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h new file mode 100644 -index 0000000..b0a79d7 +index 0000000..4f3945a --- /dev/null +++ b/fs/aufs/dir.h -@@ -0,0 +1,118 @@ +@@ -0,0 +1,124 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -9409,7 +9554,10 @@ index 0000000..b0a79d7 + +struct au_vdir_dehstr { + struct hlist_node hash; -+ struct au_vdir_destr *str; ++ union { ++ struct au_vdir_destr *str; ++ struct llist_node lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +struct au_vdir_de { @@ -9447,7 +9595,10 @@ index 0000000..b0a79d7 + + unsigned long vd_version; + unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; ++ union { ++ unsigned long vd_jiffy; ++ struct llist_node vd_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -9471,7 +9622,7 @@ index 0000000..b0a79d7 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, + unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh); -+void au_vdir_free(struct au_vdir *vdir); ++void au_vdir_free(struct au_vdir *vdir, int atonce); +int au_vdir_init(struct file *file); +int au_vdir_fill_de(struct file *file, struct dir_context *ctx); + @@ -9498,10 +9649,10 @@ index 0000000..b0a79d7 +#endif /* __AUFS_DIR_H__ */ diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c new file mode 100644 -index 0000000..dfb3a71 +index 0000000..eb0e1a7 --- /dev/null +++ b/fs/aufs/dynop.c -@@ -0,0 +1,356 @@ +@@ -0,0 +1,358 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima + */ @@ -9518,17 +9669,17 @@ index 0000000..dfb3a71 + * How large will these lists be? + * Usually just a few elements, 20-30 at most for each, I guess. + */ -+static struct au_splhead dynop[AuDyLast]; ++static struct au_sphlhead dynop[AuDyLast]; + -+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op) ++static struct au_dykey *dy_gfind_get(struct au_sphlhead *sphl, const void *h_op) +{ + struct au_dykey *key, *tmp; -+ struct list_head *head; ++ struct hlist_head *head; + + key = NULL; -+ head = &spl->head; ++ head = &sphl->head; + rcu_read_lock(); -+ list_for_each_entry_rcu(tmp, head, dk_list) ++ hlist_for_each_entry_rcu(tmp, head, dk_hnode) + if (tmp->dk_op.dy_hop == h_op) { + key = tmp; + kref_get(&key->dk_kref); @@ -9575,24 +9726,24 @@ index 0000000..dfb3a71 +} + +/* kref_get() if @key is already added */ -+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key) ++static struct au_dykey *dy_gadd(struct au_sphlhead *sphl, struct au_dykey *key) +{ + struct au_dykey *tmp, *found; -+ struct list_head *head; ++ struct hlist_head *head; + const void *h_op = key->dk_op.dy_hop; + + found = NULL; -+ head = &spl->head; -+ spin_lock(&spl->spin); -+ list_for_each_entry(tmp, head, dk_list) ++ head = &sphl->head; ++ spin_lock(&sphl->spin); ++ hlist_for_each_entry(tmp, head, dk_hnode) + if (tmp->dk_op.dy_hop == h_op) { + kref_get(&tmp->dk_kref); + found = tmp; + break; + } + if (!found) -+ list_add_rcu(&key->dk_list, head); -+ spin_unlock(&spl->spin); ++ hlist_add_head_rcu(&key->dk_hnode, head); ++ spin_unlock(&sphl->spin); + + if (!found) + DyPrSym(key); @@ -9605,17 +9756,17 @@ index 0000000..dfb3a71 + + key = container_of(rcu, struct au_dykey, dk_rcu); + DyPrSym(key); -+ kfree(key); ++ kfree(key); /* not delayed */ +} + +static void dy_free(struct kref *kref) +{ + struct au_dykey *key; -+ struct au_splhead *spl; ++ struct au_sphlhead *sphl; + + key = container_of(kref, struct au_dykey, dk_kref); -+ spl = dynop + key->dk_op.dy_type; -+ au_spl_del_rcu(&key->dk_list, spl); ++ sphl = dynop + key->dk_op.dy_type; ++ au_sphl_del_rcu(&key->dk_hnode, sphl); + call_rcu(&key->dk_rcu, dy_free_rcu); +} + @@ -9680,6 +9831,8 @@ index 0000000..dfb3a71 + /* this one will be changed according to an aufs mount option */ + DySetAop(direct_IO); + DySetAop(migratepage); ++ DySetAop(isolate_page); ++ DySetAop(putback_page); + DySetAop(launder_page); + DySetAop(is_partially_uptodate); + DySetAop(is_dirty_writeback); @@ -9700,7 +9853,7 @@ index 0000000..dfb3a71 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) +{ + struct au_dykey *key, *old; -+ struct au_splhead *spl; ++ struct au_sphlhead *sphl; + struct op { + unsigned int sz; + void (*set)(struct au_dykey *key, const void *h_op, @@ -9714,8 +9867,8 @@ index 0000000..dfb3a71 + }; + const struct op *p; + -+ spl = dynop + op->dy_type; -+ key = dy_gfind_get(spl, op->dy_hop); ++ sphl = dynop + op->dy_type; ++ key = dy_gfind_get(sphl, op->dy_hop); + if (key) + goto out_add; /* success */ + @@ -9729,9 +9882,9 @@ index 0000000..dfb3a71 + key->dk_op.dy_hop = op->dy_hop; + kref_init(&key->dk_kref); + p->set(key, op->dy_hop, au_br_sb(br)); -+ old = dy_gadd(spl, key); ++ old = dy_gadd(sphl, key); + if (old) { -+ kfree(key); ++ au_delayed_kfree(key); + key = old; + } + @@ -9826,16 +9979,16 @@ index 0000000..dfb3a71 + +void au_dy_arefresh(int do_dx) +{ -+ struct au_splhead *spl; -+ struct list_head *head; ++ struct au_sphlhead *sphl; ++ struct hlist_head *head; + struct au_dykey *key; + -+ spl = dynop + AuDy_AOP; -+ head = &spl->head; -+ spin_lock(&spl->spin); -+ list_for_each_entry(key, head, dk_list) ++ sphl = dynop + AuDy_AOP; ++ head = &sphl->head; ++ spin_lock(&sphl->spin); ++ hlist_for_each_entry(key, head, dk_hnode) + dy_adx((void *)key, do_dx); -+ spin_unlock(&spl->spin); ++ spin_unlock(&sphl->spin); +} + +/* ---------------------------------------------------------------------- */ @@ -9848,7 +10001,7 @@ index 0000000..dfb3a71 + BUILD_BUG_ON(offsetof(struct au_dyaop, da_key)); + + for (i = 0; i < AuDyLast; i++) -+ au_spl_init(dynop + i); ++ au_sphl_init(dynop + i); +} + +void au_dy_fin(void) @@ -9856,11 +10009,11 @@ index 0000000..dfb3a71 + int i; + + for (i = 0; i < AuDyLast; i++) -+ WARN_ON(!list_empty(&dynop[i].head)); ++ WARN_ON(!hlist_empty(&dynop[i].head)); +} diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h new file mode 100644 -index 0000000..8680bfc +index 0000000..5db2da2 --- /dev/null +++ b/fs/aufs/dynop.h @@ -0,0 +1,61 @@ @@ -9892,7 +10045,7 @@ index 0000000..8680bfc + +struct au_dykey { + union { -+ struct list_head dk_list; ++ struct hlist_node dk_hnode; + struct rcu_head dk_rcu; + }; + struct au_dynop dk_op; @@ -9927,7 +10080,7 @@ index 0000000..8680bfc +#endif /* __AUFS_DYNOP_H__ */ diff --git a/fs/aufs/export.c b/fs/aufs/export.c new file mode 100644 -index 0000000..98a7036 +index 0000000..6b5a7be --- /dev/null +++ b/fs/aufs/export.c @@ -0,0 +1,824 @@ @@ -10337,7 +10490,7 @@ index 0000000..98a7036 + } + +out_name: -+ free_page((unsigned long)arg.name); ++ au_delayed_free_page((unsigned long)arg.name); +out_file: + fput(file); +out: @@ -10491,7 +10644,7 @@ index 0000000..98a7036 + dentry = ERR_PTR(-ESTALE); + } +out_pathname: -+ free_page((unsigned long)pathname); ++ au_delayed_free_page((unsigned long)pathname); +out_h_parent: + dput(h_parent); +out: @@ -10757,10 +10910,10 @@ index 0000000..98a7036 +} diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c new file mode 100644 -index 0000000..504b767 +index 0000000..00475fb --- /dev/null +++ b/fs/aufs/f_op.c -@@ -0,0 +1,757 @@ +@@ -0,0 +1,759 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -10849,6 +11002,7 @@ index 0000000..504b767 +{ + struct au_finfo *finfo; + aufs_bindex_t bindex; ++ int delayed; + + finfo = au_fi(file); + au_sphl_del(&finfo->fi_hlist, @@ -10857,7 +11011,8 @@ index 0000000..504b767 + if (bindex >= 0) + au_set_h_fptr(file, bindex, NULL); + -+ au_finfo_fin(file); ++ delayed = (current->flags & PF_KTHREAD) || in_interrupt(); ++ au_finfo_fin(file, delayed); + return 0; +} + @@ -11938,10 +12093,10 @@ index 0000000..e3cb6ed +} diff --git a/fs/aufs/file.c b/fs/aufs/file.c new file mode 100644 -index 0000000..4b68aef +index 0000000..bfc1d1b --- /dev/null +++ b/fs/aufs/file.c -@@ -0,0 +1,830 @@ +@@ -0,0 +1,844 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -12204,7 +12359,7 @@ index 0000000..4b68aef + } + if (unlikely(err)) { + finfo->fi_hdir = NULL; -+ au_finfo_fin(file); ++ au_finfo_fin(file, /*atonce*/0); + } + +out: @@ -12524,6 +12679,7 @@ index 0000000..4b68aef + +static void au_do_refresh_dir(struct file *file) +{ ++ int execed; + aufs_bindex_t bindex, bbot, new_bindex, brid; + struct au_hfile *p, tmp, *q; + struct au_finfo *finfo; @@ -12562,6 +12718,7 @@ index 0000000..4b68aef + } + } + ++ execed = vfsub_file_execed(file); + p = fidir->fd_hfile; + if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { + bbot = au_sbbot(sb); @@ -12570,14 +12727,14 @@ index 0000000..4b68aef + if (p->hf_file) { + if (file_inode(p->hf_file)) + break; -+ au_hfput(p, file); ++ au_hfput(p, execed); + } + } else { + bbot = au_br_index(sb, brid); + for (finfo->fi_btop = 0; finfo->fi_btop < bbot; + finfo->fi_btop++, p++) + if (p->hf_file) -+ au_hfput(p, file); ++ au_hfput(p, execed); + bbot = au_sbbot(sb); + } + @@ -12587,7 +12744,7 @@ index 0000000..4b68aef + if (p->hf_file) { + if (file_inode(p->hf_file)) + break; -+ au_hfput(p, file); ++ au_hfput(p, execed); + } + AuDebugOn(fidir->fd_bbot < finfo->fi_btop); +} @@ -12597,23 +12754,26 @@ index 0000000..4b68aef + */ +static int refresh_file(struct file *file, int (*reopen)(struct file *file)) +{ -+ int err, need_reopen; ++ int err, need_reopen, nbr; + aufs_bindex_t bbot, bindex; + struct dentry *dentry; ++ struct super_block *sb; + struct au_finfo *finfo; + struct au_hfile *hfile; + + dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ nbr = au_sbbot(sb) + 1; + finfo = au_fi(file); + if (!finfo->fi_hdir) { + hfile = &finfo->fi_htop; + AuDebugOn(!hfile->hf_file); -+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id); ++ bindex = au_br_index(sb, hfile->hf_br->br_id); + AuDebugOn(bindex < 0); + if (bindex != finfo->fi_btop) + au_set_fbtop(file, bindex); + } else { -+ err = au_fidir_realloc(finfo, au_sbbot(dentry->d_sb) + 1); ++ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + au_do_refresh_dir(file); @@ -12623,6 +12783,9 @@ index 0000000..4b68aef + need_reopen = 1; + if (!au_test_mmapped(file)) + err = au_file_refresh_by_inode(file, &need_reopen); ++ if (finfo->fi_hdir) ++ /* harmless if err */ ++ au_fidir_realloc(finfo, nbr, /*may_shrink*/1); + if (!err && need_reopen && !d_unlinked(dentry)) + err = reopen(file); + if (!err) { @@ -12730,6 +12893,10 @@ index 0000000..4b68aef + struct page *page, enum migrate_mode mode) +{ AuUnsupport(); return 0; } +#endif ++static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) ++{ AuUnsupport(); return true; } ++static void aufs_putback_page(struct page *page) ++{ AuUnsupport(); } +static int aufs_launder_page(struct page *page) +{ AuUnsupport(); return 0; } +static int aufs_is_partially_uptodate(struct page *page, @@ -12764,6 +12931,8 @@ index 0000000..4b68aef + .releasepage = aufs_releasepage, + /* is fallback_migrate_page ok? */ + /* .migratepage = aufs_migratepage, */ ++ .isolate_page = aufs_isolate_page, ++ .putback_page = aufs_putback_page, + .launder_page = aufs_launder_page, + .is_partially_uptodate = aufs_is_partially_uptodate, + .is_dirty_writeback = aufs_is_dirty_writeback, @@ -12774,10 +12943,10 @@ index 0000000..4b68aef +}; diff --git a/fs/aufs/file.h b/fs/aufs/file.h new file mode 100644 -index 0000000..96ab0a0 +index 0000000..f53b381 --- /dev/null +++ b/fs/aufs/file.h -@@ -0,0 +1,278 @@ +@@ -0,0 +1,281 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -12830,7 +12999,10 @@ index 0000000..96ab0a0 + struct au_fidir *fi_hdir; /* for dir only */ + + struct hlist_node fi_hlist; -+ struct file *fi_file; /* very ugly */ ++ union { ++ struct file *fi_file; /* very ugly */ ++ struct llist_node fi_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -12881,16 +13053,16 @@ index 0000000..96ab0a0 +struct file *au_read_pre(struct file *file, int keep_fi); + +/* finfo.c */ -+void au_hfput(struct au_hfile *hf, struct file *file); ++void au_hfput(struct au_hfile *hf, int execed); +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, + struct file *h_file); + +void au_update_figen(struct file *file); +struct au_fidir *au_fidir_alloc(struct super_block *sb); -+int au_fidir_realloc(struct au_finfo *finfo, int nbr); ++int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink); + +void au_fi_init_once(void *_fi); -+void au_finfo_fin(struct file *file); ++void au_finfo_fin(struct file *file, int atonce); +int au_finfo_init(struct file *file, struct au_fidir *fidir); + +/* ioctl.c */ @@ -13058,10 +13230,10 @@ index 0000000..96ab0a0 +#endif /* __AUFS_FILE_H__ */ diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c new file mode 100644 -index 0000000..07f6eb3 +index 0000000..0f016ed --- /dev/null +++ b/fs/aufs/finfo.c -@@ -0,0 +1,136 @@ +@@ -0,0 +1,138 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -13072,10 +13244,9 @@ index 0000000..07f6eb3 + +#include "aufs.h" + -+void au_hfput(struct au_hfile *hf, struct file *file) ++void au_hfput(struct au_hfile *hf, int execed) +{ -+ /* todo: direct access f_flags */ -+ if (vfsub_file_flags(file) & __FMODE_EXEC) ++ if (execed) + allow_write_access(hf->hf_file); + fput(hf->hf_file); + hf->hf_file = NULL; @@ -13097,7 +13268,7 @@ index 0000000..07f6eb3 + hf = fidir->fd_hfile + bindex; + + if (hf && hf->hf_file) -+ au_hfput(hf, file); ++ au_hfput(hf, vfsub_file_execed(file)); + if (val) { + FiMustWriteLock(file); + AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry)); @@ -13131,7 +13302,7 @@ index 0000000..07f6eb3 + return fidir; +} + -+int au_fidir_realloc(struct au_finfo *finfo, int nbr) ++int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink) +{ + int err; + struct au_fidir *fidir, *p; @@ -13142,7 +13313,7 @@ index 0000000..07f6eb3 + + err = -ENOMEM; + p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), -+ GFP_NOFS); ++ GFP_NOFS, may_shrink); + if (p) { + p->fd_nent = nbr; + finfo->fi_hdir = p; @@ -13154,7 +13325,7 @@ index 0000000..07f6eb3 + +/* ---------------------------------------------------------------------- */ + -+void au_finfo_fin(struct file *file) ++void au_finfo_fin(struct file *file, int atonce) +{ + struct au_finfo *finfo; + @@ -13163,7 +13334,10 @@ index 0000000..07f6eb3 + finfo = au_fi(file); + AuDebugOn(finfo->fi_hdir); + AuRwDestroy(&finfo->fi_rwsem); -+ au_cache_free_finfo(finfo); ++ if (!atonce) ++ au_cache_dfree_finfo(finfo); ++ else ++ au_cache_free_finfo(finfo); +} + +void au_fi_init_once(void *_finfo) @@ -13200,7 +13374,7 @@ index 0000000..07f6eb3 +} diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h new file mode 100644 -index 0000000..725b2ff +index 0000000..95b78b9 --- /dev/null +++ b/fs/aufs/fstype.h @@ -0,0 +1,387 @@ @@ -13234,7 +13408,7 @@ index 0000000..725b2ff + +static inline int au_test_iso9660(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++#if IS_ENABLED(CONFIG_ISO9660_FS) + return sb->s_magic == ISOFS_SUPER_MAGIC; +#else + return 0; @@ -13243,7 +13417,7 @@ index 0000000..725b2ff + +static inline int au_test_romfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_ROMFS_FS) + return sb->s_magic == ROMFS_MAGIC; +#else + return 0; @@ -13252,7 +13426,7 @@ index 0000000..725b2ff + +static inline int au_test_cramfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++#if IS_ENABLED(CONFIG_CRAMFS) + return sb->s_magic == CRAMFS_MAGIC; +#endif + return 0; @@ -13260,7 +13434,7 @@ index 0000000..725b2ff + +static inline int au_test_nfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_NFS_FS) + return sb->s_magic == NFS_SUPER_MAGIC; +#else + return 0; @@ -13269,7 +13443,7 @@ index 0000000..725b2ff + +static inline int au_test_fuse(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++#if IS_ENABLED(CONFIG_FUSE_FS) + return sb->s_magic == FUSE_SUPER_MAGIC; +#else + return 0; @@ -13278,7 +13452,7 @@ index 0000000..725b2ff + +static inline int au_test_xfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_XFS_FS) + return sb->s_magic == XFS_SB_MAGIC; +#else + return 0; @@ -13296,7 +13470,7 @@ index 0000000..725b2ff + +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++#if IS_ENABLED(CONFIG_ECRYPT_FS) + return !strcmp(au_sbtype(sb), "ecryptfs"); +#else + return 0; @@ -13310,7 +13484,7 @@ index 0000000..725b2ff + +static inline int au_test_ubifs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_UBIFS_FS) + return sb->s_magic == UBIFS_SUPER_MAGIC; +#else + return 0; @@ -13337,7 +13511,7 @@ index 0000000..725b2ff + +static inline int au_test_configfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_CONFIGFS_FS) + return sb->s_magic == CONFIGFS_MAGIC; +#else + return 0; @@ -13346,7 +13520,7 @@ index 0000000..725b2ff + +static inline int au_test_minix(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++#if IS_ENABLED(CONFIG_MINIX_FS) + return sb->s_magic == MINIX3_SUPER_MAGIC + || sb->s_magic == MINIX2_SUPER_MAGIC + || sb->s_magic == MINIX2_SUPER_MAGIC2 @@ -13359,7 +13533,7 @@ index 0000000..725b2ff + +static inline int au_test_fat(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++#if IS_ENABLED(CONFIG_FAT_FS) + return sb->s_magic == MSDOS_SUPER_MAGIC; +#else + return 0; @@ -13387,7 +13561,7 @@ index 0000000..725b2ff + +static inline int au_test_squashfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++#if IS_ENABLED(CONFIG_SQUASHFS) + return sb->s_magic == SQUASHFS_MAGIC; +#else + return 0; @@ -13396,7 +13570,7 @@ index 0000000..725b2ff + +static inline int au_test_btrfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_BTRFS_FS) + return sb->s_magic == BTRFS_SUPER_MAGIC; +#else + return 0; @@ -13405,7 +13579,7 @@ index 0000000..725b2ff + +static inline int au_test_xenfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++#if IS_ENABLED(CONFIG_XENFS) + return sb->s_magic == XENFS_SUPER_MAGIC; +#else + return 0; @@ -13423,7 +13597,7 @@ index 0000000..725b2ff + +static inline int au_test_nilfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE) ++#if IS_ENABLED(CONFIG_NILFS) + return sb->s_magic == NILFS_SUPER_MAGIC; +#else + return 0; @@ -13432,7 +13606,7 @@ index 0000000..725b2ff + +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE) ++#if IS_ENABLED(CONFIG_HFSPLUS_FS) + return sb->s_magic == HFSPLUS_SUPER_MAGIC; +#else + return 0; @@ -13593,7 +13767,7 @@ index 0000000..725b2ff +#endif /* __AUFS_FSTYPE_H__ */ diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c new file mode 100644 -index 0000000..6afef3f +index 0000000..110f8f5 --- /dev/null +++ b/fs/aufs/hfsnotify.c @@ -0,0 +1,274 @@ @@ -13618,7 +13792,7 @@ index 0000000..6afef3f + struct au_hnotify *hn = container_of(mark, struct au_hnotify, + hn_mark); + /* AuDbg("here\n"); */ -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + smp_mb__before_atomic(); + if (atomic64_dec_and_test(&au_hfsn_ifree)) + wake_up(&au_hfsn_wq); @@ -13742,7 +13916,7 @@ index 0000000..6afef3f + struct au_br_hfsnotify *hfsn = group->private; + + /* AuDbg("here\n"); */ -+ kfree(hfsn); ++ au_delayed_kfree(hfsn); +} + +static int au_hfsn_handle_event(struct fsnotify_group *group, @@ -13836,7 +14010,7 @@ index 0000000..6afef3f + goto out; /* success */ + +out_hfsn: -+ kfree(hfsn); ++ au_delayed_kfree(hfsn); +out: + return err; +} @@ -13922,10 +14096,10 @@ index 0000000..145c6ac +} diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c new file mode 100644 -index 0000000..3016c5e +index 0000000..a05aed8 --- /dev/null +++ b/fs/aufs/hnotify.c -@@ -0,0 +1,697 @@ +@@ -0,0 +1,710 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -13950,7 +14124,7 @@ index 0000000..3016c5e + AuTraceErr(err); + if (unlikely(err)) { + hinode->hi_notify = NULL; -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + /* + * The upper dir was removed by udba, but the same named + * dir left. In this case, aufs assignes a new inode @@ -13974,7 +14148,7 @@ index 0000000..3016c5e + if (hn) { + hinode->hi_notify = NULL; + if (au_hnotify_op.free(hinode, hn)) -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + } +} + @@ -14408,7 +14582,7 @@ index 0000000..3016c5e + || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { + inode = lookup_wlock_by_ino(sb, bfound, h_ino); + try_iput = 1; -+ } ++ } + + args.flags = a->flags[AuHn_CHILD]; + args.dentry = dentry; @@ -14447,7 +14621,7 @@ index 0000000..3016c5e + iput(a->dir); + si_write_unlock(sb); + au_nwt_done(&sbinfo->si_nowait); -+ kfree(a); ++ au_delayed_kfree(a); +} + +/* ---------------------------------------------------------------------- */ @@ -14553,7 +14727,7 @@ index 0000000..3016c5e + iput(args->h_child_inode); + iput(args->h_dir); + iput(args->dir); -+ kfree(args); ++ au_delayed_kfree(args); + } + +out: @@ -14594,17 +14768,26 @@ index 0000000..3016c5e + +static void au_hn_destroy_cache(void) +{ -+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]); -+ au_cachep[AuCache_HNOTIFY] = NULL; ++ struct au_cache *cp; ++ ++ flush_delayed_work(&au_dfree.dwork); ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ AuDebugOn(!llist_empty(&cp->llist)); ++ kmem_cache_destroy(cp->cache); ++ cp->cache = NULL; +} + ++AU_CACHE_DFREE_FUNC(hnotify, HNOTIFY, hn_lnode); ++ +int __init au_hnotify_init(void) +{ + int err; ++ struct au_cache *cp; + + err = -ENOMEM; -+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify); -+ if (au_cachep[AuCache_HNOTIFY]) { ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ cp->cache = AuCache(au_hnotify); ++ if (cp->cache) { + err = 0; + if (au_hnotify_op.init) + err = au_hnotify_op.init(); @@ -14617,18 +14800,22 @@ index 0000000..3016c5e + +void au_hnotify_fin(void) +{ ++ struct au_cache *cp; ++ + if (au_hnotify_op.fin) + au_hnotify_op.fin(); ++ + /* cf. au_cache_fin() */ -+ if (au_cachep[AuCache_HNOTIFY]) ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ if (cp->cache) + au_hn_destroy_cache(); +} diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c new file mode 100644 -index 0000000..cc1e312 +index 0000000..c730ec7 --- /dev/null +++ b/fs/aufs/i_op.c -@@ -0,0 +1,1401 @@ +@@ -0,0 +1,1438 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -14644,17 +14831,20 @@ index 0000000..cc1e312 +#include "aufs.h" + +static int h_permission(struct inode *h_inode, int mask, -+ struct vfsmount *h_mnt, int brperm) ++ struct path *h_path, int brperm) +{ + int err; + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); + ++ err = -EPERM; ++ if (write_mask && IS_IMMUTABLE(h_inode)) ++ goto out; ++ + err = -EACCES; -+ if ((write_mask && IS_IMMUTABLE(h_inode)) -+ || ((mask & MAY_EXEC) -+ && S_ISREG(h_inode->i_mode) -+ && ((h_mnt->mnt_flags & MNT_NOEXEC) -+ || !(h_inode->i_mode & S_IXUGO)))) ++ if (((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && (path_noexec(h_path) ++ || !(h_inode->i_mode & S_IXUGO)))) + goto out; + + /* @@ -14738,7 +14928,7 @@ index 0000000..cc1e312 + err = 0; + bindex = au_ibtop(inode); + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm); ++ err = h_permission(h_inode, mask, &br->br_path, br->br_perm); + if (write_mask + && !err + && !special_file(h_inode->i_mode)) { @@ -14764,7 +14954,7 @@ index 0000000..cc1e312 + break; + + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, au_br_mnt(br), ++ err = h_permission(h_inode, mask, &br->br_path, + br->br_perm); + } + } @@ -14899,8 +15089,7 @@ index 0000000..cc1e312 +{ + int err, h_opened = *opened; + unsigned int lkup_flags; -+ struct dentry *parent; -+ struct dentry *d; ++ struct dentry *parent, *d; + struct au_sphlhead *aopen; + struct vfsub_aopen_args args = { + .open_flag = open_flag, @@ -14995,10 +15184,10 @@ index 0000000..cc1e312 + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuDbgDentry(dentry); -+ if (unlikely(err)) ++ if (unlikely(err < 0)) + goto out; +out_no_open: -+ if (!err && !(*opened & FILE_CREATED)) { ++ if (err >= 0 && !(*opened & FILE_CREATED)) { + AuLabel(out_no_open); + dget(dentry); + err = finish_no_open(file, dentry); @@ -15612,7 +15801,7 @@ index 0000000..cc1e312 +out_si: + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -15705,7 +15894,7 @@ index 0000000..cc1e312 + di_write_unlock(dentry); + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -15925,20 +16114,55 @@ index 0000000..cc1e312 + +/* ---------------------------------------------------------------------- */ + ++static int au_is_special(struct inode *inode) ++{ ++ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK)); ++} ++ +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags) +{ + int err; ++ aufs_bindex_t bindex; + struct super_block *sb; + struct inode *h_inode; ++ struct vfsmount *h_mnt; + + sb = inode->i_sb; ++ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode), ++ "unexpected s_flags 0x%lx", sb->s_flags); ++ + /* mmap_sem might be acquired already, cf. aufs_mmap() */ + lockdep_off(); + si_read_lock(sb, AuLock_FLUSH); + ii_write_lock_child(inode); + lockdep_on(); -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ err = vfsub_update_time(h_inode, ts, flags); ++ ++ err = 0; ++ bindex = au_ibtop(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!au_test_ro(sb, bindex, inode)) { ++ h_mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mnt_want_write(h_mnt); ++ if (!err) { ++ err = vfsub_update_time(h_inode, ts, flags); ++ vfsub_mnt_drop_write(h_mnt); ++ } ++ } else if (au_is_special(h_inode)) { ++ /* ++ * Never copy-up here. ++ * These special files may already be opened and used for ++ * communicating. If we copied it up, then the communication ++ * would be corrupted. ++ */ ++ AuWarn1("timestamps for i%lu are ignored " ++ "since it is on readonly branch (hi%lu).\n", ++ inode->i_ino, h_inode->i_ino); ++ } else if (flags & ~S_ATIME) { ++ err = -EIO; ++ AuIOErr1("unexpected flags 0x%x\n", flags); ++ AuDebugOn(1); ++ } ++ + lockdep_off(); + if (!err) + au_cpup_attr_timesizes(inode); @@ -16032,7 +16256,7 @@ index 0000000..cc1e312 +}; diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c new file mode 100644 -index 0000000..8e3fb61 +index 0000000..2a9aa09 --- /dev/null +++ b/fs/aufs/i_op_add.c @@ -0,0 +1,911 @@ @@ -16370,7 +16594,7 @@ index 0000000..8e3fb61 + if (!try_aopen) + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -16834,7 +17058,7 @@ index 0000000..8e3fb61 + } + aufs_read_and_write_unlock2(dentry, src_dentry); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -16943,13 +17167,13 @@ index 0000000..8e3fb61 + } + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c new file mode 100644 -index 0000000..35b923c +index 0000000..2fe8f07 --- /dev/null +++ b/fs/aufs/i_op_del.c @@ -0,0 +1,498 @@ @@ -17336,7 +17560,7 @@ index 0000000..35b923c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -17446,14 +17670,14 @@ index 0000000..35b923c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c new file mode 100644 -index 0000000..df697de +index 0000000..43a0909 --- /dev/null +++ b/fs/aufs/i_op_ren.c @@ -0,0 +1,1002 @@ @@ -18454,17 +18678,17 @@ index 0000000..df697de + iput(a->dst_inode); + if (a->thargs) + au_whtmp_rmdir_free(a->thargs); -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c new file mode 100644 -index 0000000..fae4c27 +index 0000000..975cff3 --- /dev/null +++ b/fs/aufs/iinfo.c -@@ -0,0 +1,271 @@ +@@ -0,0 +1,272 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -18672,7 +18896,7 @@ index 0000000..fae4c27 + return -ENOMEM; +} + -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr) ++int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) +{ + int err, i; + struct au_hinode *hip; @@ -18680,7 +18904,8 @@ index 0000000..fae4c27 + AuRwMustWriteLock(&iinfo->ii_rwsem); + + err = -ENOMEM; -+ hip = krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS); ++ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, ++ may_shrink); + if (hip) { + iinfo->ii_hinode = hip; + i = iinfo->ii_bbot + 1; @@ -18721,7 +18946,7 @@ index 0000000..fae4c27 + + iinfo = au_ii(inode); + if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); ++ au_vdir_free(iinfo->ii_vdir, /*atonce*/0); + + bindex = iinfo->ii_btop; + if (bindex >= 0) { @@ -18733,15 +18958,15 @@ index 0000000..fae4c27 + hi++; + } + } -+ kfree(iinfo->ii_hinode); ++ au_delayed_kfree(iinfo->ii_hinode); + AuRwDestroy(&iinfo->ii_rwsem); +} diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c new file mode 100644 -index 0000000..a4b994e +index 0000000..8f7446d --- /dev/null +++ b/fs/aufs/inode.c -@@ -0,0 +1,504 @@ +@@ -0,0 +1,506 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -18771,7 +18996,7 @@ index 0000000..a4b994e + +static int au_ii_refresh(struct inode *inode, int *update) +{ -+ int err, e; ++ int err, e, nbr; + umode_t type; + aufs_bindex_t bindex, new_bindex; + struct super_block *sb; @@ -18783,9 +19008,10 @@ index 0000000..a4b994e + + *update = 0; + sb = inode->i_sb; ++ nbr = au_sbbot(sb) + 1; + type = inode->i_mode & S_IFMT; + iinfo = au_ii(inode); -+ err = au_hinode_realloc(iinfo, au_sbbot(sb) + 1); ++ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + @@ -18823,6 +19049,7 @@ index 0000000..a4b994e + } + } + au_update_ibrange(inode, /*do_put_zero*/0); ++ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */ + e = au_dy_irefresh(inode); + if (unlikely(e && !err)) + err = e; @@ -19248,10 +19475,10 @@ index 0000000..a4b994e +} diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h new file mode 100644 -index 0000000..3fc5a58 +index 0000000..33d9f5e --- /dev/null +++ b/fs/aufs/inode.h -@@ -0,0 +1,681 @@ +@@ -0,0 +1,687 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -19276,7 +19503,10 @@ index 0000000..3fc5a58 + /* never use fsnotify_add_vfsmount_mark() */ + struct fsnotify_mark hn_mark; +#endif -+ struct inode *hn_aufs_inode; /* no get/put */ ++ union { ++ struct inode *hn_aufs_inode; /* no get/put */ ++ struct llist_node hn_lnode; /* delayed free */ ++ }; +#endif +} ____cacheline_aligned_in_smp; + @@ -19319,7 +19549,10 @@ index 0000000..3fc5a58 +struct au_icntnr { + struct au_iinfo iinfo; + struct inode vfs_inode; -+ struct hlist_node plink; ++ union { ++ struct hlist_node plink; ++ struct llist_node lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* au_pin flags */ @@ -19506,7 +19739,7 @@ index 0000000..3fc5a58 +void au_hinode_init(struct au_hinode *hinode); +int au_iinfo_init(struct inode *inode); +void au_iinfo_fin(struct inode *inode); -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr); ++int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink); + +#ifdef CONFIG_PROC_FS +/* plink.c */ @@ -20147,10 +20380,10 @@ index 0000000..2ebfdc4 +#endif diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c new file mode 100644 -index 0000000..5711e7a +index 0000000..c3ca50f --- /dev/null +++ b/fs/aufs/loop.c -@@ -0,0 +1,133 @@ +@@ -0,0 +1,134 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20244,7 +20477,8 @@ index 0000000..5711e7a + new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; + a = au_kzrealloc(au_warn_loopback_array, + au_warn_loopback_nelem * sizeof(unsigned long), -+ new_nelem * sizeof(unsigned long), GFP_ATOMIC); ++ new_nelem * sizeof(unsigned long), GFP_ATOMIC, ++ /*may_shrink*/0); + if (a) { + au_warn_loopback_nelem = new_nelem; + au_warn_loopback_array = a; @@ -20282,7 +20516,7 @@ index 0000000..5711e7a +{ + if (backing_file_func) + symbol_put(loop_backing_file); -+ kfree(au_warn_loopback_array); ++ au_delayed_kfree(au_warn_loopback_array); +} diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h new file mode 100644 @@ -20367,10 +20601,10 @@ index 0000000..4f83bdf +endif diff --git a/fs/aufs/module.c b/fs/aufs/module.c new file mode 100644 -index 0000000..88f8f41 +index 0000000..5092b4b --- /dev/null +++ b/fs/aufs/module.c -@@ -0,0 +1,209 @@ +@@ -0,0 +1,319 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20383,29 +20617,120 @@ index 0000000..88f8f41 +#include +#include "aufs.h" + -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++/* shrinkable realloc */ ++void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) +{ -+ if (new_sz <= nused) -+ return p; ++ size_t sz; ++ int diff; + -+ p = krealloc(p, new_sz, gfp); -+ if (p) ++ sz = 0; ++ diff = -1; ++ if (p) { ++#if 0 /* unused */ ++ if (!new_sz) { ++ au_delayed_kfree(p); ++ p = NULL; ++ goto out; ++ } ++#else ++ AuDebugOn(!new_sz); ++#endif ++ sz = ksize(p); ++ diff = au_kmidx_sub(sz, new_sz); ++ } ++ if (sz && !diff) ++ goto out; ++ ++ if (sz < new_sz) ++ /* expand or SLOB */ ++ p = krealloc(p, new_sz, gfp); ++ else if (new_sz < sz && may_shrink) { ++ /* shrink */ ++ void *q; ++ ++ q = kmalloc(new_sz, gfp); ++ if (q) { ++ if (p) { ++ memcpy(q, p, new_sz); ++ au_delayed_kfree(p); ++ } ++ p = q; ++ } else ++ p = NULL; ++ } ++ ++out: ++ return p; ++} ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, ++ int may_shrink) ++{ ++ p = au_krealloc(p, new_sz, gfp, may_shrink); ++ if (p && new_sz > nused) + memset(p + nused, 0, new_sz - nused); + return p; +} + +/* ---------------------------------------------------------------------- */ -+ +/* + * aufs caches + */ -+struct kmem_cache *au_cachep[AuCache_Last] = { -+ [0] = NULL -+}; ++ ++struct au_dfree au_dfree; ++ ++/* delayed free */ ++static void au_do_dfree(struct work_struct *work __maybe_unused) ++{ ++ struct llist_head *head; ++ struct llist_node *node, *next; ++ ++#define AU_CACHE_DFREE_DO_BODY(name, idx, lnode) do { \ ++ head = &au_dfree.cache[AuCache_##idx].llist; \ ++ node = llist_del_all(head); \ ++ for (; node; node = next) { \ ++ struct au_##name *p \ ++ = llist_entry(node, struct au_##name, \ ++ lnode); \ ++ next = llist_next(node); \ ++ au_cache_free_##name(p); \ ++ } \ ++ } while (0) ++ ++ AU_CACHE_DFREE_DO_BODY(dinfo, DINFO, di_lnode); ++ AU_CACHE_DFREE_DO_BODY(icntnr, ICNTNR, lnode); ++ AU_CACHE_DFREE_DO_BODY(finfo, FINFO, fi_lnode); ++ AU_CACHE_DFREE_DO_BODY(vdir, VDIR, vd_lnode); ++ AU_CACHE_DFREE_DO_BODY(vdir_dehstr, DEHSTR, lnode); ++#ifdef CONFIG_AUFS_HNOTIFY ++ AU_CACHE_DFREE_DO_BODY(hnotify, HNOTIFY, hn_lnode); ++#endif ++ ++#define AU_DFREE_DO_BODY(llist, func) do { \ ++ node = llist_del_all(llist); \ ++ for (; node; node = next) { \ ++ next = llist_next(node); \ ++ func(node); \ ++ } \ ++ } while (0) ++ ++ AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_KFREE, kfree); ++ AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_FREE_PAGE, au_free_page); ++ ++#undef AU_CACHE_DFREE_DO_BODY ++#undef AU_DFREE_DO_BODY ++} ++ ++AU_CACHE_DFREE_FUNC(dinfo, DINFO, di_lnode); ++AU_CACHE_DFREE_FUNC(icntnr, ICNTNR, lnode); ++AU_CACHE_DFREE_FUNC(finfo, FINFO, fi_lnode); ++AU_CACHE_DFREE_FUNC(vdir, VDIR, vd_lnode); ++AU_CACHE_DFREE_FUNC(vdir_dehstr, DEHSTR, lnode); + +static void au_cache_fin(void) +{ + int i; ++ struct au_cache *cp; + + /* + * Make sure all delayed rcu free inodes are flushed before we @@ -20415,27 +20740,33 @@ index 0000000..88f8f41 + + /* excluding AuCache_HNOTIFY */ + BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); ++ flush_delayed_work(&au_dfree.dwork); + for (i = 0; i < AuCache_HNOTIFY; i++) { -+ kmem_cache_destroy(au_cachep[i]); -+ au_cachep[i] = NULL; ++ cp = au_dfree.cache + i; ++ AuDebugOn(!llist_empty(&cp->llist)); ++ kmem_cache_destroy(cp->cache); ++ cp->cache = NULL; + } +} + +static int __init au_cache_init(void) +{ -+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); -+ if (au_cachep[AuCache_DINFO]) ++ struct au_cache *cp; ++ ++ cp = au_dfree.cache; ++ cp[AuCache_DINFO].cache = AuCacheCtor(au_dinfo, au_di_init_once); ++ if (cp[AuCache_DINFO].cache) + /* SLAB_DESTROY_BY_RCU */ -+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, -+ au_icntnr_init_once); -+ if (au_cachep[AuCache_ICNTNR]) -+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo, -+ au_fi_init_once); -+ if (au_cachep[AuCache_FINFO]) -+ au_cachep[AuCache_VDIR] = AuCache(au_vdir); -+ if (au_cachep[AuCache_VDIR]) -+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); -+ if (au_cachep[AuCache_DEHSTR]) ++ cp[AuCache_ICNTNR].cache = AuCacheCtor(au_icntnr, ++ au_icntnr_init_once); ++ if (cp[AuCache_ICNTNR].cache) ++ cp[AuCache_FINFO].cache = AuCacheCtor(au_finfo, ++ au_fi_init_once); ++ if (cp[AuCache_FINFO].cache) ++ cp[AuCache_VDIR].cache = AuCache(au_vdir); ++ if (cp[AuCache_VDIR].cache) ++ cp[AuCache_DEHSTR].cache = AuCache(au_vdir_dehstr); ++ if (cp[AuCache_DEHSTR].cache) + return 0; + + au_cache_fin(); @@ -20497,6 +20828,7 @@ index 0000000..88f8f41 +{ + int err, i; + char *p; ++ struct au_cache *cp; + + p = au_esc_chars; + for (i = 1; i <= ' '; i++) @@ -20511,6 +20843,16 @@ index 0000000..88f8f41 + for (i = 0; i < AuIop_Last; i++) + aufs_iop_nogetattr[i].getattr = NULL; + ++ /* First, initialize au_dfree */ ++ for (i = 0; i < AuCache_Last; i++) { /* including hnotify */ ++ cp = au_dfree.cache + i; ++ cp->cache = NULL; ++ init_llist_head(&cp->llist); ++ } ++ for (i = 0; i < AU_DFREE_Last; i++) ++ init_llist_head(au_dfree.llist + i); ++ INIT_DELAYED_WORK(&au_dfree.dwork, au_do_dfree); ++ + au_sbilist_init(); + sysaufs_brs_init(); + au_debug_init(); @@ -20561,6 +20903,7 @@ index 0000000..88f8f41 +out_sysaufs: + sysaufs_fin(); + au_dy_fin(); ++ flush_delayed_work(&au_dfree.dwork); +out: + return err; +} @@ -20576,16 +20919,17 @@ index 0000000..88f8f41 + au_procfs_fin(); + sysaufs_fin(); + au_dy_fin(); ++ flush_delayed_work(&au_dfree.dwork); +} + +module_init(aufs_init); +module_exit(aufs_exit); diff --git a/fs/aufs/module.h b/fs/aufs/module.h new file mode 100644 -index 0000000..1383e3d +index 0000000..6f968ba --- /dev/null +++ b/fs/aufs/module.h -@@ -0,0 +1,76 @@ +@@ -0,0 +1,143 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20600,6 +20944,7 @@ index 0000000..1383e3d +#ifdef __KERNEL__ + +#include ++#include "debug.h" + +struct path; +struct seq_file; @@ -20612,7 +20957,19 @@ index 0000000..1383e3d + +extern int au_dir_roflags; + -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink); ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, ++ int may_shrink); ++ ++static inline int au_kmidx_sub(size_t sz, size_t new_sz) ++{ ++#ifndef CONFIG_SLOB ++ return kmalloc_index(sz) - kmalloc_index(new_sz); ++#else ++ return -1; /* SLOB is untested */ ++#endif ++} ++ +int au_seq_path(struct seq_file *seq, struct path *path); + +#ifdef CONFIG_PROC_FS @@ -20626,7 +20983,7 @@ index 0000000..1383e3d + +/* ---------------------------------------------------------------------- */ + -+/* kmem cache */ ++/* kmem cache and delayed free */ +enum { + AuCache_DINFO, + AuCache_ICNTNR, @@ -20637,19 +20994,54 @@ index 0000000..1383e3d + AuCache_Last +}; + ++enum { ++ AU_DFREE_KFREE, ++ AU_DFREE_FREE_PAGE, ++ AU_DFREE_Last ++}; ++ ++struct au_cache { ++ struct kmem_cache *cache; ++ struct llist_head llist; /* delayed free */ ++}; ++ ++/* ++ * in order to reduce the cost of the internal timer, consolidate all the ++ * delayed free works into a single delayed_work. ++ */ ++struct au_dfree { ++ struct au_cache cache[AuCache_Last]; ++ struct llist_head llist[AU_DFREE_Last]; ++ struct delayed_work dwork; ++}; ++ ++extern struct au_dfree au_dfree; ++ +#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) +#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) +#define AuCacheCtor(type, ctor) \ + kmem_cache_create(#type, sizeof(struct type), \ + __alignof__(struct type), AuCacheFlags, ctor) + -+extern struct kmem_cache *au_cachep[]; ++#define AU_DFREE_DELAY msecs_to_jiffies(10) ++#define AU_DFREE_BODY(lnode, llist) do { \ ++ if (llist_add(lnode, llist)) \ ++ schedule_delayed_work(&au_dfree.dwork, \ ++ AU_DFREE_DELAY); \ ++ } while (0) ++#define AU_CACHE_DFREE_FUNC(name, idx, lnode) \ ++ void au_cache_dfree_##name(struct au_##name *p) \ ++ { \ ++ struct au_cache *cp = au_dfree.cache + AuCache_##idx; \ ++ AU_DFREE_BODY(&p->lnode, &cp->llist); \ ++ } + +#define AuCacheFuncs(name, index) \ +static inline struct au_##name *au_cache_alloc_##name(void) \ -+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++{ return kmem_cache_alloc(au_dfree.cache[AuCache_##index].cache, GFP_NOFS); } \ +static inline void au_cache_free_##name(struct au_##name *p) \ -+{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++{ kmem_cache_free(au_dfree.cache[AuCache_##index].cache, p); } \ ++void au_cache_dfree_##name(struct au_##name *p) + +AuCacheFuncs(dinfo, DINFO); +AuCacheFuncs(icntnr, ICNTNR); @@ -20660,11 +21052,30 @@ index 0000000..1383e3d +AuCacheFuncs(hnotify, HNOTIFY); +#endif + ++static inline void au_delayed_kfree(const void *p) ++{ ++ AuDebugOn(!p); ++ AuDebugOn(ksize(p) < sizeof(struct llist_node)); ++ ++ AU_DFREE_BODY((void *)p, au_dfree.llist + AU_DFREE_KFREE); ++} ++ ++/* cast only */ ++static inline void au_free_page(void *p) ++{ ++ free_page((unsigned long)p); ++} ++ ++static inline void au_delayed_free_page(unsigned long addr) ++{ ++ AU_DFREE_BODY((void *)addr, au_dfree.llist + AU_DFREE_FREE_PAGE); ++} ++ +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c new file mode 100644 -index 0000000..a48aa1c +index 0000000..b0e5b84 --- /dev/null +++ b/fs/aufs/mvdown.c @@ -0,0 +1,691 @@ @@ -21354,17 +21765,17 @@ index 0000000..a48aa1c + e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); + if (unlikely(e)) + err = -EFAULT; -+ kfree(args); ++ au_delayed_kfree(args); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c new file mode 100644 -index 0000000..79c7d71 +index 0000000..1d21f0d --- /dev/null +++ b/fs/aufs/opts.c -@@ -0,0 +1,1846 @@ +@@ -0,0 +1,1847 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -22610,7 +23021,7 @@ index 0000000..79c7d71 + } + } + -+ kfree(a); ++ au_delayed_kfree(a); + dump_opts(opts); + if (unlikely(err)) + au_opts_free(opts); @@ -23032,7 +23443,8 @@ index 0000000..79c7d71 + au_hn_inode_unlock(hdir); + + if (!err && do_free) { -+ kfree(wbr); ++ if (wbr) ++ au_delayed_kfree(wbr); + br->br_wbr = NULL; + } + } @@ -23417,10 +23829,10 @@ index 0000000..0d6c2e1 +#endif /* __AUFS_OPTS_H__ */ diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c new file mode 100644 -index 0000000..c42734d +index 0000000..d8d75e8 --- /dev/null +++ b/fs/aufs/plink.c -@@ -0,0 +1,489 @@ +@@ -0,0 +1,501 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -23455,6 +23867,7 @@ index 0000000..c42734d +{ + int err; + pid_t pid, ppid; ++ struct task_struct *parent, *prev; + struct au_sbinfo *sbi; + + SiMustAnyLock(sb); @@ -23469,11 +23882,22 @@ index 0000000..c42734d + goto out; + + /* todo: it highly depends upon /sbin/mount.aufs */ ++ prev = NULL; ++ parent = current; ++ ppid = 0; + rcu_read_lock(); -+ ppid = task_pid_vnr(rcu_dereference(current->real_parent)); ++ while (1) { ++ parent = rcu_dereference(parent->real_parent); ++ if (parent == prev) ++ break; ++ ppid = task_pid_vnr(parent); ++ if (pid == ppid) { ++ rcu_read_unlock(); ++ goto out; ++ } ++ prev = parent; ++ } + rcu_read_unlock(); -+ if (pid == ppid) -+ goto out; + + if (au_ftest_lock(flags, NOPLMW)) { + /* if there is no i_mutex lock in VFS, we don't need to wait */ @@ -24775,10 +25199,10 @@ index 0000000..6c0d5a9 +#endif /* __AUFS_RWSEM_H__ */ diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c new file mode 100644 -index 0000000..aa97059 +index 0000000..e113b51 --- /dev/null +++ b/fs/aufs/sbinfo.c -@@ -0,0 +1,340 @@ +@@ -0,0 +1,342 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -24801,7 +25225,7 @@ index 0000000..aa97059 + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + for (i = 0; i < AuPlink_NHASH; i++) + AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head)); -+ au_nwt_fin(&sbinfo->si_nowait); ++ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); + + AuDebugOn(percpu_counter_sum(&sbinfo->si_ninodes)); + percpu_counter_destroy(&sbinfo->si_ninodes); @@ -24812,14 +25236,15 @@ index 0000000..aa97059 + au_br_free(sbinfo); + au_rw_write_unlock(&sbinfo->si_rwsem); + -+ kfree(sbinfo->si_branch); ++ au_delayed_kfree(sbinfo->si_branch); + for (i = 0; i < AU_NPIDMAP; i++) -+ kfree(sbinfo->au_si_pid.pid_bitmap[i]); ++ if (sbinfo->au_si_pid.pid_bitmap[i]) ++ au_delayed_kfree(sbinfo->au_si_pid.pid_bitmap[i]); + mutex_destroy(&sbinfo->au_si_pid.pid_mtx); + mutex_destroy(&sbinfo->si_xib_mtx); + AuRwDestroy(&sbinfo->si_rwsem); + -+ kfree(sbinfo); ++ au_delayed_kfree(sbinfo); +} + +int au_si_alloc(struct super_block *sb) @@ -24891,14 +25316,14 @@ index 0000000..aa97059 + return 0; /* success */ + +out_br: -+ kfree(sbinfo->si_branch); ++ au_delayed_kfree(sbinfo->si_branch); +out_sbinfo: -+ kfree(sbinfo); ++ au_delayed_kfree(sbinfo); +out: + return err; +} + -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink) +{ + int err, sz; + struct au_branch **brp; @@ -24909,7 +25334,8 @@ index 0000000..aa97059 + sz = sizeof(*brp) * (sbinfo->si_bbot + 1); + if (unlikely(!sz)) + sz = sizeof(*brp); -+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS, ++ may_shrink); + if (brp) { + sbinfo->si_branch = brp; + err = 0; @@ -25121,10 +25547,10 @@ index 0000000..aa97059 +} diff --git a/fs/aufs/spl.h b/fs/aufs/spl.h new file mode 100644 -index 0000000..f9b5288 +index 0000000..8f519db3 --- /dev/null +++ b/fs/aufs/spl.h -@@ -0,0 +1,98 @@ +@@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -25138,6 +25564,7 @@ index 0000000..f9b5288 + +#ifdef __KERNEL__ + ++#if 0 +struct au_splhead { + spinlock_t spin; + struct list_head head; @@ -25170,6 +25597,7 @@ index 0000000..f9b5288 + list_del_rcu(list); + spin_unlock(&spl->spin); +} ++#endif + +/* ---------------------------------------------------------------------- */ + @@ -25225,10 +25653,10 @@ index 0000000..f9b5288 +#endif /* __AUFS_SPL_H__ */ diff --git a/fs/aufs/super.c b/fs/aufs/super.c new file mode 100644 -index 0000000..8bd2d9c +index 0000000..58a773c --- /dev/null +++ b/fs/aufs/super.c -@@ -0,0 +1,1026 @@ +@@ -0,0 +1,1025 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -25264,8 +25692,7 @@ index 0000000..8bd2d9c +{ + struct inode *inode = container_of(head, struct inode, i_rcu); + -+ INIT_HLIST_HEAD(&inode->i_dentry); -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++ au_cache_dfree_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); +} + +static void aufs_destroy_inode(struct inode *inode) @@ -26047,7 +26474,7 @@ index 0000000..8bd2d9c +out_mtx: + inode_unlock(inode); +out_opts: -+ free_page((unsigned long)opts.opt); ++ au_delayed_free_page((unsigned long)opts.opt); +out: + err = cvt_err(err); + AuTraceErr(err); @@ -26188,7 +26615,7 @@ index 0000000..8bd2d9c + kobject_put(&sbinfo->si_kobj); + sb->s_fs_info = NULL; +out_opts: -+ free_page((unsigned long)opts.opt); ++ au_delayed_free_page((unsigned long)opts.opt); +out: + AuTraceErr(err); + err = cvt_err(err); @@ -26257,7 +26684,7 @@ index 0000000..8bd2d9c +}; diff --git a/fs/aufs/super.h b/fs/aufs/super.h new file mode 100644 -index 0000000..b8ca149 +index 0000000..e4ac866 --- /dev/null +++ b/fs/aufs/super.h @@ -0,0 +1,625 @@ @@ -26529,7 +26956,7 @@ index 0000000..b8ca149 +/* sbinfo.c */ +void au_si_free(struct kobject *kobj); +int au_si_alloc(struct super_block *sb); -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink); + +unsigned int au_sigen_inc(struct super_block *sb); +aufs_bindex_t au_new_br_id(struct super_block *sb); @@ -27079,7 +27506,7 @@ index 0000000..1f79983 +#endif /* __SYSAUFS_H__ */ diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c new file mode 100644 -index 0000000..0efb77a +index 0000000..f4c3170 --- /dev/null +++ b/fs/aufs/sysfs.c @@ -0,0 +1,340 @@ @@ -27258,7 +27685,7 @@ index 0000000..0efb77a + if (unlikely(err == PAGE_SIZE)) + err = -EFBIG; + } -+ kfree(seq); ++ au_delayed_kfree(seq); +out_unlock: + si_read_unlock(sb); +out: @@ -27329,9 +27756,9 @@ index 0000000..0efb77a + err = -EFAULT; + +out_seq: -+ kfree(seq); ++ au_delayed_kfree(seq); +out_buf: -+ free_page((unsigned long)buf); ++ au_delayed_free_page((unsigned long)buf); +out: + si_read_unlock(sb); + return err; @@ -27575,10 +28002,10 @@ index 0000000..7d22979 +} diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c new file mode 100644 -index 0000000..0a9ff00 +index 0000000..b2eb4c0 --- /dev/null +++ b/fs/aufs/vdir.c -@@ -0,0 +1,876 @@ +@@ -0,0 +1,887 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -27678,7 +28105,7 @@ index 0000000..0a9ff00 + struct hlist_node *node; + + hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ kfree(pos); ++ au_delayed_kfree(pos); +} + +static void au_nhash_de_do_free(struct hlist_head *head) @@ -27687,7 +28114,7 @@ index 0000000..0a9ff00 + struct hlist_node *node; + + hlist_for_each_entry_safe(pos, node, head, hash) -+ au_cache_free_vdir_dehstr(pos); ++ au_cache_dfree_vdir_dehstr(pos); +} + +static void au_nhash_do_free(struct au_nhash *nhash, @@ -27705,7 +28132,7 @@ index 0000000..0a9ff00 + nhash_count(head); + free(head++); + } -+ kfree(nhash->nh_head); ++ au_delayed_kfree(nhash->nh_head); +} + +void au_nhash_wh_free(struct au_nhash *whlist) @@ -27748,6 +28175,8 @@ index 0000000..0a9ff00 + AuDebugOn(!nhash->nh_num || !nhash->nh_head); + + v = 0; ++ if (len > 8) ++ len = 8; + while (len--) + v += *name++; + /* v = hash_long(v, magic_bit); */ @@ -27845,8 +28274,8 @@ index 0000000..0a9ff00 + unsigned char **o; + + err = -ENOMEM; -+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), -+ GFP_NOFS); ++ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS, /*may_shrink*/0); + if (unlikely(!o)) + goto out; + @@ -27916,15 +28345,23 @@ index 0000000..0a9ff00 + +/* ---------------------------------------------------------------------- */ + -+void au_vdir_free(struct au_vdir *vdir) ++void au_vdir_free(struct au_vdir *vdir, int atonce) +{ + unsigned char **deblk; + + deblk = vdir->vd_deblk; -+ while (vdir->vd_nblk--) -+ kfree(*deblk++); -+ kfree(vdir->vd_deblk); -+ au_cache_free_vdir(vdir); ++ if (!atonce) { ++ while (vdir->vd_nblk--) ++ au_delayed_kfree(*deblk++); ++ au_delayed_kfree(vdir->vd_deblk); ++ au_cache_dfree_vdir(vdir); ++ } else { ++ /* not delayed */ ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++ } +} + +static struct au_vdir *alloc_vdir(struct file *file) @@ -27958,10 +28395,10 @@ index 0000000..0a9ff00 + if (!err) + return vdir; /* success */ + -+ kfree(vdir->vd_deblk); ++ au_delayed_kfree(vdir->vd_deblk); + +out_free: -+ au_cache_free_vdir(vdir); ++ au_cache_dfree_vdir(vdir); +out: + vdir = ERR_PTR(err); + return vdir; @@ -27973,7 +28410,7 @@ index 0000000..0a9ff00 + union au_vdir_deblk_p p, deblk_end; + + while (vdir->vd_nblk > 1) { -+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ au_delayed_kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ + vdir->vd_nblk--; + } @@ -28104,7 +28541,7 @@ index 0000000..0a9ff00 + } + } + -+ free_page((unsigned long)o); ++ au_delayed_free_page((unsigned long)o); + +out: + AuTraceErr(err); @@ -28243,7 +28680,7 @@ index 0000000..0a9ff00 + if (allocated) + au_set_ivdir(inode, allocated); + } else if (allocated) -+ au_vdir_free(allocated); ++ au_vdir_free(allocated, /*atonce*/0); + +out: + return err; @@ -28261,8 +28698,8 @@ index 0000000..0a9ff00 + if (tgt->vd_nblk < src->vd_nblk) { + unsigned char **p; + -+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, -+ GFP_NOFS); ++ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS, /*may_shrink*/0); + if (unlikely(!p)) + goto out; + tgt->vd_deblk = p; @@ -28272,7 +28709,8 @@ index 0000000..0a9ff00 + unsigned char *p; + + tgt->vd_deblk_sz = deblk_sz; -+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS); ++ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS, ++ /*may_shrink*/1); + if (unlikely(!p)) + goto out; + tgt->vd_deblk[0] = p; @@ -28337,7 +28775,7 @@ index 0000000..0a9ff00 + if (allocated) + au_set_fvdir_cache(file, allocated); + } else if (allocated) -+ au_vdir_free(allocated); ++ au_vdir_free(allocated, /*atonce*/0); + +out: + return err; @@ -29334,10 +29772,10 @@ index 0000000..2e54bad +} diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h new file mode 100644 -index 0000000..291bfae +index 0000000..64fff0f --- /dev/null +++ b/fs/aufs/vfsub.h -@@ -0,0 +1,297 @@ +@@ -0,0 +1,303 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -29523,6 +29961,12 @@ index 0000000..291bfae + return flags; +} + ++static inline int vfsub_file_execed(struct file *file) ++{ ++ /* todo: direct access f_flags */ ++ return !!(vfsub_file_flags(file) & __FMODE_EXEC); ++} ++ +#if 0 /* reserved */ +static inline void vfsub_file_accessed(struct file *h_file) +{ @@ -29637,7 +30081,7 @@ index 0000000..291bfae +#endif /* __AUFS_VFSUB_H__ */ diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c new file mode 100644 -index 0000000..91a010a +index 0000000..79eb9b4 --- /dev/null +++ b/fs/aufs/wbr_policy.c @@ -0,0 +1,752 @@ @@ -30091,7 +30535,7 @@ index 0000000..91a010a + + mfs->mfsrr_bytes = bavail; + AuDbg("b%d\n", mfs->mfs_bindex); -+ kfree(st); ++ au_delayed_kfree(st); +} + +static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) @@ -30395,7 +30839,7 @@ index 0000000..91a010a +}; diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c new file mode 100644 -index 0000000..16a96f88 +index 0000000..54feb08 --- /dev/null +++ b/fs/aufs/whout.c @@ -0,0 +1,1047 @@ @@ -30550,7 +30994,7 @@ index 0000000..16a96f88 + +out_name: + if (name != defname) -+ kfree(name); ++ au_delayed_kfree(name); +out: + AuTraceErrPtr(dentry); + return dentry; @@ -30989,7 +31433,7 @@ index 0000000..16a96f88 + au_br_put(a->br); + si_write_unlock(a->sb); + au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ kfree(arg); ++ au_delayed_kfree(arg); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} @@ -31017,7 +31461,7 @@ index 0000000..16a96f88 + if (unlikely(wkq_err)) { + atomic_dec(&br->br_wbr->wbr_wh_running); + au_br_put(br); -+ kfree(arg); ++ au_delayed_kfree(arg); + } + do_dec = 0; + } @@ -31176,7 +31620,7 @@ index 0000000..16a96f88 + wh_dentry = ERR_PTR(err); + if (!err) { + wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ kfree(wh_name.name); ++ au_delayed_kfree(wh_name.name); + } + return wh_dentry; +} @@ -31252,7 +31696,7 @@ index 0000000..16a96f88 + break; + } + } -+ free_page((unsigned long)wh_name.name); ++ au_delayed_free_page((unsigned long)wh_name.name); + +out: + return err; @@ -31294,7 +31738,7 @@ index 0000000..16a96f88 + rdhash = AUFS_RDHASH_DEF; + err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); + if (unlikely(err)) { -+ kfree(whtmp); ++ au_delayed_kfree(whtmp); + whtmp = ERR_PTR(err); + } + @@ -31309,7 +31753,7 @@ index 0000000..16a96f88 + dput(whtmp->wh_dentry); + iput(whtmp->dir); + au_nhash_wh_free(&whtmp->whlist); -+ kfree(whtmp); ++ au_delayed_kfree(whtmp); +} + +/* @@ -31526,10 +31970,10 @@ index 0000000..4077dd1 +#endif /* __AUFS_WHOUT_H__ */ diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c new file mode 100644 -index 0000000..65c0137 +index 0000000..216d08f --- /dev/null +++ b/fs/aufs/wkq.c -@@ -0,0 +1,205 @@ +@@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -31573,7 +32017,7 @@ index 0000000..65c0137 + else { + kobject_put(wkinfo->kobj); + module_put(THIS_MODULE); /* todo: ?? */ -+ kfree(wkinfo); ++ au_delayed_kfree(wkinfo); + } +} + @@ -31596,7 +32040,7 @@ index 0000000..65c0137 + +static void au_wkq_comp_free(struct completion *comp) +{ -+ kfree(comp); ++ au_delayed_kfree(comp); +} + +#else @@ -31677,7 +32121,7 @@ index 0000000..65c0137 + int err; + struct au_wkinfo *wkinfo; + -+ percpu_counter_inc(&au_sbi(sb)->si_nowait.nw_len); ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); + + /* + * wkq_func() must free this wkinfo. @@ -31707,16 +32151,11 @@ index 0000000..65c0137 + +void au_nwt_init(struct au_nowait_tasks *nwt) +{ -+ percpu_counter_init(&nwt->nw_len, 0, GFP_NOFS); ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb(); */ /* atomic_set */ + init_waitqueue_head(&nwt->nw_wq); +} + -+void au_nwt_fin(struct au_nowait_tasks *nwt) -+{ -+ AuDebugOn(percpu_counter_sum(&nwt->nw_len)); -+ percpu_counter_destroy(&nwt->nw_len); -+} -+ +void au_wkq_fin(void) +{ + destroy_workqueue(au_wkq); @@ -31737,10 +32176,10 @@ index 0000000..65c0137 +} diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h new file mode 100644 -index 0000000..0b870cc +index 0000000..6d63f74 --- /dev/null +++ b/fs/aufs/wkq.h -@@ -0,0 +1,82 @@ +@@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -31765,7 +32204,7 @@ index 0000000..0b870cc + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue + */ +struct au_nowait_tasks { -+ struct percpu_counter nw_len; ++ atomic_t nw_len; + wait_queue_head_t nw_wq; +}; + @@ -31792,7 +32231,6 @@ index 0000000..0b870cc +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags); +void au_nwt_init(struct au_nowait_tasks *nwt); -+void au_nwt_fin(struct au_nowait_tasks *nwt); +int __init au_wkq_init(void); +void au_wkq_fin(void); + @@ -31810,14 +32248,13 @@ index 0000000..0b870cc + +static inline void au_nwt_done(struct au_nowait_tasks *nwt) +{ -+ percpu_counter_dec(&nwt->nw_len); -+ if (!percpu_counter_sum(&nwt->nw_len)) ++ if (atomic_dec_and_test(&nwt->nw_len)) + wake_up_all(&nwt->nw_wq); +} + +static inline int au_nwt_flush(struct au_nowait_tasks *nwt) +{ -+ wait_event(nwt->nw_wq, !percpu_counter_sum(&nwt->nw_len)); ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); + return 0; +} + @@ -31825,10 +32262,10 @@ index 0000000..0b870cc +#endif /* __AUFS_WKQ_H__ */ diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c new file mode 100644 -index 0000000..c12518f +index 0000000..2a148c9 --- /dev/null +++ b/fs/aufs/xattr.c -@@ -0,0 +1,332 @@ +@@ -0,0 +1,334 @@ +/* + * Copyright (C) 2014-2016 Junjiro R. Okajima + */ @@ -31994,10 +32431,12 @@ index 0000000..c12518f + AuTraceErr(err); + } + -+ kfree(value); ++ if (value) ++ au_delayed_kfree(value); + +out_free: -+ kfree(o); ++ if (o) ++ au_delayed_kfree(o); +out: + if (!unlocked) + inode_unlock(h_isrc); @@ -32163,10 +32602,10 @@ index 0000000..c12518f +#endif diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c new file mode 100644 -index 0000000..4d1d5d4 +index 0000000..2a411f9 --- /dev/null +++ b/fs/aufs/xino.c -@@ -0,0 +1,1304 @@ +@@ -0,0 +1,1305 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -32494,7 +32933,7 @@ index 0000000..4d1d5d4 + AuErr1("statfs err %d, ignored\n", err); + +out_st: -+ kfree(st); ++ au_delayed_kfree(st); +out: + return err; +} @@ -32529,7 +32968,7 @@ index 0000000..4d1d5d4 + au_br_put(br); + si_write_unlock(sb); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(args); ++ au_delayed_kfree(args); +} + +static int xino_trunc_test(struct super_block *sb, struct au_branch *br) @@ -32571,7 +33010,7 @@ index 0000000..4d1d5d4 + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) { + AuErr1("no memory\n"); -+ goto out_args; ++ goto out; + } + + au_br_get(br); @@ -32583,9 +33022,8 @@ index 0000000..4d1d5d4 + + pr_err("wkq %d\n", wkq_err); + au_br_put(br); ++ au_delayed_kfree(args); + -+out_args: -+ kfree(args); +out: + atomic_dec(&br->br_xino_running); +} @@ -33108,7 +33546,7 @@ index 0000000..4d1d5d4 + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); + else + AuDbg("b%d\n", bindex); -+ free_page((unsigned long)page); ++ au_delayed_free_page((unsigned long)page); + +out: + return err; @@ -33185,7 +33623,8 @@ index 0000000..4d1d5d4 + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; -+ free_page((unsigned long)sbinfo->si_xib_buf); ++ if (sbinfo->si_xib_buf) ++ au_delayed_free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; +} + @@ -33228,7 +33667,8 @@ index 0000000..4d1d5d4 + goto out; /* success */ + +out_free: -+ free_page((unsigned long)sbinfo->si_xib_buf); ++ if (sbinfo->si_xib_buf) ++ au_delayed_free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; + if (err >= 0) + err = -EIO; @@ -33321,7 +33761,7 @@ index 0000000..4d1d5d4 + fput(p->new); + else + break; -+ kfree(fpair); ++ au_delayed_kfree(fpair); +out: + return err; +} @@ -33432,7 +33872,7 @@ index 0000000..4d1d5d4 + if (!IS_ERR(file)) + au_xino_brid_set(sb, br->br_id); + } -+ free_page((unsigned long)page); ++ au_delayed_free_page((unsigned long)page); + } else { + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); + if (IS_ERR(file)) @@ -33472,10 +33912,10 @@ index 0000000..4d1d5d4 + return err; +} diff --git a/fs/dcache.c b/fs/dcache.c -index d6847d7..c3c0b6d 100644 +index 5c7cc95..df0268c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1202,7 +1202,7 @@ enum d_walk_ret { +@@ -1164,7 +1164,7 @@ enum d_walk_ret { * * The @enter() and @finish() callbacks are called with d_lock held. */ @@ -33507,10 +33947,10 @@ index 350a2c8..6f42279 100644 return error; diff --git a/fs/inode.c b/fs/inode.c -index 4ccbc21..aa6d071 100644 +index 7e3ef3a..675fe84 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1591,7 +1591,7 @@ EXPORT_SYMBOL(generic_update_time); +@@ -1593,7 +1593,7 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -33520,10 +33960,10 @@ index 4ccbc21..aa6d071 100644 int (*update_time)(struct inode *, struct timespec *, int); diff --git a/fs/proc/base.c b/fs/proc/base.c -index a11eb71..8f10865 100644 +index ac0df4d..42255e5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1939,7 +1939,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) +@@ -1938,7 +1938,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { @@ -33549,7 +33989,7 @@ index f8595e8..cb8eda0 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 4648c7f..061cb85 100644 +index f6fa99e..2750949 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -298,7 +298,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) @@ -33564,7 +34004,7 @@ index 4648c7f..061cb85 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1624,7 +1627,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1634,7 +1637,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) struct proc_maps_private *proc_priv = &numa_priv->proc_maps; struct vm_area_struct *vma = v; struct numa_maps *md = &numa_priv->md; @@ -33590,7 +34030,7 @@ index faacb0c..17b43be 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/fs/read_write.c b/fs/read_write.c -index 933b53a..2d13282 100644 +index 66215a7..a1da117 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -515,6 +515,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, @@ -33663,10 +34103,10 @@ index 7444f5f..bdac0be 100644 static inline void fput_light(struct file *file, int fput_needed) { diff --git a/include/linux/fs.h b/include/linux/fs.h -index dd28814..b689a48 100644 +index 901e25d..a71aa9e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1306,6 +1306,7 @@ extern void fasync_free(struct fasync_struct *); +@@ -1275,6 +1275,7 @@ extern void fasync_free(struct fasync_struct *); /* can be called from interrupts */ extern void kill_fasync(struct fasync_struct **, int, int); @@ -33674,7 +34114,7 @@ index dd28814..b689a48 100644 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern void f_setown(struct file *filp, unsigned long arg, int force); extern void f_delown(struct file *filp); -@@ -1690,6 +1691,7 @@ struct file_operations { +@@ -1699,6 +1700,7 @@ struct file_operations { ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); @@ -33682,7 +34122,7 @@ index dd28814..b689a48 100644 int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -@@ -1750,6 +1752,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, +@@ -1759,6 +1761,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec *fast_pointer, struct iovec **ret_pointer); @@ -33695,7 +34135,7 @@ index dd28814..b689a48 100644 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); -@@ -2105,6 +2113,7 @@ extern int current_umask(void); +@@ -2123,6 +2131,7 @@ extern int current_umask(void); extern void ihold(struct inode * inode); extern void iput(struct inode *); extern int generic_update_time(struct inode *, struct timespec *, int); @@ -33704,10 +34144,10 @@ index dd28814..b689a48 100644 /* /sys/fs */ extern struct kobject *fs_kobj; diff --git a/include/linux/mm.h b/include/linux/mm.h -index ece042d..1e24513 100644 +index ef815b9..a772481 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1239,6 +1239,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, +@@ -1278,6 +1278,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, } #endif @@ -33737,10 +34177,10 @@ index ece042d..1e24513 100644 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, int write); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index ca3e517..10bc491 100644 +index 903200f..55fc528 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -274,6 +274,7 @@ struct vm_region { +@@ -275,6 +275,7 @@ struct vm_region { unsigned long vm_top; /* region allocated to here */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ struct file *vm_file; /* the backing file or NULL */ @@ -33748,7 +34188,7 @@ index ca3e517..10bc491 100644 int vm_usage; /* region usage count (access under nommu_region_sem) */ bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -348,6 +349,7 @@ struct vm_area_struct { +@@ -349,6 +350,7 @@ struct vm_area_struct { unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE units */ struct file * vm_file; /* File we map to (can be NULL). */ @@ -33772,7 +34212,7 @@ index da2751d..2e0fca6 100644 + unsigned int flags); #endif diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index 8bdae34..65dbd5f 100644 +index 185f8ea..5deb0d1 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -59,6 +59,7 @@ header-y += atmsvc.h @@ -33785,7 +34225,7 @@ index 8bdae34..65dbd5f 100644 header-y += auxvec.h diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h new file mode 100644 -index 0000000..4e08bdf +index 0000000..e220283 --- /dev/null +++ b/include/uapi/linux/aufs_type.h @@ -0,0 +1,406 @@ @@ -33817,7 +34257,7 @@ index 0000000..4e08bdf + +#include + -+#define AUFS_VERSION "4.x-rcN" ++#define AUFS_VERSION "4.8" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -34196,10 +34636,10 @@ index 0000000..4e08bdf + +#endif /* __AUFS_TYPE_H__ */ diff --git a/kernel/fork.c b/kernel/fork.c -index 4a7ec0c..8c8f7ac 100644 +index beb3172..ad4cfa8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -479,7 +479,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -477,7 +477,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -34209,10 +34649,10 @@ index 4a7ec0c..8c8f7ac 100644 atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); diff --git a/mm/Makefile b/mm/Makefile -index 78c6f7d..aea4230 100644 +index 2ca1faf..6b9da3f 100644 --- a/mm/Makefile +++ b/mm/Makefile -@@ -37,7 +37,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ +@@ -40,7 +40,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ @@ -34222,10 +34662,10 @@ index 78c6f7d..aea4230 100644 obj-y += init-mm.o diff --git a/mm/filemap.c b/mm/filemap.c -index 20f3b1f..ee827ce 100644 +index 2d0986a..4a31bad 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2208,7 +2208,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +@@ -2284,7 +2284,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) int ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -34235,10 +34675,10 @@ index 20f3b1f..ee827ce 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/memory.c b/mm/memory.c -index cd1f29e..f0c204c 100644 +index 793fe0f..45f39f3 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -2100,7 +2100,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, +@@ -2113,7 +2113,7 @@ static inline int wp_page_reuse(struct fault_env *fe, pte_t orig_pte, } if (!page_mkwrite) @@ -34248,10 +34688,10 @@ index cd1f29e..f0c204c 100644 return VM_FAULT_WRITE; diff --git a/mm/mmap.c b/mm/mmap.c -index de2c176..b7f391c 100644 +index ca9d91b..f3ebc5a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -162,7 +162,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +@@ -163,7 +163,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -34260,7 +34700,7 @@ index de2c176..b7f391c 100644 mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); return next; -@@ -782,7 +782,7 @@ again: remove_next = 1 + (end > next->vm_end); +@@ -790,7 +790,7 @@ again: if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -34269,7 +34709,7 @@ index de2c176..b7f391c 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1563,8 +1563,8 @@ out: +@@ -1574,8 +1574,8 @@ out: return addr; unmap_and_free_vma: @@ -34279,7 +34719,7 @@ index de2c176..b7f391c 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2358,7 +2358,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2380,7 +2380,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -34288,7 +34728,7 @@ index de2c176..b7f391c 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2377,7 +2377,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2399,7 +2399,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -34297,7 +34737,7 @@ index de2c176..b7f391c 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2528,7 +2528,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2550,7 +2550,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -34306,7 +34746,7 @@ index de2c176..b7f391c 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n", current->comm, current->pid); -@@ -2597,10 +2597,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2625,10 +2625,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } } @@ -34335,7 +34775,7 @@ index de2c176..b7f391c 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -2873,7 +2890,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2903,7 +2920,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -34345,7 +34785,7 @@ index de2c176..b7f391c 100644 new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); diff --git a/mm/nommu.c b/mm/nommu.c -index c2e588802..c39edc4 100644 +index 95daf81..5086a29 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -644,7 +644,7 @@ static void __put_nommu_region(struct vm_region *region) diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch new file mode 100644 index 00000000..f7d2ac73 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch @@ -0,0 +1,75 @@ +From 5a920b85f2c6e3fd7d9dd9bb3f3345e9085e2360 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 4 Oct 2016 14:37:32 -0300 +Subject: drm/i915/gen9: fix DDB partitioning for multi-screen cases + +With the previous code we were only recomputing the DDB partitioning +for the CRTCs included in the atomic commit, so any other active CRTCs +would end up having their DDB registers zeroed. In this patch we make +sure that the computed state starts as a copy of the current +partitioning, and then we only zero the DDBs that we're actually +going to recompute. + +How to reproduce the bug: + 1 - Enable the primary plane on pipe A + 2 - Enable the primary plane on pipe B + 3 - Enable the cursor or sprite plane on pipe A + +Step 3 will zero the DDB partitioning for pipe B since it's not +included in the commit that enabled the cursor or sprite for pipe A. + +I expect this to fix many FIFO underrun problems on gen9+. + +v2: + - Mention the cursor on the steps to reproduce the problem (Paulo). + - Add Testcase tag provided by Maarten (Maarten). + +Testcase: kms_cursor_legacy.cursorA-vs-flipB-atomic-transitions +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96226 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96828 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97450 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97596 +Bugzilla: https://www.phoronix.com/scan.php?page=news_item&px=Intel-Skylake-Multi-Screen-Woes +Cc: stable@vger.kernel.org +Signed-off-by: Paulo Zanoni +Reviewed-by: Lyude +Link: http://patchwork.freedesktop.org/patch/msgid/1475602652-17326-1-git-send-email-paulo.r.zanoni@intel.com + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 7f1748a..fe6c1c6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3362,13 +3362,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, + int num_active; + int id, i; + ++ /* Clear the partitioning for disabled planes. */ ++ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); ++ memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); ++ + if (WARN_ON(!state)) + return 0; + + if (!cstate->base.active) { + ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0; +- memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); +- memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); + return 0; + } + +@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state) + intel_state->wm_results.dirty_pipes = ~0; + } + ++ /* ++ * We're not recomputing for the pipes not included in the commit, so ++ * make sure we start with the current state. ++ */ ++ memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); ++ + for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { + struct intel_crtc_state *cstate; + +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch b/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch index cece1d9f..a3e3aa52 100644 --- a/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch +++ b/kernel/kernel/files/patches/mageia/net-add-recursion-limit-to-GRO.patch @@ -1,9 +1,10 @@ - +From fcd91dd449867c6bfe56a81cabba76b829fd05cd Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca - -https://bugzilla.redhat.com/show_bug.cgi?id=1375944 -https://patchwork.ozlabs.org/patch/680412/ - +Date: Thu, 20 Oct 2016 15:58:02 +0200 +Subject: [PATCH] net: add recursion limit to GRO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Currently, GRO can do unlimited recursion through the gro_receive handlers. This was fixed for tunneling protocols by limiting tunnel GRO @@ -13,7 +14,9 @@ receive a packet composed entirely of VLAN headers. This patch adds a recursion counter to the GRO layer to prevent stack overflow. When a gro_receive function hits the recursion limit, GRO is -aborted for this skb and it is processed normally. +aborted for this skb and it is processed normally. This recursion +counter is put in the GRO CB, but could be turned into a percpu counter +if we run out of space in the CB. Thanks to Vladimír Beneš for the initial bug report. @@ -23,10 +26,24 @@ Fixes: 66e5133f19e9 ("vlan: Add GRO support for non hardware accelerated vlan") Signed-off-by: Sabrina Dubroca Reviewed-by: Jiri Benc Acked-by: Hannes Frederic Sowa - +Acked-by: Tom Herbert +Signed-off-by: David S. Miller +--- + drivers/net/geneve.c | 2 +- + drivers/net/vxlan.c | 2 +- + include/linux/netdevice.h | 39 ++++++++++++++++++++++++++++++++++++++- + net/8021q/vlan.c | 2 +- + net/core/dev.c | 1 + + net/ethernet/eth.c | 2 +- + net/ipv4/af_inet.c | 2 +- + net/ipv4/fou.c | 4 ++-- + net/ipv4/gre_offload.c | 2 +- + net/ipv4/udp_offload.c | 2 +- + net/ipv6/ip6_offload.c | 2 +- + 11 files changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c -index 3c20e87bb761..16af1ce99233 100644 +index 3c20e87..16af1ce 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk, @@ -39,7 +56,7 @@ index 3c20e87bb761..16af1ce99233 100644 out_unlock: diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index e7d16687538b..c1639a3e95a4 100644 +index e7d1668..c1639a3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -583,7 +583,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk, @@ -52,7 +69,7 @@ index e7d16687538b..c1639a3e95a4 100644 out: diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 136ae6bbe81e..11a7218c3661 100644 +index 465e128..91ee364 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2169,7 +2169,10 @@ struct napi_gro_cb { @@ -67,7 +84,7 @@ index 136ae6bbe81e..11a7218c3661 100644 /* used to support CHECKSUM_COMPLETE for tunneling protocols */ __wsum csum; -@@ -2180,6 +2183,25 @@ struct napi_gro_cb { +@@ -2180,6 +2183,40 @@ struct napi_gro_cb { #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) @@ -82,19 +99,34 @@ index 136ae6bbe81e..11a7218c3661 100644 + struct sk_buff **head, + struct sk_buff *skb) +{ -+ if (gro_recursion_inc_test(skb)) { ++ if (unlikely(gro_recursion_inc_test(skb))) { + NAPI_GRO_CB(skb)->flush |= 1; + return NULL; + } + + return cb(head, skb); +} ++ ++typedef struct sk_buff **(*gro_receive_sk_t)(struct sock *, struct sk_buff **, ++ struct sk_buff *); ++static inline struct sk_buff **call_gro_receive_sk(gro_receive_sk_t cb, ++ struct sock *sk, ++ struct sk_buff **head, ++ struct sk_buff *skb) ++{ ++ if (unlikely(gro_recursion_inc_test(skb))) { ++ NAPI_GRO_CB(skb)->flush |= 1; ++ return NULL; ++ } ++ ++ return cb(sk, head, skb); ++} + struct packet_type { __be16 type; /* This is really htons(ether_type). */ struct net_device *dev; /* NULL is wildcarded here */ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c -index 8de138d3306b..f2531ad66b68 100644 +index 8de138d..f2531ad 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -664,7 +664,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head, @@ -107,7 +139,7 @@ index 8de138d3306b..f2531ad66b68 100644 out_unlock: rcu_read_unlock(); diff --git a/net/core/dev.c b/net/core/dev.c -index f1fe26f66458..f7cd4b8b035d 100644 +index b09ac57..dbc8713 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4511,6 +4511,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff @@ -119,7 +151,7 @@ index f1fe26f66458..f7cd4b8b035d 100644 NAPI_GRO_CB(skb)->is_atomic = 1; NAPI_GRO_CB(skb)->gro_remcsum_start = 0; diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c -index 66dff5e3d772..02acfff36028 100644 +index 66dff5e..02acfff 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -439,7 +439,7 @@ struct sk_buff **eth_gro_receive(struct sk_buff **head, @@ -132,7 +164,7 @@ index 66dff5e3d772..02acfff36028 100644 out_unlock: rcu_read_unlock(); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 1effc986739e..9648c97e541f 100644 +index 1effc98..9648c97 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1391,7 +1391,7 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) @@ -145,7 +177,7 @@ index 1effc986739e..9648c97e541f 100644 out_unlock: rcu_read_unlock(); diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c -index cf50f7e2b012..030d1531e897 100644 +index cf50f7e..030d153 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -249,7 +249,7 @@ static struct sk_buff **fou_gro_receive(struct sock *sk, @@ -167,7 +199,7 @@ index cf50f7e2b012..030d1531e897 100644 out_unlock: diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c -index 96e0efecefa6..d5cac99170b1 100644 +index 96e0efe..d5cac99 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c @@ -229,7 +229,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head, @@ -180,26 +212,20 @@ index 96e0efecefa6..d5cac99170b1 100644 out_unlock: diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c -index f9333c963607..7b5879bcd08b 100644 +index f9333c9..b2be1d9 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c -@@ -295,7 +295,13 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb, +@@ -295,7 +295,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb, skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */ skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); - pp = udp_sk(sk)->gro_receive(sk, head, skb); -+ -+ if (gro_recursion_inc_test(skb)) { -+ flush = 1; -+ pp = NULL; -+ } else { -+ pp = udp_sk(sk)->gro_receive(sk, head, skb); -+ } ++ pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb); out_unlock: rcu_read_unlock(); diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c -index e7bfd55899a3..1fcf61f1cbc3 100644 +index e7bfd55..1fcf61f 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -246,7 +246,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, @@ -211,3 +237,6 @@ index e7bfd55899a3..1fcf61f1cbc3 100644 out_unlock: rcu_read_unlock(); +-- +2.10.1 + diff --git a/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch b/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch index 536fce2e..c251e081 100644 --- a/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch +++ b/kernel/kernel/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch @@ -1,5 +1,7 @@ - +From cf4747d7535a936105f0abe8d8109d3fe339162b Mon Sep 17 00:00:00 2001 From: Larry Finger +Date: Wed, 12 Oct 2016 13:54:04 -0500 +Subject: [PATCH] rtlwifi: Fix regression caused by commit d86e64768859 In commit d86e64768859 ("rtlwifi: rtl818x: constify local structures"), the configuration struct for most of the drivers was changed to be @@ -19,11 +21,9 @@ previous patch, is now constantfied. Fixes: d86e64768859 ("rtlwifi: rtl818x: constify local structures") Suggested-by: Johannes Berg Signed-off-by: Larry Finger -Cc: Stable +Cc: Stable # 4.8 Cc: Julia Lawall ---- - -V2 - Fix warnings that were generated for some compiler versions. +Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/core.c | 2 +- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 8 ++++---- @@ -86,10 +86,10 @@ index e7b11b4..f361808 100644 .mod_params = &rtl88ee_mod_params, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c -index 5c46a98..691ddef 100644 +index 87aa209..8b6e37c 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c -@@ -92,6 +92,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) +@@ -96,6 +96,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -97,7 +97,7 @@ index 5c46a98..691ddef 100644 rtl8192ce_bt_reg_init(hw); -@@ -163,15 +164,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) +@@ -167,15 +168,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) } /* request fw */ @@ -117,7 +117,7 @@ index 5c46a98..691ddef 100644 rtlpriv->io.dev, GFP_KERNEL, hw, rtl_fw_cb); if (err) { -@@ -258,7 +256,6 @@ static const struct rtl_hal_cfg rtl92ce_hal_cfg = { +@@ -262,7 +260,6 @@ static const struct rtl_hal_cfg rtl92ce_hal_cfg = { .bar_id = 2, .write_readback = true, .name = "rtl92c_pci", @@ -126,10 +126,10 @@ index 5c46a98..691ddef 100644 .mod_params = &rtl92ce_mod_params, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c -index 92588e0..b84e13a 100644 +index 7c6f7f0..f953320 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c -@@ -55,6 +55,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) +@@ -59,6 +59,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); int err; @@ -137,7 +137,7 @@ index 92588e0..b84e13a 100644 rtlpriv->dm.dm_initialgain_enable = true; rtlpriv->dm.dm_flag = 0; -@@ -73,18 +74,18 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) +@@ -77,18 +78,18 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) } if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { @@ -161,7 +161,7 @@ index 92588e0..b84e13a 100644 GFP_KERNEL, hw, rtl_fw_cb); return err; } -@@ -183,7 +184,6 @@ static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { +@@ -187,7 +188,6 @@ static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { static struct rtl_hal_cfg rtl92cu_hal_cfg = { .name = "rtl92c_usb", @@ -170,10 +170,10 @@ index 92588e0..b84e13a 100644 .mod_params = &rtl92cu_mod_params, .usb_interface_cfg = &rtl92cu_interface_cfg, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c -index a9c39eb..2d65e40 100644 +index 0538a4d..1ebfee1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c -@@ -88,6 +88,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) +@@ -92,6 +92,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -181,7 +181,7 @@ index a9c39eb..2d65e40 100644 rtlpriv->dm.dm_initialgain_enable = true; rtlpriv->dm.dm_flag = 0; -@@ -177,10 +178,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) +@@ -181,10 +182,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->max_fw_size = 0x8000; pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); @@ -194,7 +194,7 @@ index a9c39eb..2d65e40 100644 rtlpriv->io.dev, GFP_KERNEL, hw, rtl_fw_cb); if (err) { -@@ -262,7 +263,6 @@ static const struct rtl_hal_cfg rtl92de_hal_cfg = { +@@ -266,7 +267,6 @@ static const struct rtl_hal_cfg rtl92de_hal_cfg = { .bar_id = 2, .write_readback = true, .name = "rtl8192de", @@ -238,10 +238,10 @@ index ac299cb..46b605de3 100644 .mod_params = &rtl92ee_mod_params, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c -index a652d45..998cefb 100644 +index 5e8e02d..3e1eaea 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c -@@ -85,12 +85,13 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) +@@ -89,12 +89,13 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) struct ieee80211_hw *hw = context; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rt_firmware *pfirmware = NULL; @@ -256,7 +256,7 @@ index a652d45..998cefb 100644 rtlpriv->max_fw_size = 0; return; } -@@ -113,6 +114,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) +@@ -117,6 +118,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); int err = 0; u16 earlyrxthreshold = 7; @@ -264,7 +264,7 @@ index a652d45..998cefb 100644 rtlpriv->dm.dm_initialgain_enable = true; rtlpriv->dm.dm_flag = 0; -@@ -210,9 +212,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) +@@ -214,9 +216,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 + sizeof(struct fw_hdr); pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" @@ -276,7 +276,7 @@ index a652d45..998cefb 100644 rtlpriv->io.dev, GFP_KERNEL, hw, rtl92se_fw_cb); if (err) { -@@ -306,7 +308,6 @@ static const struct rtl_hal_cfg rtl92se_hal_cfg = { +@@ -310,7 +312,6 @@ static const struct rtl_hal_cfg rtl92se_hal_cfg = { .bar_id = 1, .write_readback = false, .name = "rtl92s_pci", @@ -424,3 +424,6 @@ index 595f7d5..dafe486 100644 struct rtl_hal_ops *ops; struct rtl_mod_params *mod_params; struct rtl_hal_usbint_cfg *usb_interface_cfg; +-- +2.10.1 + diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series index 5f3d0487..e7a005b7 100644 --- a/kernel/kernel/files/patches/mageia/series +++ b/kernel/kernel/files/patches/mageia/series @@ -14,86 +14,6 @@ ### ### Stable Queue ### -stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch -stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch -stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch -stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch -stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch -stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch -stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch -stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch -stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch -stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch -stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch -stable-drm-radeon-narrow-asic_init-for-virtualization.patch -stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch -stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch -stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch -stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch -stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch -stable-hid-add-quirk-for-akai-midimix.patch -stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch -stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch -stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch -stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch -stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch -stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch -stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch -stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch -stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch -stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch -stable-drm-i915-introduce-intel_has_sagv.patch -stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch -stable-revert-drm-i915-check-live-status-before-reading-edid.patch -stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch -stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch -stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch -stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch -stable-drm-i915-allow-dp-to-work-w-o-edid.patch -stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch -stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch -stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch -stable-rt2x00usb-fix-error-return-code.patch -stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch -stable-genirq-generic_chip-add-irq_unmap-callback.patch -stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch -stable-uio-fix-dmem_region_start-computation.patch -stable-arm-clk-imx35-fix-name-for-ckil-clk.patch -stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch -stable-i40e-remove-a-stray-unlock.patch -stable-i40e-fix-broken-i40e_config_rss_aq-function.patch -stable-mwifiex-correct-aid-value-during-tdls-setup.patch -stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch -stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch -stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch -stable-ath10k-fix-reporting-channel-survey-data.patch -stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch -stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch -stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch -stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch -stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch -stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch -stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch -stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch -stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch -stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch -stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch -stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch -stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch -stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch -stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch -stable-staging-android-ion-hisi-fix-dependencies.patch -stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch -stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch -stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch -stable-staging-ks7010-declare-private-functions-static.patch -stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch -stable-ib-rdmavt-correct-sparse-annotation.patch -stable-ib-qib-remove-qpt_mask-global.patch -stable-ib-mlx5-fix-steering-resource-leak.patch -stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch -stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch -stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch ### ### Arch x86 @@ -121,6 +41,9 @@ Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch # breaks nvidia304 Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch +# fix non-booting systems +x86-smpboot-Init-apic-mapping-before-usage.patch + ### ### Core ### @@ -216,6 +139,9 @@ nvmepatch1-V4.patch nvmepatch2-V4.patch nvmepatch3-V4.patch +# fix feature check, reported on dev@ ml +dm-raid-fix-compat_features-validation.patch + ### ### Char ### @@ -228,9 +154,8 @@ Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch ### # aufs from: http://aufs.sourceforge.net/ (mga#8314) -fs-aufs-4.7.patch -fs-aufs-4.7-modular.patch -fs-aufs-4.7-ver-fix.patch +fs-aufs-4.8.patch +fs-aufs-4.8-modular.patch ### ### FireWire @@ -270,7 +195,8 @@ gpu-drm-mach64-3.18-buildfix.patch # also from https://bugs.freedesktop.org/attachment.cgi?id=127264, first reference from # https://bugs.freedesktop.org/show_bug.cgi?id=97450). Does not completely resolve the # issues but reduce. -drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch +# now in drm-next: https://cgit.freedesktop.org/~airlied/linux/commit?h=drm-next&id=5a920b85f2c6e3fd7d9dd9bb3f3345e9085e2360 +gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch ### ### Hardware Monitoring diff --git a/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch b/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch deleted file mode 100644 index 04c91a98..00000000 --- a/kernel/kernel/files/patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch +++ /dev/null @@ -1,37 +0,0 @@ -From fcff03813a7c612873303037cef5ba0329850c35 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= -Date: Thu, 8 Sep 2016 11:30:21 +0200 -Subject: ARM: clk-imx35: fix name for ckil clk -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Uwe Kleine-König - -commit fcff03813a7c612873303037cef5ba0329850c35 upstream. - -This fixes - [ 0.000000] i.MX clk 82: register failed with -17 -because the name is duplicated. - -Signed-off-by: Uwe Kleine-König -Fixes: 3713e3f5e927 ("clk: imx35: define two clocks for rtc") -Acked-by: Shawn Guo -Signed-off-by: Stephen Boyd -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/clk/imx/clk-imx35.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/clk/imx/clk-imx35.c -+++ b/drivers/clk/imx/clk-imx35.c -@@ -115,7 +115,7 @@ static void __init _mx35_clocks_init(voi - } - - clk[ckih] = imx_clk_fixed("ckih", 24000000); -- clk[ckil] = imx_clk_fixed("ckih", 32768); -+ clk[ckil] = imx_clk_fixed("ckil", 32768); - clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); - clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); - diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch deleted file mode 100644 index d7cd051d..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a3930ed060df4ccf2a06cf0b68738dec3e6ff89a Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Sat, 27 Aug 2016 19:28:00 +0800 -Subject: ASoC: dapm: Fix kcontrol creation for output driver widget - -From: Chen-Yu Tsai - -commit a3930ed060df4ccf2a06cf0b68738dec3e6ff89a upstream. - -Commit d88429a695a4 ("ASoC: dapm: Add output driver widget") added -the snd_soc_dapm_out_drv ID for the output driver widget, which is -the same as the PGA widget, with a later power sequence number. - -Commit 19a2557b76d6 ("ASoC: dapm: Add kcontrol support for PGAs") -then added kcontrol support for PGA widgets, but failed to account -for output driver widgets. Attempts to use kcontrols with output -driver widgets result in silent failures, with the developer having -little idea about what went on. - -Add snd_soc_dapm_out_drv to the switch/case block under snd_soc_dapm_pga -in dapm_create_or_share_kcontrol, since they are essentially the same. - -Fixes: 19a2557b76d6 (ASoC: dapm: Add kcontrol support for PGAs) -Signed-off-by: Chen-Yu Tsai -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/soc-dapm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - case snd_soc_dapm_pga: -+ case snd_soc_dapm_out_drv: - wname_in_long_name = true; - kcname_in_long_name = true; - break; diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch deleted file mode 100644 index 014bcdc0..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 01ad5e7de67b408d9b48b437b06a9938ddf460b5 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Sat, 27 Aug 2016 19:27:58 +0800 -Subject: ASoC: dapm: Fix possible uninitialized variable in snd_soc_dapm_get_volsw() - -From: Chen-Yu Tsai - -commit 01ad5e7de67b408d9b48b437b06a9938ddf460b5 upstream. - -If soc_dapm_read() fails, val will be uninitialized, and bogus values -will be written later: - - ret = soc_dapm_read(dapm, reg, &val); - val = (val >> shift) & mask; - -However, the compiler does not give a warning. Return on error before -val is really used to avoid this. - -This is similar to the commit 6912831623c5 ("ASoC: dapm: Fix -uninitialized variable in snd_soc_dapm_get_enum_double()") - -Fixes: ce0fc93ae56e (ASoC: Add DAPM support at the component level) -Signed-off-by: Chen-Yu Tsai -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/soc-dapm.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kc - } - mutex_unlock(&card->dapm_mutex); - -+ if (ret) -+ return ret; -+ - if (invert) - ucontrol->value.integer.value[0] = max - val; - else diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch b/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch deleted file mode 100644 index 737cd33e..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 071133a209354f39d4e5785d5a6a390e03241841 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Sat, 27 Aug 2016 19:27:59 +0800 -Subject: ASoC: dapm: Fix value setting for _ENUM_DOUBLE MUX's second channel - -From: Chen-Yu Tsai - -commit 071133a209354f39d4e5785d5a6a390e03241841 upstream. - -The value for the second channel in _ENUM_DOUBLE (double channel) MUXs -is not correctly updated, due to using the wrong bit shift. - -Use the correct bit shift, so both channels toggle together. - -Fixes: 3727b4968453 (ASoC: dapm: Consolidate MUXs and value MUXs) -Signed-off-by: Chen-Yu Tsai -Reviewed-by: Charles Keepax -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/soc-dapm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -3203,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct - if (e->shift_l != e->shift_r) { - if (item[1] > e->items) - return -EINVAL; -- val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; -+ val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; - mask |= e->mask << e->shift_r; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch deleted file mode 100644 index 610d3216..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 43d443dc257c00ef3a3f940b6abfb7537c4fcbe8 Mon Sep 17 00:00:00 2001 -From: Takashi Sakamoto -Date: Tue, 27 Sep 2016 07:45:09 +0900 -Subject: ASoC: sst-bxt-da7219_max98357a: fix obsoleted initializers for array - -From: Takashi Sakamoto - -commit 43d443dc257c00ef3a3f940b6abfb7537c4fcbe8 upstream. - -Sparse reports below warnings. - -bxt_da7219_max98357a.c:250:9: warning: obsolete array initializer, use C99 syntax -bxt_da7219_max98357a.c:275:9: warning: obsolete array initializer, use C99 syntax -bxt_da7219_max98357a.c:290:9: warning: obsolete array initializer, use C99 syntax -bxt_da7219_max98357a.c:304:9: warning: obsolete array initializer, use C99 syntax -bxt_da7219_max98357a.c:317:9: warning: obsolete array initializer, use C99 syntax - -There's no need to use obsoleted way. This commit fixes it. - -Fixes: 723bad3fef8b (ASoC: Intel: Add Broxton-P Dialog Maxim machine driver) -Signed-off-by: Takashi Sakamoto -Acked-by: Vinod Koul -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/intel/boards/bxt_da7219_max98357a.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/sound/soc/intel/boards/bxt_da7219_max98357a.c -+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c -@@ -255,7 +255,7 @@ static struct snd_soc_ops broxton_da7219 - /* broxton digital audio interface glue - connects codec <--> CPU */ - static struct snd_soc_dai_link broxton_dais[] = { - /* Front End DAI links */ -- [BXT_DPCM_AUDIO_PB] -+ [BXT_DPCM_AUDIO_PB] = - { - .name = "Bxt Audio Port", - .stream_name = "Audio", -@@ -271,7 +271,7 @@ static struct snd_soc_dai_link broxton_d - .dpcm_playback = 1, - .ops = &broxton_da7219_fe_ops, - }, -- [BXT_DPCM_AUDIO_CP] -+ [BXT_DPCM_AUDIO_CP] = - { - .name = "Bxt Audio Capture Port", - .stream_name = "Audio Record", -@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_d - .dpcm_capture = 1, - .ops = &broxton_da7219_fe_ops, - }, -- [BXT_DPCM_AUDIO_REF_CP] -+ [BXT_DPCM_AUDIO_REF_CP] = - { - .name = "Bxt Audio Reference cap", - .stream_name = "Refcap", -@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_d - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_HDMI1_PB] -+ [BXT_DPCM_AUDIO_HDMI1_PB] = - { - .name = "Bxt HDMI Port1", - .stream_name = "Hdmi1", -@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_d - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_HDMI2_PB] -+ [BXT_DPCM_AUDIO_HDMI2_PB] = - { - .name = "Bxt HDMI Port2", - .stream_name = "Hdmi2", -@@ -326,7 +326,7 @@ static struct snd_soc_dai_link broxton_d - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_HDMI3_PB] -+ [BXT_DPCM_AUDIO_HDMI3_PB] = - { - .name = "Bxt HDMI Port3", - .stream_name = "Hdmi3", diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch b/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch deleted file mode 100644 index 9d9c7243..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 5919a3898136aae4d2cb4b18b44f70f7b185aa47 Mon Sep 17 00:00:00 2001 -From: Takashi Sakamoto -Date: Tue, 27 Sep 2016 07:45:08 +0900 -Subject: ASoC: sst-bxt-rt298: fix obsoleted initializers for array - -From: Takashi Sakamoto - -commit 5919a3898136aae4d2cb4b18b44f70f7b185aa47 upstream. - -Sparse reports below warnings. - -bxt_rt298.c:275:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:290:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:304:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:317:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:331:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:344:9: warning: obsolete array initializer, use C99 syntax -bxt_rt298.c:357:9: warning: obsolete array initializer, use C99 syntax - -There's no need to use obsoleted way. This commit fixes it. - -Fixes: 76016322ec56 (ASoC: Intel: Add Broxton-P machine driver) -Signed-off-by: Takashi Sakamoto -Acked-by: Vinod Koul -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/intel/boards/bxt_rt298.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/sound/soc/intel/boards/bxt_rt298.c -+++ b/sound/soc/intel/boards/bxt_rt298.c -@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_ - /* broxton digital audio interface glue - connects codec <--> CPU */ - static struct snd_soc_dai_link broxton_rt298_dais[] = { - /* Front End DAI links */ -- [BXT_DPCM_AUDIO_PB] -+ [BXT_DPCM_AUDIO_PB] = - { - .name = "Bxt Audio Port", - .stream_name = "Audio", -@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_r - .dpcm_playback = 1, - .ops = &broxton_rt286_fe_ops, - }, -- [BXT_DPCM_AUDIO_CP] -+ [BXT_DPCM_AUDIO_CP] = - { - .name = "Bxt Audio Capture Port", - .stream_name = "Audio Record", -@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_r - .dpcm_capture = 1, - .ops = &broxton_rt286_fe_ops, - }, -- [BXT_DPCM_AUDIO_REF_CP] -+ [BXT_DPCM_AUDIO_REF_CP] = - { - .name = "Bxt Audio Reference cap", - .stream_name = "refcap", -@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_r - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_DMIC_CP] -+ [BXT_DPCM_AUDIO_DMIC_CP] = - { - .name = "Bxt Audio DMIC cap", - .stream_name = "dmiccap", -@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_r - .dynamic = 1, - .ops = &broxton_dmic_ops, - }, -- [BXT_DPCM_AUDIO_HDMI1_PB] -+ [BXT_DPCM_AUDIO_HDMI1_PB] = - { - .name = "Bxt HDMI Port1", - .stream_name = "Hdmi1", -@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_r - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_HDMI2_PB] -+ [BXT_DPCM_AUDIO_HDMI2_PB] = - { - .name = "Bxt HDMI Port2", - .stream_name = "Hdmi2", -@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_r - .nonatomic = 1, - .dynamic = 1, - }, -- [BXT_DPCM_AUDIO_HDMI3_PB] -+ [BXT_DPCM_AUDIO_HDMI3_PB] = - { - .name = "Bxt HDMI Port3", - .stream_name = "Hdmi3", diff --git a/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch b/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch deleted file mode 100644 index f029224c..00000000 --- a/kernel/kernel/files/patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8ae3ea48df0d746b663057cf0b972a18d0777b7b Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Wed, 10 Aug 2016 13:43:12 +0000 -Subject: ASoC: topology: Fix error return code in soc_tplg_dapm_widget_create() - -From: Wei Yongjun - -commit 8ae3ea48df0d746b663057cf0b972a18d0777b7b upstream. - -Fix to return error code -ENOMEM instead of 0 when failed to create -widget, as done elsewhere in this function. - -Fixes: 8a9782346dcc ("ASoC: topology: Add topology core") -Signed-off-by: Wei Yongjun -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - sound/soc/soc-topology.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/sound/soc/soc-topology.c -+++ b/sound/soc/soc-topology.c -@@ -1475,6 +1475,7 @@ widget: - if (widget == NULL) { - dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", - w->name); -+ ret = -ENOMEM; - goto hdr_err; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch deleted file mode 100644 index d29be132..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 64ed5771aca2fcfb8ea440fc679741054011fd7e Mon Sep 17 00:00:00 2001 -From: Tamizh chelvam -Date: Tue, 2 Aug 2016 16:13:14 +0530 -Subject: ath10k: Add WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT wmi service - -From: Tamizh chelvam - -commit 64ed5771aca2fcfb8ea440fc679741054011fd7e upstream. - -WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT service has missed in -the commit 7e247a9e88dc ("ath10k: add dynamic tx mode switch -config support for qca4019"). This patch adds the service to -avoid mismatch between host and target. - -Fixes: 7e247a9e88dc ("ath10k: add dynamic tx mode switch config support for qca4019") -Signed-off-by: Tamizh chelvam -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/ath/ath10k/wmi.h | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/wireless/ath/ath10k/wmi.h -+++ b/drivers/net/wireless/ath/ath10k/wmi.h -@@ -180,6 +180,7 @@ enum wmi_service { - WMI_SERVICE_MESH_NON_11S, - WMI_SERVICE_PEER_STATS, - WMI_SERVICE_RESTRT_CHNL_SUPPORT, -+ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, - WMI_SERVICE_TX_MODE_PUSH_ONLY, - WMI_SERVICE_TX_MODE_PUSH_PULL, - WMI_SERVICE_TX_MODE_DYNAMIC, -@@ -305,6 +306,7 @@ enum wmi_10_4_service { - WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT, - WMI_10_4_SERVICE_PEER_STATS, - WMI_10_4_SERVICE_MESH_11S, -+ WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, - WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, - WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, - WMI_10_4_SERVICE_TX_MODE_DYNAMIC, -@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int - SVCSTR(WMI_SERVICE_MESH_NON_11S); - SVCSTR(WMI_SERVICE_PEER_STATS); - SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT); -+ SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT); - SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY); - SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL); - SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC); -@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(cons - WMI_SERVICE_PEER_STATS, len); - SVCMAP(WMI_10_4_SERVICE_MESH_11S, - WMI_SERVICE_MESH_11S, len); -+ SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, -+ WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len); - SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, - WMI_SERVICE_TX_MODE_PUSH_ONLY, len); - SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch deleted file mode 100644 index 463c00aa..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 77eb3d693182b4eaa88c6ba406fbb92b1f1bd636 Mon Sep 17 00:00:00 2001 -From: Ashok Raj Nagarajan -Date: Fri, 2 Sep 2016 10:59:53 +0530 -Subject: ath10k: fix reporting channel survey data - -From: Ashok Raj Nagarajan - -commit 77eb3d693182b4eaa88c6ba406fbb92b1f1bd636 upstream. - -When user requests for survey dump data, driver is providing wrong survey -information. This information we sent is the survey data that we have -collected during previous user request. - -This issue occurs because we request survey dump for wrong channel. With -this change, we correctly display the correct and current survey -information to userspace. - -Fixes: fa7937e3d5c2 ("ath10k: update bss channel survey information") -Signed-off-by: Ashok Raj Nagarajan -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/ath/ath10k/mac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -6558,7 +6558,7 @@ static int ath10k_get_survey(struct ieee - goto exit; - } - -- ath10k_mac_update_bss_chan_survey(ar, survey->channel); -+ ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]); - - spin_lock_bh(&ar->data_lock); - memcpy(survey, ar_survey, sizeof(*survey)); diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch deleted file mode 100644 index 4e94923d..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch +++ /dev/null @@ -1,81 +0,0 @@ -From e4fd726f21cdae0dc9cea6cbfcb7e27f21393f88 Mon Sep 17 00:00:00 2001 -From: Ashok Raj Nagarajan -Date: Thu, 18 Aug 2016 15:30:04 +0530 -Subject: ath10k: fix sending frame in management path in push txq logic - -From: Ashok Raj Nagarajan - -commit e4fd726f21cdae0dc9cea6cbfcb7e27f21393f88 upstream. - -In the wake tx queue path, we are not checking if the frame to be sent -takes management path or not. For eg. QOS null func frame coming here will -take the management path. Since we are not incrementing the descriptor -counter (num_pending_mgmt_tx) w.r.t tx management, on tx completion it is -possible to see negative values. - -When the above counter reaches a negative value, we will not be sending a -probe response out. - - if (is_presp && - ar->hw_params.max_probe_resp_desc_thres < htt->num_pending_mgmt_tx) - -For IPQ4019, max_probe_resp_desc_thres (u32) is 24 is compared against -num_pending_mgmt_tx (int) and the above condtions comes true if the counter -is negative and we drop the probe response. - -To avoid this, check on the wake tx queue path as well for the tx path of -the frame and increment the appropriate counters - -Fixes: cac085524cf1 "ath10k: move mgmt descriptor limit handle under mgmt_tx" -Signed-off-by: Ashok Raj Nagarajan -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -3777,7 +3777,9 @@ int ath10k_mac_tx_push_txq(struct ieee80 - enum ath10k_hw_txrx_mode txmode; - enum ath10k_mac_tx_path txpath; - struct sk_buff *skb; -+ struct ieee80211_hdr *hdr; - size_t skb_len; -+ bool is_mgmt, is_presp; - int ret; - - spin_lock_bh(&ar->htt.tx_lock); -@@ -3801,6 +3803,22 @@ int ath10k_mac_tx_push_txq(struct ieee80 - skb_len = skb->len; - txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); - txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); -+ is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT); -+ -+ if (is_mgmt) { -+ hdr = (struct ieee80211_hdr *)skb->data; -+ is_presp = ieee80211_is_probe_resp(hdr->frame_control); -+ -+ spin_lock_bh(&ar->htt.tx_lock); -+ ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp); -+ -+ if (ret) { -+ ath10k_htt_tx_dec_pending(htt); -+ spin_unlock_bh(&ar->htt.tx_lock); -+ return ret; -+ } -+ spin_unlock_bh(&ar->htt.tx_lock); -+ } - - ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb); - if (unlikely(ret)) { -@@ -3808,6 +3826,8 @@ int ath10k_mac_tx_push_txq(struct ieee80 - - spin_lock_bh(&ar->htt.tx_lock); - ath10k_htt_tx_dec_pending(htt); -+ if (is_mgmt) -+ ath10k_htt_tx_mgmt_dec_pending(htt); - spin_unlock_bh(&ar->htt.tx_lock); - - return ret; diff --git a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch b/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch deleted file mode 100644 index 965cd1a1..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 18f53fe0f30331e826b075709ed7b26b9283235e Mon Sep 17 00:00:00 2001 -From: Rajkumar Manoharan -Date: Fri, 2 Sep 2016 19:46:10 +0300 -Subject: ath10k: fix throughput regression in multi client mode - -From: Rajkumar Manoharan - -commit 18f53fe0f30331e826b075709ed7b26b9283235e upstream. - -commit 7a0adc83f34d ("ath10k: improve tx scheduling") is causing -severe throughput drop in multi client mode. This issue is originally -reported in veriwave setup with 50 clients with TCP downlink traffic. -While increasing number of clients, the average throughput drops -gradually. With 50 clients, the combined peak throughput is decreased -to 98 Mbps whereas reverting given commit restored it to 550 Mbps. - -Processing txqs for every tx completion is causing overhead. Ideally for -management frame tx completion, pending txqs processing can be avoided. -The change partly reverts the commit "ath10k: improve tx scheduling". -Processing pending txqs after all skbs tx completion will yeild enough -room to burst tx frames. - -Fixes: 7a0adc83f34d ("ath10k: improve tx scheduling") -Signed-off-by: Rajkumar Manoharan -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/ath/ath10k/htt_rx.c | 2 ++ - drivers/net/wireless/ath/ath10k/txrx.c | 2 -- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath10k/htt_rx.c -+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -@@ -2394,6 +2394,8 @@ static void ath10k_htt_txrx_compl_task(u - skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q); - spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags); - -+ ath10k_mac_tx_push_pending(ar); -+ - spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); - skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); - spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); ---- a/drivers/net/wireless/ath/ath10k/txrx.c -+++ b/drivers/net/wireless/ath/ath10k/txrx.c -@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_h - ieee80211_tx_status(htt->ar->hw, msdu); - /* we do not own the msdu anymore */ - -- ath10k_mac_tx_push_pending(ar); -- - return 0; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch b/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch deleted file mode 100644 index b3e6eb41..00000000 --- a/kernel/kernel/files/patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 481e46fe7a88557b66330cbb047b25cc13eff4b9 Mon Sep 17 00:00:00 2001 -From: Suzuki K Poulose -Date: Thu, 25 Aug 2016 15:18:54 -0600 -Subject: coresight: Remove erroneous dma_free_coherent in tmc_probe - -From: Suzuki K Poulose - -commit 481e46fe7a88557b66330cbb047b25cc13eff4b9 upstream. - -commit de5461970b3e9e194 ("coresight: tmc: allocating memory when needed") -removed the static allocation of buffer for the trace data in ETR mode in -tmc_probe. However it failed to remove the "devm_free_coherent" in -tmc_probe when the probe fails due to other reasons. This patch gets -rid of the incorrect dma_free_coherent() call. - -Fixes: commit de5461970b3e9e194 ("coresight: tmc: allocating memory when needed") -Cc: Mathieu Poirier -Signed-off-by: Suzuki K Poulose -Signed-off-by: Mathieu Poirier -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/hwtracing/coresight/coresight-tmc.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/hwtracing/coresight/coresight-tmc.c -+++ b/drivers/hwtracing/coresight/coresight-tmc.c -@@ -388,9 +388,6 @@ static int tmc_probe(struct amba_device - err_misc_register: - coresight_unregister(drvdata->csdev); - err_devm_kzalloc: -- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) -- dma_free_coherent(dev, drvdata->size, -- drvdata->vaddr, drvdata->paddr); - return ret; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch b/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch deleted file mode 100644 index 5253ef79..00000000 --- a/kernel/kernel/files/patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ed4767d612fd2c39e2c4c69eba484c1219dcddb6 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Thu, 1 Sep 2016 14:25:42 +0100 -Subject: crypto: arm/ghash-ce - add missing async import/export - -From: Ard Biesheuvel - -commit ed4767d612fd2c39e2c4c69eba484c1219dcddb6 upstream. - -Since commit 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero"), -all ahash drivers are required to implement import()/export(), and must have -a non-zero statesize. Fix this for the ARM Crypto Extensions GHASH -implementation. - -Fixes: 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero") -Signed-off-by: Ard Biesheuvel -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - arch/arm/crypto/ghash-ce-glue.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/arch/arm/crypto/ghash-ce-glue.c -+++ b/arch/arm/crypto/ghash-ce-glue.c -@@ -220,6 +220,27 @@ static int ghash_async_digest(struct aha - } - } - -+static int ghash_async_import(struct ahash_request *req, const void *in) -+{ -+ struct ahash_request *cryptd_req = ahash_request_ctx(req); -+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); -+ struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm); -+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); -+ -+ desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm); -+ desc->flags = req->base.flags; -+ -+ return crypto_shash_import(desc, in); -+} -+ -+static int ghash_async_export(struct ahash_request *req, void *out) -+{ -+ struct ahash_request *cryptd_req = ahash_request_ctx(req); -+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); -+ -+ return crypto_shash_export(desc, out); -+} -+ - static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key, - unsigned int keylen) - { -@@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg - .final = ghash_async_final, - .setkey = ghash_async_setkey, - .digest = ghash_async_digest, -+ .import = ghash_async_import, -+ .export = ghash_async_export, - .halg.digestsize = GHASH_DIGEST_SIZE, -+ .halg.statesize = sizeof(struct ghash_desc_ctx), - .halg.base = { - .cra_name = "ghash", - .cra_driver_name = "ghash-ce", diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch b/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch deleted file mode 100644 index 2685ecb5..00000000 --- a/kernel/kernel/files/patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7514e3688811e610640ec2201ca14dfebfe13442 Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Sat, 17 Sep 2016 16:01:22 +0000 -Subject: crypto: ccp - Fix return value check in ccp_dmaengine_register() - -From: Wei Yongjun - -commit 7514e3688811e610640ec2201ca14dfebfe13442 upstream. - -Fix the retrn value check which testing the wrong variable -in ccp_dmaengine_register(). - -Fixes: 58ea8abf4904 ("crypto: ccp - Register the CCP as a DMA resource") -Signed-off-by: Wei Yongjun -Acked-by: Gary R Hook -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/crypto/ccp/ccp-dmaengine.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/crypto/ccp/ccp-dmaengine.c -+++ b/drivers/crypto/ccp/ccp-dmaengine.c -@@ -650,7 +650,7 @@ int ccp_dmaengine_register(struct ccp_de - dma_desc_cache_name = devm_kasprintf(ccp->dev, GFP_KERNEL, - "%s-dmaengine-desc-cache", - ccp->name); -- if (!dma_cmd_cache_name) -+ if (!dma_desc_cache_name) - return -ENOMEM; - ccp->dma_desc_cache = kmem_cache_create(dma_desc_cache_name, - sizeof(struct ccp_dma_desc), diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch b/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch deleted file mode 100644 index 7a66373f..00000000 --- a/kernel/kernel/files/patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 50d2e6dc1f83db0563c7d6603967bf9585ce934b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ondrej=20Mosn=C3=A1=C4=8Dek?= -Date: Fri, 23 Sep 2016 10:47:32 +0200 -Subject: crypto: gcm - Fix IV buffer size in crypto_gcm_setkey - -From: Ondrej Mosnáček - -commit 50d2e6dc1f83db0563c7d6603967bf9585ce934b upstream. - -The cipher block size for GCM is 16 bytes, and thus the CTR transform -used in crypto_gcm_setkey() will also expect a 16-byte IV. However, -the code currently reserves only 8 bytes for the IV, causing -an out-of-bounds access in the CTR transform. This patch fixes -the issue by setting the size of the IV buffer to 16 bytes. - -Fixes: 84c911523020 ("[CRYPTO] gcm: Add support for async ciphers") -Signed-off-by: Ondrej Mosnacek -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - crypto/gcm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/crypto/gcm.c -+++ b/crypto/gcm.c -@@ -117,7 +117,7 @@ static int crypto_gcm_setkey(struct cryp - struct crypto_skcipher *ctr = ctx->ctr; - struct { - be128 hash; -- u8 iv[8]; -+ u8 iv[16]; - - struct crypto_gcm_setkey_result result; - diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch deleted file mode 100644 index 6d98c6f5..00000000 --- a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 57cfda1ac74e58767f6305bd1ea3449177425460 Mon Sep 17 00:00:00 2001 -From: Romain Perier -Date: Tue, 9 Aug 2016 11:03:19 +0200 -Subject: crypto: marvell - Don't overwrite default creq->state during initialization - -From: Romain Perier - -commit 57cfda1ac74e58767f6305bd1ea3449177425460 upstream. - -Currently, in mv_cesa_{md5,sha1,sha256}_init creq->state is initialized -before the call to mv_cesa_ahash_init. This is wrong because this -function fills creq with zero by using memset, so its 'state' that -contains the default DIGEST is overwritten. This commit fixes the issue -by initializing creq->state just after the call to mv_cesa_ahash_init. - -Fixes: commit b0ef51067cb4 ("crypto: marvell/cesa - initialize hash...") -Signed-off-by: Romain Perier -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/crypto/marvell/hash.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/drivers/crypto/marvell/hash.c -+++ b/drivers/crypto/marvell/hash.c -@@ -805,13 +805,14 @@ static int mv_cesa_md5_init(struct ahash - struct mv_cesa_op_ctx tmpl = { }; - - mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5); -+ -+ mv_cesa_ahash_init(req, &tmpl, true); -+ - creq->state[0] = MD5_H0; - creq->state[1] = MD5_H1; - creq->state[2] = MD5_H2; - creq->state[3] = MD5_H3; - -- mv_cesa_ahash_init(req, &tmpl, true); -- - return 0; - } - -@@ -873,14 +874,15 @@ static int mv_cesa_sha1_init(struct ahas - struct mv_cesa_op_ctx tmpl = { }; - - mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1); -+ -+ mv_cesa_ahash_init(req, &tmpl, false); -+ - creq->state[0] = SHA1_H0; - creq->state[1] = SHA1_H1; - creq->state[2] = SHA1_H2; - creq->state[3] = SHA1_H3; - creq->state[4] = SHA1_H4; - -- mv_cesa_ahash_init(req, &tmpl, false); -- - return 0; - } - -@@ -942,6 +944,9 @@ static int mv_cesa_sha256_init(struct ah - struct mv_cesa_op_ctx tmpl = { }; - - mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256); -+ -+ mv_cesa_ahash_init(req, &tmpl, false); -+ - creq->state[0] = SHA256_H0; - creq->state[1] = SHA256_H1; - creq->state[2] = SHA256_H2; -@@ -951,8 +956,6 @@ static int mv_cesa_sha256_init(struct ah - creq->state[6] = SHA256_H6; - creq->state[7] = SHA256_H7; - -- mv_cesa_ahash_init(req, &tmpl, false); -- - return 0; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch b/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch deleted file mode 100644 index 18fb155e..00000000 --- a/kernel/kernel/files/patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 09951d83fc58a6f772de09c08e370f6d9970dbb6 Mon Sep 17 00:00:00 2001 -From: Romain Perier -Date: Tue, 9 Aug 2016 11:03:18 +0200 -Subject: crypto: marvell - Update transformation context for each dequeued req - -From: Romain Perier - -commit 09951d83fc58a6f772de09c08e370f6d9970dbb6 upstream. - -So far, sub part of mv_cesa_int was responsible of dequeuing complete -requests, then call the 'cleanup' operation on these reqs and call the -crypto api callback 'complete'. The problem is that the transformation -context 'ctx' is retrieved only once before the while loop. Which means -that the wrong 'cleanup' operation might be called on the wrong type of -cesa requests, it can lead to memory corruptions with this message: - -marvell-cesa f1090000.crypto: dma_pool_free cesa_padding, 5a5a5a5a/5a5a5a5a (bad dma) - -This commit fixes the issue, by updating the transformation context for -each dequeued cesa request. - -Fixes: commit 85030c5168f1 ("crypto: marvell - Add support for chai...") -Signed-off-by: Romain Perier -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/crypto/marvell/cesa.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/crypto/marvell/cesa.c -+++ b/drivers/crypto/marvell/cesa.c -@@ -166,6 +166,7 @@ static irqreturn_t mv_cesa_int(int irq, - if (!req) - break; - -+ ctx = crypto_tfm_ctx(req->tfm); - mv_cesa_complete_req(ctx, req, 0); - } - } diff --git a/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch b/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch deleted file mode 100644 index dda0b6d5..00000000 --- a/kernel/kernel/files/patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 86c7e6836479c4045a9a81ed5ea76c51d719f9c1 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Sat, 3 Sep 2016 01:22:02 +0200 -Subject: dmaengine: ipu: remove bogus NO_IRQ reference - -From: Arnd Bergmann - -commit 86c7e6836479c4045a9a81ed5ea76c51d719f9c1 upstream. - -A workaround for a warning introduced a use of the NO_IRQ -macro that should have been gone for a long time. - -It is clear from the code that the value cannot actually -be used, but apparently there was a configuration at -some point that caused a warning, so instead of just -reverting that patch, this rearranges the code in a way that -the warning cannot reappear. - -Signed-off-by: Arnd Bergmann -Fixes: 6ef41cf6f721 ("dmaengine :ipu: change ipu_irq_handler() to remove compile warning") -Signed-off-by: Vinod Koul -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/dma/ipu/ipu_irq.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - ---- a/drivers/dma/ipu/ipu_irq.c -+++ b/drivers/dma/ipu/ipu_irq.c -@@ -286,22 +286,21 @@ static void ipu_irq_handler(struct irq_d - raw_spin_unlock(&bank_lock); - while ((line = ffs(status))) { - struct ipu_irq_map *map; -- unsigned int irq = NO_IRQ; -+ unsigned int irq; - - line--; - status &= ~(1UL << line); - - raw_spin_lock(&bank_lock); - map = src2map(32 * i + line); -- if (map) -- irq = map->irq; -- raw_spin_unlock(&bank_lock); -- - if (!map) { -+ raw_spin_unlock(&bank_lock); - pr_err("IPU: Interrupt on unmapped source %u bank %d\n", - line, i); - continue; - } -+ irq = map->irq; -+ raw_spin_unlock(&bank_lock); - generic_handle_irq(irq); - } - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch b/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch deleted file mode 100644 index 849b1ee5..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9716ebc38dfabe6c8e5e3c809e9f3c61dd3740f9 Mon Sep 17 00:00:00 2001 -From: Rex Zhu -Date: Wed, 14 Sep 2016 13:20:34 +0800 -Subject: drm/amd/powerplay: fix mclk not switching back after multi-head was disabled - -From: Rex Zhu - -commit 9716ebc38dfabe6c8e5e3c809e9f3c61dd3740f9 upstream. - -Signed-off-by: Rex Zhu -Reviewed-by: Alex Deucher -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c | 2 ++ - drivers/gpu/drm/amd/powerplay/eventmgr/psm.c | 3 ++- - 2 files changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c -+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c -@@ -262,6 +262,8 @@ static const pem_event_action * const di - unblock_adjust_power_state_tasks, - set_cpu_power_state, - notify_hw_power_source_tasks, -+ get_2d_performance_state_tasks, -+ set_performance_state_tasks, - /* updateDALConfigurationTasks, - variBrightDisplayConfigurationChangeTasks, */ - adjust_power_state_tasks, ---- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c -+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c -@@ -100,11 +100,12 @@ int psm_adjust_power_state_dynamic(struc - if (requested == NULL) - return 0; - -+ phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); -+ - if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal))) - equal = false; - - if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { -- phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); - phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); - hwmgr->current_ps = requested; - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch deleted file mode 100644 index a99ae3e7..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch +++ /dev/null @@ -1,53 +0,0 @@ -From dc8184aa8621ee8048652496884d9f40d4bb407f Mon Sep 17 00:00:00 2001 -From: Rex Zhu -Date: Mon, 10 Oct 2016 15:57:21 +0800 -Subject: drm/amdgpu: change vblank_time's calculation method to reduce computational error. - -From: Rex Zhu - -commit dc8184aa8621ee8048652496884d9f40d4bb407f upstream. - -Signed-off-by: Rex Zhu -Reviewed-by: Alex Deucher -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c -@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct a - printk("\n"); - } - -+ - u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev) - { - struct drm_device *dev = adev->ddev; - struct drm_crtc *crtc; - struct amdgpu_crtc *amdgpu_crtc; -- u32 line_time_us, vblank_lines; -+ u32 vblank_in_pixels; - u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ - - if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - amdgpu_crtc = to_amdgpu_crtc(crtc); - if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { -- line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / -- amdgpu_crtc->hw_mode.clock; -- vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - -+ vblank_in_pixels = -+ amdgpu_crtc->hw_mode.crtc_htotal * -+ (amdgpu_crtc->hw_mode.crtc_vblank_end - - amdgpu_crtc->hw_mode.crtc_vdisplay + -- (amdgpu_crtc->v_border * 2); -- vblank_time_us = vblank_lines * line_time_us; -+ (amdgpu_crtc->v_border * 2)); -+ -+ vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock; - break; - } - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch deleted file mode 100644 index 7a7aa723..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e96ec90f496603c48e0945f8bdeb4cdf3088cbba Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Wed, 28 Sep 2016 12:41:50 -0400 -Subject: drm/amdgpu/dce10: disable hpd on local panels - -From: Alex Deucher - -commit e96ec90f496603c48e0945f8bdeb4cdf3088cbba upstream. - -Otherwise we can get a hotplug interrupt storm when -we turn the panel off if hpd interrupts were enabled -by the bios. - -bug: -https://bugs.freedesktop.org/show_bug.cgi?id=97471 - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c -@@ -425,16 +425,6 @@ static void dce_v10_0_hpd_init(struct am - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); - -- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -- /* don't try to enable hpd on eDP or LVDS avoid breaking the -- * aux dp channel on imac and help (but not completely fix) -- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -- * also avoid interrupt storms during dpms. -- */ -- continue; -- } -- - switch (amdgpu_connector->hpd.hpd) { - case AMDGPU_HPD_1: - idx = 0; -@@ -458,6 +448,19 @@ static void dce_v10_0_hpd_init(struct am - continue; - } - -+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -+ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -+ /* don't try to enable hpd on eDP or LVDS avoid breaking the -+ * aux dp channel on imac and help (but not completely fix) -+ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -+ * also avoid interrupt storms during dpms. -+ */ -+ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); -+ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); -+ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); -+ continue; -+ } -+ - tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); - tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); - WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch deleted file mode 100644 index de149bf4..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 140c94da3c3338c0ff4cc127cf9bec87905ca83c Mon Sep 17 00:00:00 2001 -From: Grazvydas Ignotas -Date: Mon, 3 Oct 2016 00:06:45 +0300 -Subject: drm/amdgpu/dce11: add missing drm_mode_config_cleanup call - -From: Grazvydas Ignotas - -commit 140c94da3c3338c0ff4cc127cf9bec87905ca83c upstream. - -All other amdgpu/dce_v* files have this call, it's only mysteriously -missing from dce_v11_0.c since the file was added and causes leaks. - -Fixes: aaa36a976bbb ("drm/amdgpu: Add initial VI support") -Signed-off-by: Grazvydas Ignotas -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c -@@ -3112,6 +3112,7 @@ static int dce_v11_0_sw_fini(void *handl - - dce_v11_0_afmt_fini(adev); - -+ drm_mode_config_cleanup(adev->ddev); - adev->mode_info.mode_config_initialized = false; - - return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch deleted file mode 100644 index a6a83cd3..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 3a9d993ee9809c217f4322623a9b78c8d17fdd1f Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Wed, 28 Sep 2016 12:43:33 -0400 -Subject: drm/amdgpu/dce11: disable hpd on local panels - -From: Alex Deucher - -commit 3a9d993ee9809c217f4322623a9b78c8d17fdd1f upstream. - -Otherwise we can get a hotplug interrupt storm when -we turn the panel off if hpd interrupts were enabled -by the bios. - -bug: -https://bugs.freedesktop.org/show_bug.cgi?id=97471 - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c -@@ -443,16 +443,6 @@ static void dce_v11_0_hpd_init(struct am - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); - -- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -- /* don't try to enable hpd on eDP or LVDS avoid breaking the -- * aux dp channel on imac and help (but not completely fix) -- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -- * also avoid interrupt storms during dpms. -- */ -- continue; -- } -- - switch (amdgpu_connector->hpd.hpd) { - case AMDGPU_HPD_1: - idx = 0; -@@ -476,6 +466,19 @@ static void dce_v11_0_hpd_init(struct am - continue; - } - -+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -+ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -+ /* don't try to enable hpd on eDP or LVDS avoid breaking the -+ * aux dp channel on imac and help (but not completely fix) -+ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -+ * also avoid interrupt storms during dpms. -+ */ -+ tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]); -+ tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0); -+ WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp); -+ continue; -+ } -+ - tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]); - tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1); - WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch deleted file mode 100644 index 63cda139..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 324082586cc5918e3230f0b2f326656c653201eb Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Wed, 28 Sep 2016 12:44:20 -0400 -Subject: drm/amdgpu/dce8: disable hpd on local panels - -From: Alex Deucher - -commit 324082586cc5918e3230f0b2f326656c653201eb upstream. - -Otherwise we can get a hotplug interrupt storm when -we turn the panel off if hpd interrupts were enabled -by the bios. - -bug: -https://bugs.freedesktop.org/show_bug.cgi?id=97471 - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 48 +++++++++++++++++++++++++++------- - 1 file changed, 39 insertions(+), 9 deletions(-) - ---- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c -@@ -395,15 +395,6 @@ static void dce_v8_0_hpd_init(struct amd - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); - -- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -- connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -- /* don't try to enable hpd on eDP or LVDS avoid breaking the -- * aux dp channel on imac and help (but not completely fix) -- * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -- * also avoid interrupt storms during dpms. -- */ -- continue; -- } - switch (amdgpu_connector->hpd.hpd) { - case AMDGPU_HPD_1: - WREG32(mmDC_HPD1_CONTROL, tmp); -@@ -426,6 +417,45 @@ static void dce_v8_0_hpd_init(struct amd - default: - break; - } -+ -+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || -+ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { -+ /* don't try to enable hpd on eDP or LVDS avoid breaking the -+ * aux dp channel on imac and help (but not completely fix) -+ * https://bugzilla.redhat.com/show_bug.cgi?id=726143 -+ * also avoid interrupt storms during dpms. -+ */ -+ u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl; -+ -+ switch (amdgpu_connector->hpd.hpd) { -+ case AMDGPU_HPD_1: -+ dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL; -+ break; -+ case AMDGPU_HPD_2: -+ dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL; -+ break; -+ case AMDGPU_HPD_3: -+ dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL; -+ break; -+ case AMDGPU_HPD_4: -+ dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL; -+ break; -+ case AMDGPU_HPD_5: -+ dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL; -+ break; -+ case AMDGPU_HPD_6: -+ dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL; -+ break; -+ default: -+ continue; -+ } -+ -+ dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg); -+ dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; -+ WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl); -+ continue; -+ } -+ - dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd); - amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd); - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch deleted file mode 100644 index 6e9010ec..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c4795ca642b8bd76b5b6ffba41ba909543273d43 Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Mon, 22 Aug 2016 16:31:36 -0400 -Subject: drm/amdgpu: fix IB alignment for UVD - -From: Alex Deucher - -commit c4795ca642b8bd76b5b6ffba41ba909543273d43 upstream. - -According to the hw team, it should be 16, not 8. - -Cc: Peter Fang -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -@@ -292,7 +292,7 @@ static int amdgpu_info_ioctl(struct drm_ - type = AMD_IP_BLOCK_TYPE_UVD; - ring_mask = adev->uvd.ring.ready ? 1 : 0; - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; -- ib_size_alignment = 8; -+ ib_size_alignment = 16; - break; - case AMDGPU_HW_IP_VCE: - type = AMD_IP_BLOCK_TYPE_VCE; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch b/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch deleted file mode 100644 index 4343c2f3..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ce199ad690bd0a6ac6bf9e4df2c87b59d76f84da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= -Date: Tue, 4 Oct 2016 09:43:30 +0200 -Subject: drm/amdgpu: initialize the context reset_counter in amdgpu_ctx_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Nicolai Hähnle - -commit ce199ad690bd0a6ac6bf9e4df2c87b59d76f84da upstream. - -Ensure that we really only report a GPU reset if one has happened since the -creation of the context. - -Signed-off-by: Nicolai Hähnle -Reviewed-by: Christian König -Signed-off-by: Alex Deucher -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c -@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu - ctx->rings[i].sequence = 1; - ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; - } -+ -+ ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); -+ - /* create context entity for each ring */ - for (i = 0; i < adev->num_rings; i++) { - struct amdgpu_ring *ring = adev->rings[i]; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch b/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch deleted file mode 100644 index 92192a36..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6cc4758ae91c0582f07e3c94c7de1ad0975feff5 Mon Sep 17 00:00:00 2001 -From: Stefan Agner -Date: Fri, 2 Sep 2016 11:23:37 -0700 -Subject: drm/fsl-dcu: fix endian issue when using clk_register_divider - -From: Stefan Agner - -commit 6cc4758ae91c0582f07e3c94c7de1ad0975feff5 upstream. - -Since using clk_register_divider to setup the pixel clock, regmap -is no longer used. Regmap did take care of DCU using different -endianness. Check endianness using the device-tree property -"big-endian" to determine the location of DIV_RATIO. - -Fixes: 2d701449bce1 ("drm/fsl-dcu: use common clock framework for pixel clock divider") -Reported-by: Meng Yi -Signed-off-by: Stefan Agner -Tested-by: Meng Yi -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c -+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c -@@ -330,6 +330,7 @@ static int fsl_dcu_drm_probe(struct plat - const char *pix_clk_in_name; - const struct of_device_id *id; - int ret; -+ u8 div_ratio_shift = 0; - - fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL); - if (!fsl_dev) -@@ -382,11 +383,14 @@ static int fsl_dcu_drm_probe(struct plat - pix_clk_in = fsl_dev->clk; - } - -+ if (of_property_read_bool(dev->of_node, "big-endian")) -+ div_ratio_shift = 24; -+ - pix_clk_in_name = __clk_get_name(pix_clk_in); - snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name); - fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name, - pix_clk_in_name, 0, base + DCU_DIV_RATIO, -- 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); -+ div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL); - if (IS_ERR(fsl_dev->pix_clk)) { - dev_err(dev, "failed to register pix clk\n"); - ret = PTR_ERR(fsl_dev->pix_clk); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch deleted file mode 100644 index 70ad7ba4..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch +++ /dev/null @@ -1,118 +0,0 @@ -From d721b02fd00bf133580f431b82ef37f3b746dfb2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= -Date: Mon, 8 Aug 2016 13:58:39 +0300 -Subject: drm/i915: Account for TSEG size when determining 865G stolen base -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Ville Syrjälä - -commit d721b02fd00bf133580f431b82ef37f3b746dfb2 upstream. - -Looks like the TSEG lives just above TOUD, stolen comes after TSEG. - -The spec seems somewhat self-contradictory in places, in the ESMRAMC -register desctription it says: - TSEG Size: - 10=(TOUD + 512 KB) to TOUD - 11 =(TOUD + 1 MB) to TOUD - -so that agrees with TSEG being at TOUD. But the example given -elsehwere in the spec says: - - TOUD equals 62.5 MB = 03E7FFFFh - TSEG selected as 512 KB in size, - Graphics local memory selected as 1 MB in size - General System RAM available in system = 62.5 MB - General system RAM range00000000h to 03E7FFFFh - TSEG address range03F80000h to 03FFFFFFh - TSEG pre-allocated from03F80000h to 03FFFFFFh - Graphics local memory pre-allocated from03E80000h to 03F7FFFFh - -so here we have TSEG above stolen. - -Real world evidence agrees with the TOUD->TSEG->stolen order however, so -let's fix up the code to account for the TSEG size. - -Cc: Taketo Kabe -Cc: Chris Wilson -Cc: Daniel Vetter -Cc: Thomas Gleixner -Cc: Ingo Molnar -Cc: "H. Peter Anvin" -Cc: x86@kernel.org -Fixes: 0ad98c74e093 ("drm/i915: Determine the stolen memory base address on gen2") -Fixes: a4dff76924fe ("x86/gpu: Add Intel graphics stolen memory quirk for gen2 platforms") -Reported-by: Taketo Kabe -Tested-by: Taketo Kabe -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96473 -Signed-off-by: Ville Syrjälä -Link: http://patchwork.freedesktop.org/patch/msgid/1470653919-27251-1-git-send-email-ville.syrjala@linux.intel.com -Link: http://download.intel.com/design/chipsets/datashts/25251405.pdf -Reviewed-by: Chris Wilson -Signed-off-by: Greg Kroah-Hartman - ---- - arch/x86/kernel/early-quirks.c | 9 ++------- - drivers/gpu/drm/i915/i915_gem_stolen.c | 23 +++++++++++++++++------ - 2 files changed, 19 insertions(+), 13 deletions(-) - ---- a/arch/x86/kernel/early-quirks.c -+++ b/arch/x86/kernel/early-quirks.c -@@ -317,16 +317,11 @@ static phys_addr_t __init i85x_stolen_ba - static phys_addr_t __init i865_stolen_base(int num, int slot, int func, - size_t stolen_size) - { -- u16 toud; -+ u16 toud = 0; - -- /* -- * FIXME is the graphics stolen memory region -- * always at TOUD? Ie. is it always the last -- * one to be allocated by the BIOS? -- */ - toud = read_pci_config_16(0, 0, 0, I865_TOUD); - -- return (phys_addr_t)toud << 16; -+ return (phys_addr_t)(toud << 16) + i845_tseg_size(); - } - - static phys_addr_t __init gen3_stolen_base(int num, int slot, int func, ---- a/drivers/gpu/drm/i915/i915_gem_stolen.c -+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c -@@ -115,17 +115,28 @@ static unsigned long i915_stolen_to_phys - - base = bsm & INTEL_BSM_MASK; - } else if (IS_I865G(dev)) { -+ u32 tseg_size = 0; - u16 toud = 0; -+ u8 tmp; -+ -+ pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), -+ I845_ESMRAMC, &tmp); -+ -+ if (tmp & TSEG_ENABLE) { -+ switch (tmp & I845_TSEG_SIZE_MASK) { -+ case I845_TSEG_SIZE_512K: -+ tseg_size = KB(512); -+ break; -+ case I845_TSEG_SIZE_1M: -+ tseg_size = MB(1); -+ break; -+ } -+ } - -- /* -- * FIXME is the graphics stolen memory region -- * always at TOUD? Ie. is it always the last -- * one to be allocated by the BIOS? -- */ - pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0), - I865_TOUD, &toud); - -- base = toud << 16; -+ base = (toud << 16) + tseg_size; - } else if (IS_I85X(dev)) { - u32 tseg_size = 0; - u32 tom; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch deleted file mode 100644 index 418c1e77..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 16c83fad79ca912b8b5bbdcb5272794a2be41262 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= -Date: Mon, 3 Oct 2016 10:55:16 +0300 -Subject: drm/i915: Allow DP to work w/o EDID -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Ville Syrjälä - -commit 16c83fad79ca912b8b5bbdcb5272794a2be41262 upstream. - -Allow returning "connected" or "unknown" connector status for DP branch -devices that don't have an EDID. Currently we'd claim the thing as -"disconnected" if there is no EDID. - -This stuff used to broken already, I think, but it got more broken by -commit f21a21983ef1 ("drm/i915: Splitting intel_dp_detect") - -Cc: Damien Cassou -Cc: freedesktop.org@gp.mailgun.org -Cc: Arno -Cc: Shubhangi Shrivastava -Cc: Sivakumar Thulasimani -Cc: Ander Conselvan de Oliveira -Tested-by: Arno -Fixes: f21a21983ef1 ("drm/i915: Splitting intel_dp_detect") -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83348 -Signed-off-by: Ville Syrjälä -Link: http://patchwork.freedesktop.org/patch/msgid/1475481316-8194-2-git-send-email-ville.syrjala@linux.intel.com -Reviewed-by: Ander Conselvan de Oliveira -(cherry picked from commit 5cb651a7959310ef4dbb0b93f005b10286789656) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_dp.c | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_dp.c -+++ b/drivers/gpu/drm/i915/intel_dp.c -@@ -4207,7 +4207,7 @@ intel_dp_unset_edid(struct intel_dp *int - intel_dp->has_audio = false; - } - --static void -+static enum drm_connector_status - intel_dp_long_pulse(struct intel_connector *intel_connector) - { - struct drm_connector *connector = &intel_connector->base; -@@ -4232,7 +4232,7 @@ intel_dp_long_pulse(struct intel_connect - else - status = connector_status_disconnected; - -- if (status != connector_status_connected) { -+ if (status == connector_status_disconnected) { - intel_dp->compliance_test_active = 0; - intel_dp->compliance_test_type = 0; - intel_dp->compliance_test_data = 0; -@@ -4284,8 +4284,8 @@ intel_dp_long_pulse(struct intel_connect - intel_dp->aux.i2c_defer_count = 0; - - intel_dp_set_edid(intel_dp); -- -- status = connector_status_connected; -+ if (is_edp(intel_dp) || intel_connector->detect_edid) -+ status = connector_status_connected; - intel_dp->detect_done = true; - - /* Try to read the source of the interrupt */ -@@ -4303,12 +4303,11 @@ intel_dp_long_pulse(struct intel_connect - } - - out: -- if ((status != connector_status_connected) && -- (intel_dp->is_mst == false)) -+ if (status != connector_status_connected && !intel_dp->is_mst) - intel_dp_unset_edid(intel_dp); - - intel_display_power_put(to_i915(dev), power_domain); -- return; -+ return status; - } - - static enum drm_connector_status -@@ -4317,7 +4316,7 @@ intel_dp_detect(struct drm_connector *co - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct intel_encoder *intel_encoder = &intel_dig_port->base; -- struct intel_connector *intel_connector = to_intel_connector(connector); -+ enum drm_connector_status status = connector->status; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); -@@ -4332,14 +4331,11 @@ intel_dp_detect(struct drm_connector *co - - /* If full detect is not performed yet, do a full detect */ - if (!intel_dp->detect_done) -- intel_dp_long_pulse(intel_dp->attached_connector); -+ status = intel_dp_long_pulse(intel_dp->attached_connector); - - intel_dp->detect_done = false; - -- if (is_edp(intel_dp) || intel_connector->detect_edid) -- return connector_status_connected; -- else -- return connector_status_disconnected; -+ return status; - } - - static void diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch deleted file mode 100644 index 4cf6873a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch +++ /dev/null @@ -1,76 +0,0 @@ -From a3fd4c67af3d8a81d241b3d51b3525f36f1d68bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= -Date: Mon, 26 Sep 2016 11:30:46 +0300 -Subject: drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Ville Syrjälä - -commit a3fd4c67af3d8a81d241b3d51b3525f36f1d68bb upstream. - -DPLL_SDVO_HIGH_SPEED must be set for SDVO/HDMI/DP, but nowhere is it -forbidden to set it for LVDS/CRT as well. So let's also set it on -CRT to make it possible to share the DPLL between HDMI and CRT. - -What that bit apparently does is enable the x5 clock to the port, -which then pumps out the bits on both edges of the clock. The DAC -doesn't need that clock since it's not pumping out bits, but I don't -think it hurts to have the DPLL output that clock anyway. - -This is fairly important on IVB since it has only two DPLLs with three -pipes. So trying to drive three or more PCH ports with three pipes -is only possible when at least one of the DPLLs gets shared between -two of the pipes. - -SNB doesn't really need to do this since it has only two pipes. It could -be done to avoid enabling the second DPLL at all in certain cases, but -I'm not sure that's such a huge win. So let's not do it for SNB, at -least for now. On ILK it never makes sense as the DPLLs can't be shared. - -v2: Just always enable the high speed clock to keep things simple (Daniel) - Beef up the commit message a bit (Daniel) - -Cc: Nick Yamane -Cc: Daniel Vetter -Tested-by: Nick Yamane -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97204 -Signed-off-by: Ville Syrjälä -Link: http://patchwork.freedesktop.org/patch/msgid/1474878646-17711-1-git-send-email-ville.syrjala@linux.intel.com -Reviewed-by: Ander Conselvan de Oliveira -(cherry picked from commit 7d7f8633a82763577727762ff3ac1df3017cb8fe) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -9007,6 +9007,24 @@ static void ironlake_compute_dpll(struct - if (intel_crtc_has_dp_encoder(crtc_state)) - dpll |= DPLL_SDVO_HIGH_SPEED; - -+ /* -+ * The high speed IO clock is only really required for -+ * SDVO/HDMI/DP, but we also enable it for CRT to make it -+ * possible to share the DPLL between CRT and HDMI. Enabling -+ * the clock needlessly does no real harm, except use up a -+ * bit of power potentially. -+ * -+ * We'll limit this to IVB with 3 pipes, since it has only two -+ * DPLLs and so DPLL sharing is the only way to get three pipes -+ * driving PCH ports at the same time. On SNB we could do this, -+ * and potentially avoid enabling the second DPLL, but it's not -+ * clear if it''s a win or loss power wise. No point in doing -+ * this on ILK at all since it has a fixed DPLL<->pipe mapping. -+ */ -+ if (INTEL_INFO(dev_priv)->num_pipes == 3 && -+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) -+ dpll |= DPLL_SDVO_HIGH_SPEED; -+ - /* compute bitmask from p1 value */ - dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - /* also FPA1 */ diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch deleted file mode 100644 index 800bedae..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 16e1203db8ab740c912ea62761fdf27d7811b886 Mon Sep 17 00:00:00 2001 -From: Jani Nikula -Date: Mon, 19 Sep 2016 13:35:25 +0300 -Subject: drm/i915/backlight: setup and cache pwm alternate increment value -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Jani Nikula - -commit 16e1203db8ab740c912ea62761fdf27d7811b886 upstream. - -This will also be needed later on when setting up the alternate -increment in backlight enable. - -Cc: Shawn Lee -Reviewed-by: Ville Syrjälä -Signed-off-by: Jani Nikula -Link: http://patchwork.freedesktop.org/patch/msgid/9984b20bc59aee90b83caf59ce91f3fb122c9627.1474281249.git.jani.nikula@intel.com -(cherry picked from commit 32b421e79e6b546da1d469f1229403ac9142d695) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_drv.h | 1 + - drivers/gpu/drm/i915/intel_panel.c | 14 +++++++++++--- - 2 files changed, 12 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -236,6 +236,7 @@ struct intel_panel { - bool enabled; - bool combination_mode; /* gen 2/4 only */ - bool active_low_pwm; -+ bool alternate_pwm_increment; /* lpt+ */ - - /* PWM chip */ - bool util_pin_active_low; /* bxt+ */ ---- a/drivers/gpu/drm/i915/intel_panel.c -+++ b/drivers/gpu/drm/i915/intel_panel.c -@@ -1242,10 +1242,10 @@ static u32 bxt_hz_to_pwm(struct intel_co - */ - static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) - { -- struct drm_i915_private *dev_priv = to_i915(connector->base.dev); -+ struct intel_panel *panel = &connector->panel; - u32 mul; - -- if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY) -+ if (panel->backlight.alternate_pwm_increment) - mul = 128; - else - mul = 16; -@@ -1261,9 +1261,10 @@ static u32 spt_hz_to_pwm(struct intel_co - static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) - { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); -+ struct intel_panel *panel = &connector->panel; - u32 mul, clock; - -- if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY) -+ if (panel->backlight.alternate_pwm_increment) - mul = 16; - else - mul = 128; -@@ -1414,6 +1415,13 @@ static int lpt_setup_backlight(struct in - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 pch_ctl1, pch_ctl2, val; -+ bool alt; -+ -+ if (HAS_PCH_LPT(dev_priv)) -+ alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; -+ else -+ alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; -+ panel->backlight.alternate_pwm_increment = alt; - - pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); - panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch deleted file mode 100644 index 97d4e08a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 915b417946030e1f365c63728875cffd8db8e880 Mon Sep 17 00:00:00 2001 -From: Shawn Lee -Date: Mon, 19 Sep 2016 13:35:26 +0300 -Subject: drm/i915/backlight: setup backlight pwm alternate increment on backlight enable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Shawn Lee - -commit 915b417946030e1f365c63728875cffd8db8e880 upstream. - -Backlight enable is supposed to do a full setup of the backlight. We -were missing the PWM alternate increment bit in the south chicken -registers on lpt+ pch. This potentially caused a PWM frequency change -when the chicken register value was lost e.g. on suspend. - -v2 by Jani, rebase on the patch caching alt increment - -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97486 -References: https://bugs.freedesktop.org/show_bug.cgi?id=67454 -Cc: Cooper Chiou -Cc: Wei Shun Chen -Cc: Gary C Wang -Reviewed-by: Ville Syrjälä -Signed-off-by: Shawn Lee -Signed-off-by: Jani Nikula -Link: http://patchwork.freedesktop.org/patch/msgid/8265f5935bd31c039ddfc82819d26c2ca1ae9cba.1474281249.git.jani.nikula@intel.com -(cherry picked from commit e29aff05f239f8dd24e9ee7816fd96726e20105a) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_panel.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/i915/intel_panel.c -+++ b/drivers/gpu/drm/i915/intel_panel.c -@@ -841,7 +841,7 @@ static void lpt_enable_backlight(struct - { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; -- u32 pch_ctl1, pch_ctl2; -+ u32 pch_ctl1, pch_ctl2, schicken; - - pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); - if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { -@@ -850,6 +850,22 @@ static void lpt_enable_backlight(struct - I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); - } - -+ if (HAS_PCH_LPT(dev_priv)) { -+ schicken = I915_READ(SOUTH_CHICKEN2); -+ if (panel->backlight.alternate_pwm_increment) -+ schicken |= LPT_PWM_GRANULARITY; -+ else -+ schicken &= ~LPT_PWM_GRANULARITY; -+ I915_WRITE(SOUTH_CHICKEN2, schicken); -+ } else { -+ schicken = I915_READ(SOUTH_CHICKEN1); -+ if (panel->backlight.alternate_pwm_increment) -+ schicken |= SPT_PWM_GRANULARITY; -+ else -+ schicken &= ~SPT_PWM_GRANULARITY; -+ I915_WRITE(SOUTH_CHICKEN1, schicken); -+ } -+ - pch_ctl2 = panel->backlight.max << 16; - I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); - diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch deleted file mode 100644 index 0b3edb20..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch +++ /dev/null @@ -1,111 +0,0 @@ -From cf6c525a31fac11b0775b8c06c00a508c6356d9b Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:32 -0300 -Subject: drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations - -From: Paulo Zanoni - -commit cf6c525a31fac11b0775b8c06c00a508c6356d9b upstream. - -The confusing thing is that plane_blocks_per_line is listed as part of -the method 2 calculation but is also used for other things. We -calculated it in two different places and different ways: one inside -skl_wm_method2() and the other inside skl_compute_plane_wm(). The -skl_wm_method2() implementation is the one that matches the -specification. - -With this patch we fix the skl_compute_plane_wm() calculation and just -pass it as a parameter to skl_wm_method2(). We also take care to not -modify the value of plane_bytes_per_line since we're going to rely on -it having a correct value in later patches. - -This should affect the watermarks for Linear and Y-tiled. - -From my analysis, it looks like the two plane_blocks_per_line -variables got out of sync on 0fda65680e92, but we can't really say -that commit was a regression, it looks like just an incomplete fix. -There's always the possibility that 0fda65680e92 matched our -specification at that time, and then later the specification changed. - -v2: Try to add a "Fixes" tag (Maarten). - -Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling") -Cc: Tvrtko Ursulin -Reviewed-by: Lyude -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-7-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 7a1a8aed67e0a60772defe3f6499eb340da48634) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 39 +++++++++++++++------------------------ - 1 file changed, 15 insertions(+), 24 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3475,30 +3475,14 @@ static uint32_t skl_wm_method1(uint32_t - } - - static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, -- uint32_t horiz_pixels, uint8_t cpp, -- uint64_t tiling, uint32_t latency, -- uint32_t y_min_scanlines) -+ uint32_t latency, uint32_t plane_blocks_per_line) - { - uint32_t ret; -- uint32_t plane_bytes_per_line, plane_blocks_per_line; - uint32_t wm_intermediate_val; - - if (latency == 0) - return UINT_MAX; - -- plane_bytes_per_line = horiz_pixels * cpp; -- -- if (tiling == I915_FORMAT_MOD_Y_TILED || -- tiling == I915_FORMAT_MOD_Yf_TILED) { -- plane_bytes_per_line *= y_min_scanlines; -- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -- plane_blocks_per_line /= y_min_scanlines; -- } else if (tiling == DRM_FORMAT_MOD_NONE) { -- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; -- } else { -- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -- } -- - wm_intermediate_val = latency * pixel_rate; - ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) * - plane_blocks_per_line; -@@ -3587,17 +3571,24 @@ static int skl_compute_plane_wm(const st - y_min_scanlines = 4; - } - -+ plane_bytes_per_line = width * cpp; -+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || -+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { -+ plane_blocks_per_line = -+ DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512); -+ plane_blocks_per_line /= y_min_scanlines; -+ } else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) { -+ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) -+ + 1; -+ } else { -+ plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -+ } -+ - method1 = skl_wm_method1(plane_pixel_rate, cpp, latency); - method2 = skl_wm_method2(plane_pixel_rate, - cstate->base.adjusted_mode.crtc_htotal, -- width, -- cpp, -- fb->modifier[0], - latency, -- y_min_scanlines); -- -- plane_bytes_per_line = width * cpp; -- plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -+ plane_blocks_per_line); - - if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || - fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch deleted file mode 100644 index 9cd60dd2..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 73fed0ef8567f1e1cba079994353e60208ded964 Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:33 -0300 -Subject: drm/i915/gen9: fix the watermark res_blocks value - -From: Paulo Zanoni - -commit 73fed0ef8567f1e1cba079994353e60208ded964 upstream. - -We forgot the "res_blocks += y_tile_minimum" that's described on step -V of our documentation. - -Again, this should only affect the Y tiling cases. - -It looks like the relevant code was introduced in 0fda65680e92, but -there's always the possibility that it matched our specification when -it was introduced, and then the specification changed while the code -stayed the same. So we can't really say this was a regression, but -let's try to add a "Fixes" tag anyway to help backporting. - -v2: Try to add a "Fixes" tag (Maarten). - -Fixes: 0fda65680e92 ("drm/i915/skl: Update watermarks for Y tiling") -Cc: Tvrtko Ursulin -Reviewed-by: Lyude -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-8-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 75676ed423a6acf9e2b1df52fbc036a51e11fb7a) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3533,7 +3533,7 @@ static int skl_compute_plane_wm(const st - uint8_t cpp; - uint32_t width = 0, height = 0; - uint32_t plane_pixel_rate; -- uint32_t y_min_scanlines; -+ uint32_t y_tile_minimum, y_min_scanlines; - - if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { - *enabled = false; -@@ -3590,10 +3590,10 @@ static int skl_compute_plane_wm(const st - latency, - plane_blocks_per_line); - -+ y_tile_minimum = plane_blocks_per_line * y_min_scanlines; -+ - if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || - fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { -- uint32_t y_tile_minimum = plane_blocks_per_line * -- y_min_scanlines; - selected_result = max(method2, y_tile_minimum); - } else { - if ((ddb_allocation / plane_blocks_per_line) >= 1) -@@ -3607,10 +3607,12 @@ static int skl_compute_plane_wm(const st - - if (level >= 1 && level <= 7) { - if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || -- fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) -+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { -+ res_blocks += y_tile_minimum; - res_lines += y_min_scanlines; -- else -+ } else { - res_blocks++; -+ } - } - - if (res_blocks >= ddb_allocation || res_lines > 31) { diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch deleted file mode 100644 index 54ffa0ea..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:30 -0300 -Subject: drm/i915/gen9: fix the WaWmMemoryReadLatency implementation - -From: Paulo Zanoni - -commit 4e4d3814a9bb4d71cd3ff0701d8d7041edefd8f0 upstream. - -Bspec says: - "The mailbox response data may not account for memory read latency. - If the mailbox response data for level 0 is 0us, add 2 microseconds - to the result for each valid level." - -This means we should only do the +2 in case wm[0] == 0, not always. - -So split the sanitizing implementation from the WA implementation and -fix the WA implementation. - -v2: Add Fixes tag (Maarten). - -Fixes: 367294be7c25 ("drm/i915/gen9: Add 2us read latency to WM level") -Cc: Vandana Kannan -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-5-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 0727e40a48a1d08cf54ce2c01e120864b92e59bf) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++-------------------- - 1 file changed, 22 insertions(+), 20 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct - GEN9_MEM_LATENCY_LEVEL_MASK; - - /* -+ * If a level n (n > 1) has a 0us latency, all levels m (m >= n) -+ * need to be disabled. We make sure to sanitize the values out -+ * of the punit to satisfy this requirement. -+ */ -+ for (level = 1; level <= max_level; level++) { -+ if (wm[level] == 0) { -+ for (i = level + 1; i <= max_level; i++) -+ wm[i] = 0; -+ break; -+ } -+ } -+ -+ /* - * WaWmMemoryReadLatency:skl - * - * punit doesn't take into account the read latency so we need -- * to add 2us to the various latency levels we retrieve from -- * the punit. -- * - W0 is a bit special in that it's the only level that -- * can't be disabled if we want to have display working, so -- * we always add 2us there. -- * - For levels >=1, punit returns 0us latency when they are -- * disabled, so we respect that and don't add 2us then -- * -- * Additionally, if a level n (n > 1) has a 0us latency, all -- * levels m (m >= n) need to be disabled. We make sure to -- * sanitize the values out of the punit to satisfy this -- * requirement. -+ * to add 2us to the various latency levels we retrieve from the -+ * punit when level 0 response data us 0us. - */ -- wm[0] += 2; -- for (level = 1; level <= max_level; level++) -- if (wm[level] != 0) -+ if (wm[0] == 0) { -+ wm[0] += 2; -+ for (level = 1; level <= max_level; level++) { -+ if (wm[level] == 0) -+ break; - wm[level] += 2; -- else { -- for (i = level + 1; i <= max_level; i++) -- wm[i] = 0; -- -- break; - } -+ } -+ - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - uint64_t sskpd = I915_READ64(MCH_SSKPD); - diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch deleted file mode 100644 index 43111119..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch +++ /dev/null @@ -1,133 +0,0 @@ -From ccc1057477bc99678896b51adce6b6ee4019dc37 Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:31 -0300 -Subject: drm/i915/gen9: minimum scanlines for Y tile is not always 4 - -From: Paulo Zanoni - -commit ccc1057477bc99678896b51adce6b6ee4019dc37 upstream. - -During watermarks calculations, this value is used in 3 different -places. Only one of them was not using a hardcoded 4. Move the code up -so everybody can benefit from the actual value. - -This should only help on situations with Y tiling + 90/270 rotation + -1 or 2 bpp or NV12. - -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-6-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 1186fa85eb9b3cc0589990fbc39617e50e38759a) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 56 ++++++++++++++++++++++------------------ - 1 file changed, 32 insertions(+), 24 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3476,7 +3476,8 @@ static uint32_t skl_wm_method1(uint32_t - - static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, - uint32_t horiz_pixels, uint8_t cpp, -- uint64_t tiling, uint32_t latency) -+ uint64_t tiling, uint32_t latency, -+ uint32_t y_min_scanlines) - { - uint32_t ret; - uint32_t plane_bytes_per_line, plane_blocks_per_line; -@@ -3489,9 +3490,9 @@ static uint32_t skl_wm_method2(uint32_t - - if (tiling == I915_FORMAT_MOD_Y_TILED || - tiling == I915_FORMAT_MOD_Yf_TILED) { -- plane_bytes_per_line *= 4; -+ plane_bytes_per_line *= y_min_scanlines; - plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -- plane_blocks_per_line /= 4; -+ plane_blocks_per_line /= y_min_scanlines; - } else if (tiling == DRM_FORMAT_MOD_NONE) { - plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1; - } else { -@@ -3548,6 +3549,7 @@ static int skl_compute_plane_wm(const st - uint8_t cpp; - uint32_t width = 0, height = 0; - uint32_t plane_pixel_rate; -+ uint32_t y_min_scanlines; - - if (latency == 0 || !cstate->base.active || !intel_pstate->visible) { - *enabled = false; -@@ -3563,38 +3565,44 @@ static int skl_compute_plane_wm(const st - cpp = drm_format_plane_cpp(fb->pixel_format, 0); - plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); - -+ if (intel_rotation_90_or_270(pstate->rotation)) { -+ int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? -+ drm_format_plane_cpp(fb->pixel_format, 1) : -+ drm_format_plane_cpp(fb->pixel_format, 0); -+ -+ switch (cpp) { -+ case 1: -+ y_min_scanlines = 16; -+ break; -+ case 2: -+ y_min_scanlines = 8; -+ break; -+ default: -+ WARN(1, "Unsupported pixel depth for rotation"); -+ case 4: -+ y_min_scanlines = 4; -+ break; -+ } -+ } else { -+ y_min_scanlines = 4; -+ } -+ - method1 = skl_wm_method1(plane_pixel_rate, cpp, latency); - method2 = skl_wm_method2(plane_pixel_rate, - cstate->base.adjusted_mode.crtc_htotal, - width, - cpp, - fb->modifier[0], -- latency); -+ latency, -+ y_min_scanlines); - - plane_bytes_per_line = width * cpp; - plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); - - if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || - fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { -- uint32_t min_scanlines = 4; -- uint32_t y_tile_minimum; -- if (intel_rotation_90_or_270(pstate->rotation)) { -- int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? -- drm_format_plane_cpp(fb->pixel_format, 1) : -- drm_format_plane_cpp(fb->pixel_format, 0); -- -- switch (cpp) { -- case 1: -- min_scanlines = 16; -- break; -- case 2: -- min_scanlines = 8; -- break; -- case 8: -- WARN(1, "Unsupported pixel depth for rotation"); -- } -- } -- y_tile_minimum = plane_blocks_per_line * min_scanlines; -+ uint32_t y_tile_minimum = plane_blocks_per_line * -+ y_min_scanlines; - selected_result = max(method2, y_tile_minimum); - } else { - if ((ddb_allocation / plane_blocks_per_line) >= 1) -@@ -3609,7 +3617,7 @@ static int skl_compute_plane_wm(const st - if (level >= 1 && level <= 7) { - if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || - fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) -- res_lines += 4; -+ res_lines += y_min_scanlines; - else - res_blocks++; - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch deleted file mode 100644 index 8fec07d2..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch +++ /dev/null @@ -1,92 +0,0 @@ -From be5c571b2ff3a164d2e14ccc100cb5b2b3d3fb7c Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 29 Sep 2016 16:36:48 -0300 -Subject: drm/i915/gen9: only add the planes actually affected by ddb changes - -From: Paulo Zanoni - -commit be5c571b2ff3a164d2e14ccc100cb5b2b3d3fb7c upstream. - -We were previously adding all the planes owned by the CRTC even when -the ddb partitioning didn't change for them. As a consequence, a lot -of functions were being called when we were just moving the cursor -around the screen, such as skylake_update_primary_plane(). - -This was causing flickering on the primary plane when moving the -cursor. I'm not 100% sure which operation caused the flickering, but -we were writing to a lot of registers, so it could be any of these -writes. With this patch, just moving the mouse won't add the primary -plane to the commit since it won't trigger a change in DDB -partitioning. - -v2: Use skl_ddb_entry_equal() (Lyude). -v3: Change Reported-and-bisected-by: to Reported-by: for checkpatch - -Fixes: 05a76d3d6ad1 ("drm/i915/skl: Ensure pipes with changed wms get added to the state") -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97888 -Cc: Mike Lothian -Reported-by: Mike Lothian -Signed-off-by: Paulo Zanoni -Signed-off-by: Lyude -Link: http://patchwork.freedesktop.org/patch/msgid/1475177808-29955-1-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 7f60e200e254cd53ad1bd74a56bdd23e813ac4b7) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 37 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3940,6 +3940,41 @@ pipes_modified(struct drm_atomic_state * - return ret; - } - -+int -+skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) -+{ -+ struct drm_atomic_state *state = cstate->base.state; -+ struct drm_device *dev = state->dev; -+ struct drm_crtc *crtc = cstate->base.crtc; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); -+ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; -+ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; -+ struct drm_plane_state *plane_state; -+ struct drm_plane *plane; -+ enum pipe pipe = intel_crtc->pipe; -+ int id; -+ -+ WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); -+ -+ drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { -+ id = skl_wm_plane_id(to_intel_plane(plane)); -+ -+ if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], -+ &new_ddb->plane[pipe][id]) && -+ skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id], -+ &new_ddb->y_plane[pipe][id])) -+ continue; -+ -+ plane_state = drm_atomic_get_plane_state(state, plane); -+ if (IS_ERR(plane_state)) -+ return PTR_ERR(plane_state); -+ } -+ -+ return 0; -+} -+ - static int - skl_compute_ddb(struct drm_atomic_state *state) - { -@@ -4004,7 +4039,7 @@ skl_compute_ddb(struct drm_atomic_state - if (ret) - return ret; - -- ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); -+ ret = skl_ddb_add_affected_planes(cstate); - if (ret) - return ret; - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch deleted file mode 100644 index c25ade40..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:28 -0300 -Subject: drm/i915: introduce intel_has_sagv() - -From: Paulo Zanoni - -commit 6e7fdb873d6255ca3c999dd5c6c18962a769ed3e upstream. - -And use it to move knowledge about the SAGV-supporting platforms from -the callers to the SAGV code. - -We'll add more platforms to intel_has_sagv(), so IMHO it makes more -sense to move all this to a single function instead of patching all -the callers every time we add SAGV support to a new platform. - -v2: Move I915_SAGV_NOT_CONTROLLED to the new function (Lyude). - -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-3-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 56feca91973459d0b62cbb2610b62d341025ed89) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_display.c | 5 ++--- - drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++---- - 2 files changed, 20 insertions(+), 7 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -13891,7 +13891,7 @@ static void intel_atomic_commit_tail(str - * SKL workaround: bspec recommends we disable the SAGV when we - * have more then one pipe enabled - */ -- if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state)) -+ if (!intel_can_enable_sagv(state)) - intel_disable_sagv(dev_priv); - - intel_modeset_verify_disabled(dev); -@@ -13949,8 +13949,7 @@ static void intel_atomic_commit_tail(str - intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); - } - -- if (IS_SKYLAKE(dev_priv) && intel_state->modeset && -- intel_can_enable_sagv(state)) -+ if (intel_state->modeset && intel_can_enable_sagv(state)) - intel_enable_sagv(dev_priv); - - drm_atomic_helper_commit_hw_done(state); ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -2878,6 +2878,13 @@ skl_wm_plane_id(const struct intel_plane - } - } - -+static bool -+intel_has_sagv(struct drm_i915_private *dev_priv) -+{ -+ return IS_SKYLAKE(dev_priv) && -+ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED; -+} -+ - /* - * SAGV dynamically adjusts the system agent voltage and clock frequencies - * depending on power and performance requirements. The display engine access -@@ -2894,8 +2901,10 @@ intel_enable_sagv(struct drm_i915_privat - { - int ret; - -- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || -- dev_priv->sagv_status == I915_SAGV_ENABLED) -+ if (!intel_has_sagv(dev_priv)) -+ return 0; -+ -+ if (dev_priv->sagv_status == I915_SAGV_ENABLED) - return 0; - - DRM_DEBUG_KMS("Enabling the SAGV\n"); -@@ -2943,8 +2952,10 @@ intel_disable_sagv(struct drm_i915_priva - { - int ret, result; - -- if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || -- dev_priv->sagv_status == I915_SAGV_DISABLED) -+ if (!intel_has_sagv(dev_priv)) -+ return 0; -+ -+ if (dev_priv->sagv_status == I915_SAGV_DISABLED) - return 0; - - DRM_DEBUG_KMS("Disabling the SAGV\n"); -@@ -2985,6 +2996,9 @@ bool intel_can_enable_sagv(struct drm_at - enum pipe pipe; - int level, plane; - -+ if (!intel_has_sagv(dev_priv)) -+ return false; -+ - /* - * SKL workaround: bspec recommends we disable the SAGV when we have - * more then one pipe enabled diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch deleted file mode 100644 index 85b64a22..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch +++ /dev/null @@ -1,43 +0,0 @@ -From f856f847b22c52be82f712ea6ada946c6db884d7 Mon Sep 17 00:00:00 2001 -From: Chris Wilson -Date: Mon, 3 Oct 2016 13:45:14 +0100 -Subject: drm/i915: Just clear the mmiodebug before a register access - -From: Chris Wilson - -commit f856f847b22c52be82f712ea6ada946c6db884d7 upstream. - -When we enable the per-register access mmiodebug, it is to detect which -access is illegal. Reporting on earlier untraced access outside of the -mmiodebug does not help debugging (as the suspicion is immediately put -upon the current register which is not at fault)! - -References: https://bugs.freedesktop.org/show_bug.cgi?id=97985 -Signed-off-by: Chris Wilson -Cc: Mika Kuoppala -Reviewed-by: Mika Kuoppala -Link: http://patchwork.freedesktop.org/patch/msgid/20161003124516.12388-1-chris@chris-wilson.co.uk -(cherry picked from commit dda960335e020835f7f1c12760e7f0b525b451e2) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_uncore.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_uncore.c -+++ b/drivers/gpu/drm/i915/intel_uncore.c -@@ -796,10 +796,9 @@ __unclaimed_reg_debug(struct drm_i915_pr - const bool read, - const bool before) - { -- if (WARN(check_for_unclaimed_mmio(dev_priv), -- "Unclaimed register detected %s %s register 0x%x\n", -- before ? "before" : "after", -- read ? "reading" : "writing to", -+ if (WARN(check_for_unclaimed_mmio(dev_priv) && !before, -+ "Unclaimed %s register 0x%x\n", -+ read ? "read from" : "write to", - i915_mmio_reg_offset(reg))) - i915.mmio_debug--; /* Only report the first N failures */ - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch deleted file mode 100644 index ef3c31b9..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 17777d61f4a87d7b6d5585e8fdffa83773c594e7 Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:29 -0300 -Subject: drm/i915/kbl: KBL also needs to run the SAGV code - -From: Paulo Zanoni - -commit 17777d61f4a87d7b6d5585e8fdffa83773c594e7 upstream. - -According to BSpec, it's the "core CPUs" that need the code, which -means SKL and KBL, but not BXT. - -I don't have a KBL to test this patch on it. - -v2: Only SKL should have I915_SAGV_NOT_CONTROLLED. - -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-4-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 6e3100ec21e7c774a0fc01e36a1e0739530c2f71) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -2881,8 +2881,14 @@ skl_wm_plane_id(const struct intel_plane - static bool - intel_has_sagv(struct drm_i915_private *dev_priv) - { -- return IS_SKYLAKE(dev_priv) && -- dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED; -+ if (IS_KABYLAKE(dev_priv)) -+ return true; -+ -+ if (IS_SKYLAKE(dev_priv) && -+ dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED) -+ return true; -+ -+ return false; - } - - /* -@@ -2920,7 +2926,7 @@ intel_enable_sagv(struct drm_i915_privat - * Some skl systems, pre-release machines in particular, - * don't actually have an SAGV. - */ -- if (ret == -ENXIO) { -+ if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) { - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); - dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; - return 0; -@@ -2974,7 +2980,7 @@ intel_disable_sagv(struct drm_i915_priva - * Some skl systems, pre-release machines in particular, - * don't actually have an SAGV. - */ -- if (result == -ENXIO) { -+ if (IS_SKYLAKE(dev_priv) && result == -ENXIO) { - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); - dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; - return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch deleted file mode 100644 index e4402b0b..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 896e5bb022bce64e29ce2e1b2fc2a7476d311a15 Mon Sep 17 00:00:00 2001 -From: Lyude -Date: Wed, 24 Aug 2016 07:48:09 +0200 -Subject: drm/i915: Move CRTC updating in atomic_commit into it's own hook -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Lyude - -commit 896e5bb022bce64e29ce2e1b2fc2a7476d311a15 upstream. - -Since we have to write ddb allocations at the same time as we do other -plane updates, we're going to need to be able to control the order in -which we execute modesets on each pipe. The easiest way to do this is to -just factor this section of intel_atomic_commit_tail() -(intel_atomic_commit() for stable branches) into it's own function, and -add an appropriate display function hook for it. - -Based off of Matt Rope's suggestions - -Changes since v1: - - Drop pipe_config->base.active check in intel_update_crtcs() since we - check that before calling the function - -Signed-off-by: Lyude -Reviewed-by: Matt Roper -[omitting CC for stable, since this patch will need to be changed for -such backports first] -Cc: Ville Syrjälä -Cc: Daniel Vetter -Cc: Radhakrishna Sripada -Cc: Hans de Goede -Signed-off-by: Lyude -Signed-off-by: Maarten Lankhorst -Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-1-git-send-email-cpaul@redhat.com -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/i915_drv.h | 2 - drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++++++----------- - 2 files changed, 54 insertions(+), 22 deletions(-) - ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -631,6 +631,8 @@ struct drm_i915_display_funcs { - struct intel_crtc_state *crtc_state); - void (*crtc_enable)(struct drm_crtc *crtc); - void (*crtc_disable)(struct drm_crtc *crtc); -+ void (*update_crtcs)(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask); - void (*audio_codec_enable)(struct drm_connector *connector, - struct intel_encoder *encoder, - const struct drm_display_mode *adjusted_mode); ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -13682,6 +13682,52 @@ static bool needs_vblank_wait(struct int - return false; - } - -+static void intel_update_crtc(struct drm_crtc *crtc, -+ struct drm_atomic_state *state, -+ struct drm_crtc_state *old_crtc_state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state); -+ bool modeset = needs_modeset(crtc->state); -+ -+ if (modeset) { -+ update_scanline_offset(intel_crtc); -+ dev_priv->display.crtc_enable(crtc); -+ } else { -+ intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); -+ } -+ -+ if (drm_atomic_get_existing_plane_state(state, crtc->primary)) { -+ intel_fbc_enable( -+ intel_crtc, pipe_config, -+ to_intel_plane_state(crtc->primary->state)); -+ } -+ -+ drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); -+ -+ if (needs_vblank_wait(pipe_config)) -+ *crtc_vblank_mask |= drm_crtc_mask(crtc); -+} -+ -+static void intel_update_crtcs(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_crtc *crtc; -+ struct drm_crtc_state *old_crtc_state; -+ int i; -+ -+ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -+ if (!crtc->state->active) -+ continue; -+ -+ intel_update_crtc(crtc, state, old_crtc_state, -+ crtc_vblank_mask); -+ } -+} -+ - static void intel_atomic_commit_tail(struct drm_atomic_state *state) - { - struct drm_device *dev = state->dev; -@@ -13780,17 +13826,9 @@ static void intel_atomic_commit_tail(str - intel_modeset_verify_disabled(dev); - } - -- /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -+ /* Complete the events for pipes that have now been disabled */ - for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - bool modeset = needs_modeset(crtc->state); -- struct intel_crtc_state *pipe_config = -- to_intel_crtc_state(crtc->state); -- -- if (modeset && crtc->state->active) { -- update_scanline_offset(to_intel_crtc(crtc)); -- dev_priv->display.crtc_enable(crtc); -- } - - /* Complete events for now disable pipes here. */ - if (modeset && !crtc->state->active && crtc->state->event) { -@@ -13800,21 +13838,11 @@ static void intel_atomic_commit_tail(str - - crtc->state->event = NULL; - } -- -- if (!modeset) -- intel_pre_plane_update(to_intel_crtc_state(old_crtc_state)); -- -- if (crtc->state->active && -- drm_atomic_get_existing_plane_state(state, crtc->primary)) -- intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state)); -- -- if (crtc->state->active) -- drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); -- -- if (pipe_config->base.active && needs_vblank_wait(pipe_config)) -- crtc_vblank_mask |= 1 << i; - } - -+ /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -+ dev_priv->display.update_crtcs(state, &crtc_vblank_mask); -+ - /* FIXME: We should call drm_atomic_helper_commit_hw_done() here - * already, but still need the state for the delayed optimization. To - * fix this: -@@ -15275,6 +15303,8 @@ void intel_init_display_hooks(struct drm - dev_priv->display.crtc_disable = i9xx_crtc_disable; - } - -+ dev_priv->display.update_crtcs = intel_update_crtcs; -+ - /* Returns the core display clock speed */ - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - dev_priv->display.get_display_clock_speed = diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch deleted file mode 100644 index 5cb94eba..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 1015811609c0328b5ed670d07748591b837e74eb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= -Date: Mon, 3 Oct 2016 10:55:15 +0300 -Subject: drm/i915: Move long hpd handling into the hotplug work -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Ville Syrjälä - -commit 1015811609c0328b5ed670d07748591b837e74eb upstream. - -We can't rely on connector->status in the detect() hook if the long hpd -was already handled by the dig_port_work as that won't update -connector->status. Thus we have to defer the long hpd handling entirely -until the hotplug work runs to avoid the double long hpd handling -the "detect_done" flag is trying to prevent. - -We'll start to depend on connector->status being up to date in a -following patch. - -Cc: Damien Cassou -Cc: freedesktop.org@gp.mailgun.org -Cc: Arno -Cc: Shubhangi Shrivastava -Cc: Sivakumar Thulasimani -Cc: Ander Conselvan de Oliveira -Tested-by: Arno -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83348 -Signed-off-by: Ville Syrjälä -Link: http://patchwork.freedesktop.org/patch/msgid/1475481316-8194-1-git-send-email-ville.syrjala@linux.intel.com -Reviewed-by: Ander Conselvan de Oliveira -(cherry picked from commit 27d4efc5591a5853de54713bc717de73c8951e17) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_dp.c | 48 +++++++++++++++++++--------------------- - 1 file changed, 23 insertions(+), 25 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_dp.c -+++ b/drivers/gpu/drm/i915/intel_dp.c -@@ -4696,36 +4696,34 @@ intel_dp_hpd_pulse(struct intel_digital_ - port_name(intel_dig_port->port), - long_hpd ? "long" : "short"); - -+ if (long_hpd) { -+ intel_dp->detect_done = false; -+ return IRQ_NONE; -+ } -+ - power_domain = intel_display_port_aux_power_domain(intel_encoder); - intel_display_power_get(dev_priv, power_domain); - -- if (long_hpd) { -- intel_dp_long_pulse(intel_dp->attached_connector); -- if (intel_dp->is_mst) -- ret = IRQ_HANDLED; -- goto put_power; -- -- } else { -- if (intel_dp->is_mst) { -- if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { -- /* -- * If we were in MST mode, and device is not -- * there, get out of MST mode -- */ -- DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", -- intel_dp->is_mst, intel_dp->mst_mgr.mst_state); -- intel_dp->is_mst = false; -- drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, -- intel_dp->is_mst); -- goto put_power; -- } -+ if (intel_dp->is_mst) { -+ if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { -+ /* -+ * If we were in MST mode, and device is not -+ * there, get out of MST mode -+ */ -+ DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", -+ intel_dp->is_mst, intel_dp->mst_mgr.mst_state); -+ intel_dp->is_mst = false; -+ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, -+ intel_dp->is_mst); -+ intel_dp->detect_done = false; -+ goto put_power; - } -+ } - -- if (!intel_dp->is_mst) { -- if (!intel_dp_short_pulse(intel_dp)) { -- intel_dp_long_pulse(intel_dp->attached_connector); -- goto put_power; -- } -+ if (!intel_dp->is_mst) { -+ if (!intel_dp_short_pulse(intel_dp)) { -+ intel_dp->detect_done = false; -+ goto put_power; - } - } - diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch deleted file mode 100644 index 0397a5f6..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 674f823b455cdb94d5773406c1caac170f87e1c4 Mon Sep 17 00:00:00 2001 -From: Paulo Zanoni -Date: Thu, 22 Sep 2016 18:00:27 -0300 -Subject: drm/i915: SAGV is not SKL-only, so rename a few things - -From: Paulo Zanoni - -commit 674f823b455cdb94d5773406c1caac170f87e1c4 upstream. - -The plan is to introduce intel_has_sagv() and then use it to discover -which platforms actually support it. - -I thought about keeping the functions with their current skl names, -but found two problems: (i) skl_has_sagv() would become a very -confusing name, and (ii) intel_atomic_commit_tail() doesn't seem to be -calling any functions whose name start with a platform name, so the -"intel_" naming scheme seems make more sense than the "firstplatorm_" -naming scheme here. - -Reviewed-by: Lyude -Reviewed-by: Maarten Lankhorst -Signed-off-by: Paulo Zanoni -Link: http://patchwork.freedesktop.org/patch/msgid/1474578035-424-2-git-send-email-paulo.r.zanoni@intel.com -(cherry picked from commit 16dcdc4edbcf5cb130004737f2548401776170f1) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/i915_drv.h | 10 +++++----- - drivers/gpu/drm/i915/intel_display.c | 8 ++++---- - drivers/gpu/drm/i915/intel_drv.h | 6 +++--- - drivers/gpu/drm/i915/intel_pm.c | 26 +++++++++++++------------- - 4 files changed, 25 insertions(+), 25 deletions(-) - ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -1967,11 +1967,11 @@ struct drm_i915_private { - struct vlv_s0ix_state vlv_s0ix_state; - - enum { -- I915_SKL_SAGV_UNKNOWN = 0, -- I915_SKL_SAGV_DISABLED, -- I915_SKL_SAGV_ENABLED, -- I915_SKL_SAGV_NOT_CONTROLLED -- } skl_sagv_status; -+ I915_SAGV_UNKNOWN = 0, -+ I915_SAGV_DISABLED, -+ I915_SAGV_ENABLED, -+ I915_SAGV_NOT_CONTROLLED -+ } sagv_status; - - struct { - /* ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -13891,8 +13891,8 @@ static void intel_atomic_commit_tail(str - * SKL workaround: bspec recommends we disable the SAGV when we - * have more then one pipe enabled - */ -- if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) -- skl_disable_sagv(dev_priv); -+ if (IS_SKYLAKE(dev_priv) && !intel_can_enable_sagv(state)) -+ intel_disable_sagv(dev_priv); - - intel_modeset_verify_disabled(dev); - } -@@ -13950,8 +13950,8 @@ static void intel_atomic_commit_tail(str - } - - if (IS_SKYLAKE(dev_priv) && intel_state->modeset && -- skl_can_enable_sagv(state)) -- skl_enable_sagv(dev_priv); -+ intel_can_enable_sagv(state)) -+ intel_enable_sagv(dev_priv); - - drm_atomic_helper_commit_hw_done(state); - ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1717,9 +1717,9 @@ void ilk_wm_get_hw_state(struct drm_devi - void skl_wm_get_hw_state(struct drm_device *dev); - void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb /* out */); --bool skl_can_enable_sagv(struct drm_atomic_state *state); --int skl_enable_sagv(struct drm_i915_private *dev_priv); --int skl_disable_sagv(struct drm_i915_private *dev_priv); -+bool intel_can_enable_sagv(struct drm_atomic_state *state); -+int intel_enable_sagv(struct drm_i915_private *dev_priv); -+int intel_disable_sagv(struct drm_i915_private *dev_priv); - bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, - const struct skl_ddb_allocation *new, - enum pipe pipe); ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -2890,12 +2890,12 @@ skl_wm_plane_id(const struct intel_plane - * - We're not using an interlaced display configuration - */ - int --skl_enable_sagv(struct drm_i915_private *dev_priv) -+intel_enable_sagv(struct drm_i915_private *dev_priv) - { - int ret; - -- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || -- dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED) -+ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || -+ dev_priv->sagv_status == I915_SAGV_ENABLED) - return 0; - - DRM_DEBUG_KMS("Enabling the SAGV\n"); -@@ -2913,19 +2913,19 @@ skl_enable_sagv(struct drm_i915_private - */ - if (ret == -ENXIO) { - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); -- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; -+ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; - return 0; - } else if (ret < 0) { - DRM_ERROR("Failed to enable the SAGV\n"); - return ret; - } - -- dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED; -+ dev_priv->sagv_status = I915_SAGV_ENABLED; - return 0; - } - - static int --skl_do_sagv_disable(struct drm_i915_private *dev_priv) -+intel_do_sagv_disable(struct drm_i915_private *dev_priv) - { - int ret; - uint32_t temp = GEN9_SAGV_DISABLE; -@@ -2939,19 +2939,19 @@ skl_do_sagv_disable(struct drm_i915_priv - } - - int --skl_disable_sagv(struct drm_i915_private *dev_priv) -+intel_disable_sagv(struct drm_i915_private *dev_priv) - { - int ret, result; - -- if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || -- dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED) -+ if (dev_priv->sagv_status == I915_SAGV_NOT_CONTROLLED || -+ dev_priv->sagv_status == I915_SAGV_DISABLED) - return 0; - - DRM_DEBUG_KMS("Disabling the SAGV\n"); - mutex_lock(&dev_priv->rps.hw_lock); - - /* bspec says to keep retrying for at least 1 ms */ -- ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1); -+ ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1); - mutex_unlock(&dev_priv->rps.hw_lock); - - if (ret == -ETIMEDOUT) { -@@ -2965,18 +2965,18 @@ skl_disable_sagv(struct drm_i915_private - */ - if (result == -ENXIO) { - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); -- dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; -+ dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; - return 0; - } else if (result < 0) { - DRM_ERROR("Failed to disable the SAGV\n"); - return result; - } - -- dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED; -+ dev_priv->sagv_status = I915_SAGV_DISABLED; - return 0; - } - --bool skl_can_enable_sagv(struct drm_atomic_state *state) -+bool intel_can_enable_sagv(struct drm_atomic_state *state) - { - struct drm_device *dev = state->dev; - struct drm_i915_private *dev_priv = to_i915(dev); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch deleted file mode 100644 index 4f468af0..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch +++ /dev/null @@ -1,79 +0,0 @@ -From ccebc23b57c313229526dc76383ce82f5e0b9001 Mon Sep 17 00:00:00 2001 -From: Lyude -Date: Mon, 29 Aug 2016 12:31:27 -0400 -Subject: drm/i915/skl: Don't try to update plane watermarks if they haven't changed - -From: Lyude - -commit ccebc23b57c313229526dc76383ce82f5e0b9001 upstream. - -i915 sometimes needs to disable planes in the middle of an atomic -commit, and then reenable them later in the same commit. Because of -this, we can't make the assumption that the state of the plane actually -changed. Since the state of the plane hasn't actually changed, neither -have it's watermarks. And if the watermarks hasn't changed then we -haven't populated skl_results with anything, which means we'll end up -zeroing out a plane's watermarks in the middle of the atomic commit -without restoring them later. - -Simple reproduction recipe: - - Get a SKL laptop, launch any kind of X session - - Get two extra monitors - - Keep hotplugging both displays (so that the display configuration - jumps from 1 active pipe to 3 active pipes and back) - - Eventually underrun - -Changes since v1: - - Fix incorrect use of "it's" -Changes since v2: - - Add reproduction recipe - -Signed-off-by: Lyude -Cc: Maarten Lankhorst -Fixes: 62e0fb880123 ("drm/i915/skl: Update plane watermarks atomically during plane updates") -Signed-off-by: Lyude -Testcase: kms_plane -Signed-off-by: Maarten Lankhorst -Link: http://patchwork.freedesktop.org/patch/msgid/1472488288-27280-1-git-send-email-cpaul@redhat.com -Cc: drm-intel-fixes@lists.freedesktop.org -Signed-off-by: Greg Kroah-Hartman - - ---- - drivers/gpu/drm/i915/intel_display.c | 7 ++++++- - drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ - 2 files changed, 14 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -3068,7 +3068,12 @@ static void skylake_disable_primary_plan - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - -- skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); -+ /* -+ * We only populate skl_results on watermark updates, and if the -+ * plane's visiblity isn't actually changing neither is its watermarks. -+ */ -+ if (!to_intel_plane_state(crtc->primary->state)->visible) -+ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); - - I915_WRITE(PLANE_CTL(pipe, 0), 0); - I915_WRITE(PLANE_SURF(pipe, 0), 0); ---- a/drivers/gpu/drm/i915/intel_sprite.c -+++ b/drivers/gpu/drm/i915/intel_sprite.c -@@ -314,6 +314,14 @@ skl_disable_plane(struct drm_plane *dpla - const int pipe = intel_plane->pipe; - const int plane = intel_plane->plane + 1; - -+ /* -+ * We only populate skl_results on watermark updates, and if the -+ * plane's visiblity isn't actually changing neither is its watermarks. -+ */ -+ if (!to_intel_plane_state(dplane->state)->visible) -+ skl_write_plane_wm(to_intel_crtc(crtc), -+ &dev_priv->wm.skl_results, plane); -+ - I915_WRITE(PLANE_CTL(pipe, plane), 0); - - I915_WRITE(PLANE_SURF(pipe, plane), 0); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch deleted file mode 100644 index 58ac3c6a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 05a76d3d6ad1ee9f9814f88949cc9305fc165460 Mon Sep 17 00:00:00 2001 -From: Lyude -Date: Wed, 17 Aug 2016 15:55:57 -0400 -Subject: drm/i915/skl: Ensure pipes with changed wms get added to the state -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Lyude - -commit 05a76d3d6ad1ee9f9814f88949cc9305fc165460 upstream. - -If we're enabling a pipe, we'll need to modify the watermarks on all -active planes. Since those planes won't be added to the state on -their own, we need to add them ourselves. - -Signed-off-by: Lyude -Reviewed-by: Matt Roper -Cc: Ville Syrjälä -Cc: Daniel Vetter -Cc: Radhakrishna Sripada -Cc: Hans de Goede -Signed-off-by: Maarten Lankhorst -Link: http://patchwork.freedesktop.org/patch/msgid/1471463761-26796-6-git-send-email-cpaul@redhat.com -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_pm.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -4065,6 +4065,10 @@ skl_compute_ddb(struct drm_atomic_state - ret = skl_ddb_add_affected_planes(cstate); - if (ret) - return ret; -+ -+ ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); -+ if (ret) -+ return ret; - } - - return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch deleted file mode 100644 index 492d656f..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch +++ /dev/null @@ -1,479 +0,0 @@ -From 27082493e9c6371b05370a619ab9d2877c5f4726 Mon Sep 17 00:00:00 2001 -From: Lyude -Date: Wed, 24 Aug 2016 07:48:10 +0200 -Subject: drm/i915/skl: Update DDB values atomically with wms/plane attrs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Lyude - -commit 27082493e9c6371b05370a619ab9d2877c5f4726 upstream. - -Now that we can hook into update_crtcs and control the order in which we -update CRTCs at each modeset, we can finish the final step of fixing -Skylake's watermark handling by performing DDB updates at the same time -as plane updates and watermark updates. - -The first major change in this patch is skl_update_crtcs(), which -handles ensuring that we order each CRTC update in our atomic commits -properly so that they honor the DDB flush order. - -The second major change in this patch is the order in which we flush the -pipes. While the previous order may have worked, it can't be used in -this approach since it no longer will do the right thing. For example, -using the old ddb flush order: - -We have pipes A, B, and C enabled, and we're disabling C. Initial ddb -allocation looks like this: - -| A | B |xxxxxxx| - -Since we're performing the ddb updates after performing any CRTC -disablements in intel_atomic_commit_tail(), the space to the right of -pipe B is unallocated. - -1. Flush pipes with new allocation contained into old space. None - apply, so we skip this -2. Flush pipes having their allocation reduced, but overlapping with a - previous allocation. None apply, so we also skip this -3. Flush pipes that got more space allocated. This applies to A and B, - giving us the following update order: A, B - -This is wrong, since updating pipe A first will cause it to overlap with -B and potentially burst into flames. Our new order (see the code -comments for details) would update the pipes in the proper order: B, A. - -As well, we calculate the order for each DDB update during the check -phase, and reference it later in the commit phase when we hit -skl_update_crtcs(). - -This long overdue patch fixes the rest of the underruns on Skylake. - -Changes since v1: - - Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm() -Changes since v2: - - Use the method for updating CRTCs that Ville suggested - - In skl_update_wm(), only copy the watermarks for the crtc that was - passed to us -Changes since v3: - - Small comment fix in skl_ddb_allocation_overlaps() -Changes since v4: - - Remove the second loop in intel_update_crtcs() and use Ville's - suggestion for updating the ddb allocations in the right order - - Get rid of the second loop and just use the ddb state as it updates - to determine what order to update everything in (thanks for the - suggestion Ville) - - Simplify skl_ddb_allocation_overlaps() - - Split actual overlap checking into it's own helper - -Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration") -Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation") -[omitting CC for stable, since this patch will need to be changed for -such backports first] - -Testcase: kms_cursor_legacy -Testcase: plane-all-modeset-transition -Signed-off-by: Lyude -Cc: Ville Syrjälä -Cc: Daniel Vetter -Cc: Radhakrishna Sripada -Cc: Hans de Goede -Cc: Matt Roper -Signed-off-by: Maarten Lankhorst -Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_display.c | 93 ++++++++++++++-- - drivers/gpu/drm/i915/intel_drv.h | 7 + - drivers/gpu/drm/i915/intel_pm.c | 200 +++++++---------------------------- - 3 files changed, 132 insertions(+), 168 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -12967,16 +12967,23 @@ static void verify_wm_state(struct drm_c - hw_entry->start, hw_entry->end); - } - -- /* cursor */ -- hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; -- sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; -- -- if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { -- DRM_ERROR("mismatch in DDB state pipe %c cursor " -- "(expected (%u,%u), found (%u,%u))\n", -- pipe_name(pipe), -- sw_entry->start, sw_entry->end, -- hw_entry->start, hw_entry->end); -+ /* -+ * cursor -+ * If the cursor plane isn't active, we may not have updated it's ddb -+ * allocation. In that case since the ddb allocation will be updated -+ * once the plane becomes visible, we can skip this check -+ */ -+ if (intel_crtc->cursor_addr) { -+ hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; -+ sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; -+ -+ if (!skl_ddb_entry_equal(hw_entry, sw_entry)) { -+ DRM_ERROR("mismatch in DDB state pipe %c cursor " -+ "(expected (%u,%u), found (%u,%u))\n", -+ pipe_name(pipe), -+ sw_entry->start, sw_entry->end, -+ hw_entry->start, hw_entry->end); -+ } - } - } - -@@ -13728,6 +13735,65 @@ static void intel_update_crtcs(struct dr - } - } - -+static void skl_update_crtcs(struct drm_atomic_state *state, -+ unsigned int *crtc_vblank_mask) -+{ -+ struct drm_device *dev = state->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ struct intel_atomic_state *intel_state = to_intel_atomic_state(state); -+ struct drm_crtc *crtc; -+ struct drm_crtc_state *old_crtc_state; -+ struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; -+ struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; -+ unsigned int updated = 0; -+ bool progress; -+ enum pipe pipe; -+ -+ /* -+ * Whenever the number of active pipes changes, we need to make sure we -+ * update the pipes in the right order so that their ddb allocations -+ * never overlap with eachother inbetween CRTC updates. Otherwise we'll -+ * cause pipe underruns and other bad stuff. -+ */ -+ do { -+ int i; -+ progress = false; -+ -+ for_each_crtc_in_state(state, crtc, old_crtc_state, i) { -+ bool vbl_wait = false; -+ unsigned int cmask = drm_crtc_mask(crtc); -+ pipe = to_intel_crtc(crtc)->pipe; -+ -+ if (updated & cmask || !crtc->state->active) -+ continue; -+ if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb, -+ pipe)) -+ continue; -+ -+ updated |= cmask; -+ -+ /* -+ * If this is an already active pipe, it's DDB changed, -+ * and this isn't the last pipe that needs updating -+ * then we need to wait for a vblank to pass for the -+ * new ddb allocation to take effect. -+ */ -+ if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) && -+ !crtc->state->active_changed && -+ intel_state->wm_results.dirty_pipes != updated) -+ vbl_wait = true; -+ -+ intel_update_crtc(crtc, state, old_crtc_state, -+ crtc_vblank_mask); -+ -+ if (vbl_wait) -+ intel_wait_for_vblank(dev, pipe); -+ -+ progress = true; -+ } -+ } while (progress); -+} -+ - static void intel_atomic_commit_tail(struct drm_atomic_state *state) - { - struct drm_device *dev = state->dev; -@@ -15303,8 +15369,6 @@ void intel_init_display_hooks(struct drm - dev_priv->display.crtc_disable = i9xx_crtc_disable; - } - -- dev_priv->display.update_crtcs = intel_update_crtcs; -- - /* Returns the core display clock speed */ - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) - dev_priv->display.get_display_clock_speed = -@@ -15394,6 +15458,11 @@ void intel_init_display_hooks(struct drm - skl_modeset_calc_cdclk; - } - -+ if (dev_priv->info.gen >= 9) -+ dev_priv->display.update_crtcs = skl_update_crtcs; -+ else -+ dev_priv->display.update_crtcs = intel_update_crtcs; -+ - switch (INTEL_INFO(dev_priv)->gen) { - case 2: - dev_priv->display.queue_flip = intel_gen2_queue_flip; ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1720,6 +1720,13 @@ void skl_ddb_get_hw_state(struct drm_i91 - bool skl_can_enable_sagv(struct drm_atomic_state *state); - int skl_enable_sagv(struct drm_i915_private *dev_priv); - int skl_disable_sagv(struct drm_i915_private *dev_priv); -+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe); -+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, -+ const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe); - void skl_write_cursor_wm(struct intel_crtc *intel_crtc, - const struct skl_wm_values *wm); - void skl_write_plane_wm(struct intel_crtc *intel_crtc, ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3843,6 +3843,11 @@ void skl_write_plane_wm(struct intel_crt - wm->plane[pipe][plane][level]); - } - I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); -+ -+ skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane), -+ &wm->ddb.plane[pipe][plane]); -+ skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane), -+ &wm->ddb.y_plane[pipe][plane]); - } - - void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -@@ -3859,170 +3864,46 @@ void skl_write_cursor_wm(struct intel_cr - wm->plane[pipe][PLANE_CURSOR][level]); - } - I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); --} -- --static void skl_write_wm_values(struct drm_i915_private *dev_priv, -- const struct skl_wm_values *new) --{ -- struct drm_device *dev = &dev_priv->drm; -- struct intel_crtc *crtc; -- -- for_each_intel_crtc(dev, crtc) { -- int i; -- enum pipe pipe = crtc->pipe; -- -- if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) -- continue; -- if (!crtc->active) -- continue; -- -- for (i = 0; i < intel_num_planes(crtc); i++) { -- skl_ddb_entry_write(dev_priv, -- PLANE_BUF_CFG(pipe, i), -- &new->ddb.plane[pipe][i]); -- skl_ddb_entry_write(dev_priv, -- PLANE_NV12_BUF_CFG(pipe, i), -- &new->ddb.y_plane[pipe][i]); -- } - -- skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), -- &new->ddb.plane[pipe][PLANE_CURSOR]); -- } -+ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), -+ &wm->ddb.plane[pipe][PLANE_CURSOR]); - } - --/* -- * When setting up a new DDB allocation arrangement, we need to correctly -- * sequence the times at which the new allocations for the pipes are taken into -- * account or we'll have pipes fetching from space previously allocated to -- * another pipe. -- * -- * Roughly the sequence looks like: -- * 1. re-allocate the pipe(s) with the allocation being reduced and not -- * overlapping with a previous light-up pipe (another way to put it is: -- * pipes with their new allocation strickly included into their old ones). -- * 2. re-allocate the other pipes that get their allocation reduced -- * 3. allocate the pipes having their allocation increased -- * -- * Steps 1. and 2. are here to take care of the following case: -- * - Initially DDB looks like this: -- * | B | C | -- * - enable pipe A. -- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C -- * allocation -- * | A | B | C | -- * -- * We need to sequence the re-allocation: C, B, A (and not B, C, A). -- */ -- --static void --skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) -+bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe) - { -- int plane; -- -- DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); -- -- for_each_plane(dev_priv, pipe, plane) { -- I915_WRITE(PLANE_SURF(pipe, plane), -- I915_READ(PLANE_SURF(pipe, plane))); -- } -- I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); -+ return new->pipe[pipe].start == old->pipe[pipe].start && -+ new->pipe[pipe].end == old->pipe[pipe].end; - } - --static bool --skl_ddb_allocation_included(const struct skl_ddb_allocation *old, -- const struct skl_ddb_allocation *new, -- enum pipe pipe) -+static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, -+ const struct skl_ddb_entry *b) - { -- uint16_t old_size, new_size; -- -- old_size = skl_ddb_entry_size(&old->pipe[pipe]); -- new_size = skl_ddb_entry_size(&new->pipe[pipe]); -- -- return old_size != new_size && -- new->pipe[pipe].start >= old->pipe[pipe].start && -- new->pipe[pipe].end <= old->pipe[pipe].end; -+ return a->start < b->end && b->start < a->end; - } - --static void skl_flush_wm_values(struct drm_i915_private *dev_priv, -- struct skl_wm_values *new_values) -+bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, -+ const struct skl_ddb_allocation *old, -+ const struct skl_ddb_allocation *new, -+ enum pipe pipe) - { -- struct drm_device *dev = &dev_priv->drm; -- struct skl_ddb_allocation *cur_ddb, *new_ddb; -- bool reallocated[I915_MAX_PIPES] = {}; -- struct intel_crtc *crtc; -- enum pipe pipe; -- -- new_ddb = &new_values->ddb; -- cur_ddb = &dev_priv->wm.skl_hw.ddb; -- -- /* -- * First pass: flush the pipes with the new allocation contained into -- * the old space. -- * -- * We'll wait for the vblank on those pipes to ensure we can safely -- * re-allocate the freed space without this pipe fetching from it. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -- -- pipe = crtc->pipe; -- -- if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) -- continue; -- -- skl_wm_flush_pipe(dev_priv, pipe, 1); -- intel_wait_for_vblank(dev, pipe); -- -- reallocated[pipe] = true; -- } -- -- -- /* -- * Second pass: flush the pipes that are having their allocation -- * reduced, but overlapping with a previous allocation. -- * -- * Here as well we need to wait for the vblank to make sure the freed -- * space is not used anymore. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -+ struct drm_device *dev = state->dev; -+ struct intel_crtc *intel_crtc; -+ enum pipe otherp; - -- pipe = crtc->pipe; -+ for_each_intel_crtc(dev, intel_crtc) { -+ otherp = intel_crtc->pipe; - -- if (reallocated[pipe]) -+ if (otherp == pipe) - continue; - -- if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < -- skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { -- skl_wm_flush_pipe(dev_priv, pipe, 2); -- intel_wait_for_vblank(dev, pipe); -- reallocated[pipe] = true; -- } -+ if (skl_ddb_entries_overlap(&new->pipe[pipe], -+ &old->pipe[otherp])) -+ return true; - } - -- /* -- * Third pass: flush the pipes that got more space allocated. -- * -- * We don't need to actively wait for the update here, next vblank -- * will just get more DDB space with the correct WM values. -- */ -- for_each_intel_crtc(dev, crtc) { -- if (!crtc->active) -- continue; -- -- pipe = crtc->pipe; -- -- /* -- * At this point, only the pipes more space than before are -- * left to re-allocate. -- */ -- if (reallocated[pipe]) -- continue; -- -- skl_wm_flush_pipe(dev_priv, pipe, 3); -- } -+ return false; - } - - static int skl_update_pipe_wm(struct drm_crtc_state *cstate, -@@ -4224,7 +4105,7 @@ static void skl_update_wm(struct drm_crt - struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); - struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; -- int pipe; -+ enum pipe pipe = intel_crtc->pipe; - - if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) - return; -@@ -4233,15 +4114,22 @@ static void skl_update_wm(struct drm_crt - - mutex_lock(&dev_priv->wm.wm_mutex); - -- skl_write_wm_values(dev_priv, results); -- skl_flush_wm_values(dev_priv, results); -- - /* -- * Store the new configuration (but only for the pipes that have -- * changed; the other values weren't recomputed). -+ * If this pipe isn't active already, we're going to be enabling it -+ * very soon. Since it's safe to update a pipe's ddb allocation while -+ * the pipe's shut off, just do so here. Already active pipes will have -+ * their watermarks updated once we update their planes. - */ -- for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) -- skl_copy_wm_for_pipe(hw_vals, results, pipe); -+ if (crtc->state->active_changed) { -+ int plane; -+ -+ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) -+ skl_write_plane_wm(intel_crtc, results, plane); -+ -+ skl_write_cursor_wm(intel_crtc, results); -+ } -+ -+ skl_copy_wm_for_pipe(hw_vals, results, pipe); - - mutex_unlock(&dev_priv->wm.wm_mutex); - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch deleted file mode 100644 index d9798c44..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch +++ /dev/null @@ -1,335 +0,0 @@ -From 62e0fb880123c98793e5c3ba8355501b0305e92e Mon Sep 17 00:00:00 2001 -From: Lyude -Date: Mon, 22 Aug 2016 12:50:08 -0400 -Subject: drm/i915/skl: Update plane watermarks atomically during plane updates -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Lyude - -commit 62e0fb880123c98793e5c3ba8355501b0305e92e upstream. - -Thanks to Ville for suggesting this as a potential solution to pipe -underruns on Skylake. - -On Skylake all of the registers for configuring planes, including the -registers for configuring their watermarks, are double buffered. New -values written to them won't take effect until said registers are -"armed", which is done by writing to the PLANE_SURF (or in the case of -cursor planes, the CURBASE register) register. - -With this in mind, up until now we've been updating watermarks on skl -like this: - - non-modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - intel_pre_plane_update: - - intel_update_watermarks() - - {vblank happens; new watermarks + old plane values => underrun } - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - end vblank evasion - } - - or - - modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - crtc_enable: - - intel_update_watermarks() - - {vblank happens; new watermarks + old plane values => underrun } - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - end vblank evasion - } - -Now we update watermarks atomically like this: - - non-modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - intel_pre_plane_update: - - intel_update_watermarks() (wm values aren't written yet) - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - write new wm values - - end vblank evasion - } - - modeset { - - calculate (during atomic check phase) - - finish_atomic_commit: - - crtc_enable: - - intel_update_watermarks() (actual wm values aren't written - yet) - - drm_atomic_helper_commit_planes_on_crtc: - - start vblank evasion - - write new plane registers - - write new wm values - - end vblank evasion - } - -So this patch moves all of the watermark writes into the right place; -inside of the vblank evasion where we update all of the registers for -each plane. While this patch doesn't fix everything, it does allow us to -update the watermark values in the way the hardware expects us to. - -Changes since original patch series: - - Remove mutex_lock/mutex_unlock since they don't do anything and we're - not touching global state - - Move skl_write_cursor_wm/skl_write_plane_wm functions into - intel_pm.c, make externally visible - - Add skl_write_plane_wm calls to skl_update_plane - - Fix conditional for for loop in skl_write_plane_wm (level < max_level - should be level <= max_level) - - Make diagram in commit more accurate to what's actually happening - - Add Fixes: - -Changes since v1: - - Use IS_GEN9() instead of IS_SKYLAKE() since these fixes apply to more - then just Skylake - - Update description to make it clear this patch doesn't fix everything - - Check if pipes were actually changed before writing watermarks - -Changes since v2: - - Write PIPE_WM_LINETIME during vblank evasion - -Changes since v3: - - Rebase against new SAGV patch changes - -Changes since v4: - - Add a parameter to choose what skl_wm_values struct to use when - writing new plane watermarks - -Changes since v5: - - Remove cursor ddb entry write in skl_write_cursor_wm(), defer until - patch 6 - - Write WM_LINETIME in intel_begin_crtc_commit() - -Changes since v6: - - Remove redundant dirty_pipes check in skl_write_plane_wm (we check - this in all places where we call this function, and it was supposed - to have been removed earlier anyway) - - In i9xx_update_cursor(), use dev_priv->info.gen >= 9 instead of - IS_GEN9(dev_priv). We do this everywhere else and I'd imagine this - needs to be done for gen10 as well - -Changes since v7: - - Fix rebase fail (unused variable obj) - - Make struct skl_wm_values *wm const - - Fix indenting - - Use INTEL_GEN() instead of dev_priv->info.gen - -Changes since v8: - - Don't forget calls to skl_write_plane_wm() when disabling planes - - Use INTEL_GEN(), not INTEL_INFO()->gen in intel_begin_crtc_commit() - -Fixes: 2d41c0b59afc ("drm/i915/skl: SKL Watermark Computation") -Signed-off-by: Lyude -Reviewed-by: Matt Roper -Cc: stable@vger.kernel.org -Cc: Ville Syrjälä -Cc: Daniel Vetter -Cc: Radhakrishna Sripada -Cc: Hans de Goede -Signed-off-by: Maarten Lankhorst -Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com -Link: http://patchwork.freedesktop.org/patch/msgid/1471884608-10671-1-git-send-email-cpaul@redhat.com -Signed-off-by: Greg Kroah-Hartman - - ---- - drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++- - drivers/gpu/drm/i915/intel_drv.h | 5 +++ - drivers/gpu/drm/i915/intel_pm.c | 50 +++++++++++++++++++++++------------ - drivers/gpu/drm/i915/intel_sprite.c | 6 ++++ - 4 files changed, 64 insertions(+), 18 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); - struct drm_framebuffer *fb = plane_state->base.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; - int pipe = intel_crtc->pipe; - u32 plane_ctl, stride_div, stride; - u32 tile_height, plane_offset, plane_size; -@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane - intel_crtc->adjusted_x = x_offset; - intel_crtc->adjusted_y = y_offset; - -+ if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) -+ skl_write_plane_wm(intel_crtc, wm, 0); -+ - I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); - I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset); - I915_WRITE(PLANE_SIZE(pipe, 0), plane_size); -@@ -3061,7 +3065,10 @@ static void skylake_disable_primary_plan - { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); -- int pipe = to_intel_crtc(crtc)->pipe; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ int pipe = intel_crtc->pipe; -+ -+ skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0); - - I915_WRITE(PLANE_CTL(pipe, 0), 0); - I915_WRITE(PLANE_SURF(pipe, 0), 0); -@@ -10306,9 +10313,13 @@ static void i9xx_update_cursor(struct dr - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; - int pipe = intel_crtc->pipe; - uint32_t cntl = 0; - -+ if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc)) -+ skl_write_cursor_wm(intel_crtc, wm); -+ - if (plane_state && plane_state->visible) { - cntl = MCURSOR_GAMMA_ENABLE; - switch (plane_state->base.crtc_w) { -@@ -14221,10 +14232,12 @@ static void intel_begin_crtc_commit(stru - struct drm_crtc_state *old_crtc_state) - { - struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *old_intel_state = - to_intel_crtc_state(old_crtc_state); - bool modeset = needs_modeset(crtc->state); -+ enum pipe pipe = intel_crtc->pipe; - - /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(intel_crtc); -@@ -14239,8 +14252,12 @@ static void intel_begin_crtc_commit(stru - - if (to_intel_crtc_state(crtc->state)->update_pipe) - intel_update_pipe_config(intel_crtc, old_intel_state); -- else if (INTEL_INFO(dev)->gen >= 9) -+ else if (INTEL_GEN(dev_priv) >= 9) { - skl_detach_scalers(intel_crtc); -+ -+ I915_WRITE(PIPE_WM_LINETIME(pipe), -+ dev_priv->wm.skl_hw.wm_linetime[pipe]); -+ } - } - - static void intel_finish_crtc_commit(struct drm_crtc *crtc, ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1720,6 +1720,11 @@ void skl_ddb_get_hw_state(struct drm_i91 - bool skl_can_enable_sagv(struct drm_atomic_state *state); - int skl_enable_sagv(struct drm_i915_private *dev_priv); - int skl_disable_sagv(struct drm_i915_private *dev_priv); -+void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm); -+void skl_write_plane_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm, -+ int plane); - uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); - bool ilk_disable_lp_wm(struct drm_device *dev); - int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); ---- a/drivers/gpu/drm/i915/intel_pm.c -+++ b/drivers/gpu/drm/i915/intel_pm.c -@@ -3828,6 +3828,39 @@ static void skl_ddb_entry_write(struct d - I915_WRITE(reg, 0); - } - -+void skl_write_plane_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm, -+ int plane) -+{ -+ struct drm_crtc *crtc = &intel_crtc->base; -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ int level, max_level = ilk_wm_max_level(dev); -+ enum pipe pipe = intel_crtc->pipe; -+ -+ for (level = 0; level <= max_level; level++) { -+ I915_WRITE(PLANE_WM(pipe, plane, level), -+ wm->plane[pipe][plane][level]); -+ } -+ I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]); -+} -+ -+void skl_write_cursor_wm(struct intel_crtc *intel_crtc, -+ const struct skl_wm_values *wm) -+{ -+ struct drm_crtc *crtc = &intel_crtc->base; -+ struct drm_device *dev = crtc->dev; -+ struct drm_i915_private *dev_priv = to_i915(dev); -+ int level, max_level = ilk_wm_max_level(dev); -+ enum pipe pipe = intel_crtc->pipe; -+ -+ for (level = 0; level <= max_level; level++) { -+ I915_WRITE(CUR_WM(pipe, level), -+ wm->plane[pipe][PLANE_CURSOR][level]); -+ } -+ I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]); -+} -+ - static void skl_write_wm_values(struct drm_i915_private *dev_priv, - const struct skl_wm_values *new) - { -@@ -3835,7 +3868,7 @@ static void skl_write_wm_values(struct d - struct intel_crtc *crtc; - - for_each_intel_crtc(dev, crtc) { -- int i, level, max_level = ilk_wm_max_level(dev); -+ int i; - enum pipe pipe = crtc->pipe; - - if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0) -@@ -3843,21 +3876,6 @@ static void skl_write_wm_values(struct d - if (!crtc->active) - continue; - -- I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]); -- -- for (level = 0; level <= max_level; level++) { -- for (i = 0; i < intel_num_planes(crtc); i++) -- I915_WRITE(PLANE_WM(pipe, i, level), -- new->plane[pipe][i][level]); -- I915_WRITE(CUR_WM(pipe, level), -- new->plane[pipe][PLANE_CURSOR][level]); -- } -- for (i = 0; i < intel_num_planes(crtc); i++) -- I915_WRITE(PLANE_WM_TRANS(pipe, i), -- new->plane_trans[pipe][i]); -- I915_WRITE(CUR_WM_TRANS(pipe), -- new->plane_trans[pipe][PLANE_CURSOR]); -- - for (i = 0; i < intel_num_planes(crtc); i++) { - skl_ddb_entry_write(dev_priv, - PLANE_BUF_CFG(pipe, i), ---- a/drivers/gpu/drm/i915/intel_sprite.c -+++ b/drivers/gpu/drm/i915/intel_sprite.c -@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_p - struct intel_plane *intel_plane = to_intel_plane(drm_plane); - struct drm_framebuffer *fb = plane_state->base.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); -+ const struct skl_wm_values *wm = &dev_priv->wm.skl_results; -+ struct drm_crtc *crtc = crtc_state->base.crtc; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - const int pipe = intel_plane->pipe; - const int plane = intel_plane->plane + 1; - u32 plane_ctl, stride_div, stride; -@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_p - crtc_w--; - crtc_h--; - -+ if (wm->dirty_pipes & drm_crtc_mask(crtc)) -+ skl_write_plane_wm(intel_crtc, wm, plane); -+ - if (key->flags) { - I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); - I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch b/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch deleted file mode 100644 index 53219119..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch +++ /dev/null @@ -1,61 +0,0 @@ -From ca5732c53bf66ad755284786897e0dd10330de87 Mon Sep 17 00:00:00 2001 -From: Chris Wilson -Date: Mon, 3 Oct 2016 13:45:15 +0100 -Subject: drm/i915: Unalias obj->phys_handle and obj->userptr - -From: Chris Wilson - -commit ca5732c53bf66ad755284786897e0dd10330de87 upstream. - -We use obj->phys_handle to choose the pread/pwrite path, but as -obj->phys_handle is a union with obj->userptr, we then mistakenly use -the phys_handle path for userptr objects within pread/pwrite. - -Testcase: igt/gem_userptr_blits/forbidden-operations -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97519 -Signed-off-by: Chris Wilson -Reviewed-by: Joonas Lahtinen -Link: http://patchwork.freedesktop.org/patch/msgid/20161003124516.12388-2-chris@chris-wilson.co.uk -(cherry picked from commit 5f12b80a0b42da253691ca03828033014bb786eb) -Signed-off-by: Jani Nikula -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/i915_drv.h | 24 +++++++++++------------- - 1 file changed, 11 insertions(+), 13 deletions(-) - ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -2282,21 +2282,19 @@ struct drm_i915_gem_object { - /** Record of address bit 17 of each page at last unbind. */ - unsigned long *bit_17; - -- union { -- /** for phy allocated objects */ -- struct drm_dma_handle *phys_handle; -- -- struct i915_gem_userptr { -- uintptr_t ptr; -- unsigned read_only :1; -- unsigned workers :4; -+ struct i915_gem_userptr { -+ uintptr_t ptr; -+ unsigned read_only :1; -+ unsigned workers :4; - #define I915_GEM_USERPTR_MAX_WORKERS 15 - -- struct i915_mm_struct *mm; -- struct i915_mmu_object *mmu_object; -- struct work_struct *work; -- } userptr; -- }; -+ struct i915_mm_struct *mm; -+ struct i915_mmu_object *mmu_object; -+ struct work_struct *work; -+ } userptr; -+ -+ /** for phys allocated objects */ -+ struct drm_dma_handle *phys_handle; - }; - #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) - diff --git a/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch b/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch deleted file mode 100644 index 242e1f81..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 56a76c0123d6cb034975901c80fce2627338ef9e Mon Sep 17 00:00:00 2001 -From: Chris Wilson -Date: Wed, 5 Oct 2016 13:21:43 +0100 -Subject: drm/prime: Pass the right module owner through to dma_buf_export() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Chris Wilson - -commit 56a76c0123d6cb034975901c80fce2627338ef9e upstream. - -dma_buf_export() adds a reference to the owning module to the dmabuf (to -prevent the driver from being unloaded whilst a third party still refers -to the dmabuf). However, drm_gem_prime_export() was passing its own -THIS_MODULE (i.e. drm.ko) rather than the driver. Extract the right -owner from the device->fops instead. - -v2: Use C99 initializers to zero out unset elements of -dma_buf_export_info -v3: Extract the right module from dev->fops. - -Testcase: igt/vgem_basic/unload -Reported-by: Petri Latvala -Signed-off-by: Chris Wilson -Cc: Petri Latvala -Cc: Christian König -Tested-by: Petri Latvala -Reviewed-by: Petri Latvala -Reviewed-by: Christian König -Signed-off-by: Daniel Vetter -Link: http://patchwork.freedesktop.org/patch/msgid/20161005122145.1507-1-chris@chris-wilson.co.uk -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/drm_prime.c | 17 ++++++++++------- - include/drm/drmP.h | 3 ++- - 2 files changed, 12 insertions(+), 8 deletions(-) - ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -335,14 +335,17 @@ static const struct dma_buf_ops drm_gem_ - * using the PRIME helpers. - */ - struct dma_buf *drm_gem_prime_export(struct drm_device *dev, -- struct drm_gem_object *obj, int flags) -+ struct drm_gem_object *obj, -+ int flags) - { -- DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -- -- exp_info.ops = &drm_gem_prime_dmabuf_ops; -- exp_info.size = obj->size; -- exp_info.flags = flags; -- exp_info.priv = obj; -+ struct dma_buf_export_info exp_info = { -+ .exp_name = KBUILD_MODNAME, /* white lie for debug */ -+ .owner = dev->driver->fops->owner, -+ .ops = &drm_gem_prime_dmabuf_ops, -+ .size = obj->size, -+ .flags = flags, -+ .priv = obj, -+ }; - - if (dev->driver->gem_prime_res_obj) - exp_info.resv = dev->driver->gem_prime_res_obj(obj); ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -938,7 +938,8 @@ static inline int drm_debugfs_remove_fil - #endif - - extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, -- struct drm_gem_object *obj, int flags); -+ struct drm_gem_object *obj, -+ int flags); - extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd); diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch deleted file mode 100644 index aae96954..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 02cfb5fccb0f9f968f0e208d89d9769aa16267bc Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Wed, 12 Oct 2016 15:28:55 -0400 -Subject: drm/radeon: change vblank_time's calculation method to reduce computational error. - -From: Alex Deucher - -commit 02cfb5fccb0f9f968f0e208d89d9769aa16267bc upstream. - -Ported from Rex's amdgpu change. - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/radeon/r600_dpm.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - ---- a/drivers/gpu/drm/radeon/r600_dpm.c -+++ b/drivers/gpu/drm/radeon/r600_dpm.c -@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct rade - struct drm_device *dev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; -- u32 line_time_us, vblank_lines; -+ u32 vblank_in_pixels; - u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ - - if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { -- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / -- radeon_crtc->hw_mode.clock; -- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - -- radeon_crtc->hw_mode.crtc_vdisplay + -- (radeon_crtc->v_border * 2); -- vblank_time_us = vblank_lines * line_time_us; -+ vblank_in_pixels = -+ radeon_crtc->hw_mode.crtc_htotal * -+ (radeon_crtc->hw_mode.crtc_vblank_end - -+ radeon_crtc->hw_mode.crtc_vdisplay + -+ (radeon_crtc->v_border * 2)); -+ -+ vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock; - break; - } - } diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch deleted file mode 100644 index 0574fb0f..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 884031f0aacf57dad1575f96714efc80de9b19cc Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Mon, 19 Sep 2016 12:35:22 -0400 -Subject: drm/radeon: narrow asic_init for virtualization - -From: Alex Deucher - -commit 884031f0aacf57dad1575f96714efc80de9b19cc upstream. - -Only needed on CIK+ due to the way pci reset is handled -by the GPU. - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/radeon/radeon_device.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/radeon/radeon_device.c -+++ b/drivers/gpu/drm/radeon/radeon_device.c -@@ -661,8 +661,9 @@ bool radeon_card_posted(struct radeon_de - { - uint32_t reg; - -- /* for pass through, always force asic_init */ -- if (radeon_device_is_virtual()) -+ /* for pass through, always force asic_init for CI */ -+ if (rdev->family >= CHIP_BONAIRE && -+ radeon_device_is_virtual()) - return false; - - /* required for EFI mode on macbook2,1 which uses an r5xx asic */ diff --git a/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch b/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch deleted file mode 100644 index 26bc118e..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 427920292b00474d978d632bc03a8e4e50029af3 Mon Sep 17 00:00:00 2001 -From: Alex Deucher -Date: Tue, 27 Sep 2016 14:51:53 -0400 -Subject: drm/radeon/si/dpm: fix phase shedding setup - -From: Alex Deucher - -commit 427920292b00474d978d632bc03a8e4e50029af3 upstream. - -Used the wrong index to setup the phase shedding mask. - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/radeon/si_dpm.c | 2 +- - drivers/gpu/drm/radeon/sislands_smc.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/radeon/si_dpm.c -+++ b/drivers/gpu/drm/radeon/si_dpm.c -@@ -4112,7 +4112,7 @@ static int si_populate_smc_voltage_table - &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) { - si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table); - -- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = -+ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] = - cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low); - - si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay, ---- a/drivers/gpu/drm/radeon/sislands_smc.h -+++ b/drivers/gpu/drm/radeon/sislands_smc.h -@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISL - #define SISLANDS_SMC_VOLTAGEMASK_VDDC 0 - #define SISLANDS_SMC_VOLTAGEMASK_MVDD 1 - #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2 -+#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 - #define SISLANDS_SMC_VOLTAGEMASK_MAX 4 - - struct SISLANDS_SMC_VOLTAGEMASKTABLE diff --git a/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch b/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch deleted file mode 100644 index a4734007..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 7edabee06a5622190d59689a64f5e17d1c343cc3 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 27 Sep 2016 09:03:13 -0700 -Subject: drm/vc4: Fix races when the CS reads from render targets. - -From: Eric Anholt - -commit 7edabee06a5622190d59689a64f5e17d1c343cc3 upstream. - -With the introduction of bin/render pipelining, the previous job may -not be completed when we start binning the next one. If the previous -job wrote our VBO, IB, or CS textures, then the binning stage might -get stale or uninitialized results. - -Fixes the major rendering failure in glmark2 -b terrain. - -Signed-off-by: Eric Anholt -Fixes: ca26d28bbaa3 ("drm/vc4: improve throughput by pipelining binning and rendering jobs") -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/vc4/vc4_drv.h | 19 ++++++++++++++++++- - drivers/gpu/drm/vc4/vc4_gem.c | 13 +++++++++++++ - drivers/gpu/drm/vc4/vc4_render_cl.c | 21 +++++++++++++++++---- - drivers/gpu/drm/vc4/vc4_validate.c | 17 ++++++++++++++--- - 4 files changed, 62 insertions(+), 8 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev) - struct vc4_bo { - struct drm_gem_cma_object base; - -- /* seqno of the last job to render to this BO. */ -+ /* seqno of the last job to render using this BO. */ - uint64_t seqno; - -+ /* seqno of the last job to use the RCL to write to this BO. -+ * -+ * Note that this doesn't include binner overflow memory -+ * writes. -+ */ -+ uint64_t write_seqno; -+ - /* List entry for the BO's position in either - * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list - */ -@@ -216,6 +223,9 @@ struct vc4_exec_info { - /* Sequence number for this bin/render job. */ - uint64_t seqno; - -+ /* Latest write_seqno of any BO that binning depends on. */ -+ uint64_t bin_dep_seqno; -+ - /* Last current addresses the hardware was processing when the - * hangcheck timer checked on us. - */ -@@ -230,6 +240,13 @@ struct vc4_exec_info { - struct drm_gem_cma_object **bo; - uint32_t bo_count; - -+ /* List of BOs that are being written by the RCL. Other than -+ * the binner temporary storage, this is all the BOs written -+ * by the job. -+ */ -+ struct drm_gem_cma_object *rcl_write_bo[4]; -+ uint32_t rcl_write_bo_count; -+ - /* Pointers for our position in vc4->job_list */ - struct list_head head; - ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_inf - list_for_each_entry(bo, &exec->unref_list, unref_head) { - bo->seqno = seqno; - } -+ -+ for (i = 0; i < exec->rcl_write_bo_count; i++) { -+ bo = to_vc4_bo(&exec->rcl_write_bo[i]->base); -+ bo->write_seqno = seqno; -+ } - } - - /* Queues a struct vc4_exec_info for execution. If no job is -@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, stru - goto fail; - - ret = vc4_validate_shader_recs(dev, exec); -+ if (ret) -+ goto fail; -+ -+ /* Block waiting on any previous rendering into the CS's VBO, -+ * IB, or textures, so that pixels are actually written by the -+ * time we try to read them. -+ */ -+ ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true); - - fail: - drm_free_large(temp); ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -45,6 +45,8 @@ struct vc4_rcl_setup { - - struct drm_gem_cma_object *rcl; - u32 next_offset; -+ -+ u32 next_write_bo_index; - }; - - static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) -@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(st - if (!*obj) - return -EINVAL; - -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (surf->offset & 0xf) { - DRM_ERROR("MSAA write must be 16b aligned.\n"); - return -EINVAL; -@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(st - - static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - struct drm_gem_cma_object **obj, -- struct drm_vc4_submit_rcl_surface *surf) -+ struct drm_vc4_submit_rcl_surface *surf, -+ bool is_write) - { - uint8_t tiling = VC4_GET_FIELD(surf->bits, - VC4_LOADSTORE_TILE_BUFFER_TILING); -@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct - if (!*obj) - return -EINVAL; - -+ if (is_write) -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { - if (surf == &exec->args->zs_write) { - DRM_ERROR("general zs write may not be a full-res.\n"); -@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(stru - if (!*obj) - return -EINVAL; - -+ exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; -+ - if (tiling > VC4_TILING_FORMAT_LT) { - DRM_ERROR("Bad tiling format\n"); - return -EINVAL; -@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read, -+ false); - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read, -+ false); - if (ret) - return ret; - -- ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write, -+ true); - if (ret) - return ret; - ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS - if (!ib) - return -EINVAL; - -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&ib->base)->write_seqno); -+ - if (offset > ib->base.size || - (ib->base.size - offset) / index_size < length) { - DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", -@@ -555,8 +558,7 @@ static bool - reloc_tex(struct vc4_exec_info *exec, - void *uniform_data_u, - struct vc4_texture_sample_info *sample, -- uint32_t texture_handle_index) -- -+ uint32_t texture_handle_index, bool is_cs) - { - struct drm_gem_cma_object *tex; - uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); -@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec, - - *validated_p0 = tex->paddr + p0; - -+ if (is_cs) { -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&tex->base)->write_seqno); -+ } -+ - return true; - fail: - DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); -@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device - if (!reloc_tex(exec, - uniform_data_u, - &validated_shader->texture_samples[tex], -- texture_handles_u[tex])) { -+ texture_handles_u[tex], -+ i == 2)) { - return -EINVAL; - } - } -@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device - uint32_t stride = *(uint8_t *)(pkt_u + o + 5); - uint32_t max_index; - -+ exec->bin_dep_seqno = max(exec->bin_dep_seqno, -+ to_vc4_bo(&vbo->base)->write_seqno); -+ - if (state->addr & 0x8) - stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; - diff --git a/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch b/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch deleted file mode 100644 index c3ae1473..00000000 --- a/kernel/kernel/files/patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 51ab70bed997f64f091a639dbe22b629725a7faf Mon Sep 17 00:00:00 2001 -From: Thomas Hellstrom -Date: Mon, 10 Oct 2016 10:51:24 -0700 -Subject: drm/vmwgfx: Limit the user-space command buffer size - -From: Thomas Hellstrom - -commit 51ab70bed997f64f091a639dbe22b629725a7faf upstream. - -With older hardware versions, the user could specify arbitrarily large -command buffer sizes, causing a vmalloc / vmap space exhaustion. - -Signed-off-by: Thomas Hellstrom -Reviewed-by: Brian Paul -Reviewed-by: Sinclair Yeh -Signed-off-by: Sinclair Yeh -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -@@ -3848,14 +3848,14 @@ static void *vmw_execbuf_cmdbuf(struct v - int ret; - - *header = NULL; -- if (!dev_priv->cman || kernel_commands) -- return kernel_commands; -- - if (command_size > SVGA_CB_MAX_SIZE) { - DRM_ERROR("Command buffer is too large.\n"); - return ERR_PTR(-EINVAL); - } - -+ if (!dev_priv->cman || kernel_commands) -+ return kernel_commands; -+ - /* If possible, add a little space for fencing. */ - cmdbuf_size = command_size + 512; - cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE); diff --git a/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch b/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch deleted file mode 100644 index 9505a731..00000000 --- a/kernel/kernel/files/patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch +++ /dev/null @@ -1,68 +0,0 @@ -From ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 Mon Sep 17 00:00:00 2001 -From: Sebastian Frias -Date: Mon, 1 Aug 2016 16:27:38 +0200 -Subject: genirq/generic_chip: Add irq_unmap callback - -From: Sebastian Frias - -commit ee26c013cdee0b947e29d6cadfb9ff3341c69ff9 upstream. - -Without this patch irq_domain_disassociate() cannot properly release the -interrupt. In fact, irq_map_generic_chip() checks a bit on 'gc->installed' -but said bit is never cleared, only set. - -Commit 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support") -added irq_map_generic_chip() function and also stated "This lacks a removal -function for now". - -This commit provides an implementation of an unmap function that can be -called by irq_domain_disassociate(). - -[ tglx: Made the function static and removed the export as we have neither - a prototype nor a modular user. ] - -Fixes: 088f40b7b027 ("genirq: Generic chip: Add linear irq domain support") -Signed-off-by: Sebastian Frias -Cc: Marc Zyngier -Cc: Mason -Cc: Jason Cooper -Link: http://lkml.kernel.org/r/579F5C5A.2070507@laposte.net -Signed-off-by: Thomas Gleixner -Signed-off-by: Greg Kroah-Hartman - ---- - kernel/irq/generic-chip.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/kernel/irq/generic-chip.c -+++ b/kernel/irq/generic-chip.c -@@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_doma - } - EXPORT_SYMBOL_GPL(irq_map_generic_chip); - -+static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq) -+{ -+ struct irq_data *data = irq_domain_get_irq_data(d, virq); -+ struct irq_domain_chip_generic *dgc = d->gc; -+ unsigned int hw_irq = data->hwirq; -+ struct irq_chip_generic *gc; -+ int irq_idx; -+ -+ gc = irq_get_domain_generic_chip(d, hw_irq); -+ if (!gc) -+ return; -+ -+ irq_idx = hw_irq % dgc->irqs_per_chip; -+ -+ clear_bit(irq_idx, &gc->installed); -+ irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL, -+ NULL); -+ -+} -+ - struct irq_domain_ops irq_generic_chip_ops = { - .map = irq_map_generic_chip, -+ .unmap = irq_unmap_generic_chip, - .xlate = irq_domain_xlate_onetwocell, - }; - EXPORT_SYMBOL_GPL(irq_generic_chip_ops); diff --git a/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch b/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch deleted file mode 100644 index 487050c3..00000000 --- a/kernel/kernel/files/patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 4973ca9a01e2354b159acedec1b9b8eb8de02ab7 Mon Sep 17 00:00:00 2001 -From: "Steinar H. Gunderson" -Date: Sun, 9 Oct 2016 14:21:50 +0200 -Subject: HID: add quirk for Akai MIDImix. - -From: Steinar H. Gunderson - -commit 4973ca9a01e2354b159acedec1b9b8eb8de02ab7 upstream. - -The Akai MIDImix (09e8:0031) is a MIDI fader controller that speaks -regular MIDI and works well with Linux. However, initialization gets -delayed due to reports timeout: - - [3643645.631124] hid-generic 0003:09E8:0031.0020: timeout initializing reports - [3643645.632416] hid-generic 0003:09E8:0031.0020: hiddev0: USB HID v1.11 Device [AKAI MIDI Mix] on usb-0000:00:14.0-2/input0 - -Adding "usbhid.quirks=0x09e8:0x0031:0x20000000" on the kernel -command line makes the issues go away. - -Signed-off-by: Steinar H. Gunderson -Signed-off-by: Jiri Kosina -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/hid/hid-ids.h | 3 +++ - drivers/hid/usbhid/hid-quirks.c | 1 + - 2 files changed, 4 insertions(+) - ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -64,6 +64,9 @@ - #define USB_VENDOR_ID_AKAI 0x2011 - #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 - -+#define USB_VENDOR_ID_AKAI_09E8 0x09E8 -+#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031 -+ - #define USB_VENDOR_ID_ALCOR 0x058f - #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 - ---- a/drivers/hid/usbhid/hid-quirks.c -+++ b/drivers/hid/usbhid/hid-quirks.c -@@ -56,6 +56,7 @@ static const struct hid_blacklist { - - { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, -+ { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, diff --git a/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch b/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch deleted file mode 100644 index 0b54b3d5..00000000 --- a/kernel/kernel/files/patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ad8529fde9e3601180a839867a8ab041109aebb5 Mon Sep 17 00:00:00 2001 -From: Dave Gerlach -Date: Tue, 20 Sep 2016 10:25:40 -0500 -Subject: hwrng: omap - Only fail if pm_runtime_get_sync returns < 0 - -From: Dave Gerlach - -commit ad8529fde9e3601180a839867a8ab041109aebb5 upstream. - -Currently omap-rng checks the return value of pm_runtime_get_sync and -reports failure if anything is returned, however it should be checking -if ret < 0 as pm_runtime_get_sync return 0 on success but also can return -1 if the device was already active which is not a failure case. Only -values < 0 are actual failures. - -Fixes: 61dc0a446e5d ("hwrng: omap - Fix assumption that runtime_get_sync will always succeed") -Signed-off-by: Dave Gerlach -Signed-off-by: Herbert Xu -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/char/hw_random/omap-rng.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/char/hw_random/omap-rng.c -+++ b/drivers/char/hw_random/omap-rng.c -@@ -385,7 +385,7 @@ static int omap_rng_probe(struct platfor - - pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); -- if (ret) { -+ if (ret < 0) { - dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret); - pm_runtime_put_noidle(&pdev->dev); - goto err_ioremap; -@@ -443,7 +443,7 @@ static int __maybe_unused omap_rng_resum - int ret; - - ret = pm_runtime_get_sync(dev); -- if (ret) { -+ if (ret < 0) { - dev_err(dev, "Failed to runtime_get device: %d\n", ret); - pm_runtime_put_noidle(dev); - return ret; diff --git a/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch b/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch deleted file mode 100644 index d74fe900..00000000 --- a/kernel/kernel/files/patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 776b2e15f8af7900409456292efd45af6de97172 Mon Sep 17 00:00:00 2001 -From: Jacob Keller -Date: Tue, 19 Jul 2016 16:23:30 -0700 -Subject: i40e: fix broken i40e_config_rss_aq function - -From: Jacob Keller - -commit 776b2e15f8af7900409456292efd45af6de97172 upstream. - -X722 hardware requires using the admin queue to configure RSS. This -function was previously re-written in commit e69ff813af35 ("i40e: rework -the functions to configure RSS with similar parameters"). -However, the previous refactor did not work correctly for a few reasons - -(a) it does not check whether seed is NULL before using it, resulting in -a NULL pointer dereference - -[ 402.954721] BUG: unable to handle kernel NULL pointer dereference at (null) -[ 402.955568] IP: [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] -[ 402.956402] PGD ad610067 PUD accc0067 PMD 0 -[ 402.957235] Oops: 0000 [#1] SMP -[ 402.958064] Modules linked in: ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_filter ebtable_ -broute bridge stp llc ebtable_nat ebtables ip6table_mangle ip6table_raw ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv -6 ip6table_security ip6table_filter ip6_tables iptable_mangle iptable_raw iptable_nat nf_conntrack_ipv4_ nf_defrag_ipv4_ nf_nat_ip -v4_ nf_nat nf_conntrack iptable_security intel_rapl i86_kg_temp_thermal coretemp kvm_intel kvm irqbypass crct10dif_clMl crc32_ -pclMl ghash_clMlni_intel iTCO_wdt iTCO_vendor_support shpchp sb_edac dcdbas pcspkr joydev ipmi_devintf wmi edac_core ipmi_ssif - acpi_ad acpi_ower_meter ipmi_si ipmi_msghandler mei_me nfsd lpc_ich mei ioatdma tpm_tis auth_rpcgss tpm nfs_acl lockd grace s -unrpc ifs nngag200 i2c_algo_bit drm_kms_helper ttm drm iigbe bnx2x i40e dca mdio ptp pps_core libcrc32c fjes crc32c_intel -[ 402.965563] CPU: 22 PID: 2461 Conm: ethtool Not tainted 4.6.0-rc7_1.2-ABNidQ+ #20 -[ 402.966719] Hardware name: Dell Inc. PowerEdge R720/0C4Y3R, BIOS 2.5.2 01/28/2015 -[ 402.967862] task: ffff880219b51dc0 ti: ffff8800b3408000 task.ti: ffff8800b3408000 -[ 402.969046] RIP: 0010:[] [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] -[ 402.970339] RSP: 0018:ffff8800b340ba90 EFLAGS: 00010246 -[ 402.971616] RAX: 0000000000000000 RBX: ffff88042ec14000 RCX: 0000000000000200 -[ 402.972961] RDX: ffff880428eb9200 RSI: 0000000000000000 RDI: ffff88042ec14000 -[ 402.974312] RBP: ffff8800b340baf8 R08: ffff880237ada8f0 R09: ffff880428eb9200 -[ 402.975709] R10: ffff880428eb9200 R11: 0000000000000000 R12: ffff88042ec2e000 -[ 402.977104] R13: ffff88042ec2e000 R14: ffff88042ec14000 R15: ffff88022ea00800 -[ 402.978541] FS: 00007f84fd054700(0000) GS:ffff880237ac0000(0000) knlGS:0000000000000000 -[ 402.980003] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 -[ 402.981508] CR2: 0000000000000000 CR3: 000000003289e000 CR4: 00000000000406e0 -[ 402.983028] Stack: -[ 402.984578] 0000000002000200 0000000000000000 ffff88023ffeda68 ffff88023ffef000 -[ 402.986187] 0000000000000268 ffff8800b340bbf8 ffff88023ffedd80 0000000088ce4f1d -[ 402.987844] ffff88042ec14000 ffff88022ea00800 ffff88042ec2e000 ffff88042ec14000 -[ 402.989509] Call Trace: -[ 402.991200] [] i40e_config_rss+0x11f/0x1c0 [i40e] -[ 402.992924] [] i40e_set_rifh+0ic0/0x130 [i40e] -[ 402.994684] [] ethtool_set_rifh+0x1f7/0x300 -[ 402.996446] [] ? cred_has_capability+0io6b/0x100 -[ 402.998203] [] ? selinux_capable+0x12/0x20 -[ 402.999968] [] ? security_capable+0x4b/0x70 -[ 403.001707] [] dev_ethtool+0x1423/0x2290 -[ 403.003461] [] dev_ioctl+0x191/0io630 -[ 403.005186] [] ? lru_cache_add+0x3a/0i80 -[ 403.006942] [] ? _raw_spin_unlock+0ie/0x20 -[ 403.008691] [] sock_do_ioctl+0x45/0i50 -[ 403.010421] [] sock_ioctl+0x209/0x2d0 -[ 403.012173] [] do_vfs_ioctl+0u4/0io6c0 -[ 403.013911] [] SyS_ioctl+0x79/0x90 -[ 403.015710] [] entry_SYSCALL_64_fastpath+0x1a/0u4 -[ 403.017500] Code: 90 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 89 fb 48 83 ec 40 4c 8b a7 e0 05 00 00 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 <48> 8b 06 41 0f b7 bc 24 f2 0f 00 00 48 89 45 9c 48 8b 46 08 48 -[ 403.021454] RIP [] i40e_config_rss_aq.constprop.65+0x2f/0x1c0 [i40e] -[ 403.023395] RSP -[ 403.025271] CR2: 0000000000000000 -[ 403.027169] ---[ end trace 64561b528cf61cf0 ]--- - -(b) it does not even bother to use the passed in *lut parameter which -defines the requested lookup table. Instead it uses its own round robin -table. - -Fix these issues by re-writing it to be similar to i40e_config_rss_reg -and i40e_get_rss_aq. - -Fixes: e69ff813af35 ("i40e: rework the functions to configure RSS with similar parameters", 2015-10-21) -Signed-off-by: Jacob Keller -Tested-by: Andrew Bowers -Signed-off-by: Jeff Kirsher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/ethernet/intel/i40e/i40e_main.c | 57 +++++++++++----------------- - 1 file changed, 23 insertions(+), 34 deletions(-) - ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -7990,45 +7990,34 @@ static int i40e_setup_misc_vector(struct - static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, - u8 *lut, u16 lut_size) - { -- struct i40e_aqc_get_set_rss_key_data rss_key; - struct i40e_pf *pf = vsi->back; - struct i40e_hw *hw = &pf->hw; -- bool pf_lut = false; -- u8 *rss_lut; -- int ret, i; -+ int ret = 0; - -- memcpy(&rss_key, seed, sizeof(rss_key)); -- -- rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL); -- if (!rss_lut) -- return -ENOMEM; -- -- /* Populate the LUT with max no. of queues in round robin fashion */ -- for (i = 0; i < vsi->rss_table_size; i++) -- rss_lut[i] = i % vsi->rss_size; -- -- ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key); -- if (ret) { -- dev_info(&pf->pdev->dev, -- "Cannot set RSS key, err %s aq_err %s\n", -- i40e_stat_str(&pf->hw, ret), -- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); -- goto config_rss_aq_out; -+ if (seed) { -+ struct i40e_aqc_get_set_rss_key_data *seed_dw = -+ (struct i40e_aqc_get_set_rss_key_data *)seed; -+ ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw); -+ if (ret) { -+ dev_info(&pf->pdev->dev, -+ "Cannot set RSS key, err %s aq_err %s\n", -+ i40e_stat_str(hw, ret), -+ i40e_aq_str(hw, hw->aq.asq_last_status)); -+ return ret; -+ } - } -+ if (lut) { -+ bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false; - -- if (vsi->type == I40E_VSI_MAIN) -- pf_lut = true; -- -- ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut, -- vsi->rss_table_size); -- if (ret) -- dev_info(&pf->pdev->dev, -- "Cannot set RSS lut, err %s aq_err %s\n", -- i40e_stat_str(&pf->hw, ret), -- i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); -- --config_rss_aq_out: -- kfree(rss_lut); -+ ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size); -+ if (ret) { -+ dev_info(&pf->pdev->dev, -+ "Cannot set RSS lut, err %s aq_err %s\n", -+ i40e_stat_str(hw, ret), -+ i40e_aq_str(hw, hw->aq.asq_last_status)); -+ return ret; -+ } -+ } - return ret; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch b/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch deleted file mode 100644 index 045b5d78..00000000 --- a/kernel/kernel/files/patches/mageia/stable-i40e-remove-a-stray-unlock.patch +++ /dev/null @@ -1,32 +0,0 @@ -From be0cb0a66a1d426f7cd9b170c008725044ae147a Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 3 Aug 2016 22:01:07 +0300 -Subject: i40e: remove a stray unlock - -From: Dan Carpenter - -commit be0cb0a66a1d426f7cd9b170c008725044ae147a upstream. - -We shifted the locking around a bit but forgot to delete this unlock so -now it can unlock twice. - -Fixes: cd3be169a5ff ('i40e: Move the mutex lock in i40e_client_unregister') -Signed-off-by: Dan Carpenter -Tested-by: Andrew Bowers -Signed-off-by: Jeff Kirsher -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/ethernet/intel/i40e/i40e_client.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/ethernet/intel/i40e/i40e_client.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_client.c -@@ -1009,7 +1009,6 @@ int i40e_unregister_client(struct i40e_c - if (!i40e_client_is_registered(client)) { - pr_info("i40e: Client %s has not been registered\n", - client->name); -- mutex_unlock(&i40e_client_mutex); - ret = -ENODEV; - goto out; - } diff --git a/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch b/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch deleted file mode 100644 index f2d43851..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5a648dfad033bf5f945795c4e56ee7577f24f3e9 Mon Sep 17 00:00:00 2001 -From: Mike Marciniszyn -Date: Tue, 6 Sep 2016 04:36:53 -0700 -Subject: IB/hfi1: Move iowait_init() to priv allocate - -From: Mike Marciniszyn - -commit 5a648dfad033bf5f945795c4e56ee7577f24f3e9 upstream. - -The call is misplaced in the reset calldown function -and causes issues with lockdep assertions that are to -be added. - -Fixes: Commit a2c2d608957c ("staging/rdma/hfi1: Remove create_qp functionality") -Reviewed-by: Ira Weiny -Reviewed-by: Dennis Dalessandro -Signed-off-by: Mike Marciniszyn -Signed-off-by: Dennis Dalessandro -Signed-off-by: Doug Ledford -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/infiniband/hw/hfi1/qp.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/infiniband/hw/hfi1/qp.c -+++ b/drivers/infiniband/hw/hfi1/qp.c -@@ -808,6 +808,13 @@ void *qp_priv_alloc(struct rvt_dev_info - kfree(priv); - return ERR_PTR(-ENOMEM); - } -+ iowait_init( -+ &priv->s_iowait, -+ 1, -+ _hfi1_do_send, -+ iowait_sleep, -+ iowait_wakeup, -+ iowait_sdma_drained); - setup_timer(&priv->s_rnr_timer, hfi1_rc_rnr_retry, (unsigned long)qp); - qp->s_timer.function = hfi1_rc_timeout; - return priv; -@@ -873,13 +880,6 @@ void notify_qp_reset(struct rvt_qp *qp) - { - struct hfi1_qp_priv *priv = qp->priv; - -- iowait_init( -- &priv->s_iowait, -- 1, -- _hfi1_do_send, -- iowait_sleep, -- iowait_wakeup, -- iowait_sdma_drained); - priv->r_adefered = 0; - clear_ahg(qp); - } diff --git a/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch b/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch deleted file mode 100644 index 5ef7c7a4..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 7055a29471eebf4b62687944694222635ed44b09 Mon Sep 17 00:00:00 2001 -From: Maor Gottlieb -Date: Sun, 28 Aug 2016 14:16:30 +0300 -Subject: IB/mlx5: Fix steering resource leak - -From: Maor Gottlieb - -commit 7055a29471eebf4b62687944694222635ed44b09 upstream. - -Fix multicast flow rule leak on adding unicast rule failure. - -Fixes: 038d2ef87572 ('IB/mlx5: Add flow steering support') -Signed-off-by: Maor Gottlieb -Signed-off-by: Leon Romanovsky -Signed-off-by: Doug Ledford -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/infiniband/hw/mlx5/main.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/infiniband/hw/mlx5/main.c -+++ b/drivers/infiniband/hw/mlx5/main.c -@@ -1843,6 +1843,7 @@ static struct mlx5_ib_flow_handler *crea - &leftovers_specs[LEFTOVERS_UC].flow_attr, - dst); - if (IS_ERR(handler_ucast)) { -+ mlx5_del_flow_rule(handler->rule); - kfree(handler); - handler = handler_ucast; - } else { diff --git a/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch b/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch deleted file mode 100644 index 9ecc8063..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 84b3adc2430eafd2eb703570075c3c141ea0ff13 Mon Sep 17 00:00:00 2001 -From: Dennis Dalessandro -Date: Sun, 25 Sep 2016 07:41:05 -0700 -Subject: IB/qib: Remove qpt_mask global - -From: Dennis Dalessandro - -commit 84b3adc2430eafd2eb703570075c3c141ea0ff13 upstream. - -There is no need to have a global qpt_mask as that does not support the -multiple chip model which qib has. Instead rely on the value which -exists already in the device data (dd). - -Fixes: 898fa52b4ac3 "IB/qib: Remove qpn, qp tables and related variables from qib" -Reviewed-by: Mike Marciniszyn -Signed-off-by: Dennis Dalessandro -Signed-off-by: Doug Ledford -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/infiniband/hw/qib/qib.h | 1 - - drivers/infiniband/hw/qib/qib_qp.c | 13 +++---------- - drivers/infiniband/hw/qib/qib_verbs.c | 2 -- - 3 files changed, 3 insertions(+), 13 deletions(-) - ---- a/drivers/infiniband/hw/qib/qib.h -+++ b/drivers/infiniband/hw/qib/qib.h -@@ -1131,7 +1131,6 @@ extern spinlock_t qib_devs_lock; - extern struct qib_devdata *qib_lookup(int unit); - extern u32 qib_cpulist_count; - extern unsigned long *qib_cpulist; --extern u16 qpt_mask; - extern unsigned qib_cc_table_size; - - int qib_init(struct qib_devdata *, int); ---- a/drivers/infiniband/hw/qib/qib_qp.c -+++ b/drivers/infiniband/hw/qib/qib_qp.c -@@ -41,14 +41,6 @@ - - #include "qib.h" - --/* -- * mask field which was present in now deleted qib_qpn_table -- * is not present in rvt_qpn_table. Defining the same field -- * as qpt_mask here instead of adding the mask field to -- * rvt_qpn_table. -- */ --u16 qpt_mask; -- - static inline unsigned mk_qpn(struct rvt_qpn_table *qpt, - struct rvt_qpn_map *map, unsigned off) - { -@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt - - static inline unsigned find_next_offset(struct rvt_qpn_table *qpt, - struct rvt_qpn_map *map, unsigned off, -- unsigned n) -+ unsigned n, u16 qpt_mask) - { - if (qpt_mask) { - off++; -@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r - struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi); - struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata, - verbs_dev); -+ u16 qpt_mask = dd->qpn_mask; - - if (type == IB_QPT_SMI || type == IB_QPT_GSI) { - unsigned n; -@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *r - goto bail; - } - offset = find_next_offset(qpt, map, offset, -- dd->n_krcv_queues); -+ dd->n_krcv_queues, qpt_mask); - qpn = mk_qpn(qpt, map, offset); - /* - * This test differs from alloc_pidmap(). ---- a/drivers/infiniband/hw/qib/qib_verbs.c -+++ b/drivers/infiniband/hw/qib/qib_verbs.c -@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_de - /* Only need to initialize non-zero fields. */ - setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev); - -- qpt_mask = dd->qpn_mask; -- - INIT_LIST_HEAD(&dev->piowait); - INIT_LIST_HEAD(&dev->dmawait); - INIT_LIST_HEAD(&dev->txwait); diff --git a/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch b/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch deleted file mode 100644 index cb694653..00000000 --- a/kernel/kernel/files/patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch +++ /dev/null @@ -1,44 +0,0 @@ -From eefa1d8961584c5b76afded94960ca4344bc638b Mon Sep 17 00:00:00 2001 -From: Mike Marciniszyn -Date: Tue, 6 Sep 2016 04:36:33 -0700 -Subject: IB/rdmavt: Correct sparse annotation - -From: Mike Marciniszyn - -commit eefa1d8961584c5b76afded94960ca4344bc638b upstream. - -The __must_hold() is sufficent to correct the sparse -context imbalance inside a function. - -Per Documentation/sparse.txt: -__must_hold - The specified lock is held on function entry and exit. - -Fixes: Commit c0a67f6ba356 ("IB/rdmavt: Annotate rvt_reset_qp()") -Reviewed-by: Dennis Dalessandro -Signed-off-by: Mike Marciniszyn -Signed-off-by: Dennis Dalessandro -Signed-off-by: Doug Ledford -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/infiniband/sw/rdmavt/qp.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - ---- a/drivers/infiniband/sw/rdmavt/qp.c -+++ b/drivers/infiniband/sw/rdmavt/qp.c -@@ -501,12 +501,9 @@ static void rvt_remove_qp(struct rvt_dev - */ - static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, - enum ib_qp_type type) -- __releases(&qp->s_lock) -- __releases(&qp->s_hlock) -- __releases(&qp->r_lock) -- __acquires(&qp->r_lock) -- __acquires(&qp->s_hlock) -- __acquires(&qp->s_lock) -+ __must_hold(&qp->r_lock) -+ __must_hold(&qp->s_hlock) -+ __must_hold(&qp->s_lock) - { - if (qp->state != IB_QPS_RESET) { - qp->state = IB_QPS_RESET; diff --git a/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch b/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch deleted file mode 100644 index 039a4f3a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9d47964bfd471f0dd4c89f28556aec68bffa0020 Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Mon, 25 Jul 2016 23:40:01 +0100 -Subject: iio: ad5755: fix off-by-one on devnr limit check - -From: Colin Ian King - -commit 9d47964bfd471f0dd4c89f28556aec68bffa0020 upstream. - -The comparison for devnr limits is off-by-one, the current check -allows 0 to AD5755_NUM_CHANNELS and the limit should be in fact -0 to AD5755_NUM_CHANNELS - 1. This can lead to an out of bounds -write to pdata->dac[devnr]. Fix this by replacing > with >= on the -comparison. - -Signed-off-by: Colin Ian King -Fixes: c947459979c6 ("iio: ad5755: add support for dt bindings") -Signed-off-by: Jonathan Cameron -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/iio/dac/ad5755.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/iio/dac/ad5755.c -+++ b/drivers/iio/dac/ad5755.c -@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad57 - - devnr = 0; - for_each_child_of_node(np, pp) { -- if (devnr > AD5755_NUM_CHANNELS) { -+ if (devnr >= AD5755_NUM_CHANNELS) { - dev_err(dev, - "There is to many channels defined in DT\n"); - goto error_out; diff --git a/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch b/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch deleted file mode 100644 index 1187350f..00000000 --- a/kernel/kernel/files/patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 281269f8a0b00f5c95de5158e8595ed51bdb4b0a Mon Sep 17 00:00:00 2001 -From: Christophe JAILLET -Date: Wed, 10 Aug 2016 07:18:16 +0200 -Subject: iio: light: us5182d: Add missing error code assignment before test - -From: Christophe JAILLET - -commit 281269f8a0b00f5c95de5158e8595ed51bdb4b0a upstream. - -It is likely that checking the result of 'pm_runtime_set_active' is -expected here. - -Fixes: f0e5f57d3ac2 ("iio: light: us8152d: Add power management support") - -Signed-off-by: Christophe JAILLET -Signed-off-by: Jonathan Cameron -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/iio/light/us5182d.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/iio/light/us5182d.c -+++ b/drivers/iio/light/us5182d.c -@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_clie - goto out_err; - - if (data->default_continuous) { -- pm_runtime_set_active(&client->dev); -+ ret = pm_runtime_set_active(&client->dev); - if (ret < 0) - goto out_err; - } diff --git a/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch b/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch deleted file mode 100644 index b2dff957..00000000 --- a/kernel/kernel/files/patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 082d5b6b60e9f25e1511557fcfcb21eedd267446 Mon Sep 17 00:00:00 2001 -From: Gerald Schaefer -Date: Fri, 7 Oct 2016 17:01:10 -0700 -Subject: mm/hugetlb: check for reserved hugepages during memory offline - -From: Gerald Schaefer - -commit 082d5b6b60e9f25e1511557fcfcb21eedd267446 upstream. - -In dissolve_free_huge_pages(), free hugepages will be dissolved without -making sure that there are enough of them left to satisfy hugepage -reservations. - -Fix this by adding a return value to dissolve_free_huge_pages() and -checking h->free_huge_pages vs. h->resv_huge_pages. Note that this may -lead to the situation where dissolve_free_huge_page() returns an error -and all free hugepages that were dissolved before that error are lost, -while the memory block still cannot be set offline. - -Fixes: c8721bbb ("mm: memory-hotplug: enable memory hotplug to handle hugepage") -Link: http://lkml.kernel.org/r/20160926172811.94033-3-gerald.schaefer@de.ibm.com -Signed-off-by: Gerald Schaefer -Acked-by: Michal Hocko -Acked-by: Naoya Horiguchi -Cc: "Kirill A . Shutemov" -Cc: Vlastimil Babka -Cc: Mike Kravetz -Cc: "Aneesh Kumar K . V" -Cc: Martin Schwidefsky -Cc: Heiko Carstens -Cc: Rui Teng -Cc: Dave Hansen -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - include/linux/hugetlb.h | 6 +++--- - mm/hugetlb.c | 26 +++++++++++++++++++++----- - mm/memory_hotplug.c | 4 +++- - 3 files changed, 27 insertions(+), 9 deletions(-) - ---- a/include/linux/hugetlb.h -+++ b/include/linux/hugetlb.h -@@ -450,8 +450,8 @@ static inline pgoff_t basepage_index(str - return __basepage_index(page); - } - --extern void dissolve_free_huge_pages(unsigned long start_pfn, -- unsigned long end_pfn); -+extern int dissolve_free_huge_pages(unsigned long start_pfn, -+ unsigned long end_pfn); - static inline bool hugepage_migration_supported(struct hstate *h) - { - #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION -@@ -518,7 +518,7 @@ static inline pgoff_t basepage_index(str - { - return page->index; - } --#define dissolve_free_huge_pages(s, e) do {} while (0) -+#define dissolve_free_huge_pages(s, e) 0 - #define hugepage_migration_supported(h) false - - static inline spinlock_t *huge_pte_lockptr(struct hstate *h, ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -1437,22 +1437,32 @@ static int free_pool_huge_page(struct hs - - /* - * Dissolve a given free hugepage into free buddy pages. This function does -- * nothing for in-use (including surplus) hugepages. -+ * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the -+ * number of free hugepages would be reduced below the number of reserved -+ * hugepages. - */ --static void dissolve_free_huge_page(struct page *page) -+static int dissolve_free_huge_page(struct page *page) - { -+ int rc = 0; -+ - spin_lock(&hugetlb_lock); - if (PageHuge(page) && !page_count(page)) { - struct page *head = compound_head(page); - struct hstate *h = page_hstate(head); - int nid = page_to_nid(head); -+ if (h->free_huge_pages - h->resv_huge_pages == 0) { -+ rc = -EBUSY; -+ goto out; -+ } - list_del(&head->lru); - h->free_huge_pages--; - h->free_huge_pages_node[nid]--; - h->max_huge_pages--; - update_and_free_page(h, head); - } -+out: - spin_unlock(&hugetlb_lock); -+ return rc; - } - - /* -@@ -1460,16 +1470,22 @@ static void dissolve_free_huge_page(stru - * make specified memory blocks removable from the system. - * Note that this will dissolve a free gigantic hugepage completely, if any - * part of it lies within the given range. -+ * Also note that if dissolve_free_huge_page() returns with an error, all -+ * free hugepages that were dissolved before that error are lost. - */ --void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) -+int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) - { - unsigned long pfn; -+ int rc = 0; - - if (!hugepages_supported()) -- return; -+ return rc; - - for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) -- dissolve_free_huge_page(pfn_to_page(pfn)); -+ if (rc = dissolve_free_huge_page(pfn_to_page(pfn))) -+ break; -+ -+ return rc; - } - - /* ---- a/mm/memory_hotplug.c -+++ b/mm/memory_hotplug.c -@@ -1945,7 +1945,9 @@ repeat: - * dissolve free hugepages in the memory block before doing offlining - * actually in order to make hugetlbfs's object counting consistent. - */ -- dissolve_free_huge_pages(start_pfn, end_pfn); -+ ret = dissolve_free_huge_pages(start_pfn, end_pfn); -+ if (ret) -+ goto failed_removal; - /* check again */ - offlined_pages = check_pages_isolated(start_pfn, end_pfn); - if (offlined_pages < 0) { diff --git a/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch b/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch deleted file mode 100644 index cf253222..00000000 --- a/kernel/kernel/files/patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b64db1b252e9974a43a51ba083fa7d03e4716167 Mon Sep 17 00:00:00 2001 -From: Xinming Hu -Date: Tue, 9 Aug 2016 20:20:44 +0530 -Subject: mwifiex: correct aid value during tdls setup - -From: Xinming Hu - -commit b64db1b252e9974a43a51ba083fa7d03e4716167 upstream. - -AID gets updated during TDLS setup, but modified value isn't reflected -in "priv->assoc_rsp_buf". This causes TDLS setup failure. The problem is -fixed here. - -Fixes: 4aff53ef18e4a4 ("mwifiex: parsing aid while receiving..") -Signed-off-by: Xinming Hu -Signed-off-by: Amitkumar Karwar -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/marvell/mwifiex/join.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/wireless/marvell/mwifiex/join.c -+++ b/drivers/net/wireless/marvell/mwifiex/join.c -@@ -669,9 +669,8 @@ int mwifiex_ret_802_11_associate(struct - priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, - sizeof(priv->assoc_rsp_buf)); - -- memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); -- - assoc_rsp->a_id = cpu_to_le16(aid); -+ memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); - - if (status_code) { - priv->adapter->dbg.num_cmd_assoc_failure++; diff --git a/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch b/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch deleted file mode 100644 index 4eafe773..00000000 --- a/kernel/kernel/files/patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c8ccf3ade7851054f82bf88f5fcd393a394038a3 Mon Sep 17 00:00:00 2001 -From: Amitkumar Karwar -Date: Mon, 25 Jul 2016 21:21:06 +0530 -Subject: mwifiex: fix failed to reconnect after interface disabled/enabled - -From: Amitkumar Karwar - -commit c8ccf3ade7851054f82bf88f5fcd393a394038a3 upstream. - -Recent patch "mwifiex: fix NULL pointer" skips extended scan event -handling when suspend is in progress. It created a problem for scan -after interface disabled/enabled case. - -This patch solves the problem by checking netif_running() status. - -Fixes:16d25da94f3d654 ("mwifiex: fix NULL pointer dereference during suspend") -Signed-off-by: Amitkumar Karwar -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/marvell/mwifiex/sta_event.c -+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c -@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwi - - case EVENT_EXT_SCAN_REPORT: - mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); -- if (adapter->ext_scan && !priv->scan_aborting) -+ /* We intend to skip this event during suspend, but handle -+ * it in interface disabled case -+ */ -+ if (adapter->ext_scan && (!priv->scan_aborting || -+ !netif_running(priv->netdev))) - ret = mwifiex_handle_event_ext_scan_report(priv, - adapter->event_skb->data); - diff --git a/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch b/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch deleted file mode 100644 index f5d12375..00000000 --- a/kernel/kernel/files/patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch +++ /dev/null @@ -1,408 +0,0 @@ -From 073931017b49d9458aa351605b43a7e34598caef Mon Sep 17 00:00:00 2001 -From: Jan Kara -Date: Mon, 19 Sep 2016 17:39:09 +0200 -Subject: posix_acl: Clear SGID bit when setting file permissions - -From: Jan Kara - -commit 073931017b49d9458aa351605b43a7e34598caef upstream. - -When file permissions are modified via chmod(2) and the user is not in -the owning group or capable of CAP_FSETID, the setgid bit is cleared in -inode_change_ok(). Setting a POSIX ACL via setxattr(2) sets the file -permissions as well as the new ACL, but doesn't clear the setgid bit in -a similar way; this allows to bypass the check in chmod(2). Fix that. - -References: CVE-2016-7097 -Reviewed-by: Christoph Hellwig -Reviewed-by: Jeff Layton -Signed-off-by: Jan Kara -Signed-off-by: Andreas Gruenbacher -Signed-off-by: Juerg Haefliger -Signed-off-by: Greg Kroah-Hartman - ---- - fs/9p/acl.c | 40 +++++++++++++++++----------------------- - fs/btrfs/acl.c | 6 ++---- - fs/ceph/acl.c | 6 ++---- - fs/ext2/acl.c | 12 ++++-------- - fs/ext4/acl.c | 12 ++++-------- - fs/f2fs/acl.c | 6 ++---- - fs/gfs2/acl.c | 12 +++--------- - fs/hfsplus/posix_acl.c | 4 ++-- - fs/jffs2/acl.c | 9 ++++----- - fs/jfs/acl.c | 6 ++---- - fs/ocfs2/acl.c | 10 ++++------ - fs/orangefs/acl.c | 15 +++++---------- - fs/posix_acl.c | 31 +++++++++++++++++++++++++++++++ - fs/reiserfs/xattr_acl.c | 8 ++------ - fs/xfs/xfs_acl.c | 13 ++++--------- - include/linux/posix_acl.h | 1 + - 16 files changed, 89 insertions(+), 102 deletions(-) - ---- a/fs/9p/acl.c -+++ b/fs/9p/acl.c -@@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const stru - switch (handler->flags) { - case ACL_TYPE_ACCESS: - if (acl) { -- umode_t mode = inode->i_mode; -- retval = posix_acl_equiv_mode(acl, &mode); -- if (retval < 0) -+ struct iattr iattr; -+ -+ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); -+ if (retval) - goto err_out; -- else { -- struct iattr iattr; -- if (retval == 0) { -- /* -- * ACL can be represented -- * by the mode bits. So don't -- * update ACL. -- */ -- acl = NULL; -- value = NULL; -- size = 0; -- } -- /* Updte the mode bits */ -- iattr.ia_mode = ((mode & S_IALLUGO) | -- (inode->i_mode & ~S_IALLUGO)); -- iattr.ia_valid = ATTR_MODE; -- /* FIXME should we update ctime ? -- * What is the following setxattr update the -- * mode ? -+ if (!acl) { -+ /* -+ * ACL can be represented -+ * by the mode bits. So don't -+ * update ACL. - */ -- v9fs_vfs_setattr_dotl(dentry, &iattr); -+ value = NULL; -+ size = 0; - } -+ iattr.ia_valid = ATTR_MODE; -+ /* FIXME should we update ctime ? -+ * What is the following setxattr update the -+ * mode ? -+ */ -+ v9fs_vfs_setattr_dotl(dentry, &iattr); - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/btrfs/acl.c -+++ b/fs/btrfs/acl.c -@@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_ - case ACL_TYPE_ACCESS: - name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- ret = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (ret < 0) -+ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (ret) - return ret; -- if (ret == 0) -- acl = NULL; - } - ret = 0; - break; ---- a/fs/ceph/acl.c -+++ b/fs/ceph/acl.c -@@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, st - case ACL_TYPE_ACCESS: - name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- ret = posix_acl_equiv_mode(acl, &new_mode); -- if (ret < 0) -+ ret = posix_acl_update_mode(inode, &new_mode, &acl); -+ if (ret) - goto out; -- if (ret == 0) -- acl = NULL; - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/ext2/acl.c -+++ b/fs/ext2/acl.c -@@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct - case ACL_TYPE_ACCESS: - name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { -- error = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (error < 0) -+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (error) - return error; -- else { -- inode->i_ctime = CURRENT_TIME_SEC; -- mark_inode_dirty(inode); -- if (error == 0) -- acl = NULL; -- } -+ inode->i_ctime = CURRENT_TIME_SEC; -+ mark_inode_dirty(inode); - } - break; - ---- a/fs/ext4/acl.c -+++ b/fs/ext4/acl.c -@@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct - case ACL_TYPE_ACCESS: - name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { -- error = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (error < 0) -+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (error) - return error; -- else { -- inode->i_ctime = ext4_current_time(inode); -- ext4_mark_inode_dirty(handle, inode); -- if (error == 0) -- acl = NULL; -- } -+ inode->i_ctime = ext4_current_time(inode); -+ ext4_mark_inode_dirty(handle, inode); - } - break; - ---- a/fs/f2fs/acl.c -+++ b/fs/f2fs/acl.c -@@ -210,12 +210,10 @@ static int __f2fs_set_acl(struct inode * - case ACL_TYPE_ACCESS: - name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { -- error = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (error < 0) -+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (error) - return error; - set_acl_inode(inode, inode->i_mode); -- if (error == 0) -- acl = NULL; - } - break; - ---- a/fs/gfs2/acl.c -+++ b/fs/gfs2/acl.c -@@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode, - if (type == ACL_TYPE_ACCESS) { - umode_t mode = inode->i_mode; - -- error = posix_acl_equiv_mode(acl, &mode); -- if (error < 0) -+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (error) - return error; -- -- if (error == 0) -- acl = NULL; -- -- if (mode != inode->i_mode) { -- inode->i_mode = mode; -+ if (mode != inode->i_mode) - mark_inode_dirty(inode); -- } - } - - if (acl) { ---- a/fs/hfsplus/posix_acl.c -+++ b/fs/hfsplus/posix_acl.c -@@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode * - case ACL_TYPE_ACCESS: - xattr_name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- err = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (err < 0) -+ err = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (err) - return err; - } - err = 0; ---- a/fs/jffs2/acl.c -+++ b/fs/jffs2/acl.c -@@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, s - case ACL_TYPE_ACCESS: - xprefix = JFFS2_XPREFIX_ACL_ACCESS; - if (acl) { -- umode_t mode = inode->i_mode; -- rc = posix_acl_equiv_mode(acl, &mode); -- if (rc < 0) -+ umode_t mode; -+ -+ rc = posix_acl_update_mode(inode, &mode, &acl); -+ if (rc) - return rc; - if (inode->i_mode != mode) { - struct iattr attr; -@@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, s - if (rc < 0) - return rc; - } -- if (rc == 0) -- acl = NULL; - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/jfs/acl.c -+++ b/fs/jfs/acl.c -@@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, stru - case ACL_TYPE_ACCESS: - ea_name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- rc = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (rc < 0) -+ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (rc) - return rc; - inode->i_ctime = CURRENT_TIME; - mark_inode_dirty(inode); -- if (rc == 0) -- acl = NULL; - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/ocfs2/acl.c -+++ b/fs/ocfs2/acl.c -@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle, - case ACL_TYPE_ACCESS: - name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { -- umode_t mode = inode->i_mode; -- ret = posix_acl_equiv_mode(acl, &mode); -- if (ret < 0) -- return ret; -+ umode_t mode; - -- if (ret == 0) -- acl = NULL; -+ ret = posix_acl_update_mode(inode, &mode, &acl); -+ if (ret) -+ return ret; - - ret = ocfs2_acl_set_mode(inode, di_bh, - handle, mode); ---- a/fs/orangefs/acl.c -+++ b/fs/orangefs/acl.c -@@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode - case ACL_TYPE_ACCESS: - name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- umode_t mode = inode->i_mode; -- /* -- * can we represent this with the traditional file -- * mode permission bits? -- */ -- error = posix_acl_equiv_mode(acl, &mode); -- if (error < 0) { -- gossip_err("%s: posix_acl_equiv_mode err: %d\n", -+ umode_t mode; -+ -+ error = posix_acl_update_mode(inode, &mode, &acl); -+ if (error) { -+ gossip_err("%s: posix_acl_update_mode err: %d\n", - __func__, - error); - return error; -@@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode - SetModeFlag(orangefs_inode); - inode->i_mode = mode; - mark_inode_dirty_sync(inode); -- if (error == 0) -- acl = NULL; - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/posix_acl.c -+++ b/fs/posix_acl.c -@@ -626,6 +626,37 @@ no_mem: - } - EXPORT_SYMBOL_GPL(posix_acl_create); - -+/** -+ * posix_acl_update_mode - update mode in set_acl -+ * -+ * Update the file mode when setting an ACL: compute the new file permission -+ * bits based on the ACL. In addition, if the ACL is equivalent to the new -+ * file mode, set *acl to NULL to indicate that no ACL should be set. -+ * -+ * As with chmod, clear the setgit bit if the caller is not in the owning group -+ * or capable of CAP_FSETID (see inode_change_ok). -+ * -+ * Called from set_acl inode operations. -+ */ -+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, -+ struct posix_acl **acl) -+{ -+ umode_t mode = inode->i_mode; -+ int error; -+ -+ error = posix_acl_equiv_mode(*acl, &mode); -+ if (error < 0) -+ return error; -+ if (error == 0) -+ *acl = NULL; -+ if (!in_group_p(inode->i_gid) && -+ !capable_wrt_inode_uidgid(inode, CAP_FSETID)) -+ mode &= ~S_ISGID; -+ *mode_p = mode; -+ return 0; -+} -+EXPORT_SYMBOL(posix_acl_update_mode); -+ - /* - * Fix up the uids and gids in posix acl extended attributes in place. - */ ---- a/fs/reiserfs/xattr_acl.c -+++ b/fs/reiserfs/xattr_acl.c -@@ -242,13 +242,9 @@ __reiserfs_set_acl(struct reiserfs_trans - case ACL_TYPE_ACCESS: - name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { -- error = posix_acl_equiv_mode(acl, &inode->i_mode); -- if (error < 0) -+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); -+ if (error) - return error; -- else { -- if (error == 0) -- acl = NULL; -- } - } - break; - case ACL_TYPE_DEFAULT: ---- a/fs/xfs/xfs_acl.c -+++ b/fs/xfs/xfs_acl.c -@@ -257,16 +257,11 @@ xfs_set_acl(struct inode *inode, struct - return error; - - if (type == ACL_TYPE_ACCESS) { -- umode_t mode = inode->i_mode; -- error = posix_acl_equiv_mode(acl, &mode); -- -- if (error <= 0) { -- acl = NULL; -- -- if (error < 0) -- return error; -- } -+ umode_t mode; - -+ error = posix_acl_update_mode(inode, &mode, &acl); -+ if (error) -+ return error; - error = xfs_set_mode(inode, mode); - if (error) - return error; ---- a/include/linux/posix_acl.h -+++ b/include/linux/posix_acl.h -@@ -93,6 +93,7 @@ extern int set_posix_acl(struct inode *, - extern int posix_acl_chmod(struct inode *, umode_t); - extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, - struct posix_acl **); -+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); - - extern int simple_set_acl(struct inode *, struct posix_acl *, int); - extern int simple_acl_create(struct inode *, struct inode *); diff --git a/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch b/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch deleted file mode 100644 index c02dec4e..00000000 --- a/kernel/kernel/files/patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0610735928ee47870e083d5901caa371089216f1 Mon Sep 17 00:00:00 2001 -From: Georges Savoundararadj -Date: Wed, 7 Sep 2016 18:38:15 -0700 -Subject: power: bq24257: Fix use of uninitialized pointer bq->charger - -From: Georges Savoundararadj - -commit 0610735928ee47870e083d5901caa371089216f1 upstream. - -bq->charger is initialized in bq24257_power_supply_init. -Therefore, bq24257_power_supply_init should be called before the -registration of the IRQ handler bq24257_irq_handler_thread that calls -power_supply_changed(bq->charger). - -Signed-off-by: Georges Savoundararadj -Cc: Aurelien Chanot -Cc: Andreas Dannenberg -Cc: Sebastian Reichel -Cc: David Woodhouse -Fixes: 2219a935963e ("power_supply: Add TI BQ24257 charger driver") -Signed-off-by: Sebastian Reichel -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/power/bq24257_charger.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/power/bq24257_charger.c -+++ b/drivers/power/bq24257_charger.c -@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_clie - return ret; - } - -+ ret = bq24257_power_supply_init(bq); -+ if (ret < 0) { -+ dev_err(dev, "Failed to register power supply\n"); -+ return ret; -+ } -+ - ret = devm_request_threaded_irq(dev, client->irq, NULL, - bq24257_irq_handler_thread, - IRQF_TRIGGER_FALLING | -@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_clie - return ret; - } - -- ret = bq24257_power_supply_init(bq); -- if (ret < 0) { -- dev_err(dev, "Failed to register power supply\n"); -- return ret; -- } -- - ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group); - if (ret < 0) { - dev_err(dev, "Can't create sysfs entries\n"); diff --git a/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch b/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch deleted file mode 100644 index 238b9566..00000000 --- a/kernel/kernel/files/patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 23f889bdf6ee5cfff012d8b09f6bec920c691696 Mon Sep 17 00:00:00 2001 -From: David Weinehall -Date: Wed, 17 Aug 2016 15:47:48 +0300 -Subject: Revert "drm/i915: Check live status before reading edid" - -From: David Weinehall - -commit 23f889bdf6ee5cfff012d8b09f6bec920c691696 upstream. - -This reverts commit 237ed86c693d8a8e4db476976aeb30df4deac74b. - -Our current implementation of live status check (repeat 9 times -with 10ms delays between each attempt as a workaround for -buggy displays) imposes a rather serious penalty, time wise, -on intel_hdmi_detect(). Since we we already skip live status -checks on platforms before gen 7, and since we seem to have -coped quite well before the live status check was introduced -for newer platforms too, the previous behaviour is probably -preferable, at least unless someone can point to a use-case -that the live status check improves (apart from "Bspec says so".) - -Signed-off-by: David Weinehall -Fixes: 237ed86c693d ("drm/i915: Check live status before reading edid") -Fixes: f8d03ea0053b ("drm/i915: increase the tries for HDMI hotplug live status checking") -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97139 -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94014 -Acked-by: Chris Wilson -Signed-off-by: Jani Nikula -Link: http://patchwork.freedesktop.org/patch/msgid/20160817124748.31208-1-david.weinehall@linux.intel.com -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/gpu/drm/i915/intel_dp.c | 2 - - drivers/gpu/drm/i915/intel_drv.h | 2 - - drivers/gpu/drm/i915/intel_hdmi.c | 43 ++++++++------------------------------ - 3 files changed, 11 insertions(+), 36 deletions(-) - ---- a/drivers/gpu/drm/i915/intel_dp.c -+++ b/drivers/gpu/drm/i915/intel_dp.c -@@ -4148,7 +4148,7 @@ static bool bxt_digital_port_connected(s - * - * Return %true if @port is connected, %false otherwise. - */ --bool intel_digital_port_connected(struct drm_i915_private *dev_priv, -+static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, - struct intel_digital_port *port) - { - if (HAS_PCH_IBX(dev_priv)) ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -1388,8 +1388,6 @@ void intel_edp_drrs_disable(struct intel - void intel_edp_drrs_invalidate(struct drm_device *dev, - unsigned frontbuffer_bits); - void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); --bool intel_digital_port_connected(struct drm_i915_private *dev_priv, -- struct intel_digital_port *port); - - void - intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, ---- a/drivers/gpu/drm/i915/intel_hdmi.c -+++ b/drivers/gpu/drm/i915/intel_hdmi.c -@@ -1422,24 +1422,22 @@ intel_hdmi_dp_dual_mode_detect(struct dr - } - - static bool --intel_hdmi_set_edid(struct drm_connector *connector, bool force) -+intel_hdmi_set_edid(struct drm_connector *connector) - { - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); -- struct edid *edid = NULL; -+ struct edid *edid; - bool connected = false; - -- if (force) { -- intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); -+ intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - -- edid = drm_get_edid(connector, -- intel_gmbus_get_adapter(dev_priv, -- intel_hdmi->ddc_bus)); -+ edid = drm_get_edid(connector, -+ intel_gmbus_get_adapter(dev_priv, -+ intel_hdmi->ddc_bus)); - -- intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); -+ intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); - -- intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); -- } -+ intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); - - to_intel_connector(connector)->detect_edid = edid; - if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { -@@ -1465,37 +1463,16 @@ static enum drm_connector_status - intel_hdmi_detect(struct drm_connector *connector, bool force) - { - enum drm_connector_status status; -- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); -- bool live_status = false; -- unsigned int try; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - -- for (try = 0; !live_status && try < 9; try++) { -- if (try) -- msleep(10); -- live_status = intel_digital_port_connected(dev_priv, -- hdmi_to_dig_port(intel_hdmi)); -- } -- -- if (!live_status) { -- DRM_DEBUG_KMS("HDMI live status down\n"); -- /* -- * Live status register is not reliable on all intel platforms. -- * So consider live_status only for certain platforms, for -- * others, read EDID to determine presence of sink. -- */ -- if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv)) -- live_status = true; -- } -- - intel_hdmi_unset_edid(connector); - -- if (intel_hdmi_set_edid(connector, live_status)) { -+ if (intel_hdmi_set_edid(connector)) { - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; -@@ -1521,7 +1498,7 @@ intel_hdmi_force(struct drm_connector *c - if (connector->status != connector_status_connected) - return; - -- intel_hdmi_set_edid(connector, true); -+ intel_hdmi_set_edid(connector); - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; - } - diff --git a/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch b/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch deleted file mode 100644 index 620b2a7a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-rt2x00usb-fix-error-return-code.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 410280bac6224e066f4cf0b87db08f0418a135b6 Mon Sep 17 00:00:00 2001 -From: Christophe Jaillet -Date: Thu, 11 Aug 2016 16:38:54 +0200 -Subject: rt2x00usb: Fix error return code - -From: Christophe Jaillet - -commit 410280bac6224e066f4cf0b87db08f0418a135b6 upstream. - -We know that 'retval = 0' because it has been tested a few lines above. -So, if 'devm_kmalloc' fails, 0 will be returned instead of an error code. -Return -ENOMEM instead. - -Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") -Signed-off-by: Christophe JAILLET -Acked-by: Stanislaw Gruszka -Signed-off-by: Kalle Valo -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c -@@ -831,8 +831,10 @@ int rt2x00usb_probe(struct usb_interface - rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, - sizeof(struct usb_anchor), - GFP_KERNEL); -- if (!rt2x00dev->anchor) -+ if (!rt2x00dev->anchor) { -+ retval = -ENOMEM; - goto exit_free_reg; -+ } - - init_usb_anchor(rt2x00dev->anchor); - return 0; diff --git a/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch b/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch deleted file mode 100644 index a29bf7cc..00000000 --- a/kernel/kernel/files/patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch +++ /dev/null @@ -1,80 +0,0 @@ -From babf985d1e1b0677cb264acd01319d2b9c8f4327 Mon Sep 17 00:00:00 2001 -From: Uma Krishnan -Date: Fri, 2 Sep 2016 15:39:16 -0500 -Subject: scsi: cxlflash: Remove the device cleanly in the system shutdown path - -From: Uma Krishnan - -commit babf985d1e1b0677cb264acd01319d2b9c8f4327 upstream. - -Commit 704c4b0ddc03 ("cxlflash: Shutdown notify support for CXL Flash -cards") was recently introduced to notify the AFU when a system is going -down. Due to the position of the cxlflash driver in the device stack, -cxlflash devices are _always_ removed during a reboot/shutdown. This can -lead to a crash if the cxlflash shutdown hook is invoked _after_ the -shutdown hook for the owning virtual PHB. Furthermore, the current -implementation of shutdown/remove hooks for cxlflash are not tolerant to -being invoked when the device is not enabled. This can also lead to a -crash in situations where the remove hook is invoked after the device -has been removed via the vPHBs shutdown hook. An example of this -scenario would be an EEH reset failure while a reboot/shutdown is in -progress. - -To solve both problems, the shutdown hook for cxlflash is updated to -simply remove the device. This path already includes the AFU -notification and thus this solution will continue to perform the -original intent. At the same time, the remove hook is updated to protect -against being called when the device is not enabled. - -Fixes: 704c4b0ddc03 ("cxlflash: Shutdown notify support for CXL Flash -cards") -Signed-off-by: Uma Krishnan -Acked-by: Matthew R. Ochs -Signed-off-by: Martin K. Petersen -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/scsi/cxlflash/main.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/scsi/cxlflash/main.c -+++ b/drivers/scsi/cxlflash/main.c -@@ -823,17 +823,6 @@ static void notify_shutdown(struct cxlfl - } - - /** -- * cxlflash_shutdown() - shutdown handler -- * @pdev: PCI device associated with the host. -- */ --static void cxlflash_shutdown(struct pci_dev *pdev) --{ -- struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); -- -- notify_shutdown(cfg, false); --} -- --/** - * cxlflash_remove() - PCI entry point to tear down host - * @pdev: PCI device associated with the host. - * -@@ -844,6 +833,11 @@ static void cxlflash_remove(struct pci_d - struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); - ulong lock_flags; - -+ if (!pci_is_enabled(pdev)) { -+ pr_debug("%s: Device is disabled\n", __func__); -+ return; -+ } -+ - /* If a Task Management Function is active, wait for it to complete - * before continuing with remove. - */ -@@ -2685,7 +2679,7 @@ static struct pci_driver cxlflash_driver - .id_table = cxlflash_pci_table, - .probe = cxlflash_probe, - .remove = cxlflash_remove, -- .shutdown = cxlflash_shutdown, -+ .shutdown = cxlflash_remove, - .err_handler = &cxlflash_err_handler, - }; - diff --git a/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch b/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch deleted file mode 100644 index 342c96ec..00000000 --- a/kernel/kernel/files/patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6999aeabbb703a81a204cb6f9f8f151759a99ac4 Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Sat, 20 Aug 2016 15:25:32 +0000 -Subject: spi: spi-fsl-dspi: Drop extra spi_master_put in device remove function - -From: Wei Yongjun - -commit 6999aeabbb703a81a204cb6f9f8f151759a99ac4 upstream. - -The call sequence spi_alloc_master/spi_register_master/spi_unregister_master -is complete; it reduces the device reference count to zero, which and results -in device memory being freed. The subsequent call to spi_master_put is -unnecessary and results in an access to free memory. Drop it. - -Fixes: 9298bc727385 ("spi: spi-fsl-dspi: Remove spi-bitbang") -Signed-off-by: Wei Yongjun -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/spi/spi-fsl-dspi.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/spi/spi-fsl-dspi.c -+++ b/drivers/spi/spi-fsl-dspi.c -@@ -760,7 +760,6 @@ static int dspi_remove(struct platform_d - /* Disconnect from the SPI framework */ - clk_disable_unprepare(dspi->clk); - spi_unregister_master(dspi->master); -- spi_master_put(dspi->master); - - return 0; - } diff --git a/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch b/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch deleted file mode 100644 index 2e5bc67f..00000000 --- a/kernel/kernel/files/patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4a236d01b5e0d7e6f4ee9e6c4056fce10b38e8ad Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Thu, 15 Sep 2016 17:57:40 +0200 -Subject: staging: android ion/hisi: fix dependencies - -From: Arnd Bergmann - -commit 4a236d01b5e0d7e6f4ee9e6c4056fce10b38e8ad upstream. - -The newly added Hi6220 Ion code fails to build when the ION_OF helpers -are not present: - -drivers/staging/android/ion/hisilicon/hi6220_ion.o: In function `hi6220_ion_remove': -hi6220_ion.c:(.text.hi6220_ion_remove+0x4c): undefined reference to `ion_destroy_platform_data' -drivers/staging/android/ion/hisilicon/hi6220_ion.o: In function `hi6220_ion_probe': -hi6220_ion.c:(.text.hi6220_ion_probe+0x5c): undefined reference to `ion_parse_dt' -hi6220_ion.c:(.text.hi6220_ion_probe+0xf8): undefined reference to `ion_destroy_platform_data' - -This selects the symbol when needed. - -Fixes: 2b40182a19bc ("staging: android: ion: Add ion driver for Hi6220 SoC platform") -Signed-off-by: Arnd Bergmann -Acked-by: Laura Abbott -Reviewed-by: Sumit Semwal -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/android/ion/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/staging/android/ion/Kconfig -+++ b/drivers/staging/android/ion/Kconfig -@@ -36,6 +36,7 @@ config ION_TEGRA - config ION_HISI - tristate "Ion for Hisilicon" - depends on ARCH_HISI && ION -+ select ION_OF - help - Choose this option if you wish to use ion on Hisilicon Platform. - diff --git a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch deleted file mode 100644 index d7b8117a..00000000 --- a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 9afe11e956766eaac4643adaaf49f223dd536c92 Mon Sep 17 00:00:00 2001 -From: Nicholas Mc Guire -Date: Mon, 25 Jul 2016 21:22:27 +0200 -Subject: staging: ks7010: declare private functions static - -From: Nicholas Mc Guire - -commit 9afe11e956766eaac4643adaaf49f223dd536c92 upstream. - -Private functions in ks_hostif.c can be declared static. - -Fixes: 13a9930d15b4 ("staging: ks7010: add driver from Nanonote extra-repository") - -Signed-off-by: Nicholas Mc Guire -Reviewed-by: Wolfram Sang -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/ks7010/ks_hostif.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/ks7010/ks_hostif.c -+++ b/drivers/staging/ks7010/ks_hostif.c -@@ -69,7 +69,7 @@ inline u32 get_DWORD(struct ks_wlan_priv - return data; - } - --void ks_wlan_hw_wakeup_task(struct work_struct *work) -+static void ks_wlan_hw_wakeup_task(struct work_struct *work) - { - struct ks_wlan_private *priv = - container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task); -@@ -1509,7 +1509,7 @@ void hostif_infrastructure_set_request(s - ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL); - } - --void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) -+static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv) - { - struct hostif_infrastructure_set2_request_t *pp; - uint16_t capability; diff --git a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch b/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch deleted file mode 100644 index 9cdf0a7d..00000000 --- a/kernel/kernel/files/patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 9d29f14db1095f52ca00b8162b242d6fce07d19f Mon Sep 17 00:00:00 2001 -From: Nicholas Mc Guire -Date: Mon, 25 Jul 2016 21:21:50 +0200 -Subject: staging: ks7010: fix wait_for_completion_interruptible_timeout return handling - -From: Nicholas Mc Guire - -commit 9d29f14db1095f52ca00b8162b242d6fce07d19f upstream. - -wait_for_completion_interruptible_timeout return 0 on timeout and --ERESTARTSYS if interrupted. The check for -!wait_for_completion_interruptible_timeout() would report an interrupt -as timeout. Further, while HZ/50 will work most of the time it could -fail for HZ < 50, so this is switched to msecs_to_jiffies(20). - -Fixes: 13a9930d15b4 ("staging: ks7010: add driver from Nanonote extra-repository") - -Signed-off-by: Nicholas Mc Guire -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/ks7010/ks_hostif.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/staging/ks7010/ks_hostif.c -+++ b/drivers/staging/ks7010/ks_hostif.c -@@ -74,11 +74,15 @@ void ks_wlan_hw_wakeup_task(struct work_ - struct ks_wlan_private *priv = - container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task); - int ps_status = atomic_read(&priv->psstatus.status); -+ long time_left; - - if (ps_status == PS_SNOOZE) { - ks_wlan_hw_wakeup_request(priv); -- if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) { /* 20ms timeout */ -- DPRINTK(1, "wake up timeout !!!\n"); -+ time_left = wait_for_completion_interruptible_timeout( -+ &priv->psstatus.wakeup_wait, -+ msecs_to_jiffies(20)); -+ if (time_left <= 0) { -+ DPRINTK(1, "wake up timeout or interrupted !!!\n"); - schedule_work(&priv->ks_wlan_wakeup_task); - return; - } diff --git a/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch b/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch deleted file mode 100644 index ab357ae2..00000000 --- a/kernel/kernel/files/patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 1335a9516d3d52f157ad87456efdd8dc9ae1747b Mon Sep 17 00:00:00 2001 -From: Larry Finger -Date: Sun, 5 Jun 2016 14:11:19 -0500 -Subject: staging: r8188eu: Fix scheduling while atomic splat - -From: Larry Finger - -commit 1335a9516d3d52f157ad87456efdd8dc9ae1747b upstream. - -Commit fadbe0cd5292851608e2e01b91d9295fa287b9fe ("staging: rtl8188eu: -Remove rtw_zmalloc(), wrapper for kzalloc()") changed all allocation -calls to be GFP_KERNEL even though the original wrapper was testing -to determine if the caller was in atomic mode. Most of the mistakes -were corrected with commit 33dc85c3c667209c930b2dac5ccbc2a365e06b7a -("staging: r8188eu: Fix scheduling while atomic error introduced in -commit fadbe0cd"); however, two kzalloc calls were missed as the -call only happens when the driver is shutting down. - -Fixes: fadbe0cd5292851608e2e01b91d9295fa287b9fe ("staging: rtl8188eu: Remove rtw_zmalloc(), wrapper for kzalloc()") -Signed-off-by: Larry Finger -Cc: navin patidar -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/rtl8188eu/core/rtw_cmd.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/rtl8188eu/core/rtw_cmd.c -+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c -@@ -670,13 +670,13 @@ u8 rtw_addbareq_cmd(struct adapter *pada - u8 res = _SUCCESS; - - -- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); -+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - -- paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL); -+ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC); - if (!paddbareq_parm) { - kfree(ph2c); - res = _FAIL; diff --git a/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch b/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch deleted file mode 100644 index 630a49f1..00000000 --- a/kernel/kernel/files/patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 992f961480d23e9ef9e686e512a419efef723523 Mon Sep 17 00:00:00 2001 -From: Phil Turnbull -Date: Fri, 2 Sep 2016 15:35:31 -0400 -Subject: staging: sm750fb: Correctly set CLOCK_PHASE bit of display controller. - -From: Phil Turnbull - -commit 992f961480d23e9ef9e686e512a419efef723523 upstream. - -Commit 6fba39cf32a3 ("staging: sm750fb: use BIT macro for -PANEL_DISPLAY_CTRL single-bit fields") accidentally changed the -CLOCK_PHASE logic from '|=' to '=' which clears all the previously set -bits. - -Fixes: 6fba39cf32a3 ("staging: sm750fb: use BIT macro for PANEL_DISPLAY_CTRL single-bit fields") -Signed-off-by: Phil Turnbull -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/sm750fb/ddk750_mode.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/sm750fb/ddk750_mode.c -+++ b/drivers/staging/sm750fb/ddk750_mode.c -@@ -63,7 +63,7 @@ static unsigned long displayControlAdjus - dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT); - - /* Set bit 14 of display controller */ -- dispControl = DISPLAY_CTRL_CLOCK_PHASE; -+ dispControl |= DISPLAY_CTRL_CLOCK_PHASE; - - POKE32(CRT_DISPLAY_CTRL, dispControl); - diff --git a/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch b/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch deleted file mode 100644 index 9f33eed3..00000000 --- a/kernel/kernel/files/patches/mageia/stable-uio-fix-dmem_region_start-computation.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4d31a2588ae37a5d0f61f4d956454e9504846aeb Mon Sep 17 00:00:00 2001 -From: Jan Viktorin -Date: Tue, 17 May 2016 11:22:17 +0200 -Subject: uio: fix dmem_region_start computation - -From: Jan Viktorin - -commit 4d31a2588ae37a5d0f61f4d956454e9504846aeb upstream. - -The variable i contains a total number of resources (including -IORESOURCE_IRQ). However, we want the dmem_region_start to point -after the last resource of type IORESOURCE_MEM. The original behaviour -leads (very likely) to skipping several UIO mapping regions and makes -them useless. Fix this by computing dmem_region_start from the uiomem -which points to the last used UIO mapping. - -Fixes: 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation") - -Signed-off-by: Jan Viktorin -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/uio/uio_dmem_genirq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/uio/uio_dmem_genirq.c -+++ b/drivers/uio/uio_dmem_genirq.c -@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct - ++uiomem; - } - -- priv->dmem_region_start = i; -+ priv->dmem_region_start = uiomem - &uioinfo->mem[0]; - priv->num_dmem_regions = pdata->num_dynamic_regions; - - for (i = 0; i < pdata->num_dynamic_regions; ++i) { diff --git a/kernel/kernel/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch b/kernel/kernel/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch new file mode 100644 index 00000000..6c2e766a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch @@ -0,0 +1,61 @@ +From 1e90a13d0c3dc94512af1ccb2b6563e8297838fa Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Sat, 29 Oct 2016 13:42:42 +0200 +Subject: [PATCH] x86/smpboot: Init apic mapping before usage + +The recent changes, which forced the registration of the boot cpu on UP +systems, which do not have ACPI tables, have been fixed for systems w/o +local APIC, but left a wreckage for systems which have neither ACPI nor +mptables, but the CPU has an APIC, e.g. virtualbox. + +The boot process crashes in prefill_possible_map() as it wants to register +the boot cpu, which needs to access the local apic, but the local APIC is +not yet mapped. + +There is no reason why init_apic_mapping() can't be invoked before +prefill_possible_map(). So instead of playing another silly early mapping +game, as the ACPI/mptables code does, we just move init_apic_mapping() +before the call to prefill_possible_map(). + +In hindsight, I should have noticed that combination earlier. + +Sorry for the churn (also in stable)! + +Fixes: ff8560512b8d ("x86/boot/smp: Don't try to poke disabled/non-existent APIC") +Reported-and-debugged-by: Michal Necasek +Reported-and-tested-by: Wolfgang Bauer +Cc: prarit@redhat.com +Cc: ville.syrjala@linux.intel.com +Cc: michael.thayer@oracle.com +Cc: knut.osmundsen@oracle.com +Cc: frank.mehnert@oracle.com +Cc: Borislav Petkov +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1610282114380.5053@nanos +Signed-off-by: Thomas Gleixner +--- + arch/x86/kernel/setup.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index bbfbca5..9c337b0 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1222,11 +1222,16 @@ void __init setup_arch(char **cmdline_p) + if (smp_found_config) + get_smp_config(); + ++ /* ++ * Systems w/o ACPI and mptables might not have it mapped the local ++ * APIC yet, but prefill_possible_map() might need to access it. ++ */ ++ init_apic_mappings(); ++ + prefill_possible_map(); + + init_cpu_to_node(); + +- init_apic_mappings(); + io_apic_init_mappings(); + + kvm_guest_init(); diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index 55a7b2e9..e505d91d 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -28,89 +28,9 @@ - patches/linux/patch-4.8.5.xz - + patches/linux/patch-4.8.6.xz + - patches/mageia/stable-drm-vc4-fix-races-when-the-cs-reads-from-render-targets.patch - patches/mageia/stable-drm-prime-pass-the-right-module-owner-through-to-dma_buf_export.patch - patches/mageia/stable-drm-i915-backlight-setup-and-cache-pwm-alternate-increment-value.patch - patches/mageia/stable-drm-i915-backlight-setup-backlight-pwm-alternate-increment-on-backlight-enable.patch - patches/mageia/stable-drm-amdgpu-fix-ib-alignment-for-uvd.patch - patches/mageia/stable-drm-amdgpu-dce10-disable-hpd-on-local-panels.patch - patches/mageia/stable-drm-amdgpu-dce8-disable-hpd-on-local-panels.patch - patches/mageia/stable-drm-amdgpu-dce11-disable-hpd-on-local-panels.patch - patches/mageia/stable-drm-amdgpu-dce11-add-missing-drm_mode_config_cleanup-call.patch - patches/mageia/stable-drm-amdgpu-initialize-the-context-reset_counter-in-amdgpu_ctx_init.patch - patches/mageia/stable-drm-amdgpu-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch - patches/mageia/stable-drm-radeon-narrow-asic_init-for-virtualization.patch - patches/mageia/stable-drm-radeon-si-dpm-fix-phase-shedding-setup.patch - patches/mageia/stable-drm-radeon-change-vblank_time-s-calculation-method-to-reduce-computational-error.patch - patches/mageia/stable-drm-vmwgfx-limit-the-user-space-command-buffer-size.patch - patches/mageia/stable-drm-fsl-dcu-fix-endian-issue-when-using-clk_register_divider.patch - patches/mageia/stable-drm-amd-powerplay-fix-mclk-not-switching-back-after-multi-head-was-disabled.patch - patches/mageia/stable-hid-add-quirk-for-akai-midimix.patch - patches/mageia/stable-drm-i915-skl-update-plane-watermarks-atomically-during-plane-updates.patch - patches/mageia/stable-drm-i915-move-crtc-updating-in-atomic_commit-into-it-s-own-hook.patch - patches/mageia/stable-drm-i915-skl-update-ddb-values-atomically-with-wms-plane-attrs.patch - patches/mageia/stable-drm-i915-skl-don-t-try-to-update-plane-watermarks-if-they-haven-t-changed.patch - patches/mageia/stable-drm-i915-gen9-only-add-the-planes-actually-affected-by-ddb-changes.patch - patches/mageia/stable-drm-i915-gen9-fix-the-wawmmemoryreadlatency-implementation.patch - patches/mageia/stable-drm-i915-gen9-minimum-scanlines-for-y-tile-is-not-always-4.patch - patches/mageia/stable-drm-i915-gen9-fix-plane_blocks_per_line-on-watermarks-calculations.patch - patches/mageia/stable-drm-i915-gen9-fix-the-watermark-res_blocks-value.patch - patches/mageia/stable-drm-i915-sagv-is-not-skl-only-so-rename-a-few-things.patch - patches/mageia/stable-drm-i915-introduce-intel_has_sagv.patch - patches/mageia/stable-drm-i915-kbl-kbl-also-needs-to-run-the-sagv-code.patch - patches/mageia/stable-revert-drm-i915-check-live-status-before-reading-edid.patch - patches/mageia/stable-drm-i915-account-for-tseg-size-when-determining-865g-stolen-base.patch - patches/mageia/stable-drm-i915-skl-ensure-pipes-with-changed-wms-get-added-to-the-state.patch - patches/mageia/stable-drm-i915-allow-pch-dpll-sharing-regardless-of-dpll_sdvo_high_speed.patch - patches/mageia/stable-drm-i915-move-long-hpd-handling-into-the-hotplug-work.patch - patches/mageia/stable-drm-i915-allow-dp-to-work-w-o-edid.patch - patches/mageia/stable-drm-i915-just-clear-the-mmiodebug-before-a-register-access.patch - patches/mageia/stable-drm-i915-unalias-obj-phys_handle-and-obj-userptr.patch - patches/mageia/stable-posix_acl-clear-sgid-bit-when-setting-file-permissions.patch - patches/mageia/stable-rt2x00usb-fix-error-return-code.patch - patches/mageia/stable-scsi-cxlflash-remove-the-device-cleanly-in-the-system-shutdown-path.patch - patches/mageia/stable-genirq-generic_chip-add-irq_unmap-callback.patch - patches/mageia/stable-coresight-remove-erroneous-dma_free_coherent-in-tmc_probe.patch - patches/mageia/stable-uio-fix-dmem_region_start-computation.patch - patches/mageia/stable-arm-clk-imx35-fix-name-for-ckil-clk.patch - patches/mageia/stable-spi-spi-fsl-dspi-drop-extra-spi_master_put-in-device-remove-function.patch - patches/mageia/stable-i40e-remove-a-stray-unlock.patch - patches/mageia/stable-i40e-fix-broken-i40e_config_rss_aq-function.patch - patches/mageia/stable-mwifiex-correct-aid-value-during-tdls-setup.patch - patches/mageia/stable-mwifiex-fix-failed-to-reconnect-after-interface-disabled-enabled.patch - patches/mageia/stable-ath10k-add-wmi_service_periodic_chan_stat_support-wmi-service.patch - patches/mageia/stable-ath10k-fix-sending-frame-in-management-path-in-push-txq-logic.patch - patches/mageia/stable-ath10k-fix-reporting-channel-survey-data.patch - patches/mageia/stable-ath10k-fix-throughput-regression-in-multi-client-mode.patch - patches/mageia/stable-crypto-marvell-don-t-overwrite-default-creq-state-during-initialization.patch - patches/mageia/stable-crypto-gcm-fix-iv-buffer-size-in-crypto_gcm_setkey.patch - patches/mageia/stable-crypto-marvell-update-transformation-context-for-each-dequeued-req.patch - patches/mageia/stable-crypto-arm-ghash-ce-add-missing-async-import-export.patch - patches/mageia/stable-crypto-ccp-fix-return-value-check-in-ccp_dmaengine_register.patch - patches/mageia/stable-hwrng-omap-only-fail-if-pm_runtime_get_sync-returns-0.patch - patches/mageia/stable-asoc-topology-fix-error-return-code-in-soc_tplg_dapm_widget_create.patch - patches/mageia/stable-asoc-dapm-fix-possible-uninitialized-variable-in-snd_soc_dapm_get_volsw.patch - patches/mageia/stable-asoc-dapm-fix-value-setting-for-_enum_double-mux-s-second-channel.patch - patches/mageia/stable-asoc-dapm-fix-kcontrol-creation-for-output-driver-widget.patch - patches/mageia/stable-asoc-sst-bxt-rt298-fix-obsoleted-initializers-for-array.patch - patches/mageia/stable-asoc-sst-bxt-da7219_max98357a-fix-obsoleted-initializers-for-array.patch - patches/mageia/stable-iio-ad5755-fix-off-by-one-on-devnr-limit-check.patch - patches/mageia/stable-iio-light-us5182d-add-missing-error-code-assignment-before-test.patch - patches/mageia/stable-staging-android-ion-hisi-fix-dependencies.patch - patches/mageia/stable-staging-sm750fb-correctly-set-clock_phase-bit-of-display-controller.patch - patches/mageia/stable-staging-r8188eu-fix-scheduling-while-atomic-splat.patch - patches/mageia/stable-staging-ks7010-fix-wait_for_completion_interruptible_timeout-return-handling.patch - patches/mageia/stable-staging-ks7010-declare-private-functions-static.patch - patches/mageia/stable-ib-hfi1-move-iowait_init-to-priv-allocate.patch - patches/mageia/stable-ib-rdmavt-correct-sparse-annotation.patch - patches/mageia/stable-ib-qib-remove-qpt_mask-global.patch - patches/mageia/stable-ib-mlx5-fix-steering-resource-leak.patch - patches/mageia/stable-power-bq24257-fix-use-of-uninitialized-pointer-bq-charger.patch - patches/mageia/stable-dmaengine-ipu-remove-bogus-no_irq-reference.patch - patches/mageia/stable-mm-hugetlb-check-for-reserved-hugepages-during-memory-offline.patch patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch @@ -118,6 +38,7 @@ patches/mageia/x86-default_poweroff_up_machines.patch patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch + patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch @@ -142,10 +63,10 @@ patches/mageia/linux-BFQ-v8r4.patch patches/mageia/nvmepatch1-V4.patch patches/mageia/nvmepatch2-V4.patch - patches/mageia/nvmepatch3-V4.patch - patches/mageia/fs-aufs-4.7.patch - patches/mageia/fs-aufs-4.7-modular.patch - patches/mageia/fs-aufs-4.7-ver-fix.patch + patches/mageia/nvmepatch3-V4.patch + patches/mageia/dm-raid-fix-compat_features-validation.patch + patches/mageia/fs-aufs-4.8.patch + patches/mageia/fs-aufs-4.8-modular.patch patches/mageia/firewire-ieee1394-module-aliases.patch patches/mageia/char-agp-intel-new-Q57-id.patch @@ -166,7 +87,7 @@ patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch patches/mageia/gpu-drm-mach64-3.17-buildfix.patch patches/mageia/gpu-drm-mach64-3.18-buildfix.patch - patches/mageia/drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch + patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -275,8 +196,8 @@ - 2016-10-30 - 4.8.5 + 2016-11-01 + 4.8.6 Version Bump. security From 88b2965e26802e2772ea4f80d775e4ffca626f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Tue, 1 Nov 2016 13:58:18 +0200 Subject: [PATCH 09/11] config --- kernel/kernel/files/configs/kernel-x86_64-config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config index b2b211b7..fb379c33 100644 --- a/kernel/kernel/files/configs/kernel-x86_64-config +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.8.5 Kernel Configuration +# Linux/x86_64 4.8.6 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y From 4be948703df9b6dd3b8bb324e5c62396403c90f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Wed, 2 Nov 2016 13:25:55 +0200 Subject: [PATCH 10/11] kernel-4.8.6 drivers ready... --- kernel/drivers/module-bbswitch/pspec.xml | 11 +++++++++-- kernel/drivers/module-broadcom-wl/pspec.xml | 11 +++++++++-- kernel/drivers/module-virtualbox-guest/pspec.xml | 11 +++++++++-- kernel/drivers/module-virtualbox/pspec.xml | 11 +++++++++-- kernel/drivers/ndiswrapper/pspec.xml | 11 +++++++++-- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/kernel/drivers/module-bbswitch/pspec.xml b/kernel/drivers/module-bbswitch/pspec.xml index d0651179..d17eb17a 100644 --- a/kernel/drivers/module-bbswitch/pspec.xml +++ b/kernel/drivers/module-bbswitch/pspec.xml @@ -11,7 +11,7 @@

Kernel module allowing to switch dedicated graphics card on Optimus laptops kernel module allowing to switch dedicated graphics card on Optimus laptops - kernel-module-headers + kernel-module-headers https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz @@ -20,7 +20,7 @@ module-bbswitch - kernel + kernel /lib/modules @@ -34,6 +34,13 @@ + + 2016-11-02 + 0.8 + Rebuild for new kernel. + Ertuğrul Erata + ertugrulerata@gmail.com + 2016-08-24 0.8 diff --git a/kernel/drivers/module-broadcom-wl/pspec.xml b/kernel/drivers/module-broadcom-wl/pspec.xml index bc8d8f2d..fdf228dc 100644 --- a/kernel/drivers/module-broadcom-wl/pspec.xml +++ b/kernel/drivers/module-broadcom-wl/pspec.xml @@ -15,7 +15,7 @@ http://www.broadcom.com/docs/linux_sta/hybrid-v35-nodebug-pcoem-6_30_223_271.tar.gz http://www.broadcom.com/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz - kernel-module-headers + kernel-module-headers patch/license.patch @@ -27,7 +27,7 @@ module-broadcom-wl - kernel + kernel module-broadcom-wl-userspace @@ -56,6 +56,13 @@ + + 2016-11-02 + 6.30.223.271 + Rebuild for new kernel. + PisiLinux Community + admin@pisilinux.org + 2016-08-24 6.30.223.271 diff --git a/kernel/drivers/module-virtualbox-guest/pspec.xml b/kernel/drivers/module-virtualbox-guest/pspec.xml index ad67c789..d3c9e3ee 100644 --- a/kernel/drivers/module-virtualbox-guest/pspec.xml +++ b/kernel/drivers/module-virtualbox-guest/pspec.xml @@ -14,14 +14,14 @@ This package provides the kernel modules needed for mouse integration and shared folder support between VirtualBox host and guest systems. https://sourceforge.net/projects/pisi-source/files/kernel-4.7/module-virtualbox-guest-5.1.6.tar.xz - kernel-module-headers + kernel-module-headers module-virtualbox-guest - kernel + kernel baselayout module-virtualbox-guest-userspace @@ -52,6 +52,13 @@ + + 2016-11-02 + 5.1.6 + Rebuild for new kernel. + Ertuğrul Erata + ertugrulerata@gmail.com + 2016-09-26 5.1.6 diff --git a/kernel/drivers/module-virtualbox/pspec.xml b/kernel/drivers/module-virtualbox/pspec.xml index 039bff23..f82470b6 100644 --- a/kernel/drivers/module-virtualbox/pspec.xml +++ b/kernel/drivers/module-virtualbox/pspec.xml @@ -14,7 +14,7 @@ This package provides the kernel support for VirtualBox. https://sourceforge.net/projects/pisi-source/files/kernel-4.7/module-virtualbox-5.1.6.tar.xz - kernel-module-headers + kernel-module-headers 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 R|I4w&XZr#G00004Sz0VHUbz4O literal 0 HcmV?d00001 diff --git a/kernel/tools/cpupowertools/files/patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch b/kernel/tools/cpupowertools/files/patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch new file mode 100644 index 00000000..fa695774 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch @@ -0,0 +1,19 @@ + +Adjust for cfg80211_scan_done() changes in kernel 4.8 + +Signed-off-by: Thomas Backlund + +--- linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c.orig ++++ linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c +@@ -1413,7 +1413,10 @@ void rtw_cfg80211_indicate_scan_done(str + } + else + { +- cfg80211_scan_done(pwdev_priv->scan_request, aborted); ++ struct cfg80211_scan_info info = { ++ .aborted = aborted, ++ }; ++ cfg80211_scan_done(pwdev_priv->scan_request, &info); + } + + pwdev_priv->scan_request = NULL; diff --git a/kernel/tools/cpupowertools/files/patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch b/kernel/tools/cpupowertools/files/patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch new file mode 100644 index 00000000..a30f81df --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch @@ -0,0 +1,37 @@ +From e461958e7a7eb8df2e022e02f782dff5f60a44d0 Mon Sep 17 00:00:00 2001 +From: Thomas Backlund +Date: Sun, 16 Oct 2016 20:09:27 +0300 +Subject: [PATCH] Revert "include/uapi/linux/atm_zatm.h: include linux/time.h" + +This reverts commit cf00713a655d3019be7faa184402f16c43a0fed3. + +It causes linux-atm build breakage between glibc headers and kernel headers... + +Fixws are in progress upstream as of: +https://patchwork.kernel.org/patch/9294305/ + +But it's not accepted yet so it might still change, and since its uapi +we dont want to expose changes that might never land upstream. + +Reported by: Pascal Terjam +Signed-off-by: Thomas Backlund + +--- + include/uapi/linux/atm_zatm.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/include/uapi/linux/atm_zatm.h b/include/uapi/linux/atm_zatm.h +index 5cd4d4d..9c9c6ad 100644 +--- a/include/uapi/linux/atm_zatm.h ++++ b/include/uapi/linux/atm_zatm.h +@@ -14,7 +14,6 @@ + + #include + #include +-#include + + #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) + /* get pool statistics */ +-- +2.10.1 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch b/kernel/tools/cpupowertools/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch deleted file mode 100644 index 27ba34e7..00000000 --- a/kernel/tools/cpupowertools/files/patches/mageia/ahci-add-new-Intel-device-IDs.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 56e74338a535cbcc2f2da08b1ea1a92920194364 Mon Sep 17 00:00:00 2001 -From: Alexandra Yates -Date: Tue, 3 Nov 2015 14:14:18 -0800 -Subject: [PATCH] ahci: add new Intel device IDs - -Adding Intel codename Lewisburg platform device IDs for SATA. - -Signed-off-by: Alexandra Yates -Signed-off-by: Tejun Heo ---- - drivers/ata/ahci.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index ff343c4..ff02bb4 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -314,6 +314,16 @@ static const struct pci_device_id ahci_pci_tbl[] = { - { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ -+ { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ -+ { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ -+ { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ -+ { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ - { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ - { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ - { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ --- -2.3.10 - diff --git a/kernel/tools/cpupowertools/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch b/kernel/tools/cpupowertools/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch deleted file mode 100644 index 0c141707..00000000 --- a/kernel/tools/cpupowertools/files/patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch +++ /dev/null @@ -1,145 +0,0 @@ -From f7c8d3a509e51f4a555371ded4957b225f1818ad Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Mon, 2 May 2016 09:06:51 +0200 -Subject: [PATCH] ARM: bcm2835: dt: Add the ethernet to the device trees - -The hub and the ethernet in its port 1 are hardwired on the board. - -Compared to the adapters that can be plugged into the USB ports, this -one has no serial EEPROM to store its MAC. Nevertheless, the Raspberry Pi -has the MAC address for this adapter in its ROM, accessible from its -firmware. - -U-Boot can read out the address and set the local-mac-address property of the -node with "ethernet" alias. Let's add the node so that U-Boot can do its -business. - -Model B rev2 and Model B+ entries were verified by me, the hierarchy and -pid/vid pair for the Version 2 was provided by Peter Chen. Original -Model B is a blind shot, though very likely correct. - -Signed-off-by: Lubomir Rintel -Acked-by: Stephen Warren ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 1 + - arch/arm/boot/dts/bcm2835-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 1 + - arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm283x.dtsi | 2 ++ - 7 files changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi - create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index ef54050..c3e01ce 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9514.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -index 86f1f2f..364086a 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9512.dtsi" - - / { - compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index 4859e9d..4420b09 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9512.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; -diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -index ff94666..b975f29 100644 ---- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2836.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-smsc9514.dtsi" - - / { - compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi -new file mode 100644 -index 0000000..12c981e ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi -@@ -0,0 +1,19 @@ -+/ { -+ aliases { -+ ethernet = ðernet; -+ }; -+}; -+ -+&usb { -+ usb1@1 { -+ compatible = "usb424,9512"; -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet: usbether@1 { -+ compatible = "usb424,ec00"; -+ reg = <1>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi -new file mode 100644 -index 0000000..3f0a56e ---- /dev/null -+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi -@@ -0,0 +1,19 @@ -+/ { -+ aliases { -+ ethernet = ðernet; -+ }; -+}; -+ -+&usb { -+ usb1@1 { -+ compatible = "usb424,9514"; -+ reg = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet: usbether@1 { -+ compatible = "usb424,ec00"; -+ reg = <1>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi -index 8aaf193..04504b7 100644 ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -287,6 +287,8 @@ - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - v3d: v3d@7ec00000 { diff --git a/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-aliases.patch b/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-aliases.patch index febdb720..4bb20cf1 100644 --- a/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-aliases.patch +++ b/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-aliases.patch @@ -8,13 +8,14 @@ Signed-off-by: Thomas Backlund drivers/md/dm-raid.c | 2 ++ 1 file changed, 2 insertions(+) ---- linux-2.6.38.2-mga2/drivers/md/dm-raid.c.orig 2011-03-15 03:20:32.000000000 +0200 -+++ linux-2.6.38.2-mga2/drivers/md/dm-raid.c 2011-04-02 21:52:21.331302590 +0300 -@@ -693,5 +693,7 @@ MODULE_DESCRIPTION(DM_NAME " raid4/5/6 t +--- linux/drivers/md/dm-raid.c.orig ++++ linux/drivers/md/dm-raid.c +@@ -3689,6 +3689,8 @@ MODULE_ALIAS("dm-raid10"); MODULE_ALIAS("dm-raid4"); MODULE_ALIAS("dm-raid5"); MODULE_ALIAS("dm-raid6"); +MODULE_ALIAS("dm-raid45"); +MODULE_ALIAS("dm-raid4-5"); MODULE_AUTHOR("Neil Brown "); + MODULE_AUTHOR("Heinz Mauelshagen "); MODULE_LICENSE("GPL"); diff --git a/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-fix-compat_features-validation.patch b/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-fix-compat_features-validation.patch new file mode 100644 index 00000000..f2261039 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/dm-raid-fix-compat_features-validation.patch @@ -0,0 +1,39 @@ +From 5c33677c87cbe44ae04df69c4a29c1750a9ec4e5 Mon Sep 17 00:00:00 2001 +From: Andy Whitcroft +Date: Tue, 11 Oct 2016 15:16:57 +0100 +Subject: [PATCH] dm raid: fix compat_features validation + +In ecbfb9f118bce4 ("dm raid: add raid level takeover support") a new +compatible feature flag was added. Validation for these compat_features +was added but this only passes for new raid mappings with this feature +flag. This causes previously created raid mappings to be failed at +import. + +Check compat_features for the only valid combination. + +Fixes: ecbfb9f118bce4 ("dm raid: add raid level takeover support") +Cc: stable@vger.kernel.org # v4.8 +Signed-off-by: Andy Whitcroft +Signed-off-by: Heinz Mauelshagen +Signed-off-by: Mike Snitzer +--- + drivers/md/dm-raid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 8abde6b..2a39700 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -2258,7 +2258,8 @@ static int super_validate(struct raid_set *rs, struct md_rdev *rdev) + if (!mddev->events && super_init_validation(rs, rdev)) + return -EINVAL; + +- if (le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) { ++ if (le32_to_cpu(sb->compat_features) && ++ le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) { + rs->ti->error = "Unable to assemble array: Unknown flag(s) in compatible feature flags"; + return -EINVAL; + } +-- +2.10.1 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-ver-fix.patch b/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-ver-fix.patch deleted file mode 100644 index 7ffd27e4..00000000 --- a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-ver-fix.patch +++ /dev/null @@ -1,16 +0,0 @@ - -Mark as 4.7 so we can rebuild aufs tools with matching 4.7 check - -Signed-off-by: Thomas Backlund - ---- linux/include/uapi/linux/aufs_type.h.orig -+++ linux/include/uapi/linux/aufs_type.h -@@ -26,7 +26,7 @@ - - #include - --#define AUFS_VERSION "4.x-rcN" -+#define AUFS_VERSION "4.7" - - /* todo? move this to linux-2.6.19/include/magic.h */ - #define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') diff --git a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-modular.patch b/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8-modular.patch similarity index 71% rename from kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-modular.patch rename to kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8-modular.patch index faedd6af..62a3b4f0 100644 --- a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7-modular.patch +++ b/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8-modular.patch @@ -18,9 +18,9 @@ security/security.c | 10 ++++++++++ 17 files changed, 41 insertions(+), 1 deletion(-) -diff -Nurp linux-4.7-rc6-aufs/fs/aufs/Kconfig linux-4.7-rc6-aufs-mod/fs/aufs/Kconfig ---- linux-4.7-rc6-aufs/fs/aufs/Kconfig 2016-07-04 19:02:29.246286120 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/aufs/Kconfig 2016-07-04 19:03:53.653714965 +0300 +diff -Nurp linux-4.8-aufs/fs/aufs/Kconfig linux-4.8-aufs-mod/fs/aufs/Kconfig +--- linux-4.8-aufs/fs/aufs/Kconfig 2016-07-04 19:02:29.246286120 +0300 ++++ linux-4.8-aufs-mod/fs/aufs/Kconfig 2016-07-04 19:03:53.653714965 +0300 @@ -1,5 +1,5 @@ config AUFS_FS - bool "Aufs (Advanced multi layered unification filesystem) support" @@ -28,9 +28,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/aufs/Kconfig linux-4.7-rc6-aufs-mod/fs/aufs/Kco help Aufs is a stackable unification filesystem such as Unionfs, which unifies several directories and provides a merged single -diff -Nurp linux-4.7-rc6-aufs/fs/dcache.c linux-4.7-rc6-aufs-mod/fs/dcache.c ---- linux-4.7-rc6-aufs/fs/dcache.c 2016-07-04 19:02:29.260286196 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/dcache.c 2016-07-04 19:03:53.653714965 +0300 +diff -Nurp linux-4.8-aufs/fs/dcache.c linux-4.8-aufs-mod/fs/dcache.c +--- linux-4.8-aufs/fs/dcache.c 2016-07-04 19:02:29.260286196 +0300 ++++ linux-4.8-aufs-mod/fs/dcache.c 2016-07-04 19:03:53.653714965 +0300 @@ -1310,6 +1310,7 @@ rename_retry: seq = 1; goto again; @@ -39,9 +39,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/dcache.c linux-4.7-rc6-aufs-mod/fs/dcache.c /* * Search for at least 1 mount point in the dentry's subdirs. -diff -Nurp linux-4.7-rc6-aufs/fs/exec.c linux-4.7-rc6-aufs-mod/fs/exec.c ---- linux-4.7-rc6-aufs/fs/exec.c 2016-07-04 17:58:15.707773651 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/exec.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/exec.c linux-4.8-aufs-mod/fs/exec.c +--- linux-4.8-aufs/fs/exec.c 2016-07-04 17:58:15.707773651 +0300 ++++ linux-4.8-aufs-mod/fs/exec.c 2016-07-04 19:03:53.654714970 +0300 @@ -104,6 +104,7 @@ bool path_noexec(const struct path *path return (path->mnt->mnt_flags & MNT_NOEXEC) || (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); @@ -50,9 +50,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/exec.c linux-4.7-rc6-aufs-mod/fs/exec.c #ifdef CONFIG_USELIB /* -diff -Nurp linux-4.7-rc6-aufs/fs/fcntl.c linux-4.7-rc6-aufs-mod/fs/fcntl.c ---- linux-4.7-rc6-aufs/fs/fcntl.c 2016-07-04 19:02:29.260286196 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/fcntl.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/fcntl.c linux-4.8-aufs-mod/fs/fcntl.c +--- linux-4.8-aufs/fs/fcntl.c 2016-07-04 19:02:29.260286196 +0300 ++++ linux-4.8-aufs-mod/fs/fcntl.c 2016-07-04 19:03:53.654714970 +0300 @@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, un out: return error; @@ -61,9 +61,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/fcntl.c linux-4.7-rc6-aufs-mod/fs/fcntl.c static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, int force) -diff -Nurp linux-4.7-rc6-aufs/fs/file_table.c linux-4.7-rc6-aufs-mod/fs/file_table.c ---- linux-4.7-rc6-aufs/fs/file_table.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/file_table.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/file_table.c linux-4.8-aufs-mod/fs/file_table.c +--- linux-4.8-aufs/fs/file_table.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/fs/file_table.c 2016-07-04 19:03:53.654714970 +0300 @@ -147,6 +147,7 @@ over: } return ERR_PTR(-ENFILE); @@ -96,9 +96,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/file_table.c linux-4.7-rc6-aufs-mod/fs/file_tab void __init files_init(void) { -diff -Nurp linux-4.7-rc6-aufs/fs/inode.c linux-4.7-rc6-aufs-mod/fs/inode.c ---- linux-4.7-rc6-aufs/fs/inode.c 2016-07-04 19:02:29.261286202 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/inode.c 2016-07-04 20:51:39.805168596 +0300 +diff -Nurp linux-4.8-aufs/fs/inode.c linux-4.8-aufs-mod/fs/inode.c +--- linux-4.8-aufs/fs/inode.c 2016-07-04 19:02:29.261286202 +0300 ++++ linux-4.8-aufs-mod/fs/inode.c 2016-07-04 20:51:39.805168596 +0300 @@ -1600,6 +1600,7 @@ int update_time(struct inode *inode, str return update_time(inode, time, flags); @@ -107,9 +107,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/inode.c linux-4.7-rc6-aufs-mod/fs/inode.c /** * touch_atime - update the access time -diff -Nurp linux-4.7-rc6-aufs/fs/namespace.c linux-4.7-rc6-aufs-mod/fs/namespace.c ---- linux-4.7-rc6-aufs/fs/namespace.c 2016-07-04 17:58:15.729773645 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/namespace.c 2016-07-04 19:03:53.654714970 +0300 +diff -Nurp linux-4.8-aufs/fs/namespace.c linux-4.8-aufs-mod/fs/namespace.c +--- linux-4.8-aufs/fs/namespace.c 2016-07-04 17:58:15.729773645 +0300 ++++ linux-4.8-aufs-mod/fs/namespace.c 2016-07-04 19:03:53.654714970 +0300 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *m mnt_dec_writers(real_mount(mnt)); preempt_enable(); @@ -126,9 +126,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/namespace.c linux-4.7-rc6-aufs-mod/fs/namespace static void cleanup_group_ids(struct mount *mnt, struct mount *end) { -diff -Nurp linux-4.7-rc6-aufs/fs/notify/group.c linux-4.7-rc6-aufs-mod/fs/notify/group.c ---- linux-4.7-rc6-aufs/fs/notify/group.c 2016-07-04 17:58:15.742773641 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/notify/group.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/notify/group.c linux-4.8-aufs-mod/fs/notify/group.c +--- linux-4.8-aufs/fs/notify/group.c 2016-07-04 17:58:15.742773641 +0300 ++++ linux-4.8-aufs-mod/fs/notify/group.c 2016-07-04 19:03:53.655714975 +0300 @@ -22,6 +22,7 @@ #include #include @@ -161,9 +161,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/notify/group.c linux-4.7-rc6-aufs-mod/fs/notify int fsnotify_fasync(int fd, struct file *file, int on) { -diff -Nurp linux-4.7-rc6-aufs/fs/notify/mark.c linux-4.7-rc6-aufs-mod/fs/notify/mark.c ---- linux-4.7-rc6-aufs/fs/notify/mark.c 2016-07-04 17:58:15.742773641 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/notify/mark.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/notify/mark.c linux-4.8-aufs-mod/fs/notify/mark.c +--- linux-4.8-aufs/fs/notify/mark.c 2016-07-04 17:58:15.742773641 +0300 ++++ linux-4.8-aufs-mod/fs/notify/mark.c 2016-07-04 19:03:53.655714975 +0300 @@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_m mark->free_mark(mark); } @@ -196,9 +196,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/notify/mark.c linux-4.7-rc6-aufs-mod/fs/notify/ /* * Nothing fancy, just initialize lists and locks and counters. -diff -Nurp linux-4.7-rc6-aufs/fs/open.c linux-4.7-rc6-aufs-mod/fs/open.c ---- linux-4.7-rc6-aufs/fs/open.c 2016-07-04 17:58:15.746773640 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/open.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/open.c linux-4.8-aufs-mod/fs/open.c +--- linux-4.8-aufs/fs/open.c 2016-07-04 17:58:15.746773640 +0300 ++++ linux-4.8-aufs-mod/fs/open.c 2016-07-04 19:03:53.655714975 +0300 @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l inode_unlock(dentry->d_inode); return ret; @@ -215,9 +215,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/open.c linux-4.7-rc6-aufs-mod/fs/open.c static int do_dentry_open(struct file *f, struct inode *inode, -diff -Nurp linux-4.7-rc6-aufs/fs/read_write.c linux-4.7-rc6-aufs-mod/fs/read_write.c ---- linux-4.7-rc6-aufs/fs/read_write.c 2016-07-04 19:02:29.262286207 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/read_write.c 2016-07-04 19:03:53.655714975 +0300 +diff -Nurp linux-4.8-aufs/fs/read_write.c linux-4.8-aufs-mod/fs/read_write.c +--- linux-4.8-aufs/fs/read_write.c 2016-07-04 19:02:29.262286207 +0300 ++++ linux-4.8-aufs-mod/fs/read_write.c 2016-07-04 19:03:53.655714975 +0300 @@ -525,6 +525,7 @@ vfs_readf_t vfs_readf(struct file *file) return new_sync_read; return ERR_PTR(-ENOSYS); @@ -234,9 +234,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/read_write.c linux-4.7-rc6-aufs-mod/fs/read_wri ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { -diff -Nurp linux-4.7-rc6-aufs/fs/splice.c linux-4.7-rc6-aufs-mod/fs/splice.c ---- linux-4.7-rc6-aufs/fs/splice.c 2016-07-04 19:02:29.262286207 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/splice.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/fs/splice.c linux-4.8-aufs-mod/fs/splice.c +--- linux-4.8-aufs/fs/splice.c 2016-07-04 19:02:29.262286207 +0300 ++++ linux-4.8-aufs-mod/fs/splice.c 2016-07-04 19:03:53.656714979 +0300 @@ -1124,6 +1124,7 @@ long do_splice_from(struct pipe_inode_in return splice_write(pipe, out, ppos, len, flags); @@ -253,9 +253,9 @@ diff -Nurp linux-4.7-rc6-aufs/fs/splice.c linux-4.7-rc6-aufs-mod/fs/splice.c /** * splice_direct_to_actor - splices data directly between two non-pipes -diff -Nurp linux-4.7-rc6-aufs/fs/xattr.c linux-4.7-rc6-aufs-mod/fs/xattr.c ---- linux-4.7-rc6-aufs/fs/xattr.c 2016-07-04 17:58:15.754773638 +0300 -+++ linux-4.7-rc6-aufs-mod/fs/xattr.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/fs/xattr.c linux-4.8-aufs-mod/fs/xattr.c +--- linux-4.8-aufs/fs/xattr.c 2016-07-04 17:58:15.754773638 +0300 ++++ linux-4.8-aufs-mod/fs/xattr.c 2016-07-04 19:03:53.656714979 +0300 @@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry *xattr_value = value; return error; @@ -264,17 +264,17 @@ diff -Nurp linux-4.7-rc6-aufs/fs/xattr.c linux-4.7-rc6-aufs-mod/fs/xattr.c ssize_t vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) -diff -Nurp linux-4.7-rc6-aufs/kernel/task_work.c linux-4.7-rc6-aufs-mod/kernel/task_work.c ---- linux-4.7-rc6-aufs/kernel/task_work.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/kernel/task_work.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/kernel/task_work.c linux-4.8-aufs-mod/kernel/task_work.c +--- linux-4.8-aufs/kernel/task_work.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/kernel/task_work.c 2016-07-04 19:03:53.656714979 +0300 @@ -118,3 +118,4 @@ void task_work_run(void) } while (work); } } +EXPORT_SYMBOL_GPL(task_work_run); -diff -Nurp linux-4.7-rc6-aufs/security/commoncap.c linux-4.7-rc6-aufs-mod/security/commoncap.c ---- linux-4.7-rc6-aufs/security/commoncap.c 2016-07-04 17:58:15.945773585 +0300 -+++ linux-4.7-rc6-aufs-mod/security/commoncap.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/security/commoncap.c linux-4.8-aufs-mod/security/commoncap.c +--- linux-4.8-aufs/security/commoncap.c 2016-07-04 17:58:15.945773585 +0300 ++++ linux-4.8-aufs-mod/security/commoncap.c 2016-07-04 19:03:53.656714979 +0300 @@ -1058,12 +1058,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; @@ -290,9 +290,9 @@ diff -Nurp linux-4.7-rc6-aufs/security/commoncap.c linux-4.7-rc6-aufs-mod/securi #ifdef CONFIG_SECURITY -diff -Nurp linux-4.7-rc6-aufs/security/device_cgroup.c linux-4.7-rc6-aufs-mod/security/device_cgroup.c ---- linux-4.7-rc6-aufs/security/device_cgroup.c 2016-05-16 01:43:13.000000000 +0300 -+++ linux-4.7-rc6-aufs-mod/security/device_cgroup.c 2016-07-04 19:03:53.656714979 +0300 +diff -Nurp linux-4.8-aufs/security/device_cgroup.c linux-4.8-aufs-mod/security/device_cgroup.c +--- linux-4.8-aufs/security/device_cgroup.c 2016-05-16 01:43:13.000000000 +0300 ++++ linux-4.8-aufs-mod/security/device_cgroup.c 2016-07-04 19:03:53.656714979 +0300 @@ -7,6 +7,7 @@ #include #include @@ -309,9 +309,9 @@ diff -Nurp linux-4.7-rc6-aufs/security/device_cgroup.c linux-4.7-rc6-aufs-mod/se int devcgroup_inode_mknod(int mode, dev_t dev) { -diff -Nurp linux-4.7-rc6-aufs/security/security.c linux-4.7-rc6-aufs-mod/security/security.c ---- linux-4.7-rc6-aufs/security/security.c 2016-07-04 17:58:15.948773584 +0300 -+++ linux-4.7-rc6-aufs-mod/security/security.c 2016-07-04 19:03:53.657714984 +0300 +diff -Nurp linux-4.8-aufs/security/security.c linux-4.8-aufs-mod/security/security.c +--- linux-4.8-aufs/security/security.c 2016-07-04 17:58:15.948773584 +0300 ++++ linux-4.8-aufs-mod/security/security.c 2016-07-04 19:03:53.657714984 +0300 @@ -434,6 +434,7 @@ int security_path_rmdir(const struct pat return 0; return call_int_hook(path_rmdir, 0, dir, dentry); diff --git a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7.patch b/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8.patch similarity index 96% rename from kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7.patch rename to kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8.patch index d2d09b83..1efb3528 100644 --- a/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.7.patch +++ b/kernel/tools/cpupowertools/files/patches/mageia/fs-aufs-4.8.patch @@ -1,4 +1,117 @@ + Documentation/ABI/testing/debugfs-aufs | 50 + Documentation/ABI/testing/sysfs-aufs | 31 + Documentation/filesystems/aufs/README | 392 +++ + Documentation/filesystems/aufs/design/01intro.txt | 157 + + Documentation/filesystems/aufs/design/02struct.txt | 245 ++ + Documentation/filesystems/aufs/design/03atomic_open.txt | 72 + Documentation/filesystems/aufs/design/03lookup.txt | 100 + Documentation/filesystems/aufs/design/04branch.txt | 61 + Documentation/filesystems/aufs/design/05wbr_policy.txt | 51 + Documentation/filesystems/aufs/design/06fhsm.txt | 105 + Documentation/filesystems/aufs/design/06mmap.txt | 59 + Documentation/filesystems/aufs/design/06xattr.txt | 81 + Documentation/filesystems/aufs/design/07export.txt | 45 + Documentation/filesystems/aufs/design/08shwh.txt | 39 + Documentation/filesystems/aufs/design/10dynop.txt | 34 + MAINTAINERS | 13 + drivers/block/loop.c | 18 + fs/Kconfig | 1 + fs/Makefile | 1 + fs/aufs/Kconfig | 185 + + fs/aufs/Makefile | 36 + fs/aufs/aufs.h | 46 + fs/aufs/branch.c | 1399 ++++++++++++ + fs/aufs/branch.h | 296 ++ + fs/aufs/cpup.c | 1378 +++++++++++ + fs/aufs/cpup.h | 81 + fs/aufs/dbgaufs.c | 425 +++ + fs/aufs/dbgaufs.h | 35 + fs/aufs/dcsub.c | 212 + + fs/aufs/dcsub.h | 123 + + fs/aufs/debug.c | 427 +++ + fs/aufs/debug.h | 212 + + fs/aufs/dentry.c | 1117 +++++++++ + fs/aufs/dentry.h | 242 ++ + fs/aufs/dinfo.c | 540 ++++ + fs/aufs/dir.c | 749 ++++++ + fs/aufs/dir.h | 124 + + fs/aufs/dynop.c | 358 +++ + fs/aufs/dynop.h | 61 + fs/aufs/export.c | 824 +++++++ + fs/aufs/f_op.c | 759 ++++++ + fs/aufs/fhsm.c | 412 +++ + fs/aufs/file.c | 844 +++++++ + fs/aufs/file.h | 281 ++ + fs/aufs/finfo.c | 138 + + fs/aufs/fstype.h | 387 +++ + fs/aufs/hfsnotify.c | 274 ++ + fs/aufs/hfsplus.c | 43 + fs/aufs/hnotify.c | 710 ++++++ + fs/aufs/i_op.c | 1438 ++++++++++++ + fs/aufs/i_op_add.c | 911 +++++++ + fs/aufs/i_op_del.c | 498 ++++ + fs/aufs/i_op_ren.c | 1002 ++++++++ + fs/aufs/iinfo.c | 272 ++ + fs/aufs/inode.c | 506 ++++ + fs/aufs/inode.h | 687 +++++ + fs/aufs/ioctl.c | 206 + + fs/aufs/loop.c | 134 + + fs/aufs/loop.h | 39 + fs/aufs/magic.mk | 30 + fs/aufs/module.c | 319 ++ + fs/aufs/module.h | 143 + + fs/aufs/mvdown.c | 691 +++++ + fs/aufs/opts.c | 1847 ++++++++++++++++ + fs/aufs/opts.h | 198 + + fs/aufs/plink.c | 501 ++++ + fs/aufs/poll.c | 39 + fs/aufs/posix_acl.c | 85 + fs/aufs/procfs.c | 156 + + fs/aufs/rdu.c | 368 +++ + fs/aufs/rwsem.h | 185 + + fs/aufs/sbinfo.c | 342 ++ + fs/aufs/spl.h | 100 + fs/aufs/super.c | 1025 ++++++++ + fs/aufs/super.h | 625 +++++ + fs/aufs/sysaufs.c | 91 + fs/aufs/sysaufs.h | 88 + fs/aufs/sysfs.c | 340 ++ + fs/aufs/sysrq.c | 144 + + fs/aufs/vdir.c | 887 +++++++ + fs/aufs/vfsub.c | 871 +++++++ + fs/aufs/vfsub.h | 303 ++ + fs/aufs/wbr_policy.c | 752 ++++++ + fs/aufs/whout.c | 1047 +++++++++ + fs/aufs/whout.h | 72 + fs/aufs/wkq.c | 200 + + fs/aufs/wkq.h | 80 + fs/aufs/xattr.c | 334 ++ + fs/aufs/xino.c | 1305 +++++++++++ + fs/dcache.c | 2 + fs/fcntl.c | 4 + fs/inode.c | 2 + fs/proc/base.c | 2 + fs/proc/nommu.c | 5 + fs/proc/task_mmu.c | 7 + fs/proc/task_nommu.c | 5 + fs/read_write.c | 22 + fs/splice.c | 10 + include/linux/file.h | 1 + include/linux/fs.h | 9 + include/linux/mm.h | 22 + include/linux/mm_types.h | 2 + include/linux/splice.h | 6 + include/uapi/linux/Kbuild | 1 + include/uapi/linux/aufs_type.h | 406 +++ + kernel/fork.c | 2 + mm/Makefile | 2 + mm/filemap.c | 2 + mm/memory.c | 2 + mm/mmap.c | 33 + mm/nommu.c | 10 + mm/prfile.c | 86 + 112 files changed, 33747 insertions(+), 30 deletions(-) Documentation/ABI/testing/debugfs-aufs | 50 + Documentation/ABI/testing/sysfs-aufs | 31 + Documentation/filesystems/aufs/README | 392 +++++ @@ -21,73 +134,73 @@ fs/aufs/Kconfig | 185 ++ fs/aufs/Makefile | 36 + fs/aufs/aufs.h | 46 + - fs/aufs/branch.c | 1393 +++++++++++++++ + fs/aufs/branch.c | 1399 +++++++++++++++ fs/aufs/branch.h | 296 ++++ - fs/aufs/cpup.c | 1370 +++++++++++++++ + fs/aufs/cpup.c | 1378 +++++++++++++++ fs/aufs/cpup.h | 81 + - fs/aufs/dbgaufs.c | 419 +++++ + fs/aufs/dbgaufs.c | 425 +++++ fs/aufs/dbgaufs.h | 35 + - fs/aufs/dcsub.c | 211 +++ + fs/aufs/dcsub.c | 212 +++ fs/aufs/dcsub.h | 123 ++ - fs/aufs/debug.c | 428 +++++ + fs/aufs/debug.c | 427 +++++ fs/aufs/debug.h | 212 +++ - fs/aufs/dentry.c | 1115 ++++++++++++ - fs/aufs/dentry.h | 239 +++ - fs/aufs/dinfo.c | 539 ++++++ - fs/aufs/dir.c | 743 ++++++++ - fs/aufs/dir.h | 118 ++ - fs/aufs/dynop.c | 356 ++++ + fs/aufs/dentry.c | 1117 ++++++++++++ + fs/aufs/dentry.h | 242 +++ + fs/aufs/dinfo.c | 540 ++++++ + fs/aufs/dir.c | 749 ++++++++ + fs/aufs/dir.h | 124 ++ + fs/aufs/dynop.c | 358 ++++ fs/aufs/dynop.h | 61 + fs/aufs/export.c | 824 +++++++++ - fs/aufs/f_op.c | 757 ++++++++ + fs/aufs/f_op.c | 759 ++++++++ fs/aufs/fhsm.c | 412 +++++ - fs/aufs/file.c | 830 +++++++++ - fs/aufs/file.h | 278 +++ - fs/aufs/finfo.c | 136 ++ + fs/aufs/file.c | 844 +++++++++ + fs/aufs/file.h | 281 +++ + fs/aufs/finfo.c | 138 ++ fs/aufs/fstype.h | 387 ++++ fs/aufs/hfsnotify.c | 274 +++ fs/aufs/hfsplus.c | 43 + - fs/aufs/hnotify.c | 697 ++++++++ - fs/aufs/i_op.c | 1401 +++++++++++++++ + fs/aufs/hnotify.c | 710 ++++++++ + fs/aufs/i_op.c | 1438 +++++++++++++++ fs/aufs/i_op_add.c | 911 ++++++++++ fs/aufs/i_op_del.c | 498 ++++++ fs/aufs/i_op_ren.c | 1002 +++++++++++ - fs/aufs/iinfo.c | 271 +++ - fs/aufs/inode.c | 504 ++++++ - fs/aufs/inode.h | 681 ++++++++ + fs/aufs/iinfo.c | 272 +++ + fs/aufs/inode.c | 506 ++++++ + fs/aufs/inode.h | 687 ++++++++ fs/aufs/ioctl.c | 206 +++ - fs/aufs/loop.c | 133 ++ + fs/aufs/loop.c | 134 ++ fs/aufs/loop.h | 39 + fs/aufs/magic.mk | 30 + - fs/aufs/module.c | 209 +++ - fs/aufs/module.h | 76 + + fs/aufs/module.c | 319 ++++ + fs/aufs/module.h | 143 ++ fs/aufs/mvdown.c | 691 ++++++++ - fs/aufs/opts.c | 1846 ++++++++++++++++++++ + fs/aufs/opts.c | 1847 ++++++++++++++++++++ fs/aufs/opts.h | 198 +++ - fs/aufs/plink.c | 489 ++++++ + fs/aufs/plink.c | 501 ++++++ fs/aufs/poll.c | 39 + fs/aufs/posix_acl.c | 85 + fs/aufs/procfs.c | 156 ++ fs/aufs/rdu.c | 368 ++++ fs/aufs/rwsem.h | 185 ++ - fs/aufs/sbinfo.c | 340 ++++ - fs/aufs/spl.h | 98 ++ - fs/aufs/super.c | 1026 +++++++++++ + fs/aufs/sbinfo.c | 342 ++++ + fs/aufs/spl.h | 100 ++ + fs/aufs/super.c | 1025 +++++++++++ fs/aufs/super.h | 625 +++++++ fs/aufs/sysaufs.c | 91 + fs/aufs/sysaufs.h | 88 + fs/aufs/sysfs.c | 340 ++++ fs/aufs/sysrq.c | 144 ++ - fs/aufs/vdir.c | 876 ++++++++++ + fs/aufs/vdir.c | 887 ++++++++++ fs/aufs/vfsub.c | 871 +++++++++ - fs/aufs/vfsub.h | 297 ++++ + fs/aufs/vfsub.h | 303 ++++ fs/aufs/wbr_policy.c | 752 ++++++++ fs/aufs/whout.c | 1047 +++++++++++ fs/aufs/whout.h | 72 + - fs/aufs/wkq.c | 205 +++ - fs/aufs/wkq.h | 82 + - fs/aufs/xattr.c | 332 ++++ - fs/aufs/xino.c | 1304 ++++++++++++++ + fs/aufs/wkq.c | 200 +++ + fs/aufs/wkq.h | 80 + + fs/aufs/xattr.c | 334 ++++ + fs/aufs/xino.c | 1305 ++++++++++++++ fs/dcache.c | 2 +- fs/fcntl.c | 4 +- fs/inode.c | 2 +- @@ -111,7 +224,7 @@ mm/mmap.c | 33 +- mm/nommu.c | 10 +- mm/prfile.c | 86 + - 112 files changed, 33420 insertions(+), 30 deletions(-) + 112 files changed, 33747 insertions(+), 30 deletions(-) diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs new file mode 100644 @@ -1726,10 +1839,10 @@ index 0000000..49afc58 +Currently this approach is applied to address_space_operations for +regular files only. diff --git a/MAINTAINERS b/MAINTAINERS -index 952fd2a..6a8f0f8 100644 +index f593300..8a17054 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2210,6 +2210,19 @@ F: include/linux/audit.h +@@ -2256,6 +2256,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -1750,10 +1863,10 @@ index 952fd2a..6a8f0f8 100644 M: Miguel Ojeda Sandonis W: http://miguelojeda.es/auxdisplay.htm diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 1fa8cc2..7339e65 100644 +index c9f2107..005e292 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -712,6 +712,24 @@ static inline int is_loop_device(struct file *file) +@@ -701,6 +701,24 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } @@ -1779,10 +1892,10 @@ index 1fa8cc2..7339e65 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/Kconfig b/fs/Kconfig -index b8fcb41..78adefb 100644 +index 2bc7ad7..3049386 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -236,6 +236,7 @@ source "fs/pstore/Kconfig" +@@ -245,6 +245,7 @@ source "fs/pstore/Kconfig" source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" @@ -1791,10 +1904,10 @@ index b8fcb41..78adefb 100644 endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile -index 85b6e13..e7bb164 100644 +index ed2b632..aa6d14b 100644 --- a/fs/Makefile +++ b/fs/Makefile -@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules +@@ -129,3 +129,4 @@ obj-y += exofs/ # Multiple modules obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ @@ -2086,10 +2199,10 @@ index 0000000..49f43b4 +#endif /* __AUFS_H__ */ diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c new file mode 100644 -index 0000000..baf786e +index 0000000..3bfbe5b --- /dev/null +++ b/fs/aufs/branch.c -@@ -0,0 +1,1393 @@ +@@ -0,0 +1,1399 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -2130,7 +2243,7 @@ index 0000000..baf786e + + if (br->br_fhsm) { + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_delayed_kfree(br->br_fhsm); + } + + key = br->br_dykey; @@ -2144,8 +2257,9 @@ index 0000000..baf786e + lockdep_off(); + path_put(&br->br_path); + lockdep_on(); -+ kfree(wbr); -+ kfree(br); ++ if (wbr) ++ au_delayed_kfree(wbr); ++ au_delayed_kfree(br); +} + +/* @@ -2232,22 +2346,23 @@ index 0000000..baf786e + goto out_wbr; + } + -+ err = au_sbr_realloc(au_sbi(sb), new_nbranch); ++ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0); + if (!err) -+ err = au_di_realloc(au_di(root), new_nbranch); ++ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0); + if (!err) { + inode = d_inode(root); -+ err = au_hinode_realloc(au_ii(inode), new_nbranch); ++ err = au_hinode_realloc(au_ii(inode), new_nbranch, /*may_shrink*/0); + } + if (!err) + return add_branch; /* success */ + +out_wbr: -+ kfree(add_branch->br_wbr); ++ if (add_branch->br_wbr) ++ au_delayed_kfree(add_branch->br_wbr); +out_hnotify: + au_hnotify_fin_br(add_branch); +out_br: -+ kfree(add_branch); ++ au_delayed_kfree(add_branch); +out: + return ERR_PTR(err); +} @@ -2413,7 +2528,7 @@ index 0000000..baf786e + br->br_perm = old_perm; + + if (!err && wbr && !au_br_writable(new_perm)) { -+ kfree(wbr); ++ au_delayed_kfree(wbr); + br->br_wbr = NULL; + } + @@ -2980,7 +3095,8 @@ index 0000000..baf786e + sbinfo->si_branch[0 + bbot] = NULL; + sbinfo->si_bbot--; + -+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + sbinfo->si_branch = p; + /* harmless error */ @@ -2999,7 +3115,8 @@ index 0000000..baf786e + /* au_h_dentry_init(au_hdentry(dinfo, bbot); */ + dinfo->di_bbot--; + -+ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + dinfo->di_hdentry = p; + /* harmless error */ @@ -3018,7 +3135,8 @@ index 0000000..baf786e + /* au_hinode_init(au_hinode(iinfo, bbot)); */ + iinfo->ii_bbot--; + -+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST); ++ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST, ++ /*may_shrink*/1); + if (p) + iinfo->ii_hinode = p; + /* harmless error */ @@ -3436,7 +3554,7 @@ index 0000000..baf786e + if (br->br_wbr) { + err = au_wbr_init(br, sb, mod->perm); + if (unlikely(err)) { -+ kfree(br->br_wbr); ++ au_delayed_kfree(br->br_wbr); + br->br_wbr = NULL; + } + } @@ -3448,7 +3566,7 @@ index 0000000..baf786e + if (!au_br_fhsm(mod->perm)) { + /* fhsm --> non-fhsm */ + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_delayed_kfree(br->br_fhsm); + br->br_fhsm = NULL; + } + } else if (au_br_fhsm(mod->perm)) @@ -3460,7 +3578,8 @@ index 0000000..baf786e + goto out; /* success */ + +out_bf: -+ kfree(bf); ++ if (bf) ++ au_delayed_kfree(bf); +out: + AuTraceErr(err); + return err; @@ -3787,10 +3906,10 @@ index 0000000..32a4d8f +#endif /* __AUFS_BRANCH_H__ */ diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c new file mode 100644 -index 0000000..52f87de +index 0000000..598a4d6 --- /dev/null +++ b/fs/aufs/cpup.c -@@ -0,0 +1,1370 @@ +@@ -0,0 +1,1378 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -4137,9 +4256,9 @@ index 0000000..52f87de + dst->f_pos = 0; + err = au_do_copy_file(dst, src, len, buf, blksize); + if (do_kfree) -+ kfree(buf); ++ au_delayed_kfree(buf); + else -+ free_page((unsigned long)buf); ++ au_delayed_free_page((unsigned long)buf); + +out: + return err; @@ -4174,6 +4293,7 @@ index 0000000..52f87de + } + }; + struct super_block *sb; ++ struct inode *h_src_inode; + struct task_struct *tsk = current; + + /* bsrc branch can be ro/rw. */ @@ -4189,7 +4309,9 @@ index 0000000..52f87de + } + + /* try stopping to update while we copyup */ -+ IMustLock(d_inode(file[SRC].dentry)); ++ h_src_inode = d_inode(file[SRC].dentry); ++ if (!au_test_nfs(h_src_inode->i_sb)) ++ IMustLock(h_src_inode); + err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); + + /* i wonder if we had O_NO_DELAY_FPUT flag */ @@ -4249,8 +4371,13 @@ index 0000000..52f87de + goto out; + } + h_src_attr->valid = 1; -+ err = au_cp_regular(cpg); -+ inode_unlock(h_src_inode); ++ if (!au_test_nfs(h_src_inode->i_sb)) { ++ err = au_cp_regular(cpg); ++ inode_unlock(h_src_inode); ++ } else { ++ inode_unlock(h_src_inode); ++ err = au_cp_regular(cpg); ++ } + rerr = au_pin_hdir_relock(cpg->pin); + if (!err && rerr) + err = rerr; @@ -4299,7 +4426,7 @@ index 0000000..52f87de + sym.k[symlen] = 0; + err = vfsub_symlink(h_dir, h_path, sym.k); + } -+ free_page((unsigned long)sym.k); ++ au_delayed_free_page((unsigned long)sym.k); + +out: + return err; @@ -4670,7 +4797,7 @@ index 0000000..52f87de + } +out_parent: + dput(dst_parent); -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -5250,10 +5377,10 @@ index 0000000..ccba2c4 +#endif /* __AUFS_CPUP_H__ */ diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c new file mode 100644 -index 0000000..21ac773 +index 0000000..4db01e8 --- /dev/null +++ b/fs/aufs/dbgaufs.c -@@ -0,0 +1,419 @@ +@@ -0,0 +1,425 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -5284,7 +5411,7 @@ index 0000000..21ac773 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused, + struct file *file) +{ -+ kfree(file->private_data); ++ au_delayed_kfree(file->private_data); + return 0; +} + @@ -5346,7 +5473,7 @@ index 0000000..21ac773 +static int dbgaufs_plink_release(struct inode *inode __maybe_unused, + struct file *file) +{ -+ free_page((unsigned long)file->private_data); ++ au_delayed_free_page((unsigned long)file->private_data); + return 0; +} + @@ -5410,7 +5537,7 @@ index 0000000..21ac773 + goto out; /* success */ + +out_free: -+ free_page((unsigned long)p); ++ au_delayed_free_page((unsigned long)p); +out: + return err; +} @@ -5512,7 +5639,10 @@ index 0000000..21ac773 + for (; bindex <= bbot; bindex++) { + br = au_sbr(sb, bindex); + xi = &br->br_xino; ++ /* debugfs acquires the parent i_mutex */ ++ lockdep_off(); + debugfs_remove(xi->xi_dbgaufs); ++ lockdep_on(); + xi->xi_dbgaufs = NULL; + } +} @@ -5537,8 +5667,11 @@ index 0000000..21ac773 + br = au_sbr(sb, bindex); + xi = &br->br_xino; + AuDebugOn(xi->xi_dbgaufs); ++ /* debugfs acquires the parent i_mutex */ ++ lockdep_off(); + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, + sbinfo, &dbgaufs_xino_fop); ++ lockdep_on(); + /* ignore an error */ + if (unlikely(!xi->xi_dbgaufs)) + AuWarn1("failed %s under debugfs\n", name); @@ -5716,10 +5849,10 @@ index 0000000..81f272e +#endif /* __DBGAUFS_H__ */ diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c new file mode 100644 -index 0000000..e72acce +index 0000000..5d46398 --- /dev/null +++ b/fs/aufs/dcsub.c -@@ -0,0 +1,211 @@ +@@ -0,0 +1,212 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -5738,7 +5871,7 @@ index 0000000..e72acce + p = dpage->dentries; + for (i = 0; i < dpage->ndentry; i++) + dput(*p++); -+ free_page((unsigned long)dpage->dentries); ++ au_delayed_free_page((unsigned long)dpage->dentries); +} + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) @@ -5761,7 +5894,7 @@ index 0000000..e72acce + return 0; /* success */ + +out_dpages: -+ kfree(dpages->dpages); ++ au_delayed_kfree(dpages->dpages); +out: + return err; +} @@ -5774,7 +5907,7 @@ index 0000000..e72acce + p = dpages->dpages; + for (i = 0; i < dpages->ndpage; i++) + au_dpage_free(p++); -+ kfree(dpages->dpages); ++ au_delayed_kfree(dpages->dpages); +} + +static int au_dpages_append(struct au_dcsub_pages *dpages, @@ -5791,7 +5924,8 @@ index 0000000..e72acce + err = -ENOMEM; + sz = dpages->ndpage * sizeof(*dpages->dpages); + p = au_kzrealloc(dpages->dpages, sz, -+ sz + sizeof(*dpages->dpages), gfp); ++ sz + sizeof(*dpages->dpages), gfp, ++ /*may_shrink*/0); + if (unlikely(!p)) + goto out; + @@ -6062,10 +6196,10 @@ index 0000000..5d2cf66 +#endif /* __AUFS_DCSUB_H__ */ diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c new file mode 100644 -index 0000000..44bdb5f +index 0000000..443fee3 --- /dev/null +++ b/fs/aufs/debug.c -@@ -0,0 +1,428 @@ +@@ -0,0 +1,427 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -6391,7 +6525,7 @@ index 0000000..44bdb5f + au_br_count_init(&a->fake); + err = do_pri_br(-1, &a->fake); + au_br_count_fin(&a->fake); -+ kfree(a); ++ au_delayed_kfree(a); + dpri("dev 0x%x\n", sb->s_dev); + if (err || !au_test_aufs(sb)) + return; @@ -6399,9 +6533,8 @@ index 0000000..44bdb5f + sbinfo = au_sbi(sb); + if (!sbinfo) + return; -+ dpri("nw %lld, gen %u, kobj %d\n", -+ percpu_counter_sum(&sbinfo->si_nowait.nw_len), -+ sbinfo->si_generation, ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, + atomic_read(&sbinfo->si_kobj.kref.refcount)); + for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++) + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); @@ -6714,10 +6847,10 @@ index 0000000..0567f31 +#endif /* __AUFS_DEBUG_H__ */ diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c new file mode 100644 -index 0000000..4bb1530 +index 0000000..5eb4f36 --- /dev/null +++ b/fs/aufs/dentry.c -@@ -0,0 +1,1115 @@ +@@ -0,0 +1,1117 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -6756,7 +6889,7 @@ index 0000000..4bb1530 + br = au_sbr(dentry->d_sb, bindex); + wh_able = !!au_br_whable(br->br_perm); + if (wh_able) -+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0); ++ wh_found = au_wh_test(h_parent, wh_name, ignore_perm); + h_dentry = ERR_PTR(wh_found); + if (!wh_found) + goto real_lookup; @@ -6921,7 +7054,7 @@ index 0000000..4bb1530 + +out_parent: + dput(parent); -+ kfree(whname.name); ++ au_delayed_kfree(whname.name); +out: + return err; +} @@ -7421,7 +7554,7 @@ index 0000000..4bb1530 + +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) +{ -+ int err, ebrange; ++ int err, ebrange, nbr; + unsigned int sigen; + struct au_dinfo *dinfo, *tmp; + struct super_block *sb; @@ -7437,8 +7570,9 @@ index 0000000..4bb1530 + if (unlikely(err)) + goto out; + ++ nbr = au_sbbot(sb) + 1; + dinfo = au_di(dentry); -+ err = au_di_realloc(dinfo, au_sbbot(sb) + 1); ++ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + ebrange = au_dbrange_test(dentry); @@ -7481,6 +7615,7 @@ index 0000000..4bb1530 + au_dbg_verify_dinode(dentry); + AuTraceErr(err); + } ++ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */ + au_rw_write_unlock(&tmp->di_rwsem); + au_di_free(tmp); + if (unlikely(err)) @@ -7835,10 +7970,10 @@ index 0000000..4bb1530 +}; diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h new file mode 100644 -index 0000000..bdc1af6 +index 0000000..01211d2 --- /dev/null +++ b/fs/aufs/dentry.h -@@ -0,0 +1,239 @@ +@@ -0,0 +1,242 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -7866,7 +8001,10 @@ index 0000000..bdc1af6 + struct au_rwsem di_rwsem; + aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; + unsigned char di_tmpfile; /* to allow the different name */ -+ struct au_hdentry *di_hdentry; ++ union { ++ struct au_hdentry *di_hdentry; ++ struct llist_node di_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -7904,7 +8042,7 @@ index 0000000..bdc1af6 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); +int au_di_init(struct dentry *dentry); +void au_di_fin(struct dentry *dentry); -+int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink); + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc); +void di_read_unlock(struct dentry *d, int flags); @@ -8080,10 +8218,10 @@ index 0000000..bdc1af6 +#endif /* __AUFS_DENTRY_H__ */ diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c new file mode 100644 -index 0000000..43b5509 +index 0000000..2626c0c --- /dev/null +++ b/fs/aufs/dinfo.c -@@ -0,0 +1,539 @@ +@@ -0,0 +1,540 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -8126,7 +8264,7 @@ index 0000000..43b5509 + goto out; + } + -+ au_cache_free_dinfo(dinfo); ++ au_cache_dfree_dinfo(dinfo); + dinfo = NULL; + +out: @@ -8146,8 +8284,8 @@ index 0000000..43b5509 + while (bindex++ <= bbot) + au_hdput(p++); + } -+ kfree(dinfo->di_hdentry); -+ au_cache_free_dinfo(dinfo); ++ au_delayed_kfree(dinfo->di_hdentry); ++ au_cache_dfree_dinfo(dinfo); +} + +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) @@ -8215,7 +8353,7 @@ index 0000000..43b5509 + au_di_free(dinfo); +} + -+int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink) +{ + int err, sz; + struct au_hdentry *hdp; @@ -8226,7 +8364,8 @@ index 0000000..43b5509 + sz = sizeof(*hdp) * (dinfo->di_bbot + 1); + if (!sz) + sz = sizeof(*hdp); -+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS, ++ may_shrink); + if (hdp) { + dinfo->di_hdentry = hdp; + err = 0; @@ -8625,10 +8764,10 @@ index 0000000..43b5509 +} diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c new file mode 100644 -index 0000000..27bef0b +index 0000000..395563e --- /dev/null +++ b/fs/aufs/dir.c -@@ -0,0 +1,743 @@ +@@ -0,0 +1,749 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -8774,7 +8913,7 @@ index 0000000..27bef0b +out: + dput(a->dentry); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(arg); ++ au_delayed_kfree(arg); +} + +void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) @@ -8810,7 +8949,7 @@ index 0000000..27bef0b + if (unlikely(wkq_err)) { + pr_err("wkq %d\n", wkq_err); + dput(dentry); -+ kfree(arg); ++ au_delayed_kfree(arg); + } + +out: @@ -8929,7 +9068,7 @@ index 0000000..27bef0b + }; + err = au_do_open(file, &args); + if (unlikely(err)) -+ kfree(fidir); ++ au_delayed_kfree(fidir); + } + si_read_unlock(sb); + return err; @@ -8941,8 +9080,11 @@ index 0000000..27bef0b + struct au_vdir *vdir_cache; + struct au_finfo *finfo; + struct au_fidir *fidir; ++ struct au_hfile *hf; + aufs_bindex_t bindex, bbot; ++ int execed, delayed; + ++ delayed = (current->flags & PF_KTHREAD) || in_interrupt(); + finfo = au_fi(file); + fidir = finfo->fi_hdir; + if (fidir) { @@ -8950,22 +9092,25 @@ index 0000000..27bef0b + &au_sbi(file->f_path.dentry->d_sb)->si_files); + vdir_cache = fidir->fd_vdir_cache; /* lock-free */ + if (vdir_cache) -+ au_vdir_free(vdir_cache); ++ au_vdir_free(vdir_cache, delayed); + + bindex = finfo->fi_btop; + if (bindex >= 0) { ++ execed = vfsub_file_execed(file); ++ hf = fidir->fd_hfile + bindex; + /* + * calls fput() instead of filp_close(), + * since no dnotify or lock for the lower file. + */ + bbot = fidir->fd_bbot; -+ for (; bindex <= bbot; bindex++) -+ au_set_h_fptr(file, bindex, NULL); ++ for (; bindex <= bbot; bindex++, hf++) ++ if (hf->hf_file) ++ au_hfput(hf, execed); + } -+ kfree(fidir); ++ au_delayed_kfree(fidir); + finfo->fi_hdir = NULL; + } -+ au_finfo_fin(file); ++ au_finfo_fin(file, delayed); + return 0; +} + @@ -9374,10 +9519,10 @@ index 0000000..27bef0b +}; diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h new file mode 100644 -index 0000000..b0a79d7 +index 0000000..4f3945a --- /dev/null +++ b/fs/aufs/dir.h -@@ -0,0 +1,118 @@ +@@ -0,0 +1,124 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -9409,7 +9554,10 @@ index 0000000..b0a79d7 + +struct au_vdir_dehstr { + struct hlist_node hash; -+ struct au_vdir_destr *str; ++ union { ++ struct au_vdir_destr *str; ++ struct llist_node lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +struct au_vdir_de { @@ -9447,7 +9595,10 @@ index 0000000..b0a79d7 + + unsigned long vd_version; + unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; ++ union { ++ unsigned long vd_jiffy; ++ struct llist_node vd_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -9471,7 +9622,7 @@ index 0000000..b0a79d7 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, + unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh); -+void au_vdir_free(struct au_vdir *vdir); ++void au_vdir_free(struct au_vdir *vdir, int atonce); +int au_vdir_init(struct file *file); +int au_vdir_fill_de(struct file *file, struct dir_context *ctx); + @@ -9498,10 +9649,10 @@ index 0000000..b0a79d7 +#endif /* __AUFS_DIR_H__ */ diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c new file mode 100644 -index 0000000..dfb3a71 +index 0000000..eb0e1a7 --- /dev/null +++ b/fs/aufs/dynop.c -@@ -0,0 +1,356 @@ +@@ -0,0 +1,358 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima + */ @@ -9518,17 +9669,17 @@ index 0000000..dfb3a71 + * How large will these lists be? + * Usually just a few elements, 20-30 at most for each, I guess. + */ -+static struct au_splhead dynop[AuDyLast]; ++static struct au_sphlhead dynop[AuDyLast]; + -+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op) ++static struct au_dykey *dy_gfind_get(struct au_sphlhead *sphl, const void *h_op) +{ + struct au_dykey *key, *tmp; -+ struct list_head *head; ++ struct hlist_head *head; + + key = NULL; -+ head = &spl->head; ++ head = &sphl->head; + rcu_read_lock(); -+ list_for_each_entry_rcu(tmp, head, dk_list) ++ hlist_for_each_entry_rcu(tmp, head, dk_hnode) + if (tmp->dk_op.dy_hop == h_op) { + key = tmp; + kref_get(&key->dk_kref); @@ -9575,24 +9726,24 @@ index 0000000..dfb3a71 +} + +/* kref_get() if @key is already added */ -+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key) ++static struct au_dykey *dy_gadd(struct au_sphlhead *sphl, struct au_dykey *key) +{ + struct au_dykey *tmp, *found; -+ struct list_head *head; ++ struct hlist_head *head; + const void *h_op = key->dk_op.dy_hop; + + found = NULL; -+ head = &spl->head; -+ spin_lock(&spl->spin); -+ list_for_each_entry(tmp, head, dk_list) ++ head = &sphl->head; ++ spin_lock(&sphl->spin); ++ hlist_for_each_entry(tmp, head, dk_hnode) + if (tmp->dk_op.dy_hop == h_op) { + kref_get(&tmp->dk_kref); + found = tmp; + break; + } + if (!found) -+ list_add_rcu(&key->dk_list, head); -+ spin_unlock(&spl->spin); ++ hlist_add_head_rcu(&key->dk_hnode, head); ++ spin_unlock(&sphl->spin); + + if (!found) + DyPrSym(key); @@ -9605,17 +9756,17 @@ index 0000000..dfb3a71 + + key = container_of(rcu, struct au_dykey, dk_rcu); + DyPrSym(key); -+ kfree(key); ++ kfree(key); /* not delayed */ +} + +static void dy_free(struct kref *kref) +{ + struct au_dykey *key; -+ struct au_splhead *spl; ++ struct au_sphlhead *sphl; + + key = container_of(kref, struct au_dykey, dk_kref); -+ spl = dynop + key->dk_op.dy_type; -+ au_spl_del_rcu(&key->dk_list, spl); ++ sphl = dynop + key->dk_op.dy_type; ++ au_sphl_del_rcu(&key->dk_hnode, sphl); + call_rcu(&key->dk_rcu, dy_free_rcu); +} + @@ -9680,6 +9831,8 @@ index 0000000..dfb3a71 + /* this one will be changed according to an aufs mount option */ + DySetAop(direct_IO); + DySetAop(migratepage); ++ DySetAop(isolate_page); ++ DySetAop(putback_page); + DySetAop(launder_page); + DySetAop(is_partially_uptodate); + DySetAop(is_dirty_writeback); @@ -9700,7 +9853,7 @@ index 0000000..dfb3a71 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) +{ + struct au_dykey *key, *old; -+ struct au_splhead *spl; ++ struct au_sphlhead *sphl; + struct op { + unsigned int sz; + void (*set)(struct au_dykey *key, const void *h_op, @@ -9714,8 +9867,8 @@ index 0000000..dfb3a71 + }; + const struct op *p; + -+ spl = dynop + op->dy_type; -+ key = dy_gfind_get(spl, op->dy_hop); ++ sphl = dynop + op->dy_type; ++ key = dy_gfind_get(sphl, op->dy_hop); + if (key) + goto out_add; /* success */ + @@ -9729,9 +9882,9 @@ index 0000000..dfb3a71 + key->dk_op.dy_hop = op->dy_hop; + kref_init(&key->dk_kref); + p->set(key, op->dy_hop, au_br_sb(br)); -+ old = dy_gadd(spl, key); ++ old = dy_gadd(sphl, key); + if (old) { -+ kfree(key); ++ au_delayed_kfree(key); + key = old; + } + @@ -9826,16 +9979,16 @@ index 0000000..dfb3a71 + +void au_dy_arefresh(int do_dx) +{ -+ struct au_splhead *spl; -+ struct list_head *head; ++ struct au_sphlhead *sphl; ++ struct hlist_head *head; + struct au_dykey *key; + -+ spl = dynop + AuDy_AOP; -+ head = &spl->head; -+ spin_lock(&spl->spin); -+ list_for_each_entry(key, head, dk_list) ++ sphl = dynop + AuDy_AOP; ++ head = &sphl->head; ++ spin_lock(&sphl->spin); ++ hlist_for_each_entry(key, head, dk_hnode) + dy_adx((void *)key, do_dx); -+ spin_unlock(&spl->spin); ++ spin_unlock(&sphl->spin); +} + +/* ---------------------------------------------------------------------- */ @@ -9848,7 +10001,7 @@ index 0000000..dfb3a71 + BUILD_BUG_ON(offsetof(struct au_dyaop, da_key)); + + for (i = 0; i < AuDyLast; i++) -+ au_spl_init(dynop + i); ++ au_sphl_init(dynop + i); +} + +void au_dy_fin(void) @@ -9856,11 +10009,11 @@ index 0000000..dfb3a71 + int i; + + for (i = 0; i < AuDyLast; i++) -+ WARN_ON(!list_empty(&dynop[i].head)); ++ WARN_ON(!hlist_empty(&dynop[i].head)); +} diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h new file mode 100644 -index 0000000..8680bfc +index 0000000..5db2da2 --- /dev/null +++ b/fs/aufs/dynop.h @@ -0,0 +1,61 @@ @@ -9892,7 +10045,7 @@ index 0000000..8680bfc + +struct au_dykey { + union { -+ struct list_head dk_list; ++ struct hlist_node dk_hnode; + struct rcu_head dk_rcu; + }; + struct au_dynop dk_op; @@ -9927,7 +10080,7 @@ index 0000000..8680bfc +#endif /* __AUFS_DYNOP_H__ */ diff --git a/fs/aufs/export.c b/fs/aufs/export.c new file mode 100644 -index 0000000..98a7036 +index 0000000..6b5a7be --- /dev/null +++ b/fs/aufs/export.c @@ -0,0 +1,824 @@ @@ -10337,7 +10490,7 @@ index 0000000..98a7036 + } + +out_name: -+ free_page((unsigned long)arg.name); ++ au_delayed_free_page((unsigned long)arg.name); +out_file: + fput(file); +out: @@ -10491,7 +10644,7 @@ index 0000000..98a7036 + dentry = ERR_PTR(-ESTALE); + } +out_pathname: -+ free_page((unsigned long)pathname); ++ au_delayed_free_page((unsigned long)pathname); +out_h_parent: + dput(h_parent); +out: @@ -10757,10 +10910,10 @@ index 0000000..98a7036 +} diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c new file mode 100644 -index 0000000..504b767 +index 0000000..00475fb --- /dev/null +++ b/fs/aufs/f_op.c -@@ -0,0 +1,757 @@ +@@ -0,0 +1,759 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -10849,6 +11002,7 @@ index 0000000..504b767 +{ + struct au_finfo *finfo; + aufs_bindex_t bindex; ++ int delayed; + + finfo = au_fi(file); + au_sphl_del(&finfo->fi_hlist, @@ -10857,7 +11011,8 @@ index 0000000..504b767 + if (bindex >= 0) + au_set_h_fptr(file, bindex, NULL); + -+ au_finfo_fin(file); ++ delayed = (current->flags & PF_KTHREAD) || in_interrupt(); ++ au_finfo_fin(file, delayed); + return 0; +} + @@ -11938,10 +12093,10 @@ index 0000000..e3cb6ed +} diff --git a/fs/aufs/file.c b/fs/aufs/file.c new file mode 100644 -index 0000000..4b68aef +index 0000000..bfc1d1b --- /dev/null +++ b/fs/aufs/file.c -@@ -0,0 +1,830 @@ +@@ -0,0 +1,844 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -12204,7 +12359,7 @@ index 0000000..4b68aef + } + if (unlikely(err)) { + finfo->fi_hdir = NULL; -+ au_finfo_fin(file); ++ au_finfo_fin(file, /*atonce*/0); + } + +out: @@ -12524,6 +12679,7 @@ index 0000000..4b68aef + +static void au_do_refresh_dir(struct file *file) +{ ++ int execed; + aufs_bindex_t bindex, bbot, new_bindex, brid; + struct au_hfile *p, tmp, *q; + struct au_finfo *finfo; @@ -12562,6 +12718,7 @@ index 0000000..4b68aef + } + } + ++ execed = vfsub_file_execed(file); + p = fidir->fd_hfile; + if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { + bbot = au_sbbot(sb); @@ -12570,14 +12727,14 @@ index 0000000..4b68aef + if (p->hf_file) { + if (file_inode(p->hf_file)) + break; -+ au_hfput(p, file); ++ au_hfput(p, execed); + } + } else { + bbot = au_br_index(sb, brid); + for (finfo->fi_btop = 0; finfo->fi_btop < bbot; + finfo->fi_btop++, p++) + if (p->hf_file) -+ au_hfput(p, file); ++ au_hfput(p, execed); + bbot = au_sbbot(sb); + } + @@ -12587,7 +12744,7 @@ index 0000000..4b68aef + if (p->hf_file) { + if (file_inode(p->hf_file)) + break; -+ au_hfput(p, file); ++ au_hfput(p, execed); + } + AuDebugOn(fidir->fd_bbot < finfo->fi_btop); +} @@ -12597,23 +12754,26 @@ index 0000000..4b68aef + */ +static int refresh_file(struct file *file, int (*reopen)(struct file *file)) +{ -+ int err, need_reopen; ++ int err, need_reopen, nbr; + aufs_bindex_t bbot, bindex; + struct dentry *dentry; ++ struct super_block *sb; + struct au_finfo *finfo; + struct au_hfile *hfile; + + dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ nbr = au_sbbot(sb) + 1; + finfo = au_fi(file); + if (!finfo->fi_hdir) { + hfile = &finfo->fi_htop; + AuDebugOn(!hfile->hf_file); -+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id); ++ bindex = au_br_index(sb, hfile->hf_br->br_id); + AuDebugOn(bindex < 0); + if (bindex != finfo->fi_btop) + au_set_fbtop(file, bindex); + } else { -+ err = au_fidir_realloc(finfo, au_sbbot(dentry->d_sb) + 1); ++ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + au_do_refresh_dir(file); @@ -12623,6 +12783,9 @@ index 0000000..4b68aef + need_reopen = 1; + if (!au_test_mmapped(file)) + err = au_file_refresh_by_inode(file, &need_reopen); ++ if (finfo->fi_hdir) ++ /* harmless if err */ ++ au_fidir_realloc(finfo, nbr, /*may_shrink*/1); + if (!err && need_reopen && !d_unlinked(dentry)) + err = reopen(file); + if (!err) { @@ -12730,6 +12893,10 @@ index 0000000..4b68aef + struct page *page, enum migrate_mode mode) +{ AuUnsupport(); return 0; } +#endif ++static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) ++{ AuUnsupport(); return true; } ++static void aufs_putback_page(struct page *page) ++{ AuUnsupport(); } +static int aufs_launder_page(struct page *page) +{ AuUnsupport(); return 0; } +static int aufs_is_partially_uptodate(struct page *page, @@ -12764,6 +12931,8 @@ index 0000000..4b68aef + .releasepage = aufs_releasepage, + /* is fallback_migrate_page ok? */ + /* .migratepage = aufs_migratepage, */ ++ .isolate_page = aufs_isolate_page, ++ .putback_page = aufs_putback_page, + .launder_page = aufs_launder_page, + .is_partially_uptodate = aufs_is_partially_uptodate, + .is_dirty_writeback = aufs_is_dirty_writeback, @@ -12774,10 +12943,10 @@ index 0000000..4b68aef +}; diff --git a/fs/aufs/file.h b/fs/aufs/file.h new file mode 100644 -index 0000000..96ab0a0 +index 0000000..f53b381 --- /dev/null +++ b/fs/aufs/file.h -@@ -0,0 +1,278 @@ +@@ -0,0 +1,281 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -12830,7 +12999,10 @@ index 0000000..96ab0a0 + struct au_fidir *fi_hdir; /* for dir only */ + + struct hlist_node fi_hlist; -+ struct file *fi_file; /* very ugly */ ++ union { ++ struct file *fi_file; /* very ugly */ ++ struct llist_node fi_lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -12881,16 +13053,16 @@ index 0000000..96ab0a0 +struct file *au_read_pre(struct file *file, int keep_fi); + +/* finfo.c */ -+void au_hfput(struct au_hfile *hf, struct file *file); ++void au_hfput(struct au_hfile *hf, int execed); +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, + struct file *h_file); + +void au_update_figen(struct file *file); +struct au_fidir *au_fidir_alloc(struct super_block *sb); -+int au_fidir_realloc(struct au_finfo *finfo, int nbr); ++int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink); + +void au_fi_init_once(void *_fi); -+void au_finfo_fin(struct file *file); ++void au_finfo_fin(struct file *file, int atonce); +int au_finfo_init(struct file *file, struct au_fidir *fidir); + +/* ioctl.c */ @@ -13058,10 +13230,10 @@ index 0000000..96ab0a0 +#endif /* __AUFS_FILE_H__ */ diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c new file mode 100644 -index 0000000..07f6eb3 +index 0000000..0f016ed --- /dev/null +++ b/fs/aufs/finfo.c -@@ -0,0 +1,136 @@ +@@ -0,0 +1,138 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -13072,10 +13244,9 @@ index 0000000..07f6eb3 + +#include "aufs.h" + -+void au_hfput(struct au_hfile *hf, struct file *file) ++void au_hfput(struct au_hfile *hf, int execed) +{ -+ /* todo: direct access f_flags */ -+ if (vfsub_file_flags(file) & __FMODE_EXEC) ++ if (execed) + allow_write_access(hf->hf_file); + fput(hf->hf_file); + hf->hf_file = NULL; @@ -13097,7 +13268,7 @@ index 0000000..07f6eb3 + hf = fidir->fd_hfile + bindex; + + if (hf && hf->hf_file) -+ au_hfput(hf, file); ++ au_hfput(hf, vfsub_file_execed(file)); + if (val) { + FiMustWriteLock(file); + AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry)); @@ -13131,7 +13302,7 @@ index 0000000..07f6eb3 + return fidir; +} + -+int au_fidir_realloc(struct au_finfo *finfo, int nbr) ++int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink) +{ + int err; + struct au_fidir *fidir, *p; @@ -13142,7 +13313,7 @@ index 0000000..07f6eb3 + + err = -ENOMEM; + p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), -+ GFP_NOFS); ++ GFP_NOFS, may_shrink); + if (p) { + p->fd_nent = nbr; + finfo->fi_hdir = p; @@ -13154,7 +13325,7 @@ index 0000000..07f6eb3 + +/* ---------------------------------------------------------------------- */ + -+void au_finfo_fin(struct file *file) ++void au_finfo_fin(struct file *file, int atonce) +{ + struct au_finfo *finfo; + @@ -13163,7 +13334,10 @@ index 0000000..07f6eb3 + finfo = au_fi(file); + AuDebugOn(finfo->fi_hdir); + AuRwDestroy(&finfo->fi_rwsem); -+ au_cache_free_finfo(finfo); ++ if (!atonce) ++ au_cache_dfree_finfo(finfo); ++ else ++ au_cache_free_finfo(finfo); +} + +void au_fi_init_once(void *_finfo) @@ -13200,7 +13374,7 @@ index 0000000..07f6eb3 +} diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h new file mode 100644 -index 0000000..725b2ff +index 0000000..95b78b9 --- /dev/null +++ b/fs/aufs/fstype.h @@ -0,0 +1,387 @@ @@ -13234,7 +13408,7 @@ index 0000000..725b2ff + +static inline int au_test_iso9660(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++#if IS_ENABLED(CONFIG_ISO9660_FS) + return sb->s_magic == ISOFS_SUPER_MAGIC; +#else + return 0; @@ -13243,7 +13417,7 @@ index 0000000..725b2ff + +static inline int au_test_romfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_ROMFS_FS) + return sb->s_magic == ROMFS_MAGIC; +#else + return 0; @@ -13252,7 +13426,7 @@ index 0000000..725b2ff + +static inline int au_test_cramfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++#if IS_ENABLED(CONFIG_CRAMFS) + return sb->s_magic == CRAMFS_MAGIC; +#endif + return 0; @@ -13260,7 +13434,7 @@ index 0000000..725b2ff + +static inline int au_test_nfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_NFS_FS) + return sb->s_magic == NFS_SUPER_MAGIC; +#else + return 0; @@ -13269,7 +13443,7 @@ index 0000000..725b2ff + +static inline int au_test_fuse(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++#if IS_ENABLED(CONFIG_FUSE_FS) + return sb->s_magic == FUSE_SUPER_MAGIC; +#else + return 0; @@ -13278,7 +13452,7 @@ index 0000000..725b2ff + +static inline int au_test_xfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_XFS_FS) + return sb->s_magic == XFS_SB_MAGIC; +#else + return 0; @@ -13296,7 +13470,7 @@ index 0000000..725b2ff + +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++#if IS_ENABLED(CONFIG_ECRYPT_FS) + return !strcmp(au_sbtype(sb), "ecryptfs"); +#else + return 0; @@ -13310,7 +13484,7 @@ index 0000000..725b2ff + +static inline int au_test_ubifs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_UBIFS_FS) + return sb->s_magic == UBIFS_SUPER_MAGIC; +#else + return 0; @@ -13337,7 +13511,7 @@ index 0000000..725b2ff + +static inline int au_test_configfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_CONFIGFS_FS) + return sb->s_magic == CONFIGFS_MAGIC; +#else + return 0; @@ -13346,7 +13520,7 @@ index 0000000..725b2ff + +static inline int au_test_minix(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++#if IS_ENABLED(CONFIG_MINIX_FS) + return sb->s_magic == MINIX3_SUPER_MAGIC + || sb->s_magic == MINIX2_SUPER_MAGIC + || sb->s_magic == MINIX2_SUPER_MAGIC2 @@ -13359,7 +13533,7 @@ index 0000000..725b2ff + +static inline int au_test_fat(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++#if IS_ENABLED(CONFIG_FAT_FS) + return sb->s_magic == MSDOS_SUPER_MAGIC; +#else + return 0; @@ -13387,7 +13561,7 @@ index 0000000..725b2ff + +static inline int au_test_squashfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++#if IS_ENABLED(CONFIG_SQUASHFS) + return sb->s_magic == SQUASHFS_MAGIC; +#else + return 0; @@ -13396,7 +13570,7 @@ index 0000000..725b2ff + +static inline int au_test_btrfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++#if IS_ENABLED(CONFIG_BTRFS_FS) + return sb->s_magic == BTRFS_SUPER_MAGIC; +#else + return 0; @@ -13405,7 +13579,7 @@ index 0000000..725b2ff + +static inline int au_test_xenfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++#if IS_ENABLED(CONFIG_XENFS) + return sb->s_magic == XENFS_SUPER_MAGIC; +#else + return 0; @@ -13423,7 +13597,7 @@ index 0000000..725b2ff + +static inline int au_test_nilfs(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE) ++#if IS_ENABLED(CONFIG_NILFS) + return sb->s_magic == NILFS_SUPER_MAGIC; +#else + return 0; @@ -13432,7 +13606,7 @@ index 0000000..725b2ff + +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE) ++#if IS_ENABLED(CONFIG_HFSPLUS_FS) + return sb->s_magic == HFSPLUS_SUPER_MAGIC; +#else + return 0; @@ -13593,7 +13767,7 @@ index 0000000..725b2ff +#endif /* __AUFS_FSTYPE_H__ */ diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c new file mode 100644 -index 0000000..6afef3f +index 0000000..110f8f5 --- /dev/null +++ b/fs/aufs/hfsnotify.c @@ -0,0 +1,274 @@ @@ -13618,7 +13792,7 @@ index 0000000..6afef3f + struct au_hnotify *hn = container_of(mark, struct au_hnotify, + hn_mark); + /* AuDbg("here\n"); */ -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + smp_mb__before_atomic(); + if (atomic64_dec_and_test(&au_hfsn_ifree)) + wake_up(&au_hfsn_wq); @@ -13742,7 +13916,7 @@ index 0000000..6afef3f + struct au_br_hfsnotify *hfsn = group->private; + + /* AuDbg("here\n"); */ -+ kfree(hfsn); ++ au_delayed_kfree(hfsn); +} + +static int au_hfsn_handle_event(struct fsnotify_group *group, @@ -13836,7 +14010,7 @@ index 0000000..6afef3f + goto out; /* success */ + +out_hfsn: -+ kfree(hfsn); ++ au_delayed_kfree(hfsn); +out: + return err; +} @@ -13922,10 +14096,10 @@ index 0000000..145c6ac +} diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c new file mode 100644 -index 0000000..3016c5e +index 0000000..a05aed8 --- /dev/null +++ b/fs/aufs/hnotify.c -@@ -0,0 +1,697 @@ +@@ -0,0 +1,710 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -13950,7 +14124,7 @@ index 0000000..3016c5e + AuTraceErr(err); + if (unlikely(err)) { + hinode->hi_notify = NULL; -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + /* + * The upper dir was removed by udba, but the same named + * dir left. In this case, aufs assignes a new inode @@ -13974,7 +14148,7 @@ index 0000000..3016c5e + if (hn) { + hinode->hi_notify = NULL; + if (au_hnotify_op.free(hinode, hn)) -+ au_cache_free_hnotify(hn); ++ au_cache_dfree_hnotify(hn); + } +} + @@ -14408,7 +14582,7 @@ index 0000000..3016c5e + || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { + inode = lookup_wlock_by_ino(sb, bfound, h_ino); + try_iput = 1; -+ } ++ } + + args.flags = a->flags[AuHn_CHILD]; + args.dentry = dentry; @@ -14447,7 +14621,7 @@ index 0000000..3016c5e + iput(a->dir); + si_write_unlock(sb); + au_nwt_done(&sbinfo->si_nowait); -+ kfree(a); ++ au_delayed_kfree(a); +} + +/* ---------------------------------------------------------------------- */ @@ -14553,7 +14727,7 @@ index 0000000..3016c5e + iput(args->h_child_inode); + iput(args->h_dir); + iput(args->dir); -+ kfree(args); ++ au_delayed_kfree(args); + } + +out: @@ -14594,17 +14768,26 @@ index 0000000..3016c5e + +static void au_hn_destroy_cache(void) +{ -+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]); -+ au_cachep[AuCache_HNOTIFY] = NULL; ++ struct au_cache *cp; ++ ++ flush_delayed_work(&au_dfree.dwork); ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ AuDebugOn(!llist_empty(&cp->llist)); ++ kmem_cache_destroy(cp->cache); ++ cp->cache = NULL; +} + ++AU_CACHE_DFREE_FUNC(hnotify, HNOTIFY, hn_lnode); ++ +int __init au_hnotify_init(void) +{ + int err; ++ struct au_cache *cp; + + err = -ENOMEM; -+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify); -+ if (au_cachep[AuCache_HNOTIFY]) { ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ cp->cache = AuCache(au_hnotify); ++ if (cp->cache) { + err = 0; + if (au_hnotify_op.init) + err = au_hnotify_op.init(); @@ -14617,18 +14800,22 @@ index 0000000..3016c5e + +void au_hnotify_fin(void) +{ ++ struct au_cache *cp; ++ + if (au_hnotify_op.fin) + au_hnotify_op.fin(); ++ + /* cf. au_cache_fin() */ -+ if (au_cachep[AuCache_HNOTIFY]) ++ cp = au_dfree.cache + AuCache_HNOTIFY; ++ if (cp->cache) + au_hn_destroy_cache(); +} diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c new file mode 100644 -index 0000000..cc1e312 +index 0000000..c730ec7 --- /dev/null +++ b/fs/aufs/i_op.c -@@ -0,0 +1,1401 @@ +@@ -0,0 +1,1438 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -14644,17 +14831,20 @@ index 0000000..cc1e312 +#include "aufs.h" + +static int h_permission(struct inode *h_inode, int mask, -+ struct vfsmount *h_mnt, int brperm) ++ struct path *h_path, int brperm) +{ + int err; + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); + ++ err = -EPERM; ++ if (write_mask && IS_IMMUTABLE(h_inode)) ++ goto out; ++ + err = -EACCES; -+ if ((write_mask && IS_IMMUTABLE(h_inode)) -+ || ((mask & MAY_EXEC) -+ && S_ISREG(h_inode->i_mode) -+ && ((h_mnt->mnt_flags & MNT_NOEXEC) -+ || !(h_inode->i_mode & S_IXUGO)))) ++ if (((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && (path_noexec(h_path) ++ || !(h_inode->i_mode & S_IXUGO)))) + goto out; + + /* @@ -14738,7 +14928,7 @@ index 0000000..cc1e312 + err = 0; + bindex = au_ibtop(inode); + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm); ++ err = h_permission(h_inode, mask, &br->br_path, br->br_perm); + if (write_mask + && !err + && !special_file(h_inode->i_mode)) { @@ -14764,7 +14954,7 @@ index 0000000..cc1e312 + break; + + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, au_br_mnt(br), ++ err = h_permission(h_inode, mask, &br->br_path, + br->br_perm); + } + } @@ -14899,8 +15089,7 @@ index 0000000..cc1e312 +{ + int err, h_opened = *opened; + unsigned int lkup_flags; -+ struct dentry *parent; -+ struct dentry *d; ++ struct dentry *parent, *d; + struct au_sphlhead *aopen; + struct vfsub_aopen_args args = { + .open_flag = open_flag, @@ -14995,10 +15184,10 @@ index 0000000..cc1e312 + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuDbgDentry(dentry); -+ if (unlikely(err)) ++ if (unlikely(err < 0)) + goto out; +out_no_open: -+ if (!err && !(*opened & FILE_CREATED)) { ++ if (err >= 0 && !(*opened & FILE_CREATED)) { + AuLabel(out_no_open); + dget(dentry); + err = finish_no_open(file, dentry); @@ -15612,7 +15801,7 @@ index 0000000..cc1e312 +out_si: + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -15705,7 +15894,7 @@ index 0000000..cc1e312 + di_write_unlock(dentry); + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -15925,20 +16114,55 @@ index 0000000..cc1e312 + +/* ---------------------------------------------------------------------- */ + ++static int au_is_special(struct inode *inode) ++{ ++ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK)); ++} ++ +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags) +{ + int err; ++ aufs_bindex_t bindex; + struct super_block *sb; + struct inode *h_inode; ++ struct vfsmount *h_mnt; + + sb = inode->i_sb; ++ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode), ++ "unexpected s_flags 0x%lx", sb->s_flags); ++ + /* mmap_sem might be acquired already, cf. aufs_mmap() */ + lockdep_off(); + si_read_lock(sb, AuLock_FLUSH); + ii_write_lock_child(inode); + lockdep_on(); -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ err = vfsub_update_time(h_inode, ts, flags); ++ ++ err = 0; ++ bindex = au_ibtop(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!au_test_ro(sb, bindex, inode)) { ++ h_mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mnt_want_write(h_mnt); ++ if (!err) { ++ err = vfsub_update_time(h_inode, ts, flags); ++ vfsub_mnt_drop_write(h_mnt); ++ } ++ } else if (au_is_special(h_inode)) { ++ /* ++ * Never copy-up here. ++ * These special files may already be opened and used for ++ * communicating. If we copied it up, then the communication ++ * would be corrupted. ++ */ ++ AuWarn1("timestamps for i%lu are ignored " ++ "since it is on readonly branch (hi%lu).\n", ++ inode->i_ino, h_inode->i_ino); ++ } else if (flags & ~S_ATIME) { ++ err = -EIO; ++ AuIOErr1("unexpected flags 0x%x\n", flags); ++ AuDebugOn(1); ++ } ++ + lockdep_off(); + if (!err) + au_cpup_attr_timesizes(inode); @@ -16032,7 +16256,7 @@ index 0000000..cc1e312 +}; diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c new file mode 100644 -index 0000000..8e3fb61 +index 0000000..2a9aa09 --- /dev/null +++ b/fs/aufs/i_op_add.c @@ -0,0 +1,911 @@ @@ -16370,7 +16594,7 @@ index 0000000..8e3fb61 + if (!try_aopen) + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -16834,7 +17058,7 @@ index 0000000..8e3fb61 + } + aufs_read_and_write_unlock2(dentry, src_dentry); +out_kfree: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; @@ -16943,13 +17167,13 @@ index 0000000..8e3fb61 + } + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c new file mode 100644 -index 0000000..35b923c +index 0000000..2fe8f07 --- /dev/null +++ b/fs/aufs/i_op_del.c @@ -0,0 +1,498 @@ @@ -17336,7 +17560,7 @@ index 0000000..35b923c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + return err; +} @@ -17446,14 +17670,14 @@ index 0000000..35b923c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c new file mode 100644 -index 0000000..df697de +index 0000000..43a0909 --- /dev/null +++ b/fs/aufs/i_op_ren.c @@ -0,0 +1,1002 @@ @@ -18454,17 +18678,17 @@ index 0000000..df697de + iput(a->dst_inode); + if (a->thargs) + au_whtmp_rmdir_free(a->thargs); -+ kfree(a); ++ au_delayed_kfree(a); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c new file mode 100644 -index 0000000..fae4c27 +index 0000000..975cff3 --- /dev/null +++ b/fs/aufs/iinfo.c -@@ -0,0 +1,271 @@ +@@ -0,0 +1,272 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -18672,7 +18896,7 @@ index 0000000..fae4c27 + return -ENOMEM; +} + -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr) ++int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) +{ + int err, i; + struct au_hinode *hip; @@ -18680,7 +18904,8 @@ index 0000000..fae4c27 + AuRwMustWriteLock(&iinfo->ii_rwsem); + + err = -ENOMEM; -+ hip = krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS); ++ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, ++ may_shrink); + if (hip) { + iinfo->ii_hinode = hip; + i = iinfo->ii_bbot + 1; @@ -18721,7 +18946,7 @@ index 0000000..fae4c27 + + iinfo = au_ii(inode); + if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); ++ au_vdir_free(iinfo->ii_vdir, /*atonce*/0); + + bindex = iinfo->ii_btop; + if (bindex >= 0) { @@ -18733,15 +18958,15 @@ index 0000000..fae4c27 + hi++; + } + } -+ kfree(iinfo->ii_hinode); ++ au_delayed_kfree(iinfo->ii_hinode); + AuRwDestroy(&iinfo->ii_rwsem); +} diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c new file mode 100644 -index 0000000..a4b994e +index 0000000..8f7446d --- /dev/null +++ b/fs/aufs/inode.c -@@ -0,0 +1,504 @@ +@@ -0,0 +1,506 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -18771,7 +18996,7 @@ index 0000000..a4b994e + +static int au_ii_refresh(struct inode *inode, int *update) +{ -+ int err, e; ++ int err, e, nbr; + umode_t type; + aufs_bindex_t bindex, new_bindex; + struct super_block *sb; @@ -18783,9 +19008,10 @@ index 0000000..a4b994e + + *update = 0; + sb = inode->i_sb; ++ nbr = au_sbbot(sb) + 1; + type = inode->i_mode & S_IFMT; + iinfo = au_ii(inode); -+ err = au_hinode_realloc(iinfo, au_sbbot(sb) + 1); ++ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0); + if (unlikely(err)) + goto out; + @@ -18823,6 +19049,7 @@ index 0000000..a4b994e + } + } + au_update_ibrange(inode, /*do_put_zero*/0); ++ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */ + e = au_dy_irefresh(inode); + if (unlikely(e && !err)) + err = e; @@ -19248,10 +19475,10 @@ index 0000000..a4b994e +} diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h new file mode 100644 -index 0000000..3fc5a58 +index 0000000..33d9f5e --- /dev/null +++ b/fs/aufs/inode.h -@@ -0,0 +1,681 @@ +@@ -0,0 +1,687 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -19276,7 +19503,10 @@ index 0000000..3fc5a58 + /* never use fsnotify_add_vfsmount_mark() */ + struct fsnotify_mark hn_mark; +#endif -+ struct inode *hn_aufs_inode; /* no get/put */ ++ union { ++ struct inode *hn_aufs_inode; /* no get/put */ ++ struct llist_node hn_lnode; /* delayed free */ ++ }; +#endif +} ____cacheline_aligned_in_smp; + @@ -19319,7 +19549,10 @@ index 0000000..3fc5a58 +struct au_icntnr { + struct au_iinfo iinfo; + struct inode vfs_inode; -+ struct hlist_node plink; ++ union { ++ struct hlist_node plink; ++ struct llist_node lnode; /* delayed free */ ++ }; +} ____cacheline_aligned_in_smp; + +/* au_pin flags */ @@ -19506,7 +19739,7 @@ index 0000000..3fc5a58 +void au_hinode_init(struct au_hinode *hinode); +int au_iinfo_init(struct inode *inode); +void au_iinfo_fin(struct inode *inode); -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr); ++int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink); + +#ifdef CONFIG_PROC_FS +/* plink.c */ @@ -20147,10 +20380,10 @@ index 0000000..2ebfdc4 +#endif diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c new file mode 100644 -index 0000000..5711e7a +index 0000000..c3ca50f --- /dev/null +++ b/fs/aufs/loop.c -@@ -0,0 +1,133 @@ +@@ -0,0 +1,134 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20244,7 +20477,8 @@ index 0000000..5711e7a + new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; + a = au_kzrealloc(au_warn_loopback_array, + au_warn_loopback_nelem * sizeof(unsigned long), -+ new_nelem * sizeof(unsigned long), GFP_ATOMIC); ++ new_nelem * sizeof(unsigned long), GFP_ATOMIC, ++ /*may_shrink*/0); + if (a) { + au_warn_loopback_nelem = new_nelem; + au_warn_loopback_array = a; @@ -20282,7 +20516,7 @@ index 0000000..5711e7a +{ + if (backing_file_func) + symbol_put(loop_backing_file); -+ kfree(au_warn_loopback_array); ++ au_delayed_kfree(au_warn_loopback_array); +} diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h new file mode 100644 @@ -20367,10 +20601,10 @@ index 0000000..4f83bdf +endif diff --git a/fs/aufs/module.c b/fs/aufs/module.c new file mode 100644 -index 0000000..88f8f41 +index 0000000..5092b4b --- /dev/null +++ b/fs/aufs/module.c -@@ -0,0 +1,209 @@ +@@ -0,0 +1,319 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20383,29 +20617,120 @@ index 0000000..88f8f41 +#include +#include "aufs.h" + -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++/* shrinkable realloc */ ++void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) +{ -+ if (new_sz <= nused) -+ return p; ++ size_t sz; ++ int diff; + -+ p = krealloc(p, new_sz, gfp); -+ if (p) ++ sz = 0; ++ diff = -1; ++ if (p) { ++#if 0 /* unused */ ++ if (!new_sz) { ++ au_delayed_kfree(p); ++ p = NULL; ++ goto out; ++ } ++#else ++ AuDebugOn(!new_sz); ++#endif ++ sz = ksize(p); ++ diff = au_kmidx_sub(sz, new_sz); ++ } ++ if (sz && !diff) ++ goto out; ++ ++ if (sz < new_sz) ++ /* expand or SLOB */ ++ p = krealloc(p, new_sz, gfp); ++ else if (new_sz < sz && may_shrink) { ++ /* shrink */ ++ void *q; ++ ++ q = kmalloc(new_sz, gfp); ++ if (q) { ++ if (p) { ++ memcpy(q, p, new_sz); ++ au_delayed_kfree(p); ++ } ++ p = q; ++ } else ++ p = NULL; ++ } ++ ++out: ++ return p; ++} ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, ++ int may_shrink) ++{ ++ p = au_krealloc(p, new_sz, gfp, may_shrink); ++ if (p && new_sz > nused) + memset(p + nused, 0, new_sz - nused); + return p; +} + +/* ---------------------------------------------------------------------- */ -+ +/* + * aufs caches + */ -+struct kmem_cache *au_cachep[AuCache_Last] = { -+ [0] = NULL -+}; ++ ++struct au_dfree au_dfree; ++ ++/* delayed free */ ++static void au_do_dfree(struct work_struct *work __maybe_unused) ++{ ++ struct llist_head *head; ++ struct llist_node *node, *next; ++ ++#define AU_CACHE_DFREE_DO_BODY(name, idx, lnode) do { \ ++ head = &au_dfree.cache[AuCache_##idx].llist; \ ++ node = llist_del_all(head); \ ++ for (; node; node = next) { \ ++ struct au_##name *p \ ++ = llist_entry(node, struct au_##name, \ ++ lnode); \ ++ next = llist_next(node); \ ++ au_cache_free_##name(p); \ ++ } \ ++ } while (0) ++ ++ AU_CACHE_DFREE_DO_BODY(dinfo, DINFO, di_lnode); ++ AU_CACHE_DFREE_DO_BODY(icntnr, ICNTNR, lnode); ++ AU_CACHE_DFREE_DO_BODY(finfo, FINFO, fi_lnode); ++ AU_CACHE_DFREE_DO_BODY(vdir, VDIR, vd_lnode); ++ AU_CACHE_DFREE_DO_BODY(vdir_dehstr, DEHSTR, lnode); ++#ifdef CONFIG_AUFS_HNOTIFY ++ AU_CACHE_DFREE_DO_BODY(hnotify, HNOTIFY, hn_lnode); ++#endif ++ ++#define AU_DFREE_DO_BODY(llist, func) do { \ ++ node = llist_del_all(llist); \ ++ for (; node; node = next) { \ ++ next = llist_next(node); \ ++ func(node); \ ++ } \ ++ } while (0) ++ ++ AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_KFREE, kfree); ++ AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_FREE_PAGE, au_free_page); ++ ++#undef AU_CACHE_DFREE_DO_BODY ++#undef AU_DFREE_DO_BODY ++} ++ ++AU_CACHE_DFREE_FUNC(dinfo, DINFO, di_lnode); ++AU_CACHE_DFREE_FUNC(icntnr, ICNTNR, lnode); ++AU_CACHE_DFREE_FUNC(finfo, FINFO, fi_lnode); ++AU_CACHE_DFREE_FUNC(vdir, VDIR, vd_lnode); ++AU_CACHE_DFREE_FUNC(vdir_dehstr, DEHSTR, lnode); + +static void au_cache_fin(void) +{ + int i; ++ struct au_cache *cp; + + /* + * Make sure all delayed rcu free inodes are flushed before we @@ -20415,27 +20740,33 @@ index 0000000..88f8f41 + + /* excluding AuCache_HNOTIFY */ + BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); ++ flush_delayed_work(&au_dfree.dwork); + for (i = 0; i < AuCache_HNOTIFY; i++) { -+ kmem_cache_destroy(au_cachep[i]); -+ au_cachep[i] = NULL; ++ cp = au_dfree.cache + i; ++ AuDebugOn(!llist_empty(&cp->llist)); ++ kmem_cache_destroy(cp->cache); ++ cp->cache = NULL; + } +} + +static int __init au_cache_init(void) +{ -+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); -+ if (au_cachep[AuCache_DINFO]) ++ struct au_cache *cp; ++ ++ cp = au_dfree.cache; ++ cp[AuCache_DINFO].cache = AuCacheCtor(au_dinfo, au_di_init_once); ++ if (cp[AuCache_DINFO].cache) + /* SLAB_DESTROY_BY_RCU */ -+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, -+ au_icntnr_init_once); -+ if (au_cachep[AuCache_ICNTNR]) -+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo, -+ au_fi_init_once); -+ if (au_cachep[AuCache_FINFO]) -+ au_cachep[AuCache_VDIR] = AuCache(au_vdir); -+ if (au_cachep[AuCache_VDIR]) -+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); -+ if (au_cachep[AuCache_DEHSTR]) ++ cp[AuCache_ICNTNR].cache = AuCacheCtor(au_icntnr, ++ au_icntnr_init_once); ++ if (cp[AuCache_ICNTNR].cache) ++ cp[AuCache_FINFO].cache = AuCacheCtor(au_finfo, ++ au_fi_init_once); ++ if (cp[AuCache_FINFO].cache) ++ cp[AuCache_VDIR].cache = AuCache(au_vdir); ++ if (cp[AuCache_VDIR].cache) ++ cp[AuCache_DEHSTR].cache = AuCache(au_vdir_dehstr); ++ if (cp[AuCache_DEHSTR].cache) + return 0; + + au_cache_fin(); @@ -20497,6 +20828,7 @@ index 0000000..88f8f41 +{ + int err, i; + char *p; ++ struct au_cache *cp; + + p = au_esc_chars; + for (i = 1; i <= ' '; i++) @@ -20511,6 +20843,16 @@ index 0000000..88f8f41 + for (i = 0; i < AuIop_Last; i++) + aufs_iop_nogetattr[i].getattr = NULL; + ++ /* First, initialize au_dfree */ ++ for (i = 0; i < AuCache_Last; i++) { /* including hnotify */ ++ cp = au_dfree.cache + i; ++ cp->cache = NULL; ++ init_llist_head(&cp->llist); ++ } ++ for (i = 0; i < AU_DFREE_Last; i++) ++ init_llist_head(au_dfree.llist + i); ++ INIT_DELAYED_WORK(&au_dfree.dwork, au_do_dfree); ++ + au_sbilist_init(); + sysaufs_brs_init(); + au_debug_init(); @@ -20561,6 +20903,7 @@ index 0000000..88f8f41 +out_sysaufs: + sysaufs_fin(); + au_dy_fin(); ++ flush_delayed_work(&au_dfree.dwork); +out: + return err; +} @@ -20576,16 +20919,17 @@ index 0000000..88f8f41 + au_procfs_fin(); + sysaufs_fin(); + au_dy_fin(); ++ flush_delayed_work(&au_dfree.dwork); +} + +module_init(aufs_init); +module_exit(aufs_exit); diff --git a/fs/aufs/module.h b/fs/aufs/module.h new file mode 100644 -index 0000000..1383e3d +index 0000000..6f968ba --- /dev/null +++ b/fs/aufs/module.h -@@ -0,0 +1,76 @@ +@@ -0,0 +1,143 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -20600,6 +20944,7 @@ index 0000000..1383e3d +#ifdef __KERNEL__ + +#include ++#include "debug.h" + +struct path; +struct seq_file; @@ -20612,7 +20957,19 @@ index 0000000..1383e3d + +extern int au_dir_roflags; + -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink); ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, ++ int may_shrink); ++ ++static inline int au_kmidx_sub(size_t sz, size_t new_sz) ++{ ++#ifndef CONFIG_SLOB ++ return kmalloc_index(sz) - kmalloc_index(new_sz); ++#else ++ return -1; /* SLOB is untested */ ++#endif ++} ++ +int au_seq_path(struct seq_file *seq, struct path *path); + +#ifdef CONFIG_PROC_FS @@ -20626,7 +20983,7 @@ index 0000000..1383e3d + +/* ---------------------------------------------------------------------- */ + -+/* kmem cache */ ++/* kmem cache and delayed free */ +enum { + AuCache_DINFO, + AuCache_ICNTNR, @@ -20637,19 +20994,54 @@ index 0000000..1383e3d + AuCache_Last +}; + ++enum { ++ AU_DFREE_KFREE, ++ AU_DFREE_FREE_PAGE, ++ AU_DFREE_Last ++}; ++ ++struct au_cache { ++ struct kmem_cache *cache; ++ struct llist_head llist; /* delayed free */ ++}; ++ ++/* ++ * in order to reduce the cost of the internal timer, consolidate all the ++ * delayed free works into a single delayed_work. ++ */ ++struct au_dfree { ++ struct au_cache cache[AuCache_Last]; ++ struct llist_head llist[AU_DFREE_Last]; ++ struct delayed_work dwork; ++}; ++ ++extern struct au_dfree au_dfree; ++ +#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) +#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) +#define AuCacheCtor(type, ctor) \ + kmem_cache_create(#type, sizeof(struct type), \ + __alignof__(struct type), AuCacheFlags, ctor) + -+extern struct kmem_cache *au_cachep[]; ++#define AU_DFREE_DELAY msecs_to_jiffies(10) ++#define AU_DFREE_BODY(lnode, llist) do { \ ++ if (llist_add(lnode, llist)) \ ++ schedule_delayed_work(&au_dfree.dwork, \ ++ AU_DFREE_DELAY); \ ++ } while (0) ++#define AU_CACHE_DFREE_FUNC(name, idx, lnode) \ ++ void au_cache_dfree_##name(struct au_##name *p) \ ++ { \ ++ struct au_cache *cp = au_dfree.cache + AuCache_##idx; \ ++ AU_DFREE_BODY(&p->lnode, &cp->llist); \ ++ } + +#define AuCacheFuncs(name, index) \ +static inline struct au_##name *au_cache_alloc_##name(void) \ -+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++{ return kmem_cache_alloc(au_dfree.cache[AuCache_##index].cache, GFP_NOFS); } \ +static inline void au_cache_free_##name(struct au_##name *p) \ -+{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++{ kmem_cache_free(au_dfree.cache[AuCache_##index].cache, p); } \ ++void au_cache_dfree_##name(struct au_##name *p) + +AuCacheFuncs(dinfo, DINFO); +AuCacheFuncs(icntnr, ICNTNR); @@ -20660,11 +21052,30 @@ index 0000000..1383e3d +AuCacheFuncs(hnotify, HNOTIFY); +#endif + ++static inline void au_delayed_kfree(const void *p) ++{ ++ AuDebugOn(!p); ++ AuDebugOn(ksize(p) < sizeof(struct llist_node)); ++ ++ AU_DFREE_BODY((void *)p, au_dfree.llist + AU_DFREE_KFREE); ++} ++ ++/* cast only */ ++static inline void au_free_page(void *p) ++{ ++ free_page((unsigned long)p); ++} ++ ++static inline void au_delayed_free_page(unsigned long addr) ++{ ++ AU_DFREE_BODY((void *)addr, au_dfree.llist + AU_DFREE_FREE_PAGE); ++} ++ +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c new file mode 100644 -index 0000000..a48aa1c +index 0000000..b0e5b84 --- /dev/null +++ b/fs/aufs/mvdown.c @@ -0,0 +1,691 @@ @@ -21354,17 +21765,17 @@ index 0000000..a48aa1c + e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); + if (unlikely(e)) + err = -EFAULT; -+ kfree(args); ++ au_delayed_kfree(args); +out: + AuTraceErr(err); + return err; +} diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c new file mode 100644 -index 0000000..79c7d71 +index 0000000..1d21f0d --- /dev/null +++ b/fs/aufs/opts.c -@@ -0,0 +1,1846 @@ +@@ -0,0 +1,1847 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -22610,7 +23021,7 @@ index 0000000..79c7d71 + } + } + -+ kfree(a); ++ au_delayed_kfree(a); + dump_opts(opts); + if (unlikely(err)) + au_opts_free(opts); @@ -23032,7 +23443,8 @@ index 0000000..79c7d71 + au_hn_inode_unlock(hdir); + + if (!err && do_free) { -+ kfree(wbr); ++ if (wbr) ++ au_delayed_kfree(wbr); + br->br_wbr = NULL; + } + } @@ -23417,10 +23829,10 @@ index 0000000..0d6c2e1 +#endif /* __AUFS_OPTS_H__ */ diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c new file mode 100644 -index 0000000..c42734d +index 0000000..d8d75e8 --- /dev/null +++ b/fs/aufs/plink.c -@@ -0,0 +1,489 @@ +@@ -0,0 +1,501 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -23455,6 +23867,7 @@ index 0000000..c42734d +{ + int err; + pid_t pid, ppid; ++ struct task_struct *parent, *prev; + struct au_sbinfo *sbi; + + SiMustAnyLock(sb); @@ -23469,11 +23882,22 @@ index 0000000..c42734d + goto out; + + /* todo: it highly depends upon /sbin/mount.aufs */ ++ prev = NULL; ++ parent = current; ++ ppid = 0; + rcu_read_lock(); -+ ppid = task_pid_vnr(rcu_dereference(current->real_parent)); ++ while (1) { ++ parent = rcu_dereference(parent->real_parent); ++ if (parent == prev) ++ break; ++ ppid = task_pid_vnr(parent); ++ if (pid == ppid) { ++ rcu_read_unlock(); ++ goto out; ++ } ++ prev = parent; ++ } + rcu_read_unlock(); -+ if (pid == ppid) -+ goto out; + + if (au_ftest_lock(flags, NOPLMW)) { + /* if there is no i_mutex lock in VFS, we don't need to wait */ @@ -24775,10 +25199,10 @@ index 0000000..6c0d5a9 +#endif /* __AUFS_RWSEM_H__ */ diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c new file mode 100644 -index 0000000..aa97059 +index 0000000..e113b51 --- /dev/null +++ b/fs/aufs/sbinfo.c -@@ -0,0 +1,340 @@ +@@ -0,0 +1,342 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -24801,7 +25225,7 @@ index 0000000..aa97059 + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + for (i = 0; i < AuPlink_NHASH; i++) + AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head)); -+ au_nwt_fin(&sbinfo->si_nowait); ++ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); + + AuDebugOn(percpu_counter_sum(&sbinfo->si_ninodes)); + percpu_counter_destroy(&sbinfo->si_ninodes); @@ -24812,14 +25236,15 @@ index 0000000..aa97059 + au_br_free(sbinfo); + au_rw_write_unlock(&sbinfo->si_rwsem); + -+ kfree(sbinfo->si_branch); ++ au_delayed_kfree(sbinfo->si_branch); + for (i = 0; i < AU_NPIDMAP; i++) -+ kfree(sbinfo->au_si_pid.pid_bitmap[i]); ++ if (sbinfo->au_si_pid.pid_bitmap[i]) ++ au_delayed_kfree(sbinfo->au_si_pid.pid_bitmap[i]); + mutex_destroy(&sbinfo->au_si_pid.pid_mtx); + mutex_destroy(&sbinfo->si_xib_mtx); + AuRwDestroy(&sbinfo->si_rwsem); + -+ kfree(sbinfo); ++ au_delayed_kfree(sbinfo); +} + +int au_si_alloc(struct super_block *sb) @@ -24891,14 +25316,14 @@ index 0000000..aa97059 + return 0; /* success */ + +out_br: -+ kfree(sbinfo->si_branch); ++ au_delayed_kfree(sbinfo->si_branch); +out_sbinfo: -+ kfree(sbinfo); ++ au_delayed_kfree(sbinfo); +out: + return err; +} + -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink) +{ + int err, sz; + struct au_branch **brp; @@ -24909,7 +25334,8 @@ index 0000000..aa97059 + sz = sizeof(*brp) * (sbinfo->si_bbot + 1); + if (unlikely(!sz)) + sz = sizeof(*brp); -+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS, ++ may_shrink); + if (brp) { + sbinfo->si_branch = brp; + err = 0; @@ -25121,10 +25547,10 @@ index 0000000..aa97059 +} diff --git a/fs/aufs/spl.h b/fs/aufs/spl.h new file mode 100644 -index 0000000..f9b5288 +index 0000000..8f519db3 --- /dev/null +++ b/fs/aufs/spl.h -@@ -0,0 +1,98 @@ +@@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -25138,6 +25564,7 @@ index 0000000..f9b5288 + +#ifdef __KERNEL__ + ++#if 0 +struct au_splhead { + spinlock_t spin; + struct list_head head; @@ -25170,6 +25597,7 @@ index 0000000..f9b5288 + list_del_rcu(list); + spin_unlock(&spl->spin); +} ++#endif + +/* ---------------------------------------------------------------------- */ + @@ -25225,10 +25653,10 @@ index 0000000..f9b5288 +#endif /* __AUFS_SPL_H__ */ diff --git a/fs/aufs/super.c b/fs/aufs/super.c new file mode 100644 -index 0000000..8bd2d9c +index 0000000..58a773c --- /dev/null +++ b/fs/aufs/super.c -@@ -0,0 +1,1026 @@ +@@ -0,0 +1,1025 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -25264,8 +25692,7 @@ index 0000000..8bd2d9c +{ + struct inode *inode = container_of(head, struct inode, i_rcu); + -+ INIT_HLIST_HEAD(&inode->i_dentry); -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++ au_cache_dfree_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); +} + +static void aufs_destroy_inode(struct inode *inode) @@ -26047,7 +26474,7 @@ index 0000000..8bd2d9c +out_mtx: + inode_unlock(inode); +out_opts: -+ free_page((unsigned long)opts.opt); ++ au_delayed_free_page((unsigned long)opts.opt); +out: + err = cvt_err(err); + AuTraceErr(err); @@ -26188,7 +26615,7 @@ index 0000000..8bd2d9c + kobject_put(&sbinfo->si_kobj); + sb->s_fs_info = NULL; +out_opts: -+ free_page((unsigned long)opts.opt); ++ au_delayed_free_page((unsigned long)opts.opt); +out: + AuTraceErr(err); + err = cvt_err(err); @@ -26257,7 +26684,7 @@ index 0000000..8bd2d9c +}; diff --git a/fs/aufs/super.h b/fs/aufs/super.h new file mode 100644 -index 0000000..b8ca149 +index 0000000..e4ac866 --- /dev/null +++ b/fs/aufs/super.h @@ -0,0 +1,625 @@ @@ -26529,7 +26956,7 @@ index 0000000..b8ca149 +/* sbinfo.c */ +void au_si_free(struct kobject *kobj); +int au_si_alloc(struct super_block *sb); -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink); + +unsigned int au_sigen_inc(struct super_block *sb); +aufs_bindex_t au_new_br_id(struct super_block *sb); @@ -27079,7 +27506,7 @@ index 0000000..1f79983 +#endif /* __SYSAUFS_H__ */ diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c new file mode 100644 -index 0000000..0efb77a +index 0000000..f4c3170 --- /dev/null +++ b/fs/aufs/sysfs.c @@ -0,0 +1,340 @@ @@ -27258,7 +27685,7 @@ index 0000000..0efb77a + if (unlikely(err == PAGE_SIZE)) + err = -EFBIG; + } -+ kfree(seq); ++ au_delayed_kfree(seq); +out_unlock: + si_read_unlock(sb); +out: @@ -27329,9 +27756,9 @@ index 0000000..0efb77a + err = -EFAULT; + +out_seq: -+ kfree(seq); ++ au_delayed_kfree(seq); +out_buf: -+ free_page((unsigned long)buf); ++ au_delayed_free_page((unsigned long)buf); +out: + si_read_unlock(sb); + return err; @@ -27575,10 +28002,10 @@ index 0000000..7d22979 +} diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c new file mode 100644 -index 0000000..0a9ff00 +index 0000000..b2eb4c0 --- /dev/null +++ b/fs/aufs/vdir.c -@@ -0,0 +1,876 @@ +@@ -0,0 +1,887 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -27678,7 +28105,7 @@ index 0000000..0a9ff00 + struct hlist_node *node; + + hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ kfree(pos); ++ au_delayed_kfree(pos); +} + +static void au_nhash_de_do_free(struct hlist_head *head) @@ -27687,7 +28114,7 @@ index 0000000..0a9ff00 + struct hlist_node *node; + + hlist_for_each_entry_safe(pos, node, head, hash) -+ au_cache_free_vdir_dehstr(pos); ++ au_cache_dfree_vdir_dehstr(pos); +} + +static void au_nhash_do_free(struct au_nhash *nhash, @@ -27705,7 +28132,7 @@ index 0000000..0a9ff00 + nhash_count(head); + free(head++); + } -+ kfree(nhash->nh_head); ++ au_delayed_kfree(nhash->nh_head); +} + +void au_nhash_wh_free(struct au_nhash *whlist) @@ -27748,6 +28175,8 @@ index 0000000..0a9ff00 + AuDebugOn(!nhash->nh_num || !nhash->nh_head); + + v = 0; ++ if (len > 8) ++ len = 8; + while (len--) + v += *name++; + /* v = hash_long(v, magic_bit); */ @@ -27845,8 +28274,8 @@ index 0000000..0a9ff00 + unsigned char **o; + + err = -ENOMEM; -+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), -+ GFP_NOFS); ++ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS, /*may_shrink*/0); + if (unlikely(!o)) + goto out; + @@ -27916,15 +28345,23 @@ index 0000000..0a9ff00 + +/* ---------------------------------------------------------------------- */ + -+void au_vdir_free(struct au_vdir *vdir) ++void au_vdir_free(struct au_vdir *vdir, int atonce) +{ + unsigned char **deblk; + + deblk = vdir->vd_deblk; -+ while (vdir->vd_nblk--) -+ kfree(*deblk++); -+ kfree(vdir->vd_deblk); -+ au_cache_free_vdir(vdir); ++ if (!atonce) { ++ while (vdir->vd_nblk--) ++ au_delayed_kfree(*deblk++); ++ au_delayed_kfree(vdir->vd_deblk); ++ au_cache_dfree_vdir(vdir); ++ } else { ++ /* not delayed */ ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++ } +} + +static struct au_vdir *alloc_vdir(struct file *file) @@ -27958,10 +28395,10 @@ index 0000000..0a9ff00 + if (!err) + return vdir; /* success */ + -+ kfree(vdir->vd_deblk); ++ au_delayed_kfree(vdir->vd_deblk); + +out_free: -+ au_cache_free_vdir(vdir); ++ au_cache_dfree_vdir(vdir); +out: + vdir = ERR_PTR(err); + return vdir; @@ -27973,7 +28410,7 @@ index 0000000..0a9ff00 + union au_vdir_deblk_p p, deblk_end; + + while (vdir->vd_nblk > 1) { -+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ au_delayed_kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ + vdir->vd_nblk--; + } @@ -28104,7 +28541,7 @@ index 0000000..0a9ff00 + } + } + -+ free_page((unsigned long)o); ++ au_delayed_free_page((unsigned long)o); + +out: + AuTraceErr(err); @@ -28243,7 +28680,7 @@ index 0000000..0a9ff00 + if (allocated) + au_set_ivdir(inode, allocated); + } else if (allocated) -+ au_vdir_free(allocated); ++ au_vdir_free(allocated, /*atonce*/0); + +out: + return err; @@ -28261,8 +28698,8 @@ index 0000000..0a9ff00 + if (tgt->vd_nblk < src->vd_nblk) { + unsigned char **p; + -+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, -+ GFP_NOFS); ++ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS, /*may_shrink*/0); + if (unlikely(!p)) + goto out; + tgt->vd_deblk = p; @@ -28272,7 +28709,8 @@ index 0000000..0a9ff00 + unsigned char *p; + + tgt->vd_deblk_sz = deblk_sz; -+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS); ++ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS, ++ /*may_shrink*/1); + if (unlikely(!p)) + goto out; + tgt->vd_deblk[0] = p; @@ -28337,7 +28775,7 @@ index 0000000..0a9ff00 + if (allocated) + au_set_fvdir_cache(file, allocated); + } else if (allocated) -+ au_vdir_free(allocated); ++ au_vdir_free(allocated, /*atonce*/0); + +out: + return err; @@ -29334,10 +29772,10 @@ index 0000000..2e54bad +} diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h new file mode 100644 -index 0000000..291bfae +index 0000000..64fff0f --- /dev/null +++ b/fs/aufs/vfsub.h -@@ -0,0 +1,297 @@ +@@ -0,0 +1,303 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -29523,6 +29961,12 @@ index 0000000..291bfae + return flags; +} + ++static inline int vfsub_file_execed(struct file *file) ++{ ++ /* todo: direct access f_flags */ ++ return !!(vfsub_file_flags(file) & __FMODE_EXEC); ++} ++ +#if 0 /* reserved */ +static inline void vfsub_file_accessed(struct file *h_file) +{ @@ -29637,7 +30081,7 @@ index 0000000..291bfae +#endif /* __AUFS_VFSUB_H__ */ diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c new file mode 100644 -index 0000000..91a010a +index 0000000..79eb9b4 --- /dev/null +++ b/fs/aufs/wbr_policy.c @@ -0,0 +1,752 @@ @@ -30091,7 +30535,7 @@ index 0000000..91a010a + + mfs->mfsrr_bytes = bavail; + AuDbg("b%d\n", mfs->mfs_bindex); -+ kfree(st); ++ au_delayed_kfree(st); +} + +static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) @@ -30395,7 +30839,7 @@ index 0000000..91a010a +}; diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c new file mode 100644 -index 0000000..16a96f88 +index 0000000..54feb08 --- /dev/null +++ b/fs/aufs/whout.c @@ -0,0 +1,1047 @@ @@ -30550,7 +30994,7 @@ index 0000000..16a96f88 + +out_name: + if (name != defname) -+ kfree(name); ++ au_delayed_kfree(name); +out: + AuTraceErrPtr(dentry); + return dentry; @@ -30989,7 +31433,7 @@ index 0000000..16a96f88 + au_br_put(a->br); + si_write_unlock(a->sb); + au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ kfree(arg); ++ au_delayed_kfree(arg); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} @@ -31017,7 +31461,7 @@ index 0000000..16a96f88 + if (unlikely(wkq_err)) { + atomic_dec(&br->br_wbr->wbr_wh_running); + au_br_put(br); -+ kfree(arg); ++ au_delayed_kfree(arg); + } + do_dec = 0; + } @@ -31176,7 +31620,7 @@ index 0000000..16a96f88 + wh_dentry = ERR_PTR(err); + if (!err) { + wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ kfree(wh_name.name); ++ au_delayed_kfree(wh_name.name); + } + return wh_dentry; +} @@ -31252,7 +31696,7 @@ index 0000000..16a96f88 + break; + } + } -+ free_page((unsigned long)wh_name.name); ++ au_delayed_free_page((unsigned long)wh_name.name); + +out: + return err; @@ -31294,7 +31738,7 @@ index 0000000..16a96f88 + rdhash = AUFS_RDHASH_DEF; + err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); + if (unlikely(err)) { -+ kfree(whtmp); ++ au_delayed_kfree(whtmp); + whtmp = ERR_PTR(err); + } + @@ -31309,7 +31753,7 @@ index 0000000..16a96f88 + dput(whtmp->wh_dentry); + iput(whtmp->dir); + au_nhash_wh_free(&whtmp->whlist); -+ kfree(whtmp); ++ au_delayed_kfree(whtmp); +} + +/* @@ -31526,10 +31970,10 @@ index 0000000..4077dd1 +#endif /* __AUFS_WHOUT_H__ */ diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c new file mode 100644 -index 0000000..65c0137 +index 0000000..216d08f --- /dev/null +++ b/fs/aufs/wkq.c -@@ -0,0 +1,205 @@ +@@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -31573,7 +32017,7 @@ index 0000000..65c0137 + else { + kobject_put(wkinfo->kobj); + module_put(THIS_MODULE); /* todo: ?? */ -+ kfree(wkinfo); ++ au_delayed_kfree(wkinfo); + } +} + @@ -31596,7 +32040,7 @@ index 0000000..65c0137 + +static void au_wkq_comp_free(struct completion *comp) +{ -+ kfree(comp); ++ au_delayed_kfree(comp); +} + +#else @@ -31677,7 +32121,7 @@ index 0000000..65c0137 + int err; + struct au_wkinfo *wkinfo; + -+ percpu_counter_inc(&au_sbi(sb)->si_nowait.nw_len); ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); + + /* + * wkq_func() must free this wkinfo. @@ -31707,16 +32151,11 @@ index 0000000..65c0137 + +void au_nwt_init(struct au_nowait_tasks *nwt) +{ -+ percpu_counter_init(&nwt->nw_len, 0, GFP_NOFS); ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb(); */ /* atomic_set */ + init_waitqueue_head(&nwt->nw_wq); +} + -+void au_nwt_fin(struct au_nowait_tasks *nwt) -+{ -+ AuDebugOn(percpu_counter_sum(&nwt->nw_len)); -+ percpu_counter_destroy(&nwt->nw_len); -+} -+ +void au_wkq_fin(void) +{ + destroy_workqueue(au_wkq); @@ -31737,10 +32176,10 @@ index 0000000..65c0137 +} diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h new file mode 100644 -index 0000000..0b870cc +index 0000000..6d63f74 --- /dev/null +++ b/fs/aufs/wkq.h -@@ -0,0 +1,82 @@ +@@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -31765,7 +32204,7 @@ index 0000000..0b870cc + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue + */ +struct au_nowait_tasks { -+ struct percpu_counter nw_len; ++ atomic_t nw_len; + wait_queue_head_t nw_wq; +}; + @@ -31792,7 +32231,6 @@ index 0000000..0b870cc +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags); +void au_nwt_init(struct au_nowait_tasks *nwt); -+void au_nwt_fin(struct au_nowait_tasks *nwt); +int __init au_wkq_init(void); +void au_wkq_fin(void); + @@ -31810,14 +32248,13 @@ index 0000000..0b870cc + +static inline void au_nwt_done(struct au_nowait_tasks *nwt) +{ -+ percpu_counter_dec(&nwt->nw_len); -+ if (!percpu_counter_sum(&nwt->nw_len)) ++ if (atomic_dec_and_test(&nwt->nw_len)) + wake_up_all(&nwt->nw_wq); +} + +static inline int au_nwt_flush(struct au_nowait_tasks *nwt) +{ -+ wait_event(nwt->nw_wq, !percpu_counter_sum(&nwt->nw_len)); ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); + return 0; +} + @@ -31825,10 +32262,10 @@ index 0000000..0b870cc +#endif /* __AUFS_WKQ_H__ */ diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c new file mode 100644 -index 0000000..c12518f +index 0000000..2a148c9 --- /dev/null +++ b/fs/aufs/xattr.c -@@ -0,0 +1,332 @@ +@@ -0,0 +1,334 @@ +/* + * Copyright (C) 2014-2016 Junjiro R. Okajima + */ @@ -31994,10 +32431,12 @@ index 0000000..c12518f + AuTraceErr(err); + } + -+ kfree(value); ++ if (value) ++ au_delayed_kfree(value); + +out_free: -+ kfree(o); ++ if (o) ++ au_delayed_kfree(o); +out: + if (!unlocked) + inode_unlock(h_isrc); @@ -32163,10 +32602,10 @@ index 0000000..c12518f +#endif diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c new file mode 100644 -index 0000000..4d1d5d4 +index 0000000..2a411f9 --- /dev/null +++ b/fs/aufs/xino.c -@@ -0,0 +1,1304 @@ +@@ -0,0 +1,1305 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + */ @@ -32494,7 +32933,7 @@ index 0000000..4d1d5d4 + AuErr1("statfs err %d, ignored\n", err); + +out_st: -+ kfree(st); ++ au_delayed_kfree(st); +out: + return err; +} @@ -32529,7 +32968,7 @@ index 0000000..4d1d5d4 + au_br_put(br); + si_write_unlock(sb); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(args); ++ au_delayed_kfree(args); +} + +static int xino_trunc_test(struct super_block *sb, struct au_branch *br) @@ -32571,7 +33010,7 @@ index 0000000..4d1d5d4 + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) { + AuErr1("no memory\n"); -+ goto out_args; ++ goto out; + } + + au_br_get(br); @@ -32583,9 +33022,8 @@ index 0000000..4d1d5d4 + + pr_err("wkq %d\n", wkq_err); + au_br_put(br); ++ au_delayed_kfree(args); + -+out_args: -+ kfree(args); +out: + atomic_dec(&br->br_xino_running); +} @@ -33108,7 +33546,7 @@ index 0000000..4d1d5d4 + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); + else + AuDbg("b%d\n", bindex); -+ free_page((unsigned long)page); ++ au_delayed_free_page((unsigned long)page); + +out: + return err; @@ -33185,7 +33623,8 @@ index 0000000..4d1d5d4 + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; -+ free_page((unsigned long)sbinfo->si_xib_buf); ++ if (sbinfo->si_xib_buf) ++ au_delayed_free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; +} + @@ -33228,7 +33667,8 @@ index 0000000..4d1d5d4 + goto out; /* success */ + +out_free: -+ free_page((unsigned long)sbinfo->si_xib_buf); ++ if (sbinfo->si_xib_buf) ++ au_delayed_free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; + if (err >= 0) + err = -EIO; @@ -33321,7 +33761,7 @@ index 0000000..4d1d5d4 + fput(p->new); + else + break; -+ kfree(fpair); ++ au_delayed_kfree(fpair); +out: + return err; +} @@ -33432,7 +33872,7 @@ index 0000000..4d1d5d4 + if (!IS_ERR(file)) + au_xino_brid_set(sb, br->br_id); + } -+ free_page((unsigned long)page); ++ au_delayed_free_page((unsigned long)page); + } else { + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); + if (IS_ERR(file)) @@ -33472,10 +33912,10 @@ index 0000000..4d1d5d4 + return err; +} diff --git a/fs/dcache.c b/fs/dcache.c -index d6847d7..c3c0b6d 100644 +index 5c7cc95..df0268c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1202,7 +1202,7 @@ enum d_walk_ret { +@@ -1164,7 +1164,7 @@ enum d_walk_ret { * * The @enter() and @finish() callbacks are called with d_lock held. */ @@ -33507,10 +33947,10 @@ index 350a2c8..6f42279 100644 return error; diff --git a/fs/inode.c b/fs/inode.c -index 4ccbc21..aa6d071 100644 +index 7e3ef3a..675fe84 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1591,7 +1591,7 @@ EXPORT_SYMBOL(generic_update_time); +@@ -1593,7 +1593,7 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -33520,10 +33960,10 @@ index 4ccbc21..aa6d071 100644 int (*update_time)(struct inode *, struct timespec *, int); diff --git a/fs/proc/base.c b/fs/proc/base.c -index a11eb71..8f10865 100644 +index ac0df4d..42255e5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1939,7 +1939,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) +@@ -1938,7 +1938,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { @@ -33549,7 +33989,7 @@ index f8595e8..cb8eda0 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 4648c7f..061cb85 100644 +index f6fa99e..2750949 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -298,7 +298,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) @@ -33564,7 +34004,7 @@ index 4648c7f..061cb85 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1624,7 +1627,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1634,7 +1637,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) struct proc_maps_private *proc_priv = &numa_priv->proc_maps; struct vm_area_struct *vma = v; struct numa_maps *md = &numa_priv->md; @@ -33590,7 +34030,7 @@ index faacb0c..17b43be 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/fs/read_write.c b/fs/read_write.c -index 933b53a..2d13282 100644 +index 66215a7..a1da117 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -515,6 +515,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, @@ -33663,10 +34103,10 @@ index 7444f5f..bdac0be 100644 static inline void fput_light(struct file *file, int fput_needed) { diff --git a/include/linux/fs.h b/include/linux/fs.h -index dd28814..b689a48 100644 +index 901e25d..a71aa9e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1306,6 +1306,7 @@ extern void fasync_free(struct fasync_struct *); +@@ -1275,6 +1275,7 @@ extern void fasync_free(struct fasync_struct *); /* can be called from interrupts */ extern void kill_fasync(struct fasync_struct **, int, int); @@ -33674,7 +34114,7 @@ index dd28814..b689a48 100644 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern void f_setown(struct file *filp, unsigned long arg, int force); extern void f_delown(struct file *filp); -@@ -1690,6 +1691,7 @@ struct file_operations { +@@ -1699,6 +1700,7 @@ struct file_operations { ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); @@ -33682,7 +34122,7 @@ index dd28814..b689a48 100644 int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -@@ -1750,6 +1752,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, +@@ -1759,6 +1761,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec *fast_pointer, struct iovec **ret_pointer); @@ -33695,7 +34135,7 @@ index dd28814..b689a48 100644 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); -@@ -2105,6 +2113,7 @@ extern int current_umask(void); +@@ -2123,6 +2131,7 @@ extern int current_umask(void); extern void ihold(struct inode * inode); extern void iput(struct inode *); extern int generic_update_time(struct inode *, struct timespec *, int); @@ -33704,10 +34144,10 @@ index dd28814..b689a48 100644 /* /sys/fs */ extern struct kobject *fs_kobj; diff --git a/include/linux/mm.h b/include/linux/mm.h -index ece042d..1e24513 100644 +index ef815b9..a772481 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1239,6 +1239,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, +@@ -1278,6 +1278,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, } #endif @@ -33737,10 +34177,10 @@ index ece042d..1e24513 100644 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, int write); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index ca3e517..10bc491 100644 +index 903200f..55fc528 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -274,6 +274,7 @@ struct vm_region { +@@ -275,6 +275,7 @@ struct vm_region { unsigned long vm_top; /* region allocated to here */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ struct file *vm_file; /* the backing file or NULL */ @@ -33748,7 +34188,7 @@ index ca3e517..10bc491 100644 int vm_usage; /* region usage count (access under nommu_region_sem) */ bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -348,6 +349,7 @@ struct vm_area_struct { +@@ -349,6 +350,7 @@ struct vm_area_struct { unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE units */ struct file * vm_file; /* File we map to (can be NULL). */ @@ -33772,7 +34212,7 @@ index da2751d..2e0fca6 100644 + unsigned int flags); #endif diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index 8bdae34..65dbd5f 100644 +index 185f8ea..5deb0d1 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -59,6 +59,7 @@ header-y += atmsvc.h @@ -33785,7 +34225,7 @@ index 8bdae34..65dbd5f 100644 header-y += auxvec.h diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h new file mode 100644 -index 0000000..4e08bdf +index 0000000..e220283 --- /dev/null +++ b/include/uapi/linux/aufs_type.h @@ -0,0 +1,406 @@ @@ -33817,7 +34257,7 @@ index 0000000..4e08bdf + +#include + -+#define AUFS_VERSION "4.x-rcN" ++#define AUFS_VERSION "4.8" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -34196,10 +34636,10 @@ index 0000000..4e08bdf + +#endif /* __AUFS_TYPE_H__ */ diff --git a/kernel/fork.c b/kernel/fork.c -index 4a7ec0c..8c8f7ac 100644 +index beb3172..ad4cfa8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -479,7 +479,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -477,7 +477,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -34209,10 +34649,10 @@ index 4a7ec0c..8c8f7ac 100644 atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); diff --git a/mm/Makefile b/mm/Makefile -index 78c6f7d..aea4230 100644 +index 2ca1faf..6b9da3f 100644 --- a/mm/Makefile +++ b/mm/Makefile -@@ -37,7 +37,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ +@@ -40,7 +40,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ @@ -34222,10 +34662,10 @@ index 78c6f7d..aea4230 100644 obj-y += init-mm.o diff --git a/mm/filemap.c b/mm/filemap.c -index 20f3b1f..ee827ce 100644 +index 2d0986a..4a31bad 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2208,7 +2208,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +@@ -2284,7 +2284,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) int ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -34235,10 +34675,10 @@ index 20f3b1f..ee827ce 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/memory.c b/mm/memory.c -index cd1f29e..f0c204c 100644 +index 793fe0f..45f39f3 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -2100,7 +2100,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, +@@ -2113,7 +2113,7 @@ static inline int wp_page_reuse(struct fault_env *fe, pte_t orig_pte, } if (!page_mkwrite) @@ -34248,10 +34688,10 @@ index cd1f29e..f0c204c 100644 return VM_FAULT_WRITE; diff --git a/mm/mmap.c b/mm/mmap.c -index de2c176..b7f391c 100644 +index ca9d91b..f3ebc5a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -162,7 +162,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +@@ -163,7 +163,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -34260,7 +34700,7 @@ index de2c176..b7f391c 100644 mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); return next; -@@ -782,7 +782,7 @@ again: remove_next = 1 + (end > next->vm_end); +@@ -790,7 +790,7 @@ again: if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -34269,7 +34709,7 @@ index de2c176..b7f391c 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1563,8 +1563,8 @@ out: +@@ -1574,8 +1574,8 @@ out: return addr; unmap_and_free_vma: @@ -34279,7 +34719,7 @@ index de2c176..b7f391c 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2358,7 +2358,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2380,7 +2380,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -34288,7 +34728,7 @@ index de2c176..b7f391c 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2377,7 +2377,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2399,7 +2399,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -34297,7 +34737,7 @@ index de2c176..b7f391c 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2528,7 +2528,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2550,7 +2550,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -34306,7 +34746,7 @@ index de2c176..b7f391c 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n", current->comm, current->pid); -@@ -2597,10 +2597,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2625,10 +2625,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } } @@ -34335,7 +34775,7 @@ index de2c176..b7f391c 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -2873,7 +2890,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2903,7 +2920,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -34345,7 +34785,7 @@ index de2c176..b7f391c 100644 new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); diff --git a/mm/nommu.c b/mm/nommu.c -index c2e588802..c39edc4 100644 +index 95daf81..5086a29 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -644,7 +644,7 @@ static void __put_nommu_region(struct vm_region *region) diff --git a/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch b/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch new file mode 100644 index 00000000..f7d2ac73 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch @@ -0,0 +1,75 @@ +From 5a920b85f2c6e3fd7d9dd9bb3f3345e9085e2360 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 4 Oct 2016 14:37:32 -0300 +Subject: drm/i915/gen9: fix DDB partitioning for multi-screen cases + +With the previous code we were only recomputing the DDB partitioning +for the CRTCs included in the atomic commit, so any other active CRTCs +would end up having their DDB registers zeroed. In this patch we make +sure that the computed state starts as a copy of the current +partitioning, and then we only zero the DDBs that we're actually +going to recompute. + +How to reproduce the bug: + 1 - Enable the primary plane on pipe A + 2 - Enable the primary plane on pipe B + 3 - Enable the cursor or sprite plane on pipe A + +Step 3 will zero the DDB partitioning for pipe B since it's not +included in the commit that enabled the cursor or sprite for pipe A. + +I expect this to fix many FIFO underrun problems on gen9+. + +v2: + - Mention the cursor on the steps to reproduce the problem (Paulo). + - Add Testcase tag provided by Maarten (Maarten). + +Testcase: kms_cursor_legacy.cursorA-vs-flipB-atomic-transitions +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96226 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96828 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97450 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97596 +Bugzilla: https://www.phoronix.com/scan.php?page=news_item&px=Intel-Skylake-Multi-Screen-Woes +Cc: stable@vger.kernel.org +Signed-off-by: Paulo Zanoni +Reviewed-by: Lyude +Link: http://patchwork.freedesktop.org/patch/msgid/1475602652-17326-1-git-send-email-paulo.r.zanoni@intel.com + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 7f1748a..fe6c1c6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3362,13 +3362,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, + int num_active; + int id, i; + ++ /* Clear the partitioning for disabled planes. */ ++ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); ++ memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); ++ + if (WARN_ON(!state)) + return 0; + + if (!cstate->base.active) { + ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0; +- memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); +- memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); + return 0; + } + +@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state) + intel_state->wm_results.dirty_pipes = ~0; + } + ++ /* ++ * We're not recomputing for the pipes not included in the commit, so ++ * make sure we start with the current state. ++ */ ++ memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); ++ + for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { + struct intel_crtc_state *cstate; + +-- +cgit v0.10.2 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch b/kernel/tools/cpupowertools/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch deleted file mode 100644 index 45b63cdd..00000000 --- a/kernel/tools/cpupowertools/files/patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch +++ /dev/null @@ -1,95 +0,0 @@ -From a36aa80f3cb2540fb1dbad6240852de4365a2e82 Mon Sep 17 00:00:00 2001 -From: Alexander Shishkin -Date: Thu, 30 Jun 2016 11:51:44 +0300 -Subject: [PATCH] intel_th: Fix a deadlock in modprobing - -Driver initialization tries to request a hub (GTH) driver module from -its probe callback, resulting in a deadlock. - -This patch solves the problem by adding a deferred work for requesting -the hub module. - -Signed-off-by: Alexander Shishkin -Cc: # 4.4.x- ---- - drivers/hwtracing/intel_th/core.c | 35 ++++++++++++++++++++++++++++++++++- - drivers/hwtracing/intel_th/intel_th.h | 3 +++ - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c -index 1be543e..0b112ae 100644 ---- a/drivers/hwtracing/intel_th/core.c -+++ b/drivers/hwtracing/intel_th/core.c -@@ -465,6 +465,38 @@ static struct intel_th_subdevice { - }, - }; - -+#ifdef CONFIG_MODULES -+static void __intel_th_request_hub_module(struct work_struct *work) -+{ -+ struct intel_th *th = container_of(work, struct intel_th, -+ request_module_work); -+ -+ request_module("intel_th_%s", th->hub->name); -+} -+ -+static int intel_th_request_hub_module(struct intel_th *th) -+{ -+ INIT_WORK(&th->request_module_work, __intel_th_request_hub_module); -+ schedule_work(&th->request_module_work); -+ -+ return 0; -+} -+ -+static void intel_th_request_hub_module_flush(struct intel_th *th) -+{ -+ flush_work(&th->request_module_work); -+} -+#else -+static inline int intel_th_request_hub_module(struct intel_th *th) -+{ -+ return -EINVAL; -+} -+ -+static inline void intel_th_request_hub_module_flush(struct intel_th *th) -+{ -+} -+#endif /* CONFIG_MODULES */ -+ - static int intel_th_populate(struct intel_th *th, struct resource *devres, - unsigned int ndevres, int irq) - { -@@ -535,7 +567,7 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres, - /* need switch driver to be loaded to enumerate the rest */ - if (subdev->type == INTEL_TH_SWITCH && !req) { - th->hub = thdev; -- err = request_module("intel_th_%s", subdev->name); -+ err = intel_th_request_hub_module(th); - if (!err) - req++; - } -@@ -652,6 +684,7 @@ void intel_th_free(struct intel_th *th) - { - int i; - -+ intel_th_request_hub_module_flush(th); - for (i = 0; i < TH_SUBDEVICE_MAX; i++) - if (th->thdev[i] != th->hub) - intel_th_device_remove(th->thdev[i]); -diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h -index 0df22e3..0482848 100644 ---- a/drivers/hwtracing/intel_th/intel_th.h -+++ b/drivers/hwtracing/intel_th/intel_th.h -@@ -205,6 +205,9 @@ struct intel_th { - - int id; - int major; -+#ifdef CONFIG_MODULES -+ struct work_struct request_module_work; -+#endif /* CONFIG_MODULES */ - #ifdef CONFIG_INTEL_TH_DEBUG - struct dentry *dbg; - #endif --- -2.9.2 - diff --git a/kernel/tools/cpupowertools/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch b/kernel/tools/cpupowertools/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch deleted file mode 100644 index f6d4f341..00000000 --- a/kernel/tools/cpupowertools/files/patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7a1a47ce35821b40f5b2ce46379ba14393bc3873 Mon Sep 17 00:00:00 2001 -From: Alexander Shishkin -Date: Tue, 28 Jun 2016 18:55:23 +0300 -Subject: [PATCH] intel_th: pci: Add Kaby Lake PCH-H support - -This adds Intel(R) Trace Hub PCI ID for Kaby Lake PCH-H. - -Signed-off-by: Alexander Shishkin -Cc: ---- - drivers/hwtracing/intel_th/pci.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c -index 5e25c7e..0bba384 100644 ---- a/drivers/hwtracing/intel_th/pci.c -+++ b/drivers/hwtracing/intel_th/pci.c -@@ -80,6 +80,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), - .driver_data = (kernel_ulong_t)0, - }, -+ { -+ /* Kaby Lake PCH-H */ -+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), -+ .driver_data = (kernel_ulong_t)0, -+ }, - { 0 }, - }; - --- -2.9.2 - diff --git a/kernel/tools/cpupowertools/files/patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch b/kernel/tools/cpupowertools/files/patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch new file mode 100644 index 00000000..05b8cf99 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch @@ -0,0 +1,49 @@ +From 9f692cbe4a01dd9e3c3e954ec6b59662b68f9ce4 Mon Sep 17 00:00:00 2001 +From: Laura Abbott +Date: Fri, 9 Sep 2016 10:19:02 -0700 +Subject: [PATCH] cpupower: Correct return type of cpu_power_is_cpu_online in + cpufreq +To: Thomas Renninger +Cc: linux-pm@vger.kernel.org +Cc: linux-kernel@vger.kernel.org + +When converting to a shared library in ac5a181d065d ("cpupower: Add +cpuidle parts into library"), cpu_freq_cpu_exists was converted to +cpupower_is_cpu_online. cpu_req_cpu_exists returned 0 on success and +-ENOSYS on failure whereas cpupower_is_cpu_online returns 1 on success. +Check for the correct return value in cpufreq-set. + +See https://bugzilla.redhat.com/show_bug.cgi?id=1374212 + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Reported-by: Julian Seward +Signed-off-by: Laura Abbott +--- + tools/power/cpupower/utils/cpufreq-set.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c +index b4bf769..8971d71 100644 +--- a/tools/power/cpupower/utils/cpufreq-set.c ++++ b/tools/power/cpupower/utils/cpufreq-set.c +@@ -296,7 +296,7 @@ int cmd_freq_set(int argc, char **argv) + struct cpufreq_affected_cpus *cpus; + + if (!bitmask_isbitset(cpus_chosen, cpu) || +- cpupower_is_cpu_online(cpu)) ++ cpupower_is_cpu_online(cpu) != 1) + continue; + + cpus = cpufreq_get_related_cpus(cpu); +@@ -316,7 +316,7 @@ int cmd_freq_set(int argc, char **argv) + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu) || +- cpupower_is_cpu_online(cpu)) ++ cpupower_is_cpu_online(cpu) != 1) + continue; + + if (cpupower_is_cpu_online(cpu) != 1) +-- +2.10.0 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/linux-BFQ-v8r4.patch b/kernel/tools/cpupowertools/files/patches/mageia/linux-BFQ-v8r4.patch new file mode 100644 index 00000000..abb33847 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/linux-BFQ-v8r4.patch @@ -0,0 +1,9004 @@ +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-cgroup.c linux-4.8-bfq/block/bfq-cgroup.c +--- linux-4.8/block/bfq-cgroup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-cgroup.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,1196 @@ ++/* ++ * BFQ: CGROUPS support. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ */ ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ++/* bfqg stats flags */ ++enum bfqg_stats_flags { ++ BFQG_stats_waiting = 0, ++ BFQG_stats_idling, ++ BFQG_stats_empty, ++}; ++ ++#define BFQG_FLAG_FNS(name) \ ++static void bfqg_stats_mark_##name(struct bfqg_stats *stats) \ ++{ \ ++ stats->flags |= (1 << BFQG_stats_##name); \ ++} \ ++static void bfqg_stats_clear_##name(struct bfqg_stats *stats) \ ++{ \ ++ stats->flags &= ~(1 << BFQG_stats_##name); \ ++} \ ++static int bfqg_stats_##name(struct bfqg_stats *stats) \ ++{ \ ++ return (stats->flags & (1 << BFQG_stats_##name)) != 0; \ ++} \ ++ ++BFQG_FLAG_FNS(waiting) ++BFQG_FLAG_FNS(idling) ++BFQG_FLAG_FNS(empty) ++#undef BFQG_FLAG_FNS ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_update_group_wait_time(struct bfqg_stats *stats) ++{ ++ unsigned long long now; ++ ++ if (!bfqg_stats_waiting(stats)) ++ return; ++ ++ now = sched_clock(); ++ if (time_after64(now, stats->start_group_wait_time)) ++ blkg_stat_add(&stats->group_wait_time, ++ now - stats->start_group_wait_time); ++ bfqg_stats_clear_waiting(stats); ++} ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg, ++ struct bfq_group *curr_bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (bfqg_stats_waiting(stats)) ++ return; ++ if (bfqg == curr_bfqg) ++ return; ++ stats->start_group_wait_time = sched_clock(); ++ bfqg_stats_mark_waiting(stats); ++} ++ ++/* This should be called with the queue_lock held. */ ++static void bfqg_stats_end_empty_time(struct bfqg_stats *stats) ++{ ++ unsigned long long now; ++ ++ if (!bfqg_stats_empty(stats)) ++ return; ++ ++ now = sched_clock(); ++ if (time_after64(now, stats->start_empty_time)) ++ blkg_stat_add(&stats->empty_time, ++ now - stats->start_empty_time); ++ bfqg_stats_clear_empty(stats); ++} ++ ++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg) ++{ ++ blkg_stat_add(&bfqg->stats.dequeue, 1); ++} ++ ++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (blkg_rwstat_total(&stats->queued)) ++ return; ++ ++ /* ++ * group is already marked empty. This can happen if bfqq got new ++ * request in parent group and moved to this group while being added ++ * to service tree. Just ignore the event and move on. ++ */ ++ if (bfqg_stats_empty(stats)) ++ return; ++ ++ stats->start_empty_time = sched_clock(); ++ bfqg_stats_mark_empty(stats); ++} ++ ++static void bfqg_stats_update_idle_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ if (bfqg_stats_idling(stats)) { ++ unsigned long long now = sched_clock(); ++ ++ if (time_after64(now, stats->start_idle_time)) ++ blkg_stat_add(&stats->idle_time, ++ now - stats->start_idle_time); ++ bfqg_stats_clear_idling(stats); ++ } ++} ++ ++static void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ stats->start_idle_time = sched_clock(); ++ bfqg_stats_mark_idling(stats); ++} ++ ++static void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ ++ blkg_stat_add(&stats->avg_queue_size_sum, ++ blkg_rwstat_total(&stats->queued)); ++ blkg_stat_add(&stats->avg_queue_size_samples, 1); ++ bfqg_stats_update_group_wait_time(stats); ++} ++ ++static struct blkcg_policy blkcg_policy_bfq; ++ ++/* ++ * blk-cgroup policy-related handlers ++ * The following functions help in converting between blk-cgroup ++ * internal structures and BFQ-specific structures. ++ */ ++ ++static struct bfq_group *pd_to_bfqg(struct blkg_policy_data *pd) ++{ ++ return pd ? container_of(pd, struct bfq_group, pd) : NULL; ++} ++ ++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg) ++{ ++ return pd_to_blkg(&bfqg->pd); ++} ++ ++static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg) ++{ ++ struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq); ++ ++ return pd_to_bfqg(pd); ++} ++ ++/* ++ * bfq_group handlers ++ * The following functions help in navigating the bfq_group hierarchy ++ * by allowing to find the parent of a bfq_group or the bfq_group ++ * associated to a bfq_queue. ++ */ ++ ++static struct bfq_group *bfqg_parent(struct bfq_group *bfqg) ++{ ++ struct blkcg_gq *pblkg = bfqg_to_blkg(bfqg)->parent; ++ ++ return pblkg ? blkg_to_bfqg(pblkg) : NULL; ++} ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *group_entity = bfqq->entity.parent; ++ ++ return group_entity ? container_of(group_entity, struct bfq_group, ++ entity) : ++ bfqq->bfqd->root_group; ++} ++ ++/* ++ * The following two functions handle get and put of a bfq_group by ++ * wrapping the related blk-cgroup hooks. ++ */ ++ ++static void bfqg_get(struct bfq_group *bfqg) ++{ ++ return blkg_get(bfqg_to_blkg(bfqg)); ++} ++ ++static void bfqg_put(struct bfq_group *bfqg) ++{ ++ return blkg_put(bfqg_to_blkg(bfqg)); ++} ++ ++static void bfqg_stats_update_io_add(struct bfq_group *bfqg, ++ struct bfq_queue *bfqq, ++ int op, int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, 1); ++ bfqg_stats_end_empty_time(&bfqg->stats); ++ if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue)) ++ bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq)); ++} ++ ++static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, ++ int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, -1); ++} ++ ++static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, ++ int op_flags) ++{ ++ blkg_rwstat_add(&bfqg->stats.merged, op, op_flags, 1); ++} ++ ++static void bfqg_stats_update_completion(struct bfq_group *bfqg, ++ uint64_t start_time, uint64_t io_start_time, int op, ++ int op_flags) ++{ ++ struct bfqg_stats *stats = &bfqg->stats; ++ unsigned long long now = sched_clock(); ++ ++ if (time_after64(now, io_start_time)) ++ blkg_rwstat_add(&stats->service_time, op, op_flags, ++ now - io_start_time); ++ if (time_after64(io_start_time, start_time)) ++ blkg_rwstat_add(&stats->wait_time, op, op_flags, ++ io_start_time - start_time); ++} ++ ++/* @stats = 0 */ ++static void bfqg_stats_reset(struct bfqg_stats *stats) ++{ ++ /* queued stats shouldn't be cleared */ ++ blkg_rwstat_reset(&stats->merged); ++ blkg_rwstat_reset(&stats->service_time); ++ blkg_rwstat_reset(&stats->wait_time); ++ blkg_stat_reset(&stats->time); ++ blkg_stat_reset(&stats->avg_queue_size_sum); ++ blkg_stat_reset(&stats->avg_queue_size_samples); ++ blkg_stat_reset(&stats->dequeue); ++ blkg_stat_reset(&stats->group_wait_time); ++ blkg_stat_reset(&stats->idle_time); ++ blkg_stat_reset(&stats->empty_time); ++} ++ ++/* @to += @from */ ++static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from) ++{ ++ if (!to || !from) ++ return; ++ ++ /* queued stats shouldn't be cleared */ ++ blkg_rwstat_add_aux(&to->merged, &from->merged); ++ blkg_rwstat_add_aux(&to->service_time, &from->service_time); ++ blkg_rwstat_add_aux(&to->wait_time, &from->wait_time); ++ blkg_stat_add_aux(&from->time, &from->time); ++ blkg_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum); ++ blkg_stat_add_aux(&to->avg_queue_size_samples, ++ &from->avg_queue_size_samples); ++ blkg_stat_add_aux(&to->dequeue, &from->dequeue); ++ blkg_stat_add_aux(&to->group_wait_time, &from->group_wait_time); ++ blkg_stat_add_aux(&to->idle_time, &from->idle_time); ++ blkg_stat_add_aux(&to->empty_time, &from->empty_time); ++} ++ ++/* ++ * Transfer @bfqg's stats to its parent's dead_stats so that the ancestors' ++ * recursive stats can still account for the amount used by this bfqg after ++ * it's gone. ++ */ ++static void bfqg_stats_xfer_dead(struct bfq_group *bfqg) ++{ ++ struct bfq_group *parent; ++ ++ if (!bfqg) /* root_group */ ++ return; ++ ++ parent = bfqg_parent(bfqg); ++ ++ lockdep_assert_held(bfqg_to_blkg(bfqg)->q->queue_lock); ++ ++ if (unlikely(!parent)) ++ return; ++ ++ bfqg_stats_add_aux(&parent->stats, &bfqg->stats); ++ bfqg_stats_reset(&bfqg->stats); ++} ++ ++static void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) { ++ bfqq->ioprio = bfqq->new_ioprio; ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ bfqg_get(bfqg); ++ } ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static void bfqg_stats_exit(struct bfqg_stats *stats) ++{ ++ blkg_rwstat_exit(&stats->merged); ++ blkg_rwstat_exit(&stats->service_time); ++ blkg_rwstat_exit(&stats->wait_time); ++ blkg_rwstat_exit(&stats->queued); ++ blkg_stat_exit(&stats->time); ++ blkg_stat_exit(&stats->avg_queue_size_sum); ++ blkg_stat_exit(&stats->avg_queue_size_samples); ++ blkg_stat_exit(&stats->dequeue); ++ blkg_stat_exit(&stats->group_wait_time); ++ blkg_stat_exit(&stats->idle_time); ++ blkg_stat_exit(&stats->empty_time); ++} ++ ++static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp) ++{ ++ if (blkg_rwstat_init(&stats->merged, gfp) || ++ blkg_rwstat_init(&stats->service_time, gfp) || ++ blkg_rwstat_init(&stats->wait_time, gfp) || ++ blkg_rwstat_init(&stats->queued, gfp) || ++ blkg_stat_init(&stats->time, gfp) || ++ blkg_stat_init(&stats->avg_queue_size_sum, gfp) || ++ blkg_stat_init(&stats->avg_queue_size_samples, gfp) || ++ blkg_stat_init(&stats->dequeue, gfp) || ++ blkg_stat_init(&stats->group_wait_time, gfp) || ++ blkg_stat_init(&stats->idle_time, gfp) || ++ blkg_stat_init(&stats->empty_time, gfp)) { ++ bfqg_stats_exit(stats); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static struct bfq_group_data *cpd_to_bfqgd(struct blkcg_policy_data *cpd) ++{ ++ return cpd ? container_of(cpd, struct bfq_group_data, pd) : NULL; ++} ++ ++static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg) ++{ ++ return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq)); ++} ++ ++static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp) ++{ ++ struct bfq_group_data *bgd; ++ ++ bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); ++ if (!bgd) ++ return NULL; ++ return &bgd->pd; ++} ++ ++static void bfq_cpd_init(struct blkcg_policy_data *cpd) ++{ ++ struct bfq_group_data *d = cpd_to_bfqgd(cpd); ++ ++ d->weight = cgroup_subsys_on_dfl(io_cgrp_subsys) ? ++ CGROUP_WEIGHT_DFL : BFQ_WEIGHT_LEGACY_DFL; ++} ++ ++static void bfq_cpd_free(struct blkcg_policy_data *cpd) ++{ ++ kfree(cpd_to_bfqgd(cpd)); ++} ++ ++static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) ++{ ++ struct bfq_group *bfqg; ++ ++ bfqg = kzalloc_node(sizeof(*bfqg), gfp, node); ++ if (!bfqg) ++ return NULL; ++ ++ if (bfqg_stats_init(&bfqg->stats, gfp)) { ++ kfree(bfqg); ++ return NULL; ++ } ++ ++ return &bfqg->pd; ++} ++ ++static void bfq_pd_init(struct blkg_policy_data *pd) ++{ ++ struct blkcg_gq *blkg; ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct bfq_entity *entity; ++ struct bfq_group_data *d; ++ ++ blkg = pd_to_blkg(pd); ++ BUG_ON(!blkg); ++ bfqg = blkg_to_bfqg(blkg); ++ bfqd = blkg->q->elevator->elevator_data; ++ entity = &bfqg->entity; ++ d = blkcg_to_bfqgd(blkg->blkcg); ++ ++ entity->orig_weight = entity->weight = entity->new_weight = d->weight; ++ entity->my_sched_data = &bfqg->sched_data; ++ bfqg->my_entity = entity; /* ++ * the root_group's will be set to NULL ++ * in bfq_init_queue() ++ */ ++ bfqg->bfqd = bfqd; ++ bfqg->active_entities = 0; ++ bfqg->rq_pos_tree = RB_ROOT; ++} ++ ++static void bfq_pd_free(struct blkg_policy_data *pd) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ ++ bfqg_stats_exit(&bfqg->stats); ++ return kfree(bfqg); ++} ++ ++static void bfq_pd_reset_stats(struct blkg_policy_data *pd) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ ++ bfqg_stats_reset(&bfqg->stats); ++} ++ ++static void bfq_group_set_parent(struct bfq_group *bfqg, ++ struct bfq_group *parent) ++{ ++ struct bfq_entity *entity; ++ ++ BUG_ON(!parent); ++ BUG_ON(!bfqg); ++ BUG_ON(bfqg == parent); ++ ++ entity = &bfqg->entity; ++ entity->parent = parent->my_entity; ++ entity->sched_data = &parent->sched_data; ++} ++ ++static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ struct blkcg_gq *blkg; ++ ++ blkg = blkg_lookup(blkcg, bfqd->queue); ++ if (likely(blkg)) ++ return blkg_to_bfqg(blkg); ++ return NULL; ++} ++ ++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ struct bfq_group *bfqg, *parent; ++ struct bfq_entity *entity; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ bfqg = bfq_lookup_bfqg(bfqd, blkcg); ++ ++ if (unlikely(!bfqg)) ++ return NULL; ++ ++ /* ++ * Update chain of bfq_groups as we might be handling a leaf group ++ * which, along with some of its relatives, has not been hooked yet ++ * to the private hierarchy of BFQ. ++ */ ++ entity = &bfqg->entity; ++ for_each_entity(entity) { ++ bfqg = container_of(entity, struct bfq_group, entity); ++ BUG_ON(!bfqg); ++ if (bfqg != bfqd->root_group) { ++ parent = bfqg_parent(bfqg); ++ if (!parent) ++ parent = bfqd->root_group; ++ BUG_ON(!parent); ++ bfq_group_set_parent(bfqg, parent); ++ } ++ } ++ ++ return bfqg; ++} ++ ++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq); ++ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason); ++ ++/** ++ * bfq_bfqq_move - migrate @bfqq to @bfqg. ++ * @bfqd: queue descriptor. ++ * @bfqq: the queue to move. ++ * @bfqg: the group to move to. ++ * ++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating ++ * it on the new one. Avoid putting the entity on the old group idle tree. ++ * ++ * Must be called under the queue lock; the cgroup owning @bfqg must ++ * not disappear (by now this just means that we are called under ++ * rcu_read_lock()). ++ */ ++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(!bfq_bfqq_busy(bfqq) && !RB_EMPTY_ROOT(&bfqq->sort_list)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list) && !entity->on_st); ++ BUG_ON(bfq_bfqq_busy(bfqq) && RB_EMPTY_ROOT(&bfqq->sort_list) ++ && entity->on_st && ++ bfqq != bfqd->in_service_queue); ++ BUG_ON(!bfq_bfqq_busy(bfqq) && bfqq == bfqd->in_service_queue); ++ ++ /* If bfqq is empty, then bfq_bfqq_expire also invokes ++ * bfq_del_bfqq_busy, thereby removing bfqq and its entity ++ * from data structures related to current group. Otherwise we ++ * need to remove bfqq explicitly with bfq_deactivate_bfqq, as ++ * we do below. ++ */ ++ if (bfqq == bfqd->in_service_queue) ++ bfq_bfqq_expire(bfqd, bfqd->in_service_queue, ++ false, BFQ_BFQQ_PREEMPTED); ++ ++ BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq) ++ && &bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); ++ ++ if (bfq_bfqq_busy(bfqq)) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ else if (entity->on_st) { ++ BUG_ON(&bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); ++ } ++ bfqg_put(bfqq_group(bfqq)); ++ ++ /* ++ * Here we use a reference to bfqg. We don't need a refcounter ++ * as the cgroup reference will not be dropped, so that its ++ * destroy() callback will not be invoked. ++ */ ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++ bfqg_get(bfqg); ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); ++ if (bfq_bfqq_busy(bfqq)) { ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++ ++ if (!bfqd->in_service_queue && !bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq) ++ && &bfq_entity_service_tree(entity)->idle != ++ entity->tree); ++} ++ ++/** ++ * __bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bfqd: the queue descriptor. ++ * @bic: the bic to move. ++ * @blkcg: the blk-cgroup to move to. ++ * ++ * Move bic to blkcg, assuming that bfqd->queue is locked; the caller ++ * has to make sure that the reference to cgroup is valid across the call. ++ * ++ * NOTE: an alternative approach might have been to store the current ++ * cgroup in bfqq and getting a reference to it, reducing the lookup ++ * time here, at the price of slightly more complex code. ++ */ ++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic, ++ struct blkcg *blkcg) ++{ ++ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); ++ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); ++ struct bfq_group *bfqg; ++ struct bfq_entity *entity; ++ ++ lockdep_assert_held(bfqd->queue->queue_lock); ++ ++ bfqg = bfq_find_set_group(bfqd, blkcg); ++ ++ if (unlikely(!bfqg)) ++ bfqg = bfqd->root_group; ++ ++ if (async_bfqq) { ++ entity = &async_bfqq->entity; ++ ++ if (entity->sched_data != &bfqg->sched_data) { ++ bic_set_bfqq(bic, NULL, 0); ++ bfq_log_bfqq(bfqd, async_bfqq, ++ "bic_change_group: %p %d", ++ async_bfqq, ++ async_bfqq->ref); ++ bfq_put_queue(async_bfqq); ++ } ++ } ++ ++ if (sync_bfqq) { ++ entity = &sync_bfqq->entity; ++ if (entity->sched_data != &bfqg->sched_data) ++ bfq_bfqq_move(bfqd, sync_bfqq, bfqg); ++ } ++ ++ return bfqg; ++} ++ ++static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_group *bfqg = NULL; ++ uint64_t serial_nr; ++ ++ rcu_read_lock(); ++ serial_nr = bio_blkcg(bio)->css.serial_nr; ++ ++ /* ++ * Check whether blkcg has changed. The condition may trigger ++ * spuriously on a newly created cic but there's no harm. ++ */ ++ if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr)) ++ goto out; ++ ++ bfqg = __bfq_bic_change_cgroup(bfqd, bic, bio_blkcg(bio)); ++ bic->blkcg_serial_nr = serial_nr; ++out: ++ rcu_read_unlock(); ++} ++ ++/** ++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. ++ * @st: the service tree being flushed. ++ */ ++static void bfq_flush_idle_tree(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entity = st->first_idle; ++ ++ for (; entity ; entity = st->first_idle) ++ __bfq_deactivate_entity(entity, 0); ++} ++ ++/** ++ * bfq_reparent_leaf_entity - move leaf entity to the root_group. ++ * @bfqd: the device data structure with the root group. ++ * @entity: the entity to move. ++ */ ++static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(!bfqq); ++ bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); ++} ++ ++/** ++ * bfq_reparent_active_entities - move to the root group all active ++ * entities. ++ * @bfqd: the device data structure with the root group. ++ * @bfqg: the group to move from. ++ * @st: the service tree with the entities. ++ * ++ * Needs queue_lock to be taken and reference to be valid over the call. ++ */ ++static void bfq_reparent_active_entities(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st) ++{ ++ struct rb_root *active = &st->active; ++ struct bfq_entity *entity = NULL; ++ ++ if (!RB_EMPTY_ROOT(&st->active)) ++ entity = bfq_entity_of(rb_first(active)); ++ ++ for (; entity ; entity = bfq_entity_of(rb_first(active))) ++ bfq_reparent_leaf_entity(bfqd, entity); ++ ++ if (bfqg->sched_data.in_service_entity) ++ bfq_reparent_leaf_entity(bfqd, ++ bfqg->sched_data.in_service_entity); ++} ++ ++/** ++ * bfq_pd_offline - deactivate the entity associated with @pd, ++ * and reparent its children entities. ++ * @pd: descriptor of the policy going offline. ++ * ++ * blkio already grabs the queue_lock for us, so no need to use ++ * RCU-based magic ++ */ ++static void bfq_pd_offline(struct blkg_policy_data *pd) ++{ ++ struct bfq_service_tree *st; ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct bfq_entity *entity; ++ int i; ++ ++ BUG_ON(!pd); ++ bfqg = pd_to_bfqg(pd); ++ BUG_ON(!bfqg); ++ bfqd = bfqg->bfqd; ++ BUG_ON(bfqd && !bfqd->root_group); ++ ++ entity = bfqg->my_entity; ++ ++ if (!entity) /* root group */ ++ return; ++ ++ /* ++ * Empty all service_trees belonging to this group before ++ * deactivating the group itself. ++ */ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { ++ BUG_ON(!bfqg->sched_data.service_tree); ++ st = bfqg->sched_data.service_tree + i; ++ /* ++ * The idle tree may still contain bfq_queues belonging ++ * to exited task because they never migrated to a different ++ * cgroup from the one being destroyed now. No one else ++ * can access them so it's safe to act without any lock. ++ */ ++ bfq_flush_idle_tree(st); ++ ++ /* ++ * It may happen that some queues are still active ++ * (busy) upon group destruction (if the corresponding ++ * processes have been forced to terminate). We move ++ * all the leaf entities corresponding to these queues ++ * to the root_group. ++ * Also, it may happen that the group has an entity ++ * in service, which is disconnected from the active ++ * tree: it must be moved, too. ++ * There is no need to put the sync queues, as the ++ * scheduler has taken no reference. ++ */ ++ bfq_reparent_active_entities(bfqd, bfqg, st); ++ BUG_ON(!RB_EMPTY_ROOT(&st->active)); ++ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); ++ } ++ BUG_ON(bfqg->sched_data.next_in_service); ++ BUG_ON(bfqg->sched_data.in_service_entity); ++ ++ __bfq_deactivate_entity(entity, 0); ++ bfq_put_async_queues(bfqd, bfqg); ++ BUG_ON(entity->tree); ++ ++ /* ++ * @blkg is going offline and will be ignored by ++ * blkg_[rw]stat_recursive_sum(). Transfer stats to the parent so ++ * that they don't get lost. If IOs complete after this point, the ++ * stats for them will be lost. Oh well... ++ */ ++ bfqg_stats_xfer_dead(bfqg); ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ struct blkcg_gq *blkg; ++ ++ list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) { ++ struct bfq_group *bfqg = blkg_to_bfqg(blkg); ++ BUG_ON(!bfqg); ++ ++ bfq_end_wr_async_queues(bfqd, bfqg); ++ } ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static int bfq_io_show_weight(struct seq_file *sf, void *v) ++{ ++ struct blkcg *blkcg = css_to_blkcg(seq_css(sf)); ++ struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg); ++ unsigned int val = 0; ++ ++ if (bfqgd) ++ val = bfqgd->weight; ++ ++ seq_printf(sf, "%u\n", val); ++ ++ return 0; ++} ++ ++static int bfq_io_set_weight_legacy(struct cgroup_subsys_state *css, ++ struct cftype *cftype, ++ u64 val) ++{ ++ struct blkcg *blkcg = css_to_blkcg(css); ++ struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg); ++ struct blkcg_gq *blkg; ++ int ret = -ERANGE; ++ ++ if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT) ++ return ret; ++ ++ ret = 0; ++ spin_lock_irq(&blkcg->lock); ++ bfqgd->weight = (unsigned short)val; ++ hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) { ++ struct bfq_group *bfqg = blkg_to_bfqg(blkg); ++ ++ if (!bfqg) ++ continue; ++ /* ++ * Setting the prio_changed flag of the entity ++ * to 1 with new_weight == weight would re-set ++ * the value of the weight to its ioprio mapping. ++ * Set the flag only if necessary. ++ */ ++ if ((unsigned short)val != bfqg->entity.new_weight) { ++ bfqg->entity.new_weight = (unsigned short)val; ++ /* ++ * Make sure that the above new value has been ++ * stored in bfqg->entity.new_weight before ++ * setting the prio_changed flag. In fact, ++ * this flag may be read asynchronously (in ++ * critical sections protected by a different ++ * lock than that held here), and finding this ++ * flag set may cause the execution of the code ++ * for updating parameters whose value may ++ * depend also on bfqg->entity.new_weight (in ++ * __bfq_entity_update_weight_prio). ++ * This barrier makes sure that the new value ++ * of bfqg->entity.new_weight is correctly ++ * seen in that code. ++ */ ++ smp_wmb(); ++ bfqg->entity.prio_changed = 1; ++ } ++ } ++ spin_unlock_irq(&blkcg->lock); ++ ++ return ret; ++} ++ ++static ssize_t bfq_io_set_weight(struct kernfs_open_file *of, ++ char *buf, size_t nbytes, ++ loff_t off) ++{ ++ u64 weight; ++ /* First unsigned long found in the file is used */ ++ int ret = kstrtoull(strim(buf), 0, &weight); ++ ++ if (ret) ++ return ret; ++ ++ return bfq_io_set_weight_legacy(of_css(of), NULL, weight); ++} ++ ++static int bfqg_print_stat(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat, ++ &blkcg_policy_bfq, seq_cft(sf)->private, false); ++ return 0; ++} ++ ++static int bfqg_print_rwstat(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_rwstat, ++ &blkcg_policy_bfq, seq_cft(sf)->private, true); ++ return 0; ++} ++ ++static u64 bfqg_prfill_stat_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ u64 sum = blkg_stat_recursive_sum(pd_to_blkg(pd), ++ &blkcg_policy_bfq, off); ++ return __blkg_prfill_u64(sf, pd, sum); ++} ++ ++static u64 bfqg_prfill_rwstat_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct blkg_rwstat sum = blkg_rwstat_recursive_sum(pd_to_blkg(pd), ++ &blkcg_policy_bfq, ++ off); ++ return __blkg_prfill_rwstat(sf, pd, &sum); ++} ++ ++static int bfqg_print_stat_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_stat_recursive, &blkcg_policy_bfq, ++ seq_cft(sf)->private, false); ++ return 0; ++} ++ ++static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_rwstat_recursive, &blkcg_policy_bfq, ++ seq_cft(sf)->private, true); ++ return 0; ++} ++ ++static u64 bfqg_prfill_sectors(struct seq_file *sf, struct blkg_policy_data *pd, ++ int off) ++{ ++ u64 sum = blkg_rwstat_total(&pd->blkg->stat_bytes); ++ ++ return __blkg_prfill_u64(sf, pd, sum >> 9); ++} ++ ++static int bfqg_print_stat_sectors(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_sectors, &blkcg_policy_bfq, 0, false); ++ return 0; ++} ++ ++static u64 bfqg_prfill_sectors_recursive(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct blkg_rwstat tmp = blkg_rwstat_recursive_sum(pd->blkg, NULL, ++ offsetof(struct blkcg_gq, stat_bytes)); ++ u64 sum = atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_READ]) + ++ atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_WRITE]); ++ ++ return __blkg_prfill_u64(sf, pd, sum >> 9); ++} ++ ++static int bfqg_print_stat_sectors_recursive(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_sectors_recursive, &blkcg_policy_bfq, 0, ++ false); ++ return 0; ++} ++ ++ ++static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf, ++ struct blkg_policy_data *pd, int off) ++{ ++ struct bfq_group *bfqg = pd_to_bfqg(pd); ++ u64 samples = blkg_stat_read(&bfqg->stats.avg_queue_size_samples); ++ u64 v = 0; ++ ++ if (samples) { ++ v = blkg_stat_read(&bfqg->stats.avg_queue_size_sum); ++ v = div64_u64(v, samples); ++ } ++ __blkg_prfill_u64(sf, pd, v); ++ return 0; ++} ++ ++/* print avg_queue_size */ ++static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v) ++{ ++ blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), ++ bfqg_prfill_avg_queue_size, &blkcg_policy_bfq, ++ 0, false); ++ return 0; ++} ++ ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++{ ++ int ret; ++ ++ ret = blkcg_activate_policy(bfqd->queue, &blkcg_policy_bfq); ++ if (ret) ++ return NULL; ++ ++ return blkg_to_bfqg(bfqd->queue->root_blkg); ++} ++ ++static struct cftype bfq_blkcg_legacy_files[] = { ++ { ++ .name = "bfq.weight", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .seq_show = bfq_io_show_weight, ++ .write_u64 = bfq_io_set_weight_legacy, ++ }, ++ ++ /* statistics, covers only the tasks in the bfqg */ ++ { ++ .name = "bfq.time", ++ .private = offsetof(struct bfq_group, stats.time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.sectors", ++ .seq_show = bfqg_print_stat_sectors, ++ }, ++ { ++ .name = "bfq.io_service_bytes", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_bytes, ++ }, ++ { ++ .name = "bfq.io_serviced", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_ios, ++ }, ++ { ++ .name = "bfq.io_service_time", ++ .private = offsetof(struct bfq_group, stats.service_time), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_wait_time", ++ .private = offsetof(struct bfq_group, stats.wait_time), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_merged", ++ .private = offsetof(struct bfq_group, stats.merged), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ { ++ .name = "bfq.io_queued", ++ .private = offsetof(struct bfq_group, stats.queued), ++ .seq_show = bfqg_print_rwstat, ++ }, ++ ++ /* the same statictics which cover the bfqg and its descendants */ ++ { ++ .name = "bfq.time_recursive", ++ .private = offsetof(struct bfq_group, stats.time), ++ .seq_show = bfqg_print_stat_recursive, ++ }, ++ { ++ .name = "bfq.sectors_recursive", ++ .seq_show = bfqg_print_stat_sectors_recursive, ++ }, ++ { ++ .name = "bfq.io_service_bytes_recursive", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_bytes_recursive, ++ }, ++ { ++ .name = "bfq.io_serviced_recursive", ++ .private = (unsigned long)&blkcg_policy_bfq, ++ .seq_show = blkg_print_stat_ios_recursive, ++ }, ++ { ++ .name = "bfq.io_service_time_recursive", ++ .private = offsetof(struct bfq_group, stats.service_time), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_wait_time_recursive", ++ .private = offsetof(struct bfq_group, stats.wait_time), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_merged_recursive", ++ .private = offsetof(struct bfq_group, stats.merged), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.io_queued_recursive", ++ .private = offsetof(struct bfq_group, stats.queued), ++ .seq_show = bfqg_print_rwstat_recursive, ++ }, ++ { ++ .name = "bfq.avg_queue_size", ++ .seq_show = bfqg_print_avg_queue_size, ++ }, ++ { ++ .name = "bfq.group_wait_time", ++ .private = offsetof(struct bfq_group, stats.group_wait_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.idle_time", ++ .private = offsetof(struct bfq_group, stats.idle_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.empty_time", ++ .private = offsetof(struct bfq_group, stats.empty_time), ++ .seq_show = bfqg_print_stat, ++ }, ++ { ++ .name = "bfq.dequeue", ++ .private = offsetof(struct bfq_group, stats.dequeue), ++ .seq_show = bfqg_print_stat, ++ }, ++ { } /* terminate */ ++}; ++ ++static struct cftype bfq_blkg_files[] = { ++ { ++ .name = "bfq.weight", ++ .flags = CFTYPE_NOT_ON_ROOT, ++ .seq_show = bfq_io_show_weight, ++ .write = bfq_io_set_weight, ++ }, ++ {} /* terminate */ ++}; ++ ++#else /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++static inline void bfqg_stats_update_io_add(struct bfq_group *bfqg, ++ struct bfq_queue *bfqq, int op, int op_flags) { } ++static inline void ++bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, int op_flags) { } ++static inline void ++bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, int op_flags) { } ++static inline void bfqg_stats_update_completion(struct bfq_group *bfqg, ++ uint64_t start_time, uint64_t io_start_time, int op, ++ int op_flags) { } ++static inline void ++bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg, ++ struct bfq_group *curr_bfqg) { } ++static inline void bfqg_stats_end_empty_time(struct bfqg_stats *stats) { } ++static inline void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { } ++static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { } ++ ++static void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) { ++ bfqq->ioprio = bfqq->new_ioprio; ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ } ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static struct bfq_group * ++bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ return bfqd->root_group; ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, ++ struct blkcg *blkcg) ++{ ++ return bfqd->root_group; ++} ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq) ++{ ++ return bfqq->bfqd->root_group; ++} ++ ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ int i; ++ ++ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); ++ if (!bfqg) ++ return NULL; ++ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ return bfqg; ++} ++#endif +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq.h linux-4.8-bfq/block/bfq.h +--- linux-4.8/block/bfq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq.h 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,886 @@ ++/* ++ * BFQ-v8r4 for 4.8.0: data structures and common functions prototypes. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ */ ++ ++#ifndef _BFQ_H ++#define _BFQ_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BFQ_IOPRIO_CLASSES 3 ++#define BFQ_CL_IDLE_TIMEOUT (HZ/5) ++ ++#define BFQ_MIN_WEIGHT 1 ++#define BFQ_MAX_WEIGHT 1000 ++#define BFQ_WEIGHT_CONVERSION_COEFF 10 ++ ++#define BFQ_DEFAULT_QUEUE_IOPRIO 4 ++ ++#define BFQ_WEIGHT_LEGACY_DFL 100 ++#define BFQ_DEFAULT_GRP_IOPRIO 0 ++#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE ++ ++/* ++ * Soft real-time applications are extremely more latency sensitive ++ * than interactive ones. Over-raise the weight of the former to ++ * privilege them against the latter. ++ */ ++#define BFQ_SOFTRT_WEIGHT_FACTOR 100 ++ ++struct bfq_entity; ++ ++/** ++ * struct bfq_service_tree - per ioprio_class service tree. ++ * ++ * Each service tree represents a B-WF2Q+ scheduler on its own. Each ++ * ioprio_class has its own independent scheduler, and so its own ++ * bfq_service_tree. All the fields are protected by the queue lock ++ * of the containing bfqd. ++ */ ++struct bfq_service_tree { ++ /* tree for active entities (i.e., those backlogged) */ ++ struct rb_root active; ++ /* tree for idle entities (i.e., not backlogged, with V <= F_i)*/ ++ struct rb_root idle; ++ ++ struct bfq_entity *first_idle; /* idle entity with minimum F_i */ ++ struct bfq_entity *last_idle; /* idle entity with maximum F_i */ ++ ++ u64 vtime; /* scheduler virtual time */ ++ /* scheduler weight sum; active and idle entities contribute to it */ ++ unsigned long wsum; ++}; ++ ++/** ++ * struct bfq_sched_data - multi-class scheduler. ++ * ++ * bfq_sched_data is the basic scheduler queue. It supports three ++ * ioprio_classes, and can be used either as a toplevel queue or as an ++ * intermediate queue on a hierarchical setup. @next_in_service ++ * points to the active entity of the sched_data service trees that ++ * will be scheduled next. It is used to reduce the number of steps ++ * needed for each hierarchical-schedule update. ++ * ++ * The supported ioprio_classes are the same as in CFQ, in descending ++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. ++ * Requests from higher priority queues are served before all the ++ * requests from lower priority queues; among requests of the same ++ * queue requests are served according to B-WF2Q+. ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_sched_data { ++ struct bfq_entity *in_service_entity; /* entity in service */ ++ /* head-of-the-line entity in the scheduler (see comments above) */ ++ struct bfq_entity *next_in_service; ++ /* array of service trees, one per ioprio_class */ ++ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; ++}; ++ ++/** ++ * struct bfq_weight_counter - counter of the number of all active entities ++ * with a given weight. ++ */ ++struct bfq_weight_counter { ++ unsigned int weight; /* weight of the entities this counter refers to */ ++ unsigned int num_active; /* nr of active entities with this weight */ ++ /* ++ * Weights tree member (see bfq_data's @queue_weights_tree and ++ * @group_weights_tree) ++ */ ++ struct rb_node weights_node; ++}; ++ ++/** ++ * struct bfq_entity - schedulable entity. ++ * ++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the ++ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each ++ * entity belongs to the sched_data of the parent group in the cgroup ++ * hierarchy. Non-leaf entities have also their own sched_data, stored ++ * in @my_sched_data. ++ * ++ * Each entity stores independently its priority values; this would ++ * allow different weights on different devices, but this ++ * functionality is not exported to userspace by now. Priorities and ++ * weights are updated lazily, first storing the new values into the ++ * new_* fields, then setting the @prio_changed flag. As soon as ++ * there is a transition in the entity state that allows the priority ++ * update to take place the effective and the requested priority ++ * values are synchronized. ++ * ++ * Unless cgroups are used, the weight value is calculated from the ++ * ioprio to export the same interface as CFQ. When dealing with ++ * ``well-behaved'' queues (i.e., queues that do not spend too much ++ * time to consume their budget and have true sequential behavior, and ++ * when there are no external factors breaking anticipation) the ++ * relative weights at each level of the cgroups hierarchy should be ++ * guaranteed. All the fields are protected by the queue lock of the ++ * containing bfqd. ++ */ ++struct bfq_entity { ++ struct rb_node rb_node; /* service_tree member */ ++ /* pointer to the weight counter associated with this entity */ ++ struct bfq_weight_counter *weight_counter; ++ ++ /* ++ * flag, true if the entity is on a tree (either the active or ++ * the idle one of its service_tree). ++ */ ++ int on_st; ++ ++ u64 finish; /* B-WF2Q+ finish timestamp (aka F_i) */ ++ u64 start; /* B-WF2Q+ start timestamp (aka S_i) */ ++ ++ /* tree the entity is enqueued into; %NULL if not on a tree */ ++ struct rb_root *tree; ++ ++ /* ++ * minimum start time of the (active) subtree rooted at this ++ * entity; used for O(log N) lookups into active trees ++ */ ++ u64 min_start; ++ ++ /* amount of service received during the last service slot */ ++ int service; ++ ++ /* budget, used also to calculate F_i: F_i = S_i + @budget / @weight */ ++ int budget; ++ ++ unsigned int weight; /* weight of the queue */ ++ unsigned int new_weight; /* next weight if a change is in progress */ ++ ++ /* original weight, used to implement weight boosting */ ++ unsigned int orig_weight; ++ ++ /* parent entity, for hierarchical scheduling */ ++ struct bfq_entity *parent; ++ ++ /* ++ * For non-leaf nodes in the hierarchy, the associated ++ * scheduler queue, %NULL on leaf nodes. ++ */ ++ struct bfq_sched_data *my_sched_data; ++ /* the scheduler queue this entity belongs to */ ++ struct bfq_sched_data *sched_data; ++ ++ /* flag, set to request a weight, ioprio or ioprio_class change */ ++ int prio_changed; ++}; ++ ++struct bfq_group; ++ ++/** ++ * struct bfq_queue - leaf schedulable entity. ++ * ++ * A bfq_queue is a leaf request queue; it can be associated with an ++ * io_context or more, if it is async or shared between cooperating ++ * processes. @cgroup holds a reference to the cgroup, to be sure that it ++ * does not disappear while a bfqq still references it (mostly to avoid ++ * races between request issuing and task migration followed by cgroup ++ * destruction). ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_queue { ++ /* reference counter */ ++ int ref; ++ /* parent bfq_data */ ++ struct bfq_data *bfqd; ++ ++ /* current ioprio and ioprio class */ ++ unsigned short ioprio, ioprio_class; ++ /* next ioprio and ioprio class if a change is in progress */ ++ unsigned short new_ioprio, new_ioprio_class; ++ ++ /* ++ * Shared bfq_queue if queue is cooperating with one or more ++ * other queues. ++ */ ++ struct bfq_queue *new_bfqq; ++ /* request-position tree member (see bfq_group's @rq_pos_tree) */ ++ struct rb_node pos_node; ++ /* request-position tree root (see bfq_group's @rq_pos_tree) */ ++ struct rb_root *pos_root; ++ ++ /* sorted list of pending requests */ ++ struct rb_root sort_list; ++ /* if fifo isn't expired, next request to serve */ ++ struct request *next_rq; ++ /* number of sync and async requests queued */ ++ int queued[2]; ++ /* number of sync and async requests currently allocated */ ++ int allocated[2]; ++ /* number of pending metadata requests */ ++ int meta_pending; ++ /* fifo list of requests in sort_list */ ++ struct list_head fifo; ++ ++ /* entity representing this queue in the scheduler */ ++ struct bfq_entity entity; ++ ++ /* maximum budget allowed from the feedback mechanism */ ++ int max_budget; ++ /* budget expiration (in jiffies) */ ++ unsigned long budget_timeout; ++ ++ /* number of requests on the dispatch list or inside driver */ ++ int dispatched; ++ ++ unsigned int flags; /* status flags.*/ ++ ++ /* node for active/idle bfqq list inside parent bfqd */ ++ struct list_head bfqq_list; ++ ++ /* bit vector: a 1 for each seeky requests in history */ ++ u32 seek_history; ++ ++ /* node for the device's burst list */ ++ struct hlist_node burst_list_node; ++ ++ /* position of the last request enqueued */ ++ sector_t last_request_pos; ++ ++ /* Number of consecutive pairs of request completion and ++ * arrival, such that the queue becomes idle after the ++ * completion, but the next request arrives within an idle ++ * time slice; used only if the queue's IO_bound flag has been ++ * cleared. ++ */ ++ unsigned int requests_within_timer; ++ ++ /* pid of the process owning the queue, used for logging purposes */ ++ pid_t pid; ++ ++ /* ++ * Pointer to the bfq_io_cq owning the bfq_queue, set to %NULL ++ * if the queue is shared. ++ */ ++ struct bfq_io_cq *bic; ++ ++ /* current maximum weight-raising time for this queue */ ++ unsigned long wr_cur_max_time; ++ /* ++ * Minimum time instant such that, only if a new request is ++ * enqueued after this time instant in an idle @bfq_queue with ++ * no outstanding requests, then the task associated with the ++ * queue it is deemed as soft real-time (see the comments on ++ * the function bfq_bfqq_softrt_next_start()) ++ */ ++ unsigned long soft_rt_next_start; ++ /* ++ * Start time of the current weight-raising period if ++ * the @bfq-queue is being weight-raised, otherwise ++ * finish time of the last weight-raising period. ++ */ ++ unsigned long last_wr_start_finish; ++ /* factor by which the weight of this queue is multiplied */ ++ unsigned int wr_coeff; ++ /* ++ * Time of the last transition of the @bfq_queue from idle to ++ * backlogged. ++ */ ++ unsigned long last_idle_bklogged; ++ /* ++ * Cumulative service received from the @bfq_queue since the ++ * last transition from idle to backlogged. ++ */ ++ unsigned long service_from_backlogged; ++ /* ++ * Value of wr start time when switching to soft rt ++ */ ++ unsigned long wr_start_at_switch_to_srt; ++ ++ unsigned long split_time; /* time of last split */ ++}; ++ ++/** ++ * struct bfq_ttime - per process thinktime stats. ++ */ ++struct bfq_ttime { ++ u64 last_end_request; /* completion time of last request */ ++ ++ u64 ttime_total; /* total process thinktime */ ++ unsigned long ttime_samples; /* number of thinktime samples */ ++ u64 ttime_mean; /* average process thinktime */ ++ ++}; ++ ++/** ++ * struct bfq_io_cq - per (request_queue, io_context) structure. ++ */ ++struct bfq_io_cq { ++ /* associated io_cq structure */ ++ struct io_cq icq; /* must be the first member */ ++ /* array of two process queues, the sync and the async */ ++ struct bfq_queue *bfqq[2]; ++ /* associated @bfq_ttime struct */ ++ struct bfq_ttime ttime; ++ /* per (request_queue, blkcg) ioprio */ ++ int ioprio; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ uint64_t blkcg_serial_nr; /* the current blkcg serial */ ++#endif ++ ++ /* ++ * Snapshot of the idle window before merging; taken to ++ * remember this value while the queue is merged, so as to be ++ * able to restore it in case of split. ++ */ ++ bool saved_idle_window; ++ /* ++ * Same purpose as the previous two fields for the I/O bound ++ * classification of a queue. ++ */ ++ bool saved_IO_bound; ++ ++ /* ++ * Same purpose as the previous fields for the value of the ++ * field keeping the queue's belonging to a large burst ++ */ ++ bool saved_in_large_burst; ++ /* ++ * True if the queue belonged to a burst list before its merge ++ * with another cooperating queue. ++ */ ++ bool was_in_burst_list; ++ ++ /* ++ * Similar to previous fields: save wr information. ++ */ ++ unsigned long saved_wr_coeff; ++ unsigned long saved_last_wr_start_finish; ++ unsigned long saved_wr_start_at_switch_to_srt; ++}; ++ ++enum bfq_device_speed { ++ BFQ_BFQD_FAST, ++ BFQ_BFQD_SLOW, ++}; ++ ++/** ++ * struct bfq_data - per-device data structure. ++ * ++ * All the fields are protected by the @queue lock. ++ */ ++struct bfq_data { ++ /* request queue for the device */ ++ struct request_queue *queue; ++ ++ /* root bfq_group for the device */ ++ struct bfq_group *root_group; ++ ++ /* ++ * rbtree of weight counters of @bfq_queues, sorted by ++ * weight. Used to keep track of whether all @bfq_queues have ++ * the same weight. The tree contains one counter for each ++ * distinct weight associated to some active and not ++ * weight-raised @bfq_queue (see the comments to the functions ++ * bfq_weights_tree_[add|remove] for further details). ++ */ ++ struct rb_root queue_weights_tree; ++ /* ++ * rbtree of non-queue @bfq_entity weight counters, sorted by ++ * weight. Used to keep track of whether all @bfq_groups have ++ * the same weight. The tree contains one counter for each ++ * distinct weight associated to some active @bfq_group (see ++ * the comments to the functions bfq_weights_tree_[add|remove] ++ * for further details). ++ */ ++ struct rb_root group_weights_tree; ++ ++ /* ++ * Number of bfq_queues containing requests (including the ++ * queue in service, even if it is idling). ++ */ ++ int busy_queues; ++ /* number of weight-raised busy @bfq_queues */ ++ int wr_busy_queues; ++ /* number of queued requests */ ++ int queued; ++ /* number of requests dispatched and waiting for completion */ ++ int rq_in_driver; ++ ++ /* ++ * Maximum number of requests in driver in the last ++ * @hw_tag_samples completed requests. ++ */ ++ int max_rq_in_driver; ++ /* number of samples used to calculate hw_tag */ ++ int hw_tag_samples; ++ /* flag set to one if the driver is showing a queueing behavior */ ++ int hw_tag; ++ ++ /* number of budgets assigned */ ++ int budgets_assigned; ++ ++ /* ++ * Timer set when idling (waiting) for the next request from ++ * the queue in service. ++ */ ++ struct hrtimer idle_slice_timer; ++ /* delayed work to restart dispatching on the request queue */ ++ struct work_struct unplug_work; ++ ++ /* bfq_queue in service */ ++ struct bfq_queue *in_service_queue; ++ /* bfq_io_cq (bic) associated with the @in_service_queue */ ++ struct bfq_io_cq *in_service_bic; ++ ++ /* on-disk position of the last served request */ ++ sector_t last_position; ++ ++ /* time of last request completion (ns) */ ++ u64 last_completion; ++ ++ /* time of first rq dispatch in current observation interval (ns) */ ++ u64 first_dispatch; ++ /* time of last rq dispatch in current observation interval (ns) */ ++ u64 last_dispatch; ++ ++ /* beginning of the last budget */ ++ ktime_t last_budget_start; ++ /* beginning of the last idle slice */ ++ ktime_t last_idling_start; ++ ++ /* number of samples in current observation interval */ ++ int peak_rate_samples; ++ /* num of samples of seq dispatches in current observation interval */ ++ u32 sequential_samples; ++ /* total num of sectors transferred in current observation interval */ ++ u64 tot_sectors_dispatched; ++ /* max rq size seen during current observation interval (sectors) */ ++ u32 last_rq_max_size; ++ /* time elapsed from first dispatch in current observ. interval (us) */ ++ u64 delta_from_first; ++ /* current estimate of device peak rate */ ++ u32 peak_rate; ++ ++ /* maximum budget allotted to a bfq_queue before rescheduling */ ++ int bfq_max_budget; ++ ++ /* list of all the bfq_queues active on the device */ ++ struct list_head active_list; ++ /* list of all the bfq_queues idle on the device */ ++ struct list_head idle_list; ++ ++ /* ++ * Timeout for async/sync requests; when it fires, requests ++ * are served in fifo order. ++ */ ++ u64 bfq_fifo_expire[2]; ++ /* weight of backward seeks wrt forward ones */ ++ unsigned int bfq_back_penalty; ++ /* maximum allowed backward seek */ ++ unsigned int bfq_back_max; ++ /* maximum idling time */ ++ u32 bfq_slice_idle; ++ /* last time CLASS_IDLE was served */ ++ u64 bfq_class_idle_last_service; ++ ++ /* user-configured max budget value (0 for auto-tuning) */ ++ int bfq_user_max_budget; ++ /* ++ * Timeout for bfq_queues to consume their budget; used to ++ * prevent seeky queues from imposing long latencies to ++ * sequential or quasi-sequential ones (this also implies that ++ * seeky queues cannot receive guarantees in the service ++ * domain; after a timeout they are charged for the time they ++ * have been in service, to preserve fairness among them, but ++ * without service-domain guarantees). ++ */ ++ unsigned int bfq_timeout; ++ ++ /* ++ * Number of consecutive requests that must be issued within ++ * the idle time slice to set again idling to a queue which ++ * was marked as non-I/O-bound (see the definition of the ++ * IO_bound flag for further details). ++ */ ++ unsigned int bfq_requests_within_timer; ++ ++ /* ++ * Force device idling whenever needed to provide accurate ++ * service guarantees, without caring about throughput ++ * issues. CAVEAT: this may even increase latencies, in case ++ * of useless idling for processes that did stop doing I/O. ++ */ ++ bool strict_guarantees; ++ ++ /* ++ * Last time at which a queue entered the current burst of ++ * queues being activated shortly after each other; for more ++ * details about this and the following parameters related to ++ * a burst of activations, see the comments on the function ++ * bfq_handle_burst. ++ */ ++ unsigned long last_ins_in_burst; ++ /* ++ * Reference time interval used to decide whether a queue has ++ * been activated shortly after @last_ins_in_burst. ++ */ ++ unsigned long bfq_burst_interval; ++ /* number of queues in the current burst of queue activations */ ++ int burst_size; ++ ++ /* common parent entity for the queues in the burst */ ++ struct bfq_entity *burst_parent_entity; ++ /* Maximum burst size above which the current queue-activation ++ * burst is deemed as 'large'. ++ */ ++ unsigned long bfq_large_burst_thresh; ++ /* true if a large queue-activation burst is in progress */ ++ bool large_burst; ++ /* ++ * Head of the burst list (as for the above fields, more ++ * details in the comments on the function bfq_handle_burst). ++ */ ++ struct hlist_head burst_list; ++ ++ /* if set to true, low-latency heuristics are enabled */ ++ bool low_latency; ++ /* ++ * Maximum factor by which the weight of a weight-raised queue ++ * is multiplied. ++ */ ++ unsigned int bfq_wr_coeff; ++ /* maximum duration of a weight-raising period (jiffies) */ ++ unsigned int bfq_wr_max_time; ++ ++ /* Maximum weight-raising duration for soft real-time processes */ ++ unsigned int bfq_wr_rt_max_time; ++ /* ++ * Minimum idle period after which weight-raising may be ++ * reactivated for a queue (in jiffies). ++ */ ++ unsigned int bfq_wr_min_idle_time; ++ /* ++ * Minimum period between request arrivals after which ++ * weight-raising may be reactivated for an already busy async ++ * queue (in jiffies). ++ */ ++ unsigned long bfq_wr_min_inter_arr_async; ++ ++ /* Max service-rate for a soft real-time queue, in sectors/sec */ ++ unsigned int bfq_wr_max_softrt_rate; ++ /* ++ * Cached value of the product R*T, used for computing the ++ * maximum duration of weight raising automatically. ++ */ ++ u64 RT_prod; ++ /* device-speed class for the low-latency heuristic */ ++ enum bfq_device_speed device_speed; ++ ++ /* fallback dummy bfqq for extreme OOM conditions */ ++ struct bfq_queue oom_bfqq; ++}; ++ ++enum bfqq_state_flags { ++ BFQ_BFQQ_FLAG_just_created = 0, /* queue just allocated */ ++ BFQ_BFQQ_FLAG_busy, /* has requests or is in service */ ++ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ ++ BFQ_BFQQ_FLAG_non_blocking_wait_rq, /* ++ * waiting for a request ++ * without idling the device ++ */ ++ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ ++ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ ++ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ ++ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ ++ BFQ_BFQQ_FLAG_IO_bound, /* ++ * bfqq has timed-out at least once ++ * having consumed at most 2/10 of ++ * its budget ++ */ ++ BFQ_BFQQ_FLAG_in_large_burst, /* ++ * bfqq activated in a large burst, ++ * see comments to bfq_handle_burst. ++ */ ++ BFQ_BFQQ_FLAG_softrt_update, /* ++ * may need softrt-next-start ++ * update ++ */ ++ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ ++ BFQ_BFQQ_FLAG_split_coop /* shared bfqq will be split */ ++}; ++ ++#define BFQ_BFQQ_FNS(name) \ ++static void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ ++{ \ ++ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ ++} ++ ++BFQ_BFQQ_FNS(just_created); ++BFQ_BFQQ_FNS(busy); ++BFQ_BFQQ_FNS(wait_request); ++BFQ_BFQQ_FNS(non_blocking_wait_rq); ++BFQ_BFQQ_FNS(must_alloc); ++BFQ_BFQQ_FNS(fifo_expire); ++BFQ_BFQQ_FNS(idle_window); ++BFQ_BFQQ_FNS(sync); ++BFQ_BFQQ_FNS(IO_bound); ++BFQ_BFQQ_FNS(in_large_burst); ++BFQ_BFQQ_FNS(coop); ++BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(softrt_update); ++#undef BFQ_BFQQ_FNS ++ ++/* Logging facilities. */ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); ++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); ++ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \ ++ char __pbuf[128]; \ ++ \ ++ assert_spin_locked((bfqd)->queue->queue_lock); \ ++ blkg_path(bfqg_to_blkg(bfqq_group(bfqq)), __pbuf, sizeof(__pbuf)); \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, \ ++ (bfqq)->pid, \ ++ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ ++ __pbuf, ##args); \ ++} while (0) ++ ++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \ ++ char __pbuf[128]; \ ++ \ ++ blkg_path(bfqg_to_blkg(bfqg), __pbuf, sizeof(__pbuf)); \ ++ blk_add_trace_msg((bfqd)->queue, "%s " fmt, __pbuf, ##args); \ ++} while (0) ++ ++#else /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d%c " fmt, (bfqq)->pid, \ ++ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ ++ ##args) ++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do {} while (0) ++ ++#endif /* CONFIG_BFQ_GROUP_IOSCHED */ ++ ++#define bfq_log(bfqd, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) ++ ++/* Expiration reasons. */ ++enum bfqq_expiration { ++ BFQ_BFQQ_TOO_IDLE = 0, /* ++ * queue has been idling for ++ * too long ++ */ ++ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ ++ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ ++ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ ++ BFQ_BFQQ_PREEMPTED /* preemption in progress */ ++}; ++ ++ ++struct bfqg_stats { ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ /* number of ios merged */ ++ struct blkg_rwstat merged; ++ /* total time spent on device in ns, may not be accurate w/ queueing */ ++ struct blkg_rwstat service_time; ++ /* total time spent waiting in scheduler queue in ns */ ++ struct blkg_rwstat wait_time; ++ /* number of IOs queued up */ ++ struct blkg_rwstat queued; ++ /* total disk time and nr sectors dispatched by this group */ ++ struct blkg_stat time; ++ /* sum of number of ios queued across all samples */ ++ struct blkg_stat avg_queue_size_sum; ++ /* count of samples taken for average */ ++ struct blkg_stat avg_queue_size_samples; ++ /* how many times this group has been removed from service tree */ ++ struct blkg_stat dequeue; ++ /* total time spent waiting for it to be assigned a timeslice. */ ++ struct blkg_stat group_wait_time; ++ /* time spent idling for this blkcg_gq */ ++ struct blkg_stat idle_time; ++ /* total time with empty current active q with other requests queued */ ++ struct blkg_stat empty_time; ++ /* fields after this shouldn't be cleared on stat reset */ ++ uint64_t start_group_wait_time; ++ uint64_t start_idle_time; ++ uint64_t start_empty_time; ++ uint16_t flags; ++#endif ++}; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++/* ++ * struct bfq_group_data - per-blkcg storage for the blkio subsystem. ++ * ++ * @ps: @blkcg_policy_storage that this structure inherits ++ * @weight: weight of the bfq_group ++ */ ++struct bfq_group_data { ++ /* must be the first member */ ++ struct blkcg_policy_data pd; ++ ++ unsigned int weight; ++}; ++ ++/** ++ * struct bfq_group - per (device, cgroup) data structure. ++ * @entity: schedulable entity to insert into the parent group sched_data. ++ * @sched_data: own sched_data, to contain child entities (they may be ++ * both bfq_queues and bfq_groups). ++ * @bfqd: the bfq_data for the device this group acts upon. ++ * @async_bfqq: array of async queues for all the tasks belonging to ++ * the group, one queue per ioprio value per ioprio_class, ++ * except for the idle class that has only one queue. ++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). ++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used ++ * to avoid too many special cases during group creation/ ++ * migration. ++ * @active_entities: number of active entities belonging to the group; ++ * unused for the root group. Used to know whether there ++ * are groups with more than one active @bfq_entity ++ * (see the comments to the function ++ * bfq_bfqq_may_idle()). ++ * @rq_pos_tree: rbtree sorted by next_request position, used when ++ * determining if two or more queues have interleaving ++ * requests (see bfq_find_close_cooperator()). ++ * ++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup ++ * there is a set of bfq_groups, each one collecting the lower-level ++ * entities belonging to the group that are acting on the same device. ++ * ++ * Locking works as follows: ++ * o @bfqd is protected by the queue lock, RCU is used to access it ++ * from the readers. ++ * o All the other fields are protected by the @bfqd queue lock. ++ */ ++struct bfq_group { ++ /* must be the first member */ ++ struct blkg_policy_data pd; ++ ++ struct bfq_entity entity; ++ struct bfq_sched_data sched_data; ++ ++ void *bfqd; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct bfq_entity *my_entity; ++ ++ int active_entities; ++ ++ struct rb_root rq_pos_tree; ++ ++ struct bfqg_stats stats; ++}; ++ ++#else ++struct bfq_group { ++ struct bfq_sched_data sched_data; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct rb_root rq_pos_tree; ++}; ++#endif ++ ++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity); ++ ++static struct bfq_service_tree * ++bfq_entity_service_tree(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sched_data = entity->sched_data; ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned int idx = bfqq ? bfqq->ioprio_class - 1 : ++ BFQ_DEFAULT_GRP_CLASS - 1; ++ ++ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); ++ BUG_ON(sched_data == NULL); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "entity_service_tree %p %d", ++ sched_data->service_tree + idx, idx); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "entity_service_tree %p %d", ++ sched_data->service_tree + idx, idx); ++ } ++#endif ++ return sched_data->service_tree + idx; ++} ++ ++static struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, bool is_sync) ++{ ++ return bic->bfqq[is_sync]; ++} ++ ++static void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, ++ bool is_sync) ++{ ++ bic->bfqq[is_sync] = bfqq; ++} ++ ++static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) ++{ ++ return bic->icq.q->elevator->elevator_data; ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *group_entity = bfqq->entity.parent; ++ ++ if (!group_entity) ++ group_entity = &bfqq->bfqd->root_group->entity; ++ ++ return container_of(group_entity, struct bfq_group, entity); ++} ++ ++#else ++ ++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq) ++{ ++ return bfqq->bfqd->root_group; ++} ++ ++#endif ++ ++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio); ++static void bfq_put_queue(struct bfq_queue *bfqq); ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bio *bio, bool is_sync, ++ struct bfq_io_cq *bic); ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++#endif ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++ ++#endif /* _BFQ_H */ +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-ioc.c linux-4.8-bfq/block/bfq-ioc.c +--- linux-4.8/block/bfq-ioc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-ioc.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * BFQ: I/O context handling. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++/** ++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. ++ * @icq: the iocontext queue. ++ */ ++static struct bfq_io_cq *icq_to_bic(struct io_cq *icq) ++{ ++ /* bic->icq is the first member, %NULL will convert to %NULL */ ++ return container_of(icq, struct bfq_io_cq, icq); ++} ++ ++/** ++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. ++ * @bfqd: the lookup key. ++ * @ioc: the io_context of the process doing I/O. ++ * ++ * Queue lock must be held. ++ */ ++static struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, ++ struct io_context *ioc) ++{ ++ if (ioc) ++ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); ++ return NULL; ++} +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-iosched.c linux-4.8-bfq/block/bfq-iosched.c +--- linux-4.8/block/bfq-iosched.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-iosched.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,5288 @@ ++/* ++ * Budget Fair Queueing (BFQ) disk scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ * ++ * BFQ is a proportional-share storage-I/O scheduling algorithm based ++ * on the slice-by-slice service scheme of CFQ. But BFQ assigns ++ * budgets, measured in number of sectors, to processes instead of ++ * time slices. The device is not granted to the in-service process ++ * for a given time slice, but until it has exhausted its assigned ++ * budget. This change from the time to the service domain enables BFQ ++ * to distribute the device throughput among processes as desired, ++ * without any distortion due to throughput fluctuations, or to device ++ * internal queueing. BFQ uses an ad hoc internal scheduler, called ++ * B-WF2Q+, to schedule processes according to their budgets. More ++ * precisely, BFQ schedules queues associated with processes. Thanks to ++ * the accurate policy of B-WF2Q+, BFQ can afford to assign high ++ * budgets to I/O-bound processes issuing sequential requests (to ++ * boost the throughput), and yet guarantee a low latency to ++ * interactive and soft real-time applications. ++ * ++ * BFQ is described in [1], where also a reference to the initial, more ++ * theoretical paper on BFQ can be found. The interested reader can find ++ * in the latter paper full details on the main algorithm, as well as ++ * formulas of the guarantees and formal proofs of all the properties. ++ * With respect to the version of BFQ presented in these papers, this ++ * implementation adds a few more heuristics, such as the one that ++ * guarantees a low latency to soft real-time applications, and a ++ * hierarchical extension based on H-WF2Q+. ++ * ++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with ++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) ++ * complexity derives from the one introduced with EEVDF in [3]. ++ * ++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness ++ * with the BFQ Disk I/O Scheduler'', ++ * Proceedings of the 5th Annual International Systems and Storage ++ * Conference (SYSTOR '12), June 2012. ++ * ++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf ++ * ++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing ++ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, ++ * Oct 1997. ++ * ++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz ++ * ++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline ++ * First: A Flexible and Accurate Mechanism for Proportional Share ++ * Resource Allocation,'' technical report. ++ * ++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfq.h" ++#include "blk.h" ++ ++/* Expiration time of sync (0) and async (1) requests, in ns. */ ++static const u64 bfq_fifo_expire[2] = { NSEC_PER_SEC / 4, NSEC_PER_SEC / 8 }; ++ ++/* Maximum backwards seek, in KiB. */ ++static const int bfq_back_max = 16 * 1024; ++ ++/* Penalty of a backwards seek, in number of sectors. */ ++static const int bfq_back_penalty = 2; ++ ++/* Idling period duration, in ns. */ ++static u32 bfq_slice_idle = NSEC_PER_SEC / 125; ++ ++/* Minimum number of assigned budgets for which stats are safe to compute. */ ++static const int bfq_stats_min_budgets = 194; ++ ++/* Default maximum budget values, in sectors and number of requests. */ ++static const int bfq_default_max_budget = 16 * 1024; ++ ++/* ++ * Async to sync throughput distribution is controlled as follows: ++ * when an async request is served, the entity is charged the number ++ * of sectors of the request, multiplied by the factor below ++ */ ++static const int bfq_async_charge_factor = 10; ++ ++/* Default timeout values, in jiffies, approximating CFQ defaults. */ ++static const int bfq_timeout = HZ / 8; ++ ++struct kmem_cache *bfq_pool; ++ ++/* Below this threshold (in ns), we consider thinktime immediate. */ ++#define BFQ_MIN_TT (2 * NSEC_PER_MSEC) ++ ++/* hw_tag detection: parallel requests threshold and min samples needed. */ ++#define BFQ_HW_QUEUE_THRESHOLD 4 ++#define BFQ_HW_QUEUE_SAMPLES 32 ++ ++#define BFQQ_SEEK_THR (sector_t)(8 * 100) ++#define BFQQ_CLOSE_THR (sector_t)(8 * 1024) ++#define BFQQ_SEEKY(bfqq) (hweight32(bfqq->seek_history) > 32/8) ++ ++/* Min number of samples required to perform peak-rate update */ ++#define BFQ_RATE_MIN_SAMPLES 32 ++/* Min observation time interval required to perform a peak-rate update (ns) */ ++#define BFQ_RATE_MIN_INTERVAL 300*NSEC_PER_MSEC ++/* Target observation time interval for a peak-rate update (ns) */ ++#define BFQ_RATE_REF_INTERVAL NSEC_PER_SEC ++ ++/* Shift used for peak rate fixed precision calculations. */ ++#define BFQ_RATE_SHIFT 16 ++ ++/* ++ * By default, BFQ computes the duration of the weight raising for ++ * interactive applications automatically, using the following formula: ++ * duration = (R / r) * T, where r is the peak rate of the device, and ++ * R and T are two reference parameters. ++ * In particular, R is the peak rate of the reference device (see below), ++ * and T is a reference time: given the systems that are likely to be ++ * installed on the reference device according to its speed class, T is ++ * about the maximum time needed, under BFQ and while reading two files in ++ * parallel, to load typical large applications on these systems. ++ * In practice, the slower/faster the device at hand is, the more/less it ++ * takes to load applications with respect to the reference device. ++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive ++ * applications. ++ * ++ * BFQ uses four different reference pairs (R, T), depending on: ++ * . whether the device is rotational or non-rotational; ++ * . whether the device is slow, such as old or portable HDDs, as well as ++ * SD cards, or fast, such as newer HDDs and SSDs. ++ * ++ * The device's speed class is dynamically (re)detected in ++ * bfq_update_peak_rate() every time the estimated peak rate is updated. ++ * ++ * In the following definitions, R_slow[0]/R_fast[0] and ++ * T_slow[0]/T_fast[0] are the reference values for a slow/fast ++ * rotational device, whereas R_slow[1]/R_fast[1] and ++ * T_slow[1]/T_fast[1] are the reference values for a slow/fast ++ * non-rotational device. Finally, device_speed_thresh are the ++ * thresholds used to switch between speed classes. The reference ++ * rates are not the actual peak rates of the devices used as a ++ * reference, but slightly lower values. The reason for using these ++ * slightly lower values is that the peak-rate estimator tends to ++ * yield slightly lower values than the actual peak rate (it can yield ++ * the actual peak rate only if there is only one process doing I/O, ++ * and the process does sequential I/O). ++ * ++ * Both the reference peak rates and the thresholds are measured in ++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. ++ */ ++static int R_slow[2] = {1000, 10700}; ++static int R_fast[2] = {14000, 33000}; ++/* ++ * To improve readability, a conversion function is used to initialize the ++ * following arrays, which entails that they can be initialized only in a ++ * function. ++ */ ++static int T_slow[2]; ++static int T_fast[2]; ++static int device_speed_thresh[2]; ++ ++#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ ++ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) ++ ++#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) ++#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) ++ ++static void bfq_schedule_dispatch(struct bfq_data *bfqd); ++ ++#include "bfq-ioc.c" ++#include "bfq-sched.c" ++#include "bfq-cgroup.c" ++ ++#define bfq_class_idle(bfqq) ((bfqq)->ioprio_class == IOPRIO_CLASS_IDLE) ++#define bfq_class_rt(bfqq) ((bfqq)->ioprio_class == IOPRIO_CLASS_RT) ++ ++#define bfq_sample_valid(samples) ((samples) > 80) ++ ++/* ++ * We regard a request as SYNC, if either it's a read or has the SYNC bit ++ * set (in which case it could also be a direct WRITE). ++ */ ++static int bfq_bio_sync(struct bio *bio) ++{ ++ return bio_data_dir(bio) == READ || (bio->bi_opf & REQ_SYNC); ++} ++ ++/* ++ * Scheduler run of queue, if there are requests pending and no one in the ++ * driver that will restart queueing. ++ */ ++static void bfq_schedule_dispatch(struct bfq_data *bfqd) ++{ ++ if (bfqd->queued != 0) { ++ bfq_log(bfqd, "schedule dispatch"); ++ kblockd_schedule_work(&bfqd->unplug_work); ++ } ++} ++ ++/* ++ * Lifted from AS - choose which of rq1 and rq2 that is best served now. ++ * We choose the request that is closesr to the head right now. Distance ++ * behind the head is penalized and only allowed to a certain extent. ++ */ ++static struct request *bfq_choose_req(struct bfq_data *bfqd, ++ struct request *rq1, ++ struct request *rq2, ++ sector_t last) ++{ ++ sector_t s1, s2, d1 = 0, d2 = 0; ++ unsigned long back_max; ++#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ ++#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ ++ unsigned int wrap = 0; /* bit mask: requests behind the disk head? */ ++ ++ if (!rq1 || rq1 == rq2) ++ return rq2; ++ if (!rq2) ++ return rq1; ++ ++ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) ++ return rq1; ++ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) ++ return rq2; ++ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) ++ return rq1; ++ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) ++ return rq2; ++ ++ s1 = blk_rq_pos(rq1); ++ s2 = blk_rq_pos(rq2); ++ ++ /* ++ * By definition, 1KiB is 2 sectors. ++ */ ++ back_max = bfqd->bfq_back_max * 2; ++ ++ /* ++ * Strict one way elevator _except_ in the case where we allow ++ * short backward seeks which are biased as twice the cost of a ++ * similar forward seek. ++ */ ++ if (s1 >= last) ++ d1 = s1 - last; ++ else if (s1 + back_max >= last) ++ d1 = (last - s1) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ1_WRAP; ++ ++ if (s2 >= last) ++ d2 = s2 - last; ++ else if (s2 + back_max >= last) ++ d2 = (last - s2) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ2_WRAP; ++ ++ /* Found required data */ ++ ++ /* ++ * By doing switch() on the bit mask "wrap" we avoid having to ++ * check two variables for all permutations: --> faster! ++ */ ++ switch (wrap) { ++ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ ++ if (d1 < d2) ++ return rq1; ++ else if (d2 < d1) ++ return rq2; ++ ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; ++ ++ case BFQ_RQ2_WRAP: ++ return rq1; ++ case BFQ_RQ1_WRAP: ++ return rq2; ++ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ ++ default: ++ /* ++ * Since both rqs are wrapped, ++ * start with the one that's further behind head ++ * (--> only *one* back seek required), ++ * since back seek takes more time than forward. ++ */ ++ if (s1 <= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++} ++ ++static struct bfq_queue * ++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, ++ sector_t sector, struct rb_node **ret_parent, ++ struct rb_node ***rb_link) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *bfqq = NULL; ++ ++ parent = NULL; ++ p = &root->rb_node; ++ while (*p) { ++ struct rb_node **n; ++ ++ parent = *p; ++ bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ ++ /* ++ * Sort strictly based on sector. Smallest to the left, ++ * largest to the right. ++ */ ++ if (sector > blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_right; ++ else if (sector < blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_left; ++ else ++ break; ++ p = n; ++ bfqq = NULL; ++ } ++ ++ *ret_parent = parent; ++ if (rb_link) ++ *rb_link = p; ++ ++ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", ++ (unsigned long long) sector, ++ bfqq ? bfqq->pid : 0); ++ ++ return bfqq; ++} ++ ++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *__bfqq; ++ ++ if (bfqq->pos_root) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ ++ if (bfq_class_idle(bfqq)) ++ return; ++ if (!bfqq->next_rq) ++ return; ++ ++ bfqq->pos_root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree; ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, ++ blk_rq_pos(bfqq->next_rq), &parent, &p); ++ if (!__bfqq) { ++ rb_link_node(&bfqq->pos_node, parent, p); ++ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); ++ } else ++ bfqq->pos_root = NULL; ++} ++ ++/* ++ * Tell whether there are active queues or groups with differentiated weights. ++ */ ++static bool bfq_differentiated_weights(struct bfq_data *bfqd) ++{ ++ /* ++ * For weights to differ, at least one of the trees must contain ++ * at least two nodes. ++ */ ++ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && ++ (bfqd->queue_weights_tree.rb_node->rb_left || ++ bfqd->queue_weights_tree.rb_node->rb_right) ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ) || ++ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && ++ (bfqd->group_weights_tree.rb_node->rb_left || ++ bfqd->group_weights_tree.rb_node->rb_right) ++#endif ++ ); ++} ++ ++/* ++ * The following function returns true if every queue must receive the ++ * same share of the throughput (this condition is used when deciding ++ * whether idling may be disabled, see the comments in the function ++ * bfq_bfqq_may_idle()). ++ * ++ * Such a scenario occurs when: ++ * 1) all active queues have the same weight, ++ * 2) all active groups at the same level in the groups tree have the same ++ * weight, ++ * 3) all active groups at the same level in the groups tree have the same ++ * number of children. ++ * ++ * Unfortunately, keeping the necessary state for evaluating exactly the ++ * above symmetry conditions would be quite complex and time-consuming. ++ * Therefore this function evaluates, instead, the following stronger ++ * sub-conditions, for which it is much easier to maintain the needed ++ * state: ++ * 1) all active queues have the same weight, ++ * 2) all active groups have the same weight, ++ * 3) all active groups have at most one active child each. ++ * In particular, the last two conditions are always true if hierarchical ++ * support and the cgroups interface are not enabled, thus no state needs ++ * to be maintained in this case. ++ */ ++static bool bfq_symmetric_scenario(struct bfq_data *bfqd) ++{ ++ return !bfq_differentiated_weights(bfqd); ++} ++ ++/* ++ * If the weight-counter tree passed as input contains no counter for ++ * the weight of the input entity, then add that counter; otherwise just ++ * increment the existing counter. ++ * ++ * Note that weight-counter trees contain few nodes in mostly symmetric ++ * scenarios. For example, if all queues have the same weight, then the ++ * weight-counter tree for the queues may contain at most one node. ++ * This holds even if low_latency is on, because weight-raised queues ++ * are not inserted in the tree. ++ * In most scenarios, the rate at which nodes are created/destroyed ++ * should be low too. ++ */ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ struct rb_node **new = &(root->rb_node), *parent = NULL; ++ ++ /* ++ * Do not insert if the entity is already associated with a ++ * counter, which happens if: ++ * 1) the entity is associated with a queue, ++ * 2) a request arrival has caused the queue to become both ++ * non-weight-raised, and hence change its weight, and ++ * backlogged; in this respect, each of the two events ++ * causes an invocation of this function, ++ * 3) this is the invocation of this function caused by the ++ * second event. This second invocation is actually useless, ++ * and we handle this fact by exiting immediately. More ++ * efficient or clearer solutions might possibly be adopted. ++ */ ++ if (entity->weight_counter) ++ return; ++ ++ while (*new) { ++ struct bfq_weight_counter *__counter = container_of(*new, ++ struct bfq_weight_counter, ++ weights_node); ++ parent = *new; ++ ++ if (entity->weight == __counter->weight) { ++ entity->weight_counter = __counter; ++ goto inc_counter; ++ } ++ if (entity->weight < __counter->weight) ++ new = &((*new)->rb_left); ++ else ++ new = &((*new)->rb_right); ++ } ++ ++ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), ++ GFP_ATOMIC); ++ entity->weight_counter->weight = entity->weight; ++ rb_link_node(&entity->weight_counter->weights_node, parent, new); ++ rb_insert_color(&entity->weight_counter->weights_node, root); ++ ++inc_counter: ++ entity->weight_counter->num_active++; ++} ++ ++/* ++ * Decrement the weight counter associated with the entity, and, if the ++ * counter reaches 0, remove the counter from the tree. ++ * See the comments to the function bfq_weights_tree_add() for considerations ++ * about overhead. ++ */ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ if (!entity->weight_counter) ++ return; ++ ++ BUG_ON(RB_EMPTY_ROOT(root)); ++ BUG_ON(entity->weight_counter->weight != entity->weight); ++ ++ BUG_ON(!entity->weight_counter->num_active); ++ entity->weight_counter->num_active--; ++ if (entity->weight_counter->num_active > 0) ++ goto reset_entity_pointer; ++ ++ rb_erase(&entity->weight_counter->weights_node, root); ++ kfree(entity->weight_counter); ++ ++reset_entity_pointer: ++ entity->weight_counter = NULL; ++} ++ ++static struct request *bfq_find_next_rq(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *last) ++{ ++ struct rb_node *rbnext = rb_next(&last->rb_node); ++ struct rb_node *rbprev = rb_prev(&last->rb_node); ++ struct request *next = NULL, *prev = NULL; ++ ++ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); ++ ++ if (rbprev) ++ prev = rb_entry_rq(rbprev); ++ ++ if (rbnext) ++ next = rb_entry_rq(rbnext); ++ else { ++ rbnext = rb_first(&bfqq->sort_list); ++ if (rbnext && rbnext != &last->rb_node) ++ next = rb_entry_rq(rbnext); ++ } ++ ++ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); ++} ++ ++/* see the definition of bfq_async_charge_factor for details */ ++static unsigned long bfq_serv_to_charge(struct request *rq, ++ struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_sync(bfqq) || bfqq->wr_coeff > 1) ++ return blk_rq_sectors(rq); ++ ++ /* ++ * If there are no weight-raised queues, then amplify service ++ * by just the async charge factor; otherwise amplify service ++ * by twice the async charge factor, to further reduce latency ++ * for weight-raised queues. ++ */ ++ if (bfqq->bfqd->wr_busy_queues == 0) ++ return blk_rq_sectors(rq) * bfq_async_charge_factor; ++ ++ return blk_rq_sectors(rq) * 2 * bfq_async_charge_factor; ++} ++ ++/** ++ * bfq_updated_next_req - update the queue after a new next_rq selection. ++ * @bfqd: the device data the queue belongs to. ++ * @bfqq: the queue to update. ++ * ++ * If the first request of a queue changes we make sure that the queue ++ * has enough budget to serve at least its first request (if the ++ * request has grown). We do this because if the queue has not enough ++ * budget for its first request, it has to go through two dispatch ++ * rounds to actually get it dispatched. ++ */ ++static void bfq_updated_next_req(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct request *next_rq = bfqq->next_rq; ++ unsigned long new_budget; ++ ++ if (!next_rq) ++ return; ++ ++ if (bfqq == bfqd->in_service_queue) ++ /* ++ * In order not to break guarantees, budgets cannot be ++ * changed after an entity has been selected. ++ */ ++ return; ++ ++ BUG_ON(entity->tree != &st->active); ++ BUG_ON(entity == entity->sched_data->in_service_entity); ++ ++ new_budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ if (entity->budget != new_budget) { ++ entity->budget = new_budget; ++ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", ++ new_budget); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++} ++ ++static unsigned int bfq_wr_duration(struct bfq_data *bfqd) ++{ ++ u64 dur; ++ ++ if (bfqd->bfq_wr_max_time > 0) ++ return bfqd->bfq_wr_max_time; ++ ++ dur = bfqd->RT_prod; ++ do_div(dur, bfqd->peak_rate); ++ ++ /* ++ * Limit duration between 3 and 13 seconds. Tests show that ++ * higher values than 13 seconds often yield the opposite of ++ * the desired result, i.e., worsen responsiveness by letting ++ * non-interactive and non-soft-real-time applications ++ * preserve weight raising for a too long time interval. ++ * ++ * On the other end, lower values than 3 seconds make it ++ * difficult for most interactive tasks to complete their jobs ++ * before weight-raising finishes. ++ */ ++ if (dur > msecs_to_jiffies(13000)) ++ dur = msecs_to_jiffies(13000); ++ else if (dur < msecs_to_jiffies(3000)) ++ dur = msecs_to_jiffies(3000); ++ ++ return dur; ++} ++ ++static void ++bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ if (bic->saved_idle_window) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++ ++ if (bic->saved_IO_bound) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ else ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ bfqq->wr_coeff = bic->saved_wr_coeff; ++ bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt; ++ BUG_ON(time_is_after_jiffies(bfqq->wr_start_at_switch_to_srt)); ++ bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) || ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time))) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "resume state: switching off wr"); ++ ++ bfqq->wr_coeff = 1; ++ } ++ /* make sure weight will be updated, however we got here */ ++ bfqq->entity.prio_changed = 1; ++} ++ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ lockdep_assert_held(bfqq->bfqd->queue->queue_lock); ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = bfqq->ref - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ ++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ ++static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *item; ++ struct hlist_node *n; ++ ++ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) ++ hlist_del_init(&item->burst_list_node); ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++ bfqd->burst_size = 1; ++ bfqd->burst_parent_entity = bfqq->entity.parent; ++} ++ ++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ ++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* Increment burst size to take into account also bfqq */ ++ bfqd->burst_size++; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_to_burst %d", bfqd->burst_size); ++ ++ BUG_ON(bfqd->burst_size > bfqd->bfq_large_burst_thresh); ++ ++ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { ++ struct bfq_queue *pos, *bfqq_item; ++ struct hlist_node *n; ++ ++ /* ++ * Enough queues have been activated shortly after each ++ * other to consider this burst as large. ++ */ ++ bfqd->large_burst = true; ++ bfq_log_bfqq(bfqd, bfqq, "add_to_burst: large burst started"); ++ ++ /* ++ * We can now mark all queues in the burst list as ++ * belonging to a large burst. ++ */ ++ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, ++ burst_list_node) { ++ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_log_bfqq(bfqd, bfqq_item, "marked in large burst"); ++ } ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ bfq_log_bfqq(bfqd, bfqq, "marked in large burst"); ++ ++ /* ++ * From now on, and until the current burst finishes, any ++ * new queue being activated shortly after the last queue ++ * was inserted in the burst can be immediately marked as ++ * belonging to a large burst. So the burst list is not ++ * needed any more. Remove it. ++ */ ++ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, ++ burst_list_node) ++ hlist_del_init(&pos->burst_list_node); ++ } else /* ++ * Burst not yet large: add bfqq to the burst list. Do ++ * not increment the ref counter for bfqq, because bfqq ++ * is removed from the burst list before freeing bfqq ++ * in put_queue. ++ */ ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++} ++ ++/* ++ * If many queues belonging to the same group happen to be created ++ * shortly after each other, then the processes associated with these ++ * queues have typically a common goal. In particular, bursts of queue ++ * creations are usually caused by services or applications that spawn ++ * many parallel threads/processes. Examples are systemd during boot, ++ * or git grep. To help these processes get their job done as soon as ++ * possible, it is usually better to not grant either weight-raising ++ * or device idling to their queues. ++ * ++ * In this comment we describe, firstly, the reasons why this fact ++ * holds, and, secondly, the next function, which implements the main ++ * steps needed to properly mark these queues so that they can then be ++ * treated in a different way. ++ * ++ * The above services or applications benefit mostly from a high ++ * throughput: the quicker the requests of the activated queues are ++ * cumulatively served, the sooner the target job of these queues gets ++ * completed. As a consequence, weight-raising any of these queues, ++ * which also implies idling the device for it, is almost always ++ * counterproductive. In most cases it just lowers throughput. ++ * ++ * On the other hand, a burst of queue creations may be caused also by ++ * the start of an application that does not consist of a lot of ++ * parallel I/O-bound threads. In fact, with a complex application, ++ * several short processes may need to be executed to start-up the ++ * application. In this respect, to start an application as quickly as ++ * possible, the best thing to do is in any case to privilege the I/O ++ * related to the application with respect to all other ++ * I/O. Therefore, the best strategy to start as quickly as possible ++ * an application that causes a burst of queue creations is to ++ * weight-raise all the queues created during the burst. This is the ++ * exact opposite of the best strategy for the other type of bursts. ++ * ++ * In the end, to take the best action for each of the two cases, the ++ * two types of bursts need to be distinguished. Fortunately, this ++ * seems relatively easy, by looking at the sizes of the bursts. In ++ * particular, we found a threshold such that only bursts with a ++ * larger size than that threshold are apparently caused by ++ * services or commands such as systemd or git grep. For brevity, ++ * hereafter we call just 'large' these bursts. BFQ *does not* ++ * weight-raise queues whose creation occurs in a large burst. In ++ * addition, for each of these queues BFQ performs or does not perform ++ * idling depending on which choice boosts the throughput more. The ++ * exact choice depends on the device and request pattern at ++ * hand. ++ * ++ * Unfortunately, false positives may occur while an interactive task ++ * is starting (e.g., an application is being started). The ++ * consequence is that the queues associated with the task do not ++ * enjoy weight raising as expected. Fortunately these false positives ++ * are very rare. They typically occur if some service happens to ++ * start doing I/O exactly when the interactive task starts. ++ * ++ * Turning back to the next function, it implements all the steps ++ * needed to detect the occurrence of a large burst and to properly ++ * mark all the queues belonging to it (so that they can then be ++ * treated in a different way). This goal is achieved by maintaining a ++ * "burst list" that holds, temporarily, the queues that belong to the ++ * burst in progress. The list is then used to mark these queues as ++ * belonging to a large burst if the burst does become large. The main ++ * steps are the following. ++ * ++ * . when the very first queue is created, the queue is inserted into the ++ * list (as it could be the first queue in a possible burst) ++ * ++ * . if the current burst has not yet become large, and a queue Q that does ++ * not yet belong to the burst is activated shortly after the last time ++ * at which a new queue entered the burst list, then the function appends ++ * Q to the burst list ++ * ++ * . if, as a consequence of the previous step, the burst size reaches ++ * the large-burst threshold, then ++ * ++ * . all the queues in the burst list are marked as belonging to a ++ * large burst ++ * ++ * . the burst list is deleted; in fact, the burst list already served ++ * its purpose (keeping temporarily track of the queues in a burst, ++ * so as to be able to mark them as belonging to a large burst in the ++ * previous sub-step), and now is not needed any more ++ * ++ * . the device enters a large-burst mode ++ * ++ * . if a queue Q that does not belong to the burst is created while ++ * the device is in large-burst mode and shortly after the last time ++ * at which a queue either entered the burst list or was marked as ++ * belonging to the current large burst, then Q is immediately marked ++ * as belonging to a large burst. ++ * ++ * . if a queue Q that does not belong to the burst is created a while ++ * later, i.e., not shortly after, than the last time at which a queue ++ * either entered the burst list or was marked as belonging to the ++ * current large burst, then the current burst is deemed as finished and: ++ * ++ * . the large-burst mode is reset if set ++ * ++ * . the burst list is emptied ++ * ++ * . Q is inserted in the burst list, as Q may be the first queue ++ * in a possible new burst (then the burst list contains just Q ++ * after this step). ++ */ ++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq is already in the burst list or is part of a large ++ * burst, or finally has just been split, then there is ++ * nothing else to do. ++ */ ++ if (!hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq) || ++ time_is_after_eq_jiffies(bfqq->split_time + ++ msecs_to_jiffies(10))) ++ return; ++ ++ /* ++ * If bfqq's creation happens late enough, or bfqq belongs to ++ * a different group than the burst group, then the current ++ * burst is finished, and related data structures must be ++ * reset. ++ * ++ * In this respect, consider the special case where bfqq is ++ * the very first queue created after BFQ is selected for this ++ * device. In this case, last_ins_in_burst and ++ * burst_parent_entity are not yet significant when we get ++ * here. But it is easy to verify that, whether or not the ++ * following condition is true, bfqq will end up being ++ * inserted into the burst list. In particular the list will ++ * happen to contain only bfqq. And this is exactly what has ++ * to happen, as bfqq may be the first queue of the first ++ * burst. ++ */ ++ if (time_is_before_jiffies(bfqd->last_ins_in_burst + ++ bfqd->bfq_burst_interval) || ++ bfqq->entity.parent != bfqd->burst_parent_entity) { ++ bfqd->large_burst = false; ++ bfq_reset_burst_list(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, ++ "handle_burst: late activation or different group"); ++ goto end; ++ } ++ ++ /* ++ * If we get here, then bfqq is being activated shortly after the ++ * last queue. So, if the current burst is also large, we can mark ++ * bfqq as belonging to this large burst immediately. ++ */ ++ if (bfqd->large_burst) { ++ bfq_log_bfqq(bfqd, bfqq, "handle_burst: marked in burst"); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ goto end; ++ } ++ ++ /* ++ * If we get here, then a large-burst state has not yet been ++ * reached, but bfqq is being activated shortly after the last ++ * queue. Then we add bfqq to the burst. ++ */ ++ bfq_add_to_burst(bfqd, bfqq); ++end: ++ /* ++ * At this point, bfqq either has been added to the current ++ * burst or has caused the current burst to terminate and a ++ * possible new burst to start. In particular, in the second ++ * case, bfqq has become the first queue in the possible new ++ * burst. In both cases last_ins_in_burst needs to be moved ++ * forward. ++ */ ++ bfqd->last_ins_in_burst = jiffies; ++ ++} ++ ++static int bfq_bfqq_budget_left(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ return entity->budget - entity->service; ++} ++ ++/* ++ * If enough samples have been computed, return the current max budget ++ * stored in bfqd, which is dynamically updated according to the ++ * estimated disk peak rate; otherwise return the default max budget ++ */ ++static int bfq_max_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < bfq_stats_min_budgets) ++ return bfq_default_max_budget; ++ else ++ return bfqd->bfq_max_budget; ++} ++ ++/* ++ * Return min budget, which is a fraction of the current or default ++ * max budget (trying with 1/32) ++ */ ++static int bfq_min_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < bfq_stats_min_budgets) ++ return bfq_default_max_budget / 32; ++ else ++ return bfqd->bfq_max_budget / 32; ++} ++ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason); ++ ++/* ++ * The next function, invoked after the input queue bfqq switches from ++ * idle to busy, updates the budget of bfqq. The function also tells ++ * whether the in-service queue should be expired, by returning ++ * true. The purpose of expiring the in-service queue is to give bfqq ++ * the chance to possibly preempt the in-service queue, and the reason ++ * for preempting the in-service queue is to achieve one of the two ++ * goals below. ++ * ++ * 1. Guarantee to bfqq its reserved bandwidth even if bfqq has ++ * expired because it has remained idle. In particular, bfqq may have ++ * expired for one of the following two reasons: ++ * ++ * - BFQ_BFQQ_NO_MORE_REQUEST bfqq did not enjoy any device idling and ++ * did not make it to issue a new request before its last request ++ * was served; ++ * ++ * - BFQ_BFQQ_TOO_IDLE bfqq did enjoy device idling, but did not issue ++ * a new request before the expiration of the idling-time. ++ * ++ * Even if bfqq has expired for one of the above reasons, the process ++ * associated with the queue may be however issuing requests greedily, ++ * and thus be sensitive to the bandwidth it receives (bfqq may have ++ * remained idle for other reasons: CPU high load, bfqq not enjoying ++ * idling, I/O throttling somewhere in the path from the process to ++ * the I/O scheduler, ...). But if, after every expiration for one of ++ * the above two reasons, bfqq has to wait for the service of at least ++ * one full budget of another queue before being served again, then ++ * bfqq is likely to get a much lower bandwidth or resource time than ++ * its reserved ones. To address this issue, two countermeasures need ++ * to be taken. ++ * ++ * First, the budget and the timestamps of bfqq need to be updated in ++ * a special way on bfqq reactivation: they need to be updated as if ++ * bfqq did not remain idle and did not expire. In fact, if they are ++ * computed as if bfqq expired and remained idle until reactivation, ++ * then the process associated with bfqq is treated as if, instead of ++ * being greedy, it stopped issuing requests when bfqq remained idle, ++ * and restarts issuing requests only on this reactivation. In other ++ * words, the scheduler does not help the process recover the "service ++ * hole" between bfqq expiration and reactivation. As a consequence, ++ * the process receives a lower bandwidth than its reserved one. In ++ * contrast, to recover this hole, the budget must be updated as if ++ * bfqq was not expired at all before this reactivation, i.e., it must ++ * be set to the value of the remaining budget when bfqq was ++ * expired. Along the same line, timestamps need to be assigned the ++ * value they had the last time bfqq was selected for service, i.e., ++ * before last expiration. Thus timestamps need to be back-shifted ++ * with respect to their normal computation (see [1] for more details ++ * on this tricky aspect). ++ * ++ * Secondly, to allow the process to recover the hole, the in-service ++ * queue must be expired too, to give bfqq the chance to preempt it ++ * immediately. In fact, if bfqq has to wait for a full budget of the ++ * in-service queue to be completed, then it may become impossible to ++ * let the process recover the hole, even if the back-shifted ++ * timestamps of bfqq are lower than those of the in-service queue. If ++ * this happens for most or all of the holes, then the process may not ++ * receive its reserved bandwidth. In this respect, it is worth noting ++ * that, being the service of outstanding requests unpreemptible, a ++ * little fraction of the holes may however be unrecoverable, thereby ++ * causing a little loss of bandwidth. ++ * ++ * The last important point is detecting whether bfqq does need this ++ * bandwidth recovery. In this respect, the next function deems the ++ * process associated with bfqq greedy, and thus allows it to recover ++ * the hole, if: 1) the process is waiting for the arrival of a new ++ * request (which implies that bfqq expired for one of the above two ++ * reasons), and 2) such a request has arrived soon. The first ++ * condition is controlled through the flag non_blocking_wait_rq, ++ * while the second through the flag arrived_in_time. If both ++ * conditions hold, then the function computes the budget in the ++ * above-described special way, and signals that the in-service queue ++ * should be expired. Timestamp back-shifting is done later in ++ * __bfq_activate_entity. ++ * ++ * 2. Reduce latency. Even if timestamps are not backshifted to let ++ * the process associated with bfqq recover a service hole, bfqq may ++ * however happen to have, after being (re)activated, a lower finish ++ * timestamp than the in-service queue. That is, the next budget of ++ * bfqq may have to be completed before the one of the in-service ++ * queue. If this is the case, then preempting the in-service queue ++ * allows this goal to be achieved, apart from the unpreemptible, ++ * outstanding requests mentioned above. ++ * ++ * Unfortunately, regardless of which of the above two goals one wants ++ * to achieve, service trees need first to be updated to know whether ++ * the in-service queue must be preempted. To have service trees ++ * correctly updated, the in-service queue must be expired and ++ * rescheduled, and bfqq must be scheduled too. This is one of the ++ * most costly operations (in future versions, the scheduling ++ * mechanism may be re-designed in such a way to make it possible to ++ * know whether preemption is needed without needing to update service ++ * trees). In addition, queue preemptions almost always cause random ++ * I/O, and thus loss of throughput. Because of these facts, the next ++ * function adopts the following simple scheme to avoid both costly ++ * operations and too frequent preemptions: it requests the expiration ++ * of the in-service queue (unconditionally) only for queues that need ++ * to recover a hole, or that either are weight-raised or deserve to ++ * be weight-raised. ++ */ ++static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool arrived_in_time, ++ bool wr_or_deserves_wr) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfq_bfqq_non_blocking_wait_rq(bfqq) && arrived_in_time) { ++ /* ++ * We do not clear the flag non_blocking_wait_rq here, as ++ * the latter is used in bfq_activate_bfqq to signal ++ * that timestamps need to be back-shifted (and is ++ * cleared right after). ++ */ ++ ++ /* ++ * In next assignment we rely on that either ++ * entity->service or entity->budget are not updated ++ * on expiration if bfqq is empty (see ++ * __bfq_bfqq_recalc_budget). Thus both quantities ++ * remain unchanged after such an expiration, and the ++ * following statement therefore assigns to ++ * entity->budget the remaining budget on such an ++ * expiration. For clarity, entity->service is not ++ * updated on expiration in any case, and, in normal ++ * operation, is reset only when bfqq is selected for ++ * service (see bfq_get_next_queue). ++ */ ++ BUG_ON(bfqq->max_budget < 0); ++ entity->budget = min_t(unsigned long, ++ bfq_bfqq_budget_left(bfqq), ++ bfqq->max_budget); ++ ++ BUG_ON(entity->budget < 0); ++ return true; ++ } ++ ++ BUG_ON(bfqq->max_budget < 0); ++ entity->budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(bfqq->next_rq, bfqq)); ++ BUG_ON(entity->budget < 0); ++ ++ bfq_clear_bfqq_non_blocking_wait_rq(bfqq); ++ return wr_or_deserves_wr; ++} ++ ++static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ unsigned int old_wr_coeff, ++ bool wr_or_deserves_wr, ++ bool interactive, ++ bool in_burst, ++ bool soft_rt) ++{ ++ if (old_wr_coeff == 1 && wr_or_deserves_wr) { ++ /* start a weight-raising period */ ++ if (interactive) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ } else { ++ bfqq->wr_start_at_switch_to_srt = jiffies; ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff * ++ BFQ_SOFTRT_WEIGHT_FACTOR; ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ } ++ /* ++ * If needed, further reduce budget to make sure it is ++ * close to bfqq's backlog, so as to reduce the ++ * scheduling-error component due to a too large ++ * budget. Do not care about throughput consequences, ++ * but only about latency. Finally, do not assign a ++ * too small budget either, to avoid increasing ++ * latency by causing too frequent expirations. ++ */ ++ bfqq->entity.budget = min_t(unsigned long, ++ bfqq->entity.budget, ++ 2 * bfq_min_budget(bfqd)); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } else if (old_wr_coeff > 1) { ++ if (interactive) { /* update wr coeff and duration */ ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ } else if (in_burst) { ++ bfqq->wr_coeff = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq-> ++ wr_cur_max_time)); ++ } else if (soft_rt) { ++ /* ++ * The application is now or still meeting the ++ * requirements for being deemed soft rt. We ++ * can then correctly and safely (re)charge ++ * the weight-raising duration for the ++ * application with the weight-raising ++ * duration for soft rt applications. ++ * ++ * In particular, doing this recharge now, i.e., ++ * before the weight-raising period for the ++ * application finishes, reduces the probability ++ * of the following negative scenario: ++ * 1) the weight of a soft rt application is ++ * raised at startup (as for any newly ++ * created application), ++ * 2) since the application is not interactive, ++ * at a certain time weight-raising is ++ * stopped for the application, ++ * 3) at that time the application happens to ++ * still have pending requests, and hence ++ * is destined to not have a chance to be ++ * deemed soft rt before these requests are ++ * completed (see the comments to the ++ * function bfq_bfqq_softrt_next_start() ++ * for details on soft rt detection), ++ * 4) these pending requests experience a high ++ * latency because the application is not ++ * weight-raised while they are pending. ++ */ ++ if (bfqq->wr_cur_max_time != ++ bfqd->bfq_wr_rt_max_time) { ++ bfqq->wr_start_at_switch_to_srt = ++ bfqq->last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff * ++ BFQ_SOFTRT_WEIGHT_FACTOR; ++ bfq_log_bfqq(bfqd, bfqq, ++ "switching to soft_rt wr"); ++ } else ++ bfq_log_bfqq(bfqd, bfqq, ++ "moving forward soft_rt wr duration"); ++ bfqq->last_wr_start_finish = jiffies; ++ } ++ } ++} ++ ++static bool bfq_bfqq_idle_for_long_time(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ return bfqq->dispatched == 0 && ++ time_is_before_jiffies( ++ bfqq->budget_timeout + ++ bfqd->bfq_wr_min_idle_time); ++} ++ ++static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ int old_wr_coeff, ++ struct request *rq, ++ bool *interactive) ++{ ++ bool soft_rt, in_burst, wr_or_deserves_wr, ++ bfqq_wants_to_preempt, ++ idle_for_long_time = bfq_bfqq_idle_for_long_time(bfqd, bfqq), ++ /* ++ * See the comments on ++ * bfq_bfqq_update_budg_for_activation for ++ * details on the usage of the next variable. ++ */ ++ arrived_in_time = ktime_get_ns() <= ++ RQ_BIC(rq)->ttime.last_end_request + ++ bfqd->bfq_slice_idle * 3; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "bfq_add_request non-busy: " ++ "jiffies %lu, in_time %d, idle_long %d busyw %d " ++ "wr_coeff %u", ++ jiffies, arrived_in_time, ++ idle_for_long_time, ++ bfq_bfqq_non_blocking_wait_rq(bfqq), ++ old_wr_coeff); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq, ++ req_op(rq), rq->cmd_flags); ++ ++ /* ++ * bfqq deserves to be weight-raised if: ++ * - it is sync, ++ * - it does not belong to a large burst, ++ * - it has been idle for enough time or is soft real-time, ++ * - is linked to a bfq_io_cq (it is not shared in any sense) ++ */ ++ in_burst = bfq_bfqq_in_large_burst(bfqq); ++ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && ++ !in_burst && ++ time_is_before_jiffies(bfqq->soft_rt_next_start); ++ *interactive = ++ !in_burst && ++ idle_for_long_time; ++ wr_or_deserves_wr = bfqd->low_latency && ++ (bfqq->wr_coeff > 1 || ++ (bfq_bfqq_sync(bfqq) && ++ bfqq->bic && (*interactive || soft_rt))); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "bfq_add_request: " ++ "in_burst %d, " ++ "soft_rt %d (next %lu), inter %d, bic %p", ++ bfq_bfqq_in_large_burst(bfqq), soft_rt, ++ bfqq->soft_rt_next_start, ++ *interactive, ++ bfqq->bic); ++ ++ /* ++ * Using the last flag, update budget and check whether bfqq ++ * may want to preempt the in-service queue. ++ */ ++ bfqq_wants_to_preempt = ++ bfq_bfqq_update_budg_for_activation(bfqd, bfqq, ++ arrived_in_time, ++ wr_or_deserves_wr); ++ ++ /* ++ * If bfqq happened to be activated in a burst, but has been ++ * idle for much more than an interactive queue, then we ++ * assume that, in the overall I/O initiated in the burst, the ++ * I/O associated with bfqq is finished. So bfqq does not need ++ * to be treated as a queue belonging to a burst ++ * anymore. Accordingly, we reset bfqq's in_large_burst flag ++ * if set, and remove bfqq from the burst list if it's ++ * there. We do not decrement burst_size, because the fact ++ * that bfqq does not need to belong to the burst list any ++ * more does not invalidate the fact that bfqq was created in ++ * a burst. ++ */ ++ if (likely(!bfq_bfqq_just_created(bfqq)) && ++ idle_for_long_time && ++ time_is_before_jiffies( ++ bfqq->budget_timeout + ++ msecs_to_jiffies(10000))) { ++ hlist_del_init(&bfqq->burst_list_node); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ } ++ ++ bfq_clear_bfqq_just_created(bfqq); ++ ++ if (!bfq_bfqq_IO_bound(bfqq)) { ++ if (arrived_in_time) { ++ bfqq->requests_within_timer++; ++ if (bfqq->requests_within_timer >= ++ bfqd->bfq_requests_within_timer) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ } else ++ bfqq->requests_within_timer = 0; ++ bfq_log_bfqq(bfqd, bfqq, "requests in time %d", ++ bfqq->requests_within_timer); ++ } ++ ++ if (bfqd->low_latency) { ++ if (unlikely(time_is_after_jiffies(bfqq->split_time))) ++ /* wraparound */ ++ bfqq->split_time = ++ jiffies - bfqd->bfq_wr_min_idle_time - 1; ++ ++ if (time_is_before_jiffies(bfqq->split_time + ++ bfqd->bfq_wr_min_idle_time)) { ++ bfq_update_bfqq_wr_on_rq_arrival(bfqd, bfqq, ++ old_wr_coeff, ++ wr_or_deserves_wr, ++ *interactive, ++ in_burst, ++ soft_rt); ++ ++ if (old_wr_coeff != bfqq->wr_coeff) ++ bfqq->entity.prio_changed = 1; ++ } ++ } ++ ++ bfqq->last_idle_bklogged = jiffies; ++ bfqq->service_from_backlogged = 0; ++ bfq_clear_bfqq_softrt_update(bfqq); ++ ++ bfq_add_bfqq_busy(bfqd, bfqq); ++ ++ /* ++ * Expire in-service queue only if preemption may be needed ++ * for guarantees. In this respect, the function ++ * next_queue_may_preempt just checks a simple, necessary ++ * condition, and not a sufficient condition based on ++ * timestamps. In fact, for the latter condition to be ++ * evaluated, timestamps would need first to be updated, and ++ * this operation is quite costly (see the comments on the ++ * function bfq_bfqq_update_budg_for_activation). ++ */ ++ if (bfqd->in_service_queue && bfqq_wants_to_preempt && ++ bfqd->in_service_queue->wr_coeff < bfqq->wr_coeff && ++ next_queue_may_preempt(bfqd)) { ++ struct bfq_queue *in_serv = ++ bfqd->in_service_queue; ++ BUG_ON(in_serv == bfqq); ++ ++ bfq_bfqq_expire(bfqd, bfqd->in_service_queue, ++ false, BFQ_BFQQ_PREEMPTED); ++ BUG_ON(in_serv->entity.budget < 0); ++ } ++} ++ ++static void bfq_add_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *next_rq, *prev; ++ unsigned int old_wr_coeff = bfqq->wr_coeff; ++ bool interactive = false; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_request: size %u %s", ++ blk_rq_sectors(rq), rq_is_sync(rq) ? "S" : "A"); ++ ++ if (bfqq->wr_coeff > 1) /* queue is being weight-raised */ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ bfqq->queued[rq_is_sync(rq)]++; ++ bfqd->queued++; ++ ++ elv_rb_add(&bfqq->sort_list, rq); ++ ++ /* ++ * Check if this request is a better next-to-serve candidate. ++ */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); ++ BUG_ON(!next_rq); ++ bfqq->next_rq = next_rq; ++ ++ /* ++ * Adjust priority tree position, if next_rq changes. ++ */ ++ if (prev != bfqq->next_rq) ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ ++ if (!bfq_bfqq_busy(bfqq)) /* switching to busy ... */ ++ bfq_bfqq_handle_idle_busy_switch(bfqd, bfqq, old_wr_coeff, ++ rq, &interactive); ++ else { ++ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && ++ time_is_before_jiffies( ++ bfqq->last_wr_start_finish + ++ bfqd->bfq_wr_min_inter_arr_async)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ ++ bfqd->wr_busy_queues++; ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "non-idle wrais starting, " ++ "wr_max_time %u wr_busy %d", ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqd->wr_busy_queues); ++ } ++ if (prev != bfqq->next_rq) ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ /* ++ * Assign jiffies to last_wr_start_finish in the following ++ * cases: ++ * ++ * . if bfqq is not going to be weight-raised, because, for ++ * non weight-raised queues, last_wr_start_finish stores the ++ * arrival time of the last request; as of now, this piece ++ * of information is used only for deciding whether to ++ * weight-raise async queues ++ * ++ * . if bfqq is not weight-raised, because, if bfqq is now ++ * switching to weight-raised, then last_wr_start_finish ++ * stores the time when weight-raising starts ++ * ++ * . if bfqq is interactive, because, regardless of whether ++ * bfqq is currently weight-raised, the weight-raising ++ * period must start or restart (this case is considered ++ * separately because it is not detected by the above ++ * conditions, if bfqq is already weight-raised) ++ * ++ * last_wr_start_finish has to be updated also if bfqq is soft ++ * real-time, because the weight-raising period is constantly ++ * restarted on idle-to-busy transitions for these queues, but ++ * this is already done in bfq_bfqq_handle_idle_busy_switch if ++ * needed. ++ */ ++ if (bfqd->low_latency && ++ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) ++ bfqq->last_wr_start_finish = jiffies; ++} ++ ++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, ++ struct bio *bio) ++{ ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (!bic) ++ return NULL; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ if (bfqq) ++ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); ++ ++ return NULL; ++} ++ ++static sector_t get_sdist(sector_t last_pos, struct request *rq) ++{ ++ sector_t sdist = 0; ++ ++ if (last_pos) { ++ if (last_pos < blk_rq_pos(rq)) ++ sdist = blk_rq_pos(rq) - last_pos; ++ else ++ sdist = last_pos - blk_rq_pos(rq); ++ } ++ ++ return sdist; ++} ++ ++static void bfq_activate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ bfqd->rq_in_driver++; ++} ++ ++static void bfq_deactivate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ BUG_ON(bfqd->rq_in_driver == 0); ++ bfqd->rq_in_driver--; ++} ++ ++static void bfq_remove_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ const int sync = rq_is_sync(rq); ++ ++ BUG_ON(bfqq->entity.service > bfqq->entity.budget && ++ bfqq == bfqd->in_service_queue); ++ ++ if (bfqq->next_rq == rq) { ++ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (rq->queuelist.prev != &rq->queuelist) ++ list_del_init(&rq->queuelist); ++ BUG_ON(bfqq->queued[sync] == 0); ++ bfqq->queued[sync]--; ++ bfqd->queued--; ++ elv_rb_del(&bfqq->sort_list, rq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ BUG_ON(bfqq->entity.budget < 0); ++ ++ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) { ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ ++ /* bfqq emptied. In normal operation, when ++ * bfqq is empty, bfqq->entity.service and ++ * bfqq->entity.budget must contain, ++ * respectively, the service received and the ++ * budget used last time bfqq emptied. These ++ * facts do not hold in this case, as at least ++ * this last removal occurred while bfqq is ++ * not in service. To avoid inconsistencies, ++ * reset both bfqq->entity.service and ++ * bfqq->entity.budget. ++ */ ++ bfqq->entity.budget = bfqq->entity.service = 0; ++ } ++ ++ /* ++ * Remove queue from request-position tree as it is empty. ++ */ ++ if (bfqq->pos_root) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ } ++ ++ if (rq->cmd_flags & REQ_META) { ++ BUG_ON(bfqq->meta_pending == 0); ++ bfqq->meta_pending--; ++ } ++ bfqg_stats_update_io_remove(bfqq_group(bfqq), req_op(rq), ++ rq->cmd_flags); ++} ++ ++static int bfq_merge(struct request_queue *q, struct request **req, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct request *__rq; ++ ++ __rq = bfq_find_rq_fmerge(bfqd, bio); ++ if (__rq && elv_bio_merge_ok(__rq, bio)) { ++ *req = __rq; ++ return ELEVATOR_FRONT_MERGE; ++ } ++ ++ return ELEVATOR_NO_MERGE; ++} ++ ++static void bfq_merged_request(struct request_queue *q, struct request *req, ++ int type) ++{ ++ if (type == ELEVATOR_FRONT_MERGE && ++ rb_prev(&req->rb_node) && ++ blk_rq_pos(req) < ++ blk_rq_pos(container_of(rb_prev(&req->rb_node), ++ struct request, rb_node))) { ++ struct bfq_queue *bfqq = RQ_BFQQ(req); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *prev, *next_rq; ++ ++ /* Reposition request in its sort_list */ ++ elv_rb_del(&bfqq->sort_list, req); ++ elv_rb_add(&bfqq->sort_list, req); ++ /* Choose next request to be served for bfqq */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, ++ bfqd->last_position); ++ BUG_ON(!next_rq); ++ bfqq->next_rq = next_rq; ++ /* ++ * If next_rq changes, update both the queue's budget to ++ * fit the new request and the queue's position in its ++ * rq_pos_tree. ++ */ ++ if (prev != bfqq->next_rq) { ++ bfq_updated_next_req(bfqd, bfqq); ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ } ++ } ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfq_bio_merged(struct request_queue *q, struct request *req, ++ struct bio *bio) ++{ ++ bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio_op(bio), ++ bio->bi_opf); ++} ++#endif ++ ++static void bfq_merged_requests(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *next_bfqq = RQ_BFQQ(next); ++ ++ /* ++ * If next and rq belong to the same bfq_queue and next is older ++ * than rq, then reposition rq in the fifo (by substituting next ++ * with rq). Otherwise, if next and rq belong to different ++ * bfq_queues, never reposition rq: in fact, we would have to ++ * reposition it with respect to next's position in its own fifo, ++ * which would most certainly be too expensive with respect to ++ * the benefits. ++ */ ++ if (bfqq == next_bfqq && ++ !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && ++ next->fifo_time < rq->fifo_time) { ++ list_del_init(&rq->queuelist); ++ list_replace_init(&next->queuelist, &rq->queuelist); ++ rq->fifo_time = next->fifo_time; ++ } ++ ++ if (bfqq->next_rq == next) ++ bfqq->next_rq = rq; ++ ++ bfq_remove_request(next); ++ bfqg_stats_update_io_merged(bfqq_group(bfqq), req_op(next), ++ next->cmd_flags); ++} ++ ++/* Must be called with bfqq != NULL */ ++static void bfq_bfqq_end_wr(struct bfq_queue *bfqq) ++{ ++ BUG_ON(!bfqq); ++ ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues--; ++ bfqq->wr_coeff = 1; ++ bfqq->wr_cur_max_time = 0; ++ bfqq->last_wr_start_finish = jiffies; ++ /* ++ * Trigger a weight change on the next invocation of ++ * __bfq_entity_update_weight_prio. ++ */ ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "end_wr: wrais ending at %lu, rais_max_time %u", ++ bfqq->last_wr_start_finish, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "end_wr: wr_busy %d", ++ bfqq->bfqd->wr_busy_queues); ++} ++ ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ if (bfqg->async_bfqq[i][j]) ++ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); ++ if (bfqg->async_idle_bfqq) ++ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); ++} ++ ++static void bfq_end_wr(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ bfq_end_wr_async(bfqd); ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++} ++ ++static sector_t bfq_io_struct_pos(void *io_struct, bool request) ++{ ++ if (request) ++ return blk_rq_pos(io_struct); ++ else ++ return ((struct bio *)io_struct)->bi_iter.bi_sector; ++} ++ ++static int bfq_rq_close_to_sector(void *io_struct, bool request, ++ sector_t sector) ++{ ++ return abs(bfq_io_struct_pos(io_struct, request) - sector) <= ++ BFQQ_CLOSE_THR; ++} ++ ++static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ sector_t sector) ++{ ++ struct rb_root *root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree; ++ struct rb_node *parent, *node; ++ struct bfq_queue *__bfqq; ++ ++ if (RB_EMPTY_ROOT(root)) ++ return NULL; ++ ++ /* ++ * First, if we find a request starting at the end of the last ++ * request, choose it. ++ */ ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); ++ if (__bfqq) ++ return __bfqq; ++ ++ /* ++ * If the exact sector wasn't found, the parent of the NULL leaf ++ * will contain the closest sector (rq_pos_tree sorted by ++ * next_request position). ++ */ ++ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) ++ return __bfqq; ++ ++ if (blk_rq_pos(__bfqq->next_rq) < sector) ++ node = rb_next(&__bfqq->pos_node); ++ else ++ node = rb_prev(&__bfqq->pos_node); ++ if (!node) ++ return NULL; ++ ++ __bfqq = rb_entry(node, struct bfq_queue, pos_node); ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) ++ return __bfqq; ++ ++ return NULL; ++} ++ ++static struct bfq_queue *bfq_find_close_cooperator(struct bfq_data *bfqd, ++ struct bfq_queue *cur_bfqq, ++ sector_t sector) ++{ ++ struct bfq_queue *bfqq; ++ ++ /* ++ * We shall notice if some of the queues are cooperating, ++ * e.g., working closely on the same area of the device. In ++ * that case, we can group them together and: 1) don't waste ++ * time idling, and 2) serve the union of their requests in ++ * the best possible order for throughput. ++ */ ++ bfqq = bfqq_find_close(bfqd, cur_bfqq, sector); ++ if (!bfqq || bfqq == cur_bfqq) ++ return NULL; ++ ++ return bfqq; ++} ++ ++static struct bfq_queue * ++bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return NULL; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return NULL; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++ ++ /* ++ * Merging is just a redirection: the requests of the process ++ * owning one of the two queues are redirected to the other queue. ++ * The latter queue, in its turn, is set as shared if this is the ++ * first time that the requests of some process are redirected to ++ * it. ++ * ++ * We redirect bfqq to new_bfqq and not the opposite, because we ++ * are in the context of the process owning bfqq, hence we have ++ * the io_cq of this process. So we can immediately configure this ++ * io_cq to redirect the requests of the process to new_bfqq. ++ * ++ * NOTE, even if new_bfqq coincides with the in-service queue, the ++ * io_cq of new_bfqq is not available, because, if the in-service ++ * queue is shared, bfqd->in_service_bic may not point to the ++ * io_cq of the in-service queue. ++ * Redirecting the requests of the process owning bfqq to the ++ * currently in-service queue is in any case the best option, as ++ * we feed the in-service queue with new requests close to the ++ * last request served and, by doing so, hopefully increase the ++ * throughput. ++ */ ++ bfqq->new_bfqq = new_bfqq; ++ new_bfqq->ref += process_refs; ++ return new_bfqq; ++} ++ ++static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, ++ struct bfq_queue *new_bfqq) ++{ ++ if (bfq_class_idle(bfqq) || bfq_class_idle(new_bfqq) || ++ (bfqq->ioprio_class != new_bfqq->ioprio_class)) ++ return false; ++ ++ /* ++ * If either of the queues has already been detected as seeky, ++ * then merging it with the other queue is unlikely to lead to ++ * sequential I/O. ++ */ ++ if (BFQQ_SEEKY(bfqq) || BFQQ_SEEKY(new_bfqq)) ++ return false; ++ ++ /* ++ * Interleaved I/O is known to be done by (some) applications ++ * only for reads, so it does not make sense to merge async ++ * queues. ++ */ ++ if (!bfq_bfqq_sync(bfqq) || !bfq_bfqq_sync(new_bfqq)) ++ return false; ++ ++ return true; ++} ++ ++/* ++ * If this function returns true, then bfqq cannot be merged. The idea ++ * is that true cooperation happens very early after processes start ++ * to do I/O. Usually, late cooperations are just accidental false ++ * positives. In case bfqq is weight-raised, such false positives ++ * would evidently degrade latency guarantees for bfqq. ++ */ ++bool wr_from_too_long(struct bfq_queue *bfqq) ++{ ++ return bfqq->wr_coeff > 1 && ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ msecs_to_jiffies(100)); ++} ++ ++/* ++ * Attempt to schedule a merge of bfqq with the currently in-service ++ * queue or with a close queue among the scheduled queues. Return ++ * NULL if no merge was scheduled, a pointer to the shared bfq_queue ++ * structure otherwise. ++ * ++ * The OOM queue is not allowed to participate to cooperation: in fact, since ++ * the requests temporarily redirected to the OOM queue could be redirected ++ * again to dedicated queues at any time, the state needed to correctly ++ * handle merging with the OOM queue would be quite complex and expensive ++ * to maintain. Besides, in such a critical condition as an out of memory, ++ * the benefits of queue merging may be little relevant, or even negligible. ++ * ++ * Weight-raised queues can be merged only if their weight-raising ++ * period has just started. In fact cooperating processes are usually ++ * started together. Thus, with this filter we avoid false positives ++ * that would jeopardize low-latency guarantees. ++ * ++ * WARNING: queue merging may impair fairness among non-weight raised ++ * queues, for at least two reasons: 1) the original weight of a ++ * merged queue may change during the merged state, 2) even being the ++ * weight the same, a merged queue may be bloated with many more ++ * requests than the ones produced by its originally-associated ++ * process. ++ */ ++static struct bfq_queue * ++bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ void *io_struct, bool request) ++{ ++ struct bfq_queue *in_service_bfqq, *new_bfqq; ++ ++ if (bfqq->new_bfqq) ++ return bfqq->new_bfqq; ++ ++ if (io_struct && wr_from_too_long(bfqq) && ++ likely(bfqq != &bfqd->oom_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have looked for coop, but bfq%d wr", ++ bfqq->pid); ++ ++ if (!io_struct || ++ wr_from_too_long(bfqq) || ++ unlikely(bfqq == &bfqd->oom_bfqq)) ++ return NULL; ++ ++ /* If there is only one backlogged queue, don't search. */ ++ if (bfqd->busy_queues == 1) ++ return NULL; ++ ++ in_service_bfqq = bfqd->in_service_queue; ++ ++ if (in_service_bfqq && in_service_bfqq != bfqq && ++ bfqd->in_service_bic && wr_from_too_long(in_service_bfqq) ++ && likely(in_service_bfqq == &bfqd->oom_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have tried merge with in-service-queue, but wr"); ++ ++ if (!in_service_bfqq || in_service_bfqq == bfqq || ++ !bfqd->in_service_bic || wr_from_too_long(in_service_bfqq) || ++ unlikely(in_service_bfqq == &bfqd->oom_bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && ++ bfqq->entity.parent == in_service_bfqq->entity.parent && ++ bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) { ++ new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); ++ if (new_bfqq) ++ return new_bfqq; ++ } ++ /* ++ * Check whether there is a cooperator among currently scheduled ++ * queues. The only thing we need is that the bio/request is not ++ * NULL, as we need it to establish whether a cooperator exists. ++ */ ++check_scheduled: ++ new_bfqq = bfq_find_close_cooperator(bfqd, bfqq, ++ bfq_io_struct_pos(io_struct, request)); ++ ++ BUG_ON(new_bfqq && bfqq->entity.parent != new_bfqq->entity.parent); ++ ++ if (new_bfqq && wr_from_too_long(new_bfqq) && ++ likely(new_bfqq != &bfqd->oom_bfqq) && ++ bfq_may_be_close_cooperator(bfqq, new_bfqq)) ++ bfq_log_bfqq(bfqd, bfqq, ++ "would have merged with bfq%d, but wr", ++ new_bfqq->pid); ++ ++ if (new_bfqq && !wr_from_too_long(new_bfqq) && ++ likely(new_bfqq != &bfqd->oom_bfqq) && ++ bfq_may_be_close_cooperator(bfqq, new_bfqq)) ++ return bfq_setup_merge(bfqq, new_bfqq); ++ ++ return NULL; ++} ++ ++static void bfq_bfqq_save_state(struct bfq_queue *bfqq) ++{ ++ struct bfq_io_cq *bic = bfqq->bic; ++ ++ /* ++ * If !bfqq->bic, the queue is already shared or its requests ++ * have already been redirected to a shared queue; both idle window ++ * and weight raising state have already been saved. Do nothing. ++ */ ++ if (!bic) ++ return; ++ ++ bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); ++ bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); ++ bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); ++ bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); ++ bic->saved_wr_coeff = bfqq->wr_coeff; ++ bic->saved_wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt; ++ bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish; ++ BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); ++} ++ ++static void bfq_get_bic_reference(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic has a non-NULL value, the bic to which it belongs ++ * is about to begin using a shared bfq_queue. ++ */ ++ if (bfqq->bic) ++ atomic_long_inc(&bfqq->bic->icq.ioc->refcount); ++} ++ ++static void ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (unsigned long) new_bfqq->pid); ++ /* Save weight raising and idle window of the merged queues */ ++ bfq_bfqq_save_state(bfqq); ++ bfq_bfqq_save_state(new_bfqq); ++ if (bfq_bfqq_IO_bound(bfqq)) ++ bfq_mark_bfqq_IO_bound(new_bfqq); ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ /* ++ * If bfqq is weight-raised, then let new_bfqq inherit ++ * weight-raising. To reduce false positives, neglect the case ++ * where bfqq has just been created, but has not yet made it ++ * to be weight-raised (which may happen because EQM may merge ++ * bfqq even before bfq_add_request is executed for the first ++ * time for bfqq). Handling this case would however be very ++ * easy, thanks to the flag just_created. ++ */ ++ if (new_bfqq->wr_coeff == 1 && bfqq->wr_coeff > 1) { ++ new_bfqq->wr_coeff = bfqq->wr_coeff; ++ new_bfqq->wr_cur_max_time = bfqq->wr_cur_max_time; ++ new_bfqq->last_wr_start_finish = bfqq->last_wr_start_finish; ++ new_bfqq->wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt; ++ if (bfq_bfqq_busy(new_bfqq)) ++ bfqd->wr_busy_queues++; ++ new_bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, new_bfqq, ++ "wr start after merge with %d, rais_max_time %u", ++ bfqq->pid, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ if (bfqq->wr_coeff > 1) { /* bfqq has given its wr to new_bfqq */ ++ bfqq->wr_coeff = 1; ++ bfqq->entity.prio_changed = 1; ++ if (bfq_bfqq_busy(bfqq)) ++ bfqd->wr_busy_queues--; ++ } ++ ++ bfq_log_bfqq(bfqd, new_bfqq, "merge_bfqqs: wr_busy %d", ++ bfqd->wr_busy_queues); ++ ++ /* ++ * Grab a reference to the bic, to prevent it from being destroyed ++ * before being possibly touched by a bfq_split_bfqq(). ++ */ ++ bfq_get_bic_reference(bfqq); ++ bfq_get_bic_reference(new_bfqq); ++ /* ++ * Merge queues (that is, let bic redirect its requests to new_bfqq) ++ */ ++ bic_set_bfqq(bic, new_bfqq, 1); ++ bfq_mark_bfqq_coop(new_bfqq); ++ /* ++ * new_bfqq now belongs to at least two bics (it is a shared queue): ++ * set new_bfqq->bic to NULL. bfqq either: ++ * - does not belong to any bic any more, and hence bfqq->bic must ++ * be set to NULL, or ++ * - is a queue whose owning bics have already been redirected to a ++ * different queue, hence the queue is destined to not belong to ++ * any bic soon and bfqq->bic is already NULL (therefore the next ++ * assignment causes no harm). ++ */ ++ new_bfqq->bic = NULL; ++ bfqq->bic = NULL; ++ bfq_put_queue(bfqq); ++} ++ ++static int bfq_allow_bio_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq, *new_bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return false; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (!bic) ++ return false; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ /* ++ * We take advantage of this function to perform an early merge ++ * of the queues of possible cooperating processes. ++ */ ++ if (bfqq) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); ++ if (new_bfqq) { ++ bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); ++ /* ++ * If we get here, the bio will be queued in the ++ * shared queue, i.e., new_bfqq, so use new_bfqq ++ * to decide whether bio and rq can be merged. ++ */ ++ bfqq = new_bfqq; ++ } ++ } ++ ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static int bfq_allow_rq_merge(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ return RQ_BFQQ(rq) == RQ_BFQQ(next); ++} ++ ++/* ++ * Set the maximum time for the in-service queue to consume its ++ * budget. This prevents seeky processes from lowering the throughput. ++ * In practice, a time-slice service scheme is used with seeky ++ * processes. ++ */ ++static void bfq_set_budget_timeout(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ unsigned int timeout_coeff; ++ ++ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) ++ timeout_coeff = 1; ++ else ++ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ ++ bfqd->last_budget_start = ktime_get(); ++ ++ bfqq->budget_timeout = jiffies + ++ bfqd->bfq_timeout * timeout_coeff; ++ ++ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", ++ jiffies_to_msecs(bfqd->bfq_timeout * timeout_coeff)); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq) { ++ bfqg_stats_update_avg_queue_size(bfqq_group(bfqq)); ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ if (time_is_before_jiffies(bfqq->last_wr_start_finish) && ++ bfqq->wr_coeff > 1 && ++ bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time && ++ time_is_before_jiffies(bfqq->budget_timeout)) { ++ /* ++ * For soft real-time queues, move the start ++ * of the weight-raising period forward by the ++ * time the queue has not received any ++ * service. Otherwise, a relatively long ++ * service delay is likely to cause the ++ * weight-raising period of the queue to end, ++ * because of the short duration of the ++ * weight-raising period of a soft real-time ++ * queue. It is worth noting that this move ++ * is not so dangerous for the other queues, ++ * because soft real-time queues are not ++ * greedy. ++ * ++ * To not add a further variable, we use the ++ * overloaded field budget_timeout to ++ * determine for how long the queue has not ++ * received service, i.e., how much time has ++ * elapsed since the queue expired. However, ++ * this is a little imprecise, because ++ * budget_timeout is set to jiffies if bfqq ++ * not only expires, but also remains with no ++ * request. ++ */ ++ bfqq->last_wr_start_finish += jiffies - ++ max_t(unsigned long, bfqq->last_wr_start_finish, ++ bfqq->budget_timeout); ++ if (time_is_after_jiffies(bfqq->last_wr_start_finish)) { ++ pr_crit( ++ "BFQ WARNING:last %lu budget %lu jiffies %lu", ++ bfqq->last_wr_start_finish, ++ bfqq->budget_timeout, ++ jiffies); ++ pr_crit("diff %lu", jiffies - ++ max_t(unsigned long, ++ bfqq->last_wr_start_finish, ++ bfqq->budget_timeout)); ++ bfqq->last_wr_start_finish = jiffies; ++ } ++ } ++ ++ bfq_set_budget_timeout(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %d", ++ bfqq->entity.budget); ++ } else ++ bfq_log(bfqd, "set_in_service_queue: NULL"); ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ ++static void bfq_arm_slice_timer(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ struct bfq_io_cq *bic; ++ u32 sl; ++ ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Processes have exited, don't wait. */ ++ bic = bfqd->in_service_bic; ++ if (!bic || atomic_read(&bic->icq.ioc->active_ref) == 0) ++ return; ++ ++ bfq_mark_bfqq_wait_request(bfqq); ++ ++ /* ++ * We don't want to idle for seeks, but we do want to allow ++ * fair distribution of slice time for a process doing back-to-back ++ * seeks. So allow a little bit of time for him to submit a new rq. ++ * ++ * To prevent processes with (partly) seeky workloads from ++ * being too ill-treated, grant them a small fraction of the ++ * assigned budget before reducing the waiting time to ++ * BFQ_MIN_TT. This happened to help reduce latency. ++ */ ++ sl = bfqd->bfq_slice_idle; ++ /* ++ * Unless the queue is being weight-raised or the scenario is ++ * asymmetric, grant only minimum idle time if the queue ++ * is seeky. A long idling is preserved for a weight-raised ++ * queue, or, more in general, in an asymemtric scenario, ++ * because a long idling is needed for guaranteeing to a queue ++ * its reserved share of the throughput (in particular, it is ++ * needed if the queue has a higher weight than some other ++ * queue). ++ */ ++ if (BFQQ_SEEKY(bfqq) && bfqq->wr_coeff == 1 && ++ bfq_symmetric_scenario(bfqd)) ++ sl = min_t(u32, sl, BFQ_MIN_TT); ++ ++ bfqd->last_idling_start = ktime_get(); ++ hrtimer_start(&bfqd->idle_slice_timer, ns_to_ktime(sl), ++ HRTIMER_MODE_REL); ++ bfqg_stats_set_start_idle_time(bfqq_group(bfqq)); ++ bfq_log(bfqd, "arm idle: %ld/%ld ms", ++ sl / NSEC_PER_MSEC, bfqd->bfq_slice_idle / NSEC_PER_MSEC); ++} ++ ++/* ++ * In autotuning mode, max_budget is dynamically recomputed as the ++ * amount of sectors transferred in timeout at the estimated peak ++ * rate. This enables BFQ to utilize a full timeslice with a full ++ * budget, even if the in-service queue is served at peak rate. And ++ * this maximises throughput with sequential workloads. ++ */ ++static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd) ++{ ++ return (u64)bfqd->peak_rate * USEC_PER_MSEC * ++ jiffies_to_msecs(bfqd->bfq_timeout)>>BFQ_RATE_SHIFT; ++} ++ ++/* ++ * Update parameters related to throughput and responsiveness, as a ++ * function of the estimated peak rate. See comments on ++ * bfq_calc_max_budget(), and on T_slow and T_fast arrays. ++ */ ++void update_thr_responsiveness_params(struct bfq_data *bfqd) ++{ ++ int dev_type = blk_queue_nonrot(bfqd->queue); ++ ++ if (bfqd->bfq_user_max_budget == 0) { ++ bfqd->bfq_max_budget = ++ bfq_calc_max_budget(bfqd); ++ BUG_ON(bfqd->bfq_max_budget < 0); ++ bfq_log(bfqd, "new max_budget = %d", ++ bfqd->bfq_max_budget); ++ } ++ ++ if (bfqd->device_speed == BFQ_BFQD_FAST && ++ bfqd->peak_rate < device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_SLOW; ++ bfqd->RT_prod = R_slow[dev_type] * ++ T_slow[dev_type]; ++ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && ++ bfqd->peak_rate > device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ bfqd->RT_prod = R_fast[dev_type] * ++ T_fast[dev_type]; ++ } ++ ++ bfq_log(bfqd, ++"dev_type %s dev_speed_class = %s (%llu sects/sec), thresh %llu setcs/sec", ++ dev_type == 0 ? "ROT" : "NONROT", ++ bfqd->device_speed == BFQ_BFQD_FAST ? "FAST" : "SLOW", ++ bfqd->device_speed == BFQ_BFQD_FAST ? ++ (USEC_PER_SEC*(u64)R_fast[dev_type])>>BFQ_RATE_SHIFT : ++ (USEC_PER_SEC*(u64)R_slow[dev_type])>>BFQ_RATE_SHIFT, ++ (USEC_PER_SEC*(u64)device_speed_thresh[dev_type])>> ++ BFQ_RATE_SHIFT); ++} ++ ++void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq) ++{ ++ if (rq != NULL) { /* new rq dispatch now, reset accordingly */ ++ bfqd->last_dispatch = bfqd->first_dispatch = ktime_get_ns() ; ++ bfqd->peak_rate_samples = 1; ++ bfqd->sequential_samples = 0; ++ bfqd->tot_sectors_dispatched = bfqd->last_rq_max_size = ++ blk_rq_sectors(rq); ++ } else /* no new rq dispatched, just reset the number of samples */ ++ bfqd->peak_rate_samples = 0; /* full re-init on next disp. */ ++ ++ bfq_log(bfqd, ++ "reset_rate_computation at end, sample %u/%u tot_sects %llu", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ bfqd->tot_sectors_dispatched); ++} ++ ++void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq) ++{ ++ u32 rate, weight, divisor; ++ ++ /* ++ * For the convergence property to hold (see comments on ++ * bfq_update_peak_rate()) and for the assessment to be ++ * reliable, a minimum number of samples must be present, and ++ * a minimum amount of time must have elapsed. If not so, do ++ * not compute new rate. Just reset parameters, to get ready ++ * for a new evaluation attempt. ++ */ ++ if (bfqd->peak_rate_samples < BFQ_RATE_MIN_SAMPLES || ++ bfqd->delta_from_first < BFQ_RATE_MIN_INTERVAL) { ++ bfq_log(bfqd, ++ "update_rate_reset: only resetting, delta_first %lluus samples %d", ++ bfqd->delta_from_first>>10, bfqd->peak_rate_samples); ++ goto reset_computation; ++ } ++ ++ /* ++ * If a new request completion has occurred after last ++ * dispatch, then, to approximate the rate at which requests ++ * have been served by the device, it is more precise to ++ * extend the observation interval to the last completion. ++ */ ++ bfqd->delta_from_first = ++ max_t(u64, bfqd->delta_from_first, ++ bfqd->last_completion - bfqd->first_dispatch); ++ ++ BUG_ON(bfqd->delta_from_first == 0); ++ /* ++ * Rate computed in sects/usec, and not sects/nsec, for ++ * precision issues. ++ */ ++ rate = div64_ul(bfqd->tot_sectors_dispatched<delta_from_first, NSEC_PER_USEC)); ++ ++ bfq_log(bfqd, ++"update_rate_reset: tot_sects %llu delta_first %lluus rate %llu sects/s (%d)", ++ bfqd->tot_sectors_dispatched, bfqd->delta_from_first>>10, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ rate > 20< 20M sectors/sec) ++ */ ++ if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 && ++ rate <= bfqd->peak_rate) || ++ rate > 20<peak_rate_samples, bfqd->sequential_samples, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ goto reset_computation; ++ } else { ++ bfq_log(bfqd, ++ "update_rate_reset: do update, samples %u/%u rate/peak %llu/%llu", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ ((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT), ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ } ++ ++ /* ++ * We have to update the peak rate, at last! To this purpose, ++ * we use a low-pass filter. We compute the smoothing constant ++ * of the filter as a function of the 'weight' of the new ++ * measured rate. ++ * ++ * As can be seen in next formulas, we define this weight as a ++ * quantity proportional to how sequential the workload is, ++ * and to how long the observation time interval is. ++ * ++ * The weight runs from 0 to 8. The maximum value of the ++ * weight, 8, yields the minimum value for the smoothing ++ * constant. At this minimum value for the smoothing constant, ++ * the measured rate contributes for half of the next value of ++ * the estimated peak rate. ++ * ++ * So, the first step is to compute the weight as a function ++ * of how sequential the workload is. Note that the weight ++ * cannot reach 9, because bfqd->sequential_samples cannot ++ * become equal to bfqd->peak_rate_samples, which, in its ++ * turn, holds true because bfqd->sequential_samples is not ++ * incremented for the first sample. ++ */ ++ weight = (9 * bfqd->sequential_samples) / bfqd->peak_rate_samples; ++ ++ /* ++ * Second step: further refine the weight as a function of the ++ * duration of the observation interval. ++ */ ++ weight = min_t(u32, 8, ++ div_u64(weight * bfqd->delta_from_first, ++ BFQ_RATE_REF_INTERVAL)); ++ ++ /* ++ * Divisor ranging from 10, for minimum weight, to 2, for ++ * maximum weight. ++ */ ++ divisor = 10 - weight; ++ BUG_ON(divisor == 0); ++ ++ /* ++ * Finally, update peak rate: ++ * ++ * peak_rate = peak_rate * (divisor-1) / divisor + rate / divisor ++ */ ++ bfqd->peak_rate *= divisor-1; ++ bfqd->peak_rate /= divisor; ++ rate /= divisor; /* smoothing constant alpha = 1/divisor */ ++ ++ bfq_log(bfqd, ++ "update_rate_reset: divisor %d tmp_peak_rate %llu tmp_rate %u", ++ divisor, ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT), ++ (u32)((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT)); ++ ++ BUG_ON(bfqd->peak_rate == 0); ++ BUG_ON(bfqd->peak_rate > 20<peak_rate += rate; ++ update_thr_responsiveness_params(bfqd); ++ BUG_ON(bfqd->peak_rate > 20<peak_rate_samples == 0) { /* first dispatch */ ++ bfq_log(bfqd, ++ "update_peak_rate: goto reset, samples %d", ++ bfqd->peak_rate_samples) ; ++ bfq_reset_rate_computation(bfqd, rq); ++ goto update_last_values; /* will add one sample */ ++ } ++ ++ /* ++ * Device idle for very long: the observation interval lasting ++ * up to this dispatch cannot be a valid observation interval ++ * for computing a new peak rate (similarly to the late- ++ * completion event in bfq_completed_request()). Go to ++ * update_rate_and_reset to have the following three steps ++ * taken: ++ * - close the observation interval at the last (previous) ++ * request dispatch or completion ++ * - compute rate, if possible, for that observation interval ++ * - start a new observation interval with this dispatch ++ */ ++ if (now_ns - bfqd->last_dispatch > 100*NSEC_PER_MSEC && ++ bfqd->rq_in_driver == 0) { ++ bfq_log(bfqd, ++"update_peak_rate: jumping to updating&resetting delta_last %lluus samples %d", ++ (now_ns - bfqd->last_dispatch)>>10, ++ bfqd->peak_rate_samples) ; ++ goto update_rate_and_reset; ++ } ++ ++ /* Update sampling information */ ++ bfqd->peak_rate_samples++; ++ ++ if ((bfqd->rq_in_driver > 0 || ++ now_ns - bfqd->last_completion < BFQ_MIN_TT) ++ && get_sdist(bfqd->last_position, rq) < BFQQ_SEEK_THR) ++ bfqd->sequential_samples++; ++ ++ bfqd->tot_sectors_dispatched += blk_rq_sectors(rq); ++ ++ /* Reset max observed rq size every 32 dispatches */ ++ if (likely(bfqd->peak_rate_samples % 32)) ++ bfqd->last_rq_max_size = ++ max_t(u32, blk_rq_sectors(rq), bfqd->last_rq_max_size); ++ else ++ bfqd->last_rq_max_size = blk_rq_sectors(rq); ++ ++ bfqd->delta_from_first = now_ns - bfqd->first_dispatch; ++ ++ bfq_log(bfqd, ++ "update_peak_rate: added samples %u/%u tot_sects %llu delta_first %lluus", ++ bfqd->peak_rate_samples, bfqd->sequential_samples, ++ bfqd->tot_sectors_dispatched, ++ bfqd->delta_from_first>>10); ++ ++ /* Target observation interval not yet reached, go on sampling */ ++ if (bfqd->delta_from_first < BFQ_RATE_REF_INTERVAL) ++ goto update_last_values; ++ ++update_rate_and_reset: ++ bfq_update_rate_reset(bfqd, rq); ++update_last_values: ++ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ bfqd->last_dispatch = now_ns; ++ ++ bfq_log(bfqd, ++ "update_peak_rate: delta_first %lluus last_pos %llu peak_rate %llu", ++ (now_ns - bfqd->first_dispatch)>>10, ++ (unsigned long long) bfqd->last_position, ++ ((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT)); ++ bfq_log(bfqd, ++ "update_peak_rate: samples at end %d", bfqd->peak_rate_samples); ++} ++ ++/* ++ * Move request from internal lists to the dispatch list of the request queue ++ */ ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * For consistency, the next instruction should have been executed ++ * after removing the request from the queue and dispatching it. ++ * We execute instead this instruction before bfq_remove_request() ++ * (and hence introduce a temporary inconsistency), for efficiency. ++ * In fact, in a forced_dispatch, this prevents two counters related ++ * to bfqq->dispatched to risk to be uselessly decremented if bfqq ++ * is not in service, and then to be incremented again after ++ * incrementing bfqq->dispatched. ++ */ ++ bfqq->dispatched++; ++ bfq_update_peak_rate(q->elevator->elevator_data, rq); ++ ++ bfq_remove_request(rq); ++ elv_dispatch_sort(q, rq); ++} ++ ++/* ++ * Return expired entry, or NULL to just start from scratch in rbtree. ++ */ ++static struct request *bfq_check_fifo(struct bfq_queue *bfqq) ++{ ++ struct request *rq = NULL; ++ ++ if (bfq_bfqq_fifo_expire(bfqq)) ++ return NULL; ++ ++ bfq_mark_bfqq_fifo_expire(bfqq); ++ ++ if (list_empty(&bfqq->fifo)) ++ return NULL; ++ ++ rq = rq_entry_fifo(bfqq->fifo.next); ++ ++ if (ktime_get_ns() < rq->fifo_time) ++ return NULL; ++ ++ return rq; ++} ++ ++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ /* ++ * If this bfqq is shared between multiple processes, check ++ * to make sure that those processes are still issuing I/Os ++ * within the mean seek distance. If not, it may be time to ++ * break the queues apart again. ++ */ ++ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) ++ bfq_mark_bfqq_split_coop(bfqq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ if (bfqq->dispatched == 0) ++ /* ++ * Overloading budget_timeout field to store ++ * the time at which the queue remains with no ++ * backlog and no outstanding request; used by ++ * the weight-raising mechanism. ++ */ ++ bfqq->budget_timeout = jiffies; ++ ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ } else { ++ bfq_activate_bfqq(bfqd, bfqq); ++ /* ++ * Resort priority tree of potential close cooperators. ++ */ ++ bfq_pos_tree_add_move(bfqd, bfqq); ++ } ++} ++ ++/** ++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. ++ * @bfqd: device data. ++ * @bfqq: queue to update. ++ * @reason: reason for expiration. ++ * ++ * Handle the feedback on @bfqq budget at queue expiration. ++ * See the body for detailed comments. ++ */ ++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ enum bfqq_expiration reason) ++{ ++ struct request *next_rq; ++ int budget, min_budget; ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ min_budget = bfq_min_budget(bfqd); ++ ++ if (bfqq->wr_coeff == 1) ++ budget = bfqq->max_budget; ++ else /* ++ * Use a constant, low budget for weight-raised queues, ++ * to help achieve a low latency. Keep it slightly higher ++ * than the minimum possible budget, to cause a little ++ * bit fewer expirations. ++ */ ++ budget = 2 * min_budget; ++ ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %d, budg left %d", ++ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %d, min budg %d", ++ budget, bfq_min_budget(bfqd)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", ++ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); ++ ++ if (bfq_bfqq_sync(bfqq) && bfqq->wr_coeff == 1) { ++ switch (reason) { ++ /* ++ * Caveat: in all the following cases we trade latency ++ * for throughput. ++ */ ++ case BFQ_BFQQ_TOO_IDLE: ++ /* ++ * This is the only case where we may reduce ++ * the budget: if there is no request of the ++ * process still waiting for completion, then ++ * we assume (tentatively) that the timer has ++ * expired because the batch of requests of ++ * the process could have been served with a ++ * smaller budget. Hence, betting that ++ * process will behave in the same way when it ++ * becomes backlogged again, we reduce its ++ * next budget. As long as we guess right, ++ * this budget cut reduces the latency ++ * experienced by the process. ++ * ++ * However, if there are still outstanding ++ * requests, then the process may have not yet ++ * issued its next request just because it is ++ * still waiting for the completion of some of ++ * the still outstanding ones. So in this ++ * subcase we do not reduce its budget, on the ++ * contrary we increase it to possibly boost ++ * the throughput, as discussed in the ++ * comments to the BUDGET_TIMEOUT case. ++ */ ++ if (bfqq->dispatched > 0) /* still outstanding reqs */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ else { ++ if (budget > 5 * min_budget) ++ budget -= 4 * min_budget; ++ else ++ budget = min_budget; ++ } ++ break; ++ case BFQ_BFQQ_BUDGET_TIMEOUT: ++ /* ++ * We double the budget here because it gives ++ * the chance to boost the throughput if this ++ * is not a seeky process (and has bumped into ++ * this timeout because of, e.g., ZBR). ++ */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_BUDGET_EXHAUSTED: ++ /* ++ * The process still has backlog, and did not ++ * let either the budget timeout or the disk ++ * idling timeout expire. Hence it is not ++ * seeky, has a short thinktime and may be ++ * happy with a higher budget too. So ++ * definitely increase the budget of this good ++ * candidate to boost the disk throughput. ++ */ ++ budget = min(budget * 4, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_NO_MORE_REQUESTS: ++ /* ++ * For queues that expire for this reason, it ++ * is particularly important to keep the ++ * budget close to the actual service they ++ * need. Doing so reduces the timestamp ++ * misalignment problem described in the ++ * comments in the body of ++ * __bfq_activate_entity. In fact, suppose ++ * that a queue systematically expires for ++ * BFQ_BFQQ_NO_MORE_REQUESTS and presents a ++ * new request in time to enjoy timestamp ++ * back-shifting. The larger the budget of the ++ * queue is with respect to the service the ++ * queue actually requests in each service ++ * slot, the more times the queue can be ++ * reactivated with the same virtual finish ++ * time. It follows that, even if this finish ++ * time is pushed to the system virtual time ++ * to reduce the consequent timestamp ++ * misalignment, the queue unjustly enjoys for ++ * many re-activations a lower finish time ++ * than all newly activated queues. ++ * ++ * The service needed by bfqq is measured ++ * quite precisely by bfqq->entity.service. ++ * Since bfqq does not enjoy device idling, ++ * bfqq->entity.service is equal to the number ++ * of sectors that the process associated with ++ * bfqq requested to read/write before waiting ++ * for request completions, or blocking for ++ * other reasons. ++ */ ++ budget = max_t(int, bfqq->entity.service, min_budget); ++ break; ++ default: ++ return; ++ } ++ } else if (!bfq_bfqq_sync(bfqq)) ++ /* ++ * Async queues get always the maximum possible ++ * budget, as for them we do not care about latency ++ * (in addition, their ability to dispatch is limited ++ * by the charging factor). ++ */ ++ budget = bfqd->bfq_max_budget; ++ ++ bfqq->max_budget = budget; ++ ++ if (bfqd->budgets_assigned >= bfq_stats_min_budgets && ++ !bfqd->bfq_user_max_budget) ++ bfqq->max_budget = min(bfqq->max_budget, bfqd->bfq_max_budget); ++ ++ /* ++ * If there is still backlog, then assign a new budget, making ++ * sure that it is large enough for the next request. Since ++ * the finish time of bfqq must be kept in sync with the ++ * budget, be sure to call __bfq_bfqq_expire() *after* this ++ * update. ++ * ++ * If there is no backlog, then no need to update the budget; ++ * it will be updated on the arrival of a new request. ++ */ ++ next_rq = bfqq->next_rq; ++ if (next_rq) { ++ BUG_ON(reason == BFQ_BFQQ_TOO_IDLE || ++ reason == BFQ_BFQQ_NO_MORE_REQUESTS); ++ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %d", ++ next_rq ? blk_rq_sectors(next_rq) : 0, ++ bfqq->entity.budget); ++} ++ ++/* ++ * Return true if the process associated with bfqq is "slow". The slow ++ * flag is used, in addition to the budget timeout, to reduce the ++ * amount of service provided to seeky processes, and thus reduce ++ * their chances to lower the throughput. More details in the comments ++ * on the function bfq_bfqq_expire(). ++ * ++ * An important observation is in order: as discussed in the comments ++ * on the function bfq_update_peak_rate(), with devices with internal ++ * queues, it is hard if ever possible to know when and for how long ++ * an I/O request is processed by the device (apart from the trivial ++ * I/O pattern where a new request is dispatched only after the ++ * previous one has been completed). This makes it hard to evaluate ++ * the real rate at which the I/O requests of each bfq_queue are ++ * served. In fact, for an I/O scheduler like BFQ, serving a ++ * bfq_queue means just dispatching its requests during its service ++ * slot (i.e., until the budget of the queue is exhausted, or the ++ * queue remains idle, or, finally, a timeout fires). But, during the ++ * service slot of a bfq_queue, around 100 ms at most, the device may ++ * be even still processing requests of bfq_queues served in previous ++ * service slots. On the opposite end, the requests of the in-service ++ * bfq_queue may be completed after the service slot of the queue ++ * finishes. ++ * ++ * Anyway, unless more sophisticated solutions are used ++ * (where possible), the sum of the sizes of the requests dispatched ++ * during the service slot of a bfq_queue is probably the only ++ * approximation available for the service received by the bfq_queue ++ * during its service slot. And this sum is the quantity used in this ++ * function to evaluate the I/O speed of a process. ++ */ ++static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ bool compensate, enum bfqq_expiration reason, ++ unsigned long *delta_ms) ++{ ++ ktime_t delta_ktime; ++ u32 delta_usecs; ++ bool slow = BFQQ_SEEKY(bfqq); /* if delta too short, use seekyness */ ++ ++ if (!bfq_bfqq_sync(bfqq)) ++ return false; ++ ++ if (compensate) ++ delta_ktime = bfqd->last_idling_start; ++ else ++ delta_ktime = ktime_get(); ++ delta_ktime = ktime_sub(delta_ktime, bfqd->last_budget_start); ++ delta_usecs = ktime_to_us(delta_ktime); ++ ++ /* don't trust short/unrealistic values. */ ++ if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) { ++ if (blk_queue_nonrot(bfqd->queue)) ++ /* ++ * give same worst-case guarantees as idling ++ * for seeky ++ */ ++ *delta_ms = BFQ_MIN_TT / NSEC_PER_MSEC; ++ else /* charge at least one seek */ ++ *delta_ms = bfq_slice_idle / NSEC_PER_MSEC; ++ ++ bfq_log(bfqd, "bfq_bfqq_is_slow: unrealistic %u", delta_usecs); ++ ++ return slow; ++ } ++ ++ *delta_ms = delta_usecs / USEC_PER_MSEC; ++ ++ /* ++ * Use only long (> 20ms) intervals to filter out excessive ++ * spikes in service rate estimation. ++ */ ++ if (delta_usecs > 20000) { ++ /* ++ * Caveat for rotational devices: processes doing I/O ++ * in the slower disk zones tend to be slow(er) even ++ * if not seeky. In this respect, the estimated peak ++ * rate is likely to be an average over the disk ++ * surface. Accordingly, to not be too harsh with ++ * unlucky processes, a process is deemed slow only if ++ * its rate has been lower than half of the estimated ++ * peak rate. ++ */ ++ slow = bfqq->entity.service < bfqd->bfq_max_budget / 2; ++ bfq_log(bfqd, "bfq_bfqq_is_slow: relative rate %d/%d", ++ bfqq->entity.service, bfqd->bfq_max_budget); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "bfq_bfqq_is_slow: slow %d", slow); ++ ++ return slow; ++} ++ ++/* ++ * To be deemed as soft real-time, an application must meet two ++ * requirements. First, the application must not require an average ++ * bandwidth higher than the approximate bandwidth required to playback or ++ * record a compressed high-definition video. ++ * The next function is invoked on the completion of the last request of a ++ * batch, to compute the next-start time instant, soft_rt_next_start, such ++ * that, if the next request of the application does not arrive before ++ * soft_rt_next_start, then the above requirement on the bandwidth is met. ++ * ++ * The second requirement is that the request pattern of the application is ++ * isochronous, i.e., that, after issuing a request or a batch of requests, ++ * the application stops issuing new requests until all its pending requests ++ * have been completed. After that, the application may issue a new batch, ++ * and so on. ++ * For this reason the next function is invoked to compute ++ * soft_rt_next_start only for applications that meet this requirement, ++ * whereas soft_rt_next_start is set to infinity for applications that do ++ * not. ++ * ++ * Unfortunately, even a greedy application may happen to behave in an ++ * isochronous way if the CPU load is high. In fact, the application may ++ * stop issuing requests while the CPUs are busy serving other processes, ++ * then restart, then stop again for a while, and so on. In addition, if ++ * the disk achieves a low enough throughput with the request pattern ++ * issued by the application (e.g., because the request pattern is random ++ * and/or the device is slow), then the application may meet the above ++ * bandwidth requirement too. To prevent such a greedy application to be ++ * deemed as soft real-time, a further rule is used in the computation of ++ * soft_rt_next_start: soft_rt_next_start must be higher than the current ++ * time plus the maximum time for which the arrival of a request is waited ++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. ++ * This filters out greedy applications, as the latter issue instead their ++ * next request as soon as possible after the last one has been completed ++ * (in contrast, when a batch of requests is completed, a soft real-time ++ * application spends some time processing data). ++ * ++ * Unfortunately, the last filter may easily generate false positives if ++ * only bfqd->bfq_slice_idle is used as a reference time interval and one ++ * or both the following cases occur: ++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher ++ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with ++ * HZ=100. ++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing ++ * for a while, then suddenly 'jump' by several units to recover the lost ++ * increments. This seems to happen, e.g., inside virtual machines. ++ * To address this issue, we do not use as a reference time interval just ++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In ++ * particular we add the minimum number of jiffies for which the filter ++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual ++ * machines. ++ */ ++static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, ++"softrt_next_start: service_blkg %lu soft_rate %u sects/sec interval %u", ++ bfqq->service_from_backlogged, ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies_to_msecs(HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate)); ++ ++ return max(bfqq->last_idle_bklogged + ++ HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4); ++} ++ ++/* ++ * Return the farthest future time instant according to jiffies ++ * macros. ++ */ ++static unsigned long bfq_greatest_from_now(void) ++{ ++ return jiffies + MAX_JIFFY_OFFSET; ++} ++ ++/* ++ * Return the farthest past time instant according to jiffies ++ * macros. ++ */ ++static unsigned long bfq_smallest_from_now(void) ++{ ++ return jiffies - MAX_JIFFY_OFFSET; ++} ++ ++/** ++ * bfq_bfqq_expire - expire a queue. ++ * @bfqd: device owning the queue. ++ * @bfqq: the queue to expire. ++ * @compensate: if true, compensate for the time spent idling. ++ * @reason: the reason causing the expiration. ++ * ++ * If the process associated with bfqq does slow I/O (e.g., because it ++ * issues random requests), we charge bfqq with the time it has been ++ * in service instead of the service it has received (see ++ * bfq_bfqq_charge_time for details on how this goal is achieved). As ++ * a consequence, bfqq will typically get higher timestamps upon ++ * reactivation, and hence it will be rescheduled as if it had ++ * received more service than what it has actually received. In the ++ * end, bfqq receives less service in proportion to how slowly its ++ * associated process consumes its budgets (and hence how seriously it ++ * tends to lower the throughput). In addition, this time-charging ++ * strategy guarantees time fairness among slow processes. In ++ * contrast, if the process associated with bfqq is not slow, we ++ * charge bfqq exactly with the service it has received. ++ * ++ * Charging time to the first type of queues and the exact service to ++ * the other has the effect of using the WF2Q+ policy to schedule the ++ * former on a timeslice basis, without violating service domain ++ * guarantees among the latter. ++ */ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ bool compensate, ++ enum bfqq_expiration reason) ++{ ++ bool slow; ++ unsigned long delta = 0; ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ /* ++ * Check whether the process is slow (see bfq_bfqq_is_slow). ++ */ ++ slow = bfq_bfqq_is_slow(bfqd, bfqq, compensate, reason, &delta); ++ ++ /* ++ * Increase service_from_backlogged before next statement, ++ * because the possible next invocation of ++ * bfq_bfqq_charge_time would likely inflate ++ * entity->service. In contrast, service_from_backlogged must ++ * contain real service, to enable the soft real-time ++ * heuristic to correctly compute the bandwidth consumed by ++ * bfqq. ++ */ ++ bfqq->service_from_backlogged += entity->service; ++ ++ /* ++ * As above explained, charge slow (typically seeky) and ++ * timed-out queues with the time and not the service ++ * received, to favor sequential workloads. ++ * ++ * Processes doing I/O in the slower disk zones will tend to ++ * be slow(er) even if not seeky. Therefore, since the ++ * estimated peak rate is actually an average over the disk ++ * surface, these processes may timeout just for bad luck. To ++ * avoid punishing them, do not charge time to processes that ++ * succeeded in consuming at least 2/3 of their budget. This ++ * allows BFQ to preserve enough elasticity to still perform ++ * bandwidth, and not time, distribution with little unlucky ++ * or quasi-sequential processes. ++ */ ++ if (bfqq->wr_coeff == 1 && ++ (slow || ++ (reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ bfq_bfqq_budget_left(bfqq) >= entity->budget / 3))) ++ bfq_bfqq_charge_time(bfqd, bfqq, delta); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ if (reason == BFQ_BFQQ_TOO_IDLE && ++ entity->service <= 2 * entity->budget / 10) ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ if (bfqd->low_latency && bfqq->wr_coeff == 1) ++ bfqq->last_wr_start_finish = jiffies; ++ ++ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * If we get here, and there are no outstanding ++ * requests, then the request pattern is isochronous ++ * (see the comments on the function ++ * bfq_bfqq_softrt_next_start()). Thus we can compute ++ * soft_rt_next_start. If, instead, the queue still ++ * has outstanding requests, then we have to wait for ++ * the completion of all the outstanding requests to ++ * discover whether the request pattern is actually ++ * isochronous. ++ */ ++ BUG_ON(bfqd->busy_queues < 1); ++ if (bfqq->dispatched == 0) { ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ bfq_log_bfqq(bfqd, bfqq, "new soft_rt_next %lu", ++ bfqq->soft_rt_next_start); ++ } else { ++ /* ++ * The application is still waiting for the ++ * completion of one or more requests: ++ * prevent it from possibly being incorrectly ++ * deemed as soft real-time by setting its ++ * soft_rt_next_start to infinity. In fact, ++ * without this assignment, the application ++ * would be incorrectly deemed as soft ++ * real-time if: ++ * 1) it issued a new request before the ++ * completion of all its in-flight ++ * requests, and ++ * 2) at that time, its soft_rt_next_start ++ * happened to be in the past. ++ */ ++ bfqq->soft_rt_next_start = ++ bfq_greatest_from_now(); ++ /* ++ * Schedule an update of soft_rt_next_start to when ++ * the task may be discovered to be isochronous. ++ */ ++ bfq_mark_bfqq_softrt_update(bfqq); ++ } ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "expire (%d, slow %d, num_disp %d, idle_win %d, weight %d)", ++ reason, slow, bfqq->dispatched, ++ bfq_bfqq_idle_window(bfqq), entity->weight); ++ ++ /* ++ * Increase, decrease or leave budget unchanged according to ++ * reason. ++ */ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); ++ BUG_ON(bfqq->next_rq == NULL && ++ bfqq->entity.budget < bfqq->entity.service); ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED && ++ !bfq_class_idle(bfqq)); ++ ++ if (!bfq_bfqq_busy(bfqq) && ++ reason != BFQ_BFQQ_BUDGET_TIMEOUT && ++ reason != BFQ_BFQQ_BUDGET_EXHAUSTED) ++ bfq_mark_bfqq_non_blocking_wait_rq(bfqq); ++} ++ ++/* ++ * Budget timeout is not implemented through a dedicated timer, but ++ * just checked on request arrivals and completions, as well as on ++ * idle timer expirations. ++ */ ++static bool bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) ++{ ++ return time_is_before_eq_jiffies(bfqq->budget_timeout); ++} ++ ++/* ++ * If we expire a queue that is actively waiting (i.e., with the ++ * device idled) for the arrival of a new request, then we may incur ++ * the timestamp misalignment problem described in the body of the ++ * function __bfq_activate_entity. Hence we return true only if this ++ * condition does not hold, or if the queue is slow enough to deserve ++ * only to be kicked off for preserving a high throughput. ++ */ ++static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "may_budget_timeout: wait_request %d left %d timeout %d", ++ bfq_bfqq_wait_request(bfqq), ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, ++ bfq_bfqq_budget_timeout(bfqq)); ++ ++ return (!bfq_bfqq_wait_request(bfqq) || ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) ++ && ++ bfq_bfqq_budget_timeout(bfqq); ++} ++ ++/* ++ * For a queue that becomes empty, device idling is allowed only if ++ * this function returns true for that queue. As a consequence, since ++ * device idling plays a critical role for both throughput boosting ++ * and service guarantees, the return value of this function plays a ++ * critical role as well. ++ * ++ * In a nutshell, this function returns true only if idling is ++ * beneficial for throughput or, even if detrimental for throughput, ++ * idling is however necessary to preserve service guarantees (low ++ * latency, desired throughput distribution, ...). In particular, on ++ * NCQ-capable devices, this function tries to return false, so as to ++ * help keep the drives' internal queues full, whenever this helps the ++ * device boost the throughput without causing any service-guarantee ++ * issue. ++ * ++ * In more detail, the return value of this function is obtained by, ++ * first, computing a number of boolean variables that take into ++ * account throughput and service-guarantee issues, and, then, ++ * combining these variables in a logical expression. Most of the ++ * issues taken into account are not trivial. We discuss these issues ++ * while introducing the variables. ++ */ ++static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ bool idling_boosts_thr, idling_boosts_thr_without_issues, ++ idling_needed_for_service_guarantees, ++ asymmetric_scenario; ++ ++ if (bfqd->strict_guarantees) ++ return true; ++ ++ /* ++ * The next variable takes into account the cases where idling ++ * boosts the throughput. ++ * ++ * The value of the variable is computed considering, first, that ++ * idling is virtually always beneficial for the throughput if: ++ * (a) the device is not NCQ-capable, or ++ * (b) regardless of the presence of NCQ, the device is rotational ++ * and the request pattern for bfqq is I/O-bound and sequential. ++ * ++ * Secondly, and in contrast to the above item (b), idling an ++ * NCQ-capable flash-based device would not boost the ++ * throughput even with sequential I/O; rather it would lower ++ * the throughput in proportion to how fast the device ++ * is. Accordingly, the next variable is true if any of the ++ * above conditions (a) and (b) is true, and, in particular, ++ * happens to be false if bfqd is an NCQ-capable flash-based ++ * device. ++ */ ++ idling_boosts_thr = !bfqd->hw_tag || ++ (!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && ++ bfq_bfqq_idle_window(bfqq)); ++ ++ /* ++ * The value of the next variable, ++ * idling_boosts_thr_without_issues, is equal to that of ++ * idling_boosts_thr, unless a special case holds. In this ++ * special case, described below, idling may cause problems to ++ * weight-raised queues. ++ * ++ * When the request pool is saturated (e.g., in the presence ++ * of write hogs), if the processes associated with ++ * non-weight-raised queues ask for requests at a lower rate, ++ * then processes associated with weight-raised queues have a ++ * higher probability to get a request from the pool ++ * immediately (or at least soon) when they need one. Thus ++ * they have a higher probability to actually get a fraction ++ * of the device throughput proportional to their high ++ * weight. This is especially true with NCQ-capable drives, ++ * which enqueue several requests in advance, and further ++ * reorder internally-queued requests. ++ * ++ * For this reason, we force to false the value of ++ * idling_boosts_thr_without_issues if there are weight-raised ++ * busy queues. In this case, and if bfqq is not weight-raised, ++ * this guarantees that the device is not idled for bfqq (if, ++ * instead, bfqq is weight-raised, then idling will be ++ * guaranteed by another variable, see below). Combined with ++ * the timestamping rules of BFQ (see [1] for details), this ++ * behavior causes bfqq, and hence any sync non-weight-raised ++ * queue, to get a lower number of requests served, and thus ++ * to ask for a lower number of requests from the request ++ * pool, before the busy weight-raised queues get served ++ * again. This often mitigates starvation problems in the ++ * presence of heavy write workloads and NCQ, thereby ++ * guaranteeing a higher application and system responsiveness ++ * in these hostile scenarios. ++ */ ++ idling_boosts_thr_without_issues = idling_boosts_thr && ++ bfqd->wr_busy_queues == 0; ++ ++ /* ++ * There is then a case where idling must be performed not ++ * for throughput concerns, but to preserve service ++ * guarantees. ++ * ++ * To introduce this case, we can note that allowing the drive ++ * to enqueue more than one request at a time, and hence ++ * delegating de facto final scheduling decisions to the ++ * drive's internal scheduler, entails loss of control on the ++ * actual request service order. In particular, the critical ++ * situation is when requests from different processes happen ++ * to be present, at the same time, in the internal queue(s) ++ * of the drive. In such a situation, the drive, by deciding ++ * the service order of the internally-queued requests, does ++ * determine also the actual throughput distribution among ++ * these processes. But the drive typically has no notion or ++ * concern about per-process throughput distribution, and ++ * makes its decisions only on a per-request basis. Therefore, ++ * the service distribution enforced by the drive's internal ++ * scheduler is likely to coincide with the desired ++ * device-throughput distribution only in a completely ++ * symmetric scenario where: ++ * (i) each of these processes must get the same throughput as ++ * the others; ++ * (ii) all these processes have the same I/O pattern ++ * (either sequential or random). ++ * In fact, in such a scenario, the drive will tend to treat ++ * the requests of each of these processes in about the same ++ * way as the requests of the others, and thus to provide ++ * each of these processes with about the same throughput ++ * (which is exactly the desired throughput distribution). In ++ * contrast, in any asymmetric scenario, device idling is ++ * certainly needed to guarantee that bfqq receives its ++ * assigned fraction of the device throughput (see [1] for ++ * details). ++ * ++ * We address this issue by controlling, actually, only the ++ * symmetry sub-condition (i), i.e., provided that ++ * sub-condition (i) holds, idling is not performed, ++ * regardless of whether sub-condition (ii) holds. In other ++ * words, only if sub-condition (i) holds, then idling is ++ * allowed, and the device tends to be prevented from queueing ++ * many requests, possibly of several processes. The reason ++ * for not controlling also sub-condition (ii) is that we ++ * exploit preemption to preserve guarantees in case of ++ * symmetric scenarios, even if (ii) does not hold, as ++ * explained in the next two paragraphs. ++ * ++ * Even if a queue, say Q, is expired when it remains idle, Q ++ * can still preempt the new in-service queue if the next ++ * request of Q arrives soon (see the comments on ++ * bfq_bfqq_update_budg_for_activation). If all queues and ++ * groups have the same weight, this form of preemption, ++ * combined with the hole-recovery heuristic described in the ++ * comments on function bfq_bfqq_update_budg_for_activation, ++ * are enough to preserve a correct bandwidth distribution in ++ * the mid term, even without idling. In fact, even if not ++ * idling allows the internal queues of the device to contain ++ * many requests, and thus to reorder requests, we can rather ++ * safely assume that the internal scheduler still preserves a ++ * minimum of mid-term fairness. The motivation for using ++ * preemption instead of idling is that, by not idling, ++ * service guarantees are preserved without minimally ++ * sacrificing throughput. In other words, both a high ++ * throughput and its desired distribution are obtained. ++ * ++ * More precisely, this preemption-based, idleless approach ++ * provides fairness in terms of IOPS, and not sectors per ++ * second. This can be seen with a simple example. Suppose ++ * that there are two queues with the same weight, but that ++ * the first queue receives requests of 8 sectors, while the ++ * second queue receives requests of 1024 sectors. In ++ * addition, suppose that each of the two queues contains at ++ * most one request at a time, which implies that each queue ++ * always remains idle after it is served. Finally, after ++ * remaining idle, each queue receives very quickly a new ++ * request. It follows that the two queues are served ++ * alternatively, preempting each other if needed. This ++ * implies that, although both queues have the same weight, ++ * the queue with large requests receives a service that is ++ * 1024/8 times as high as the service received by the other ++ * queue. ++ * ++ * On the other hand, device idling is performed, and thus ++ * pure sector-domain guarantees are provided, for the ++ * following queues, which are likely to need stronger ++ * throughput guarantees: weight-raised queues, and queues ++ * with a higher weight than other queues. When such queues ++ * are active, sub-condition (i) is false, which triggers ++ * device idling. ++ * ++ * According to the above considerations, the next variable is ++ * true (only) if sub-condition (i) holds. To compute the ++ * value of this variable, we not only use the return value of ++ * the function bfq_symmetric_scenario(), but also check ++ * whether bfqq is being weight-raised, because ++ * bfq_symmetric_scenario() does not take into account also ++ * weight-raised queues (see comments on ++ * bfq_weights_tree_add()). ++ * ++ * As a side note, it is worth considering that the above ++ * device-idling countermeasures may however fail in the ++ * following unlucky scenario: if idling is (correctly) ++ * disabled in a time period during which all symmetry ++ * sub-conditions hold, and hence the device is allowed to ++ * enqueue many requests, but at some later point in time some ++ * sub-condition stops to hold, then it may become impossible ++ * to let requests be served in the desired order until all ++ * the requests already queued in the device have been served. ++ */ ++ asymmetric_scenario = bfqq->wr_coeff > 1 || ++ !bfq_symmetric_scenario(bfqd); ++ ++ /* ++ * Finally, there is a case where maximizing throughput is the ++ * best choice even if it may cause unfairness toward ++ * bfqq. Such a case is when bfqq became active in a burst of ++ * queue activations. Queues that became active during a large ++ * burst benefit only from throughput, as discussed in the ++ * comments on bfq_handle_burst. Thus, if bfqq became active ++ * in a burst and not idling the device maximizes throughput, ++ * then the device must no be idled, because not idling the ++ * device provides bfqq and all other queues in the burst with ++ * maximum benefit. Combining this and the above case, we can ++ * now establish when idling is actually needed to preserve ++ * service guarantees. ++ */ ++ idling_needed_for_service_guarantees = ++ asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq); ++ ++ /* ++ * We have now all the components we need to compute the return ++ * value of the function, which is true only if both the following ++ * conditions hold: ++ * 1) bfqq is sync, because idling make sense only for sync queues; ++ * 2) idling either boosts the throughput (without issues), or ++ * is necessary to preserve service guarantees. ++ */ ++ bfq_log_bfqq(bfqd, bfqq, "may_idle: sync %d idling_boosts_thr %d", ++ bfq_bfqq_sync(bfqq), idling_boosts_thr); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "may_idle: wr_busy %d boosts %d IO-bound %d guar %d", ++ bfqd->wr_busy_queues, ++ idling_boosts_thr_without_issues, ++ bfq_bfqq_IO_bound(bfqq), ++ idling_needed_for_service_guarantees); ++ ++ return bfq_bfqq_sync(bfqq) && ++ (idling_boosts_thr_without_issues || ++ idling_needed_for_service_guarantees); ++} ++ ++/* ++ * If the in-service queue is empty but the function bfq_bfqq_may_idle ++ * returns true, then: ++ * 1) the queue must remain in service and cannot be expired, and ++ * 2) the device must be idled to wait for the possible arrival of a new ++ * request for the queue. ++ * See the comments on the function bfq_bfqq_may_idle for the reasons ++ * why performing device idling is the best choice to boost the throughput ++ * and preserve service guarantees when bfq_bfqq_may_idle itself ++ * returns true. ++ */ ++static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && ++ bfq_bfqq_may_idle(bfqq); ++} ++ ++/* ++ * Select a queue for service. If we have a current queue in service, ++ * check whether to continue servicing it, or retrieve and set a new one. ++ */ ++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ struct request *next_rq; ++ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ ++ bfqq = bfqd->in_service_queue; ++ if (!bfqq) ++ goto new_queue; ++ ++ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); ++ ++ if (bfq_may_expire_for_budg_timeout(bfqq) && ++ !hrtimer_active(&bfqd->idle_slice_timer) && ++ !bfq_bfqq_must_idle(bfqq)) ++ goto expire; ++ ++ next_rq = bfqq->next_rq; ++ /* ++ * If bfqq has requests queued and it has enough budget left to ++ * serve them, keep the queue, otherwise expire it. ++ */ ++ if (next_rq) { ++ if (bfq_serv_to_charge(next_rq, bfqq) > ++ bfq_bfqq_budget_left(bfqq)) { ++ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; ++ goto expire; ++ } else { ++ /* ++ * The idle timer may be pending because we may ++ * not disable disk idling even when a new request ++ * arrives. ++ */ ++ if (bfq_bfqq_wait_request(bfqq)) { ++ BUG_ON(!hrtimer_active(&bfqd->idle_slice_timer)); ++ /* ++ * If we get here: 1) at least a new request ++ * has arrived but we have not disabled the ++ * timer because the request was too small, ++ * 2) then the block layer has unplugged ++ * the device, causing the dispatch to be ++ * invoked. ++ * ++ * Since the device is unplugged, now the ++ * requests are probably large enough to ++ * provide a reasonable throughput. ++ * So we disable idling. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqg_stats_update_idle_time(bfqq_group(bfqq)); ++ } ++ goto keep_queue; ++ } ++ } ++ ++ /* ++ * No requests pending. However, if the in-service queue is idling ++ * for a new request, or has requests waiting for a completion and ++ * may idle after their completion, then keep it anyway. ++ */ ++ if (hrtimer_active(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_may_idle(bfqq))) { ++ bfqq = NULL; ++ goto keep_queue; ++ } ++ ++ reason = BFQ_BFQQ_NO_MORE_REQUESTS; ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, false, reason); ++new_queue: ++ bfqq = bfq_set_in_service_queue(bfqd); ++ bfq_log(bfqd, "select_queue: new queue %d returned", ++ bfqq ? bfqq->pid : 0); ++keep_queue: ++ return bfqq; ++} ++ ++static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ ++ BUG_ON(bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time && ++ time_is_after_jiffies(bfqq->last_wr_start_finish)); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != ++ entity->orig_weight * bfqq->wr_coeff); ++ if (entity->prio_changed) ++ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ ++ /* ++ * If the queue was activated in a burst, or too much ++ * time has elapsed from the beginning of this ++ * weight-raising period, then end weight raising. ++ */ ++ if (bfq_bfqq_in_large_burst(bfqq)) ++ bfq_bfqq_end_wr(bfqq); ++ else if (time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time)) { ++ if (bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time || ++ time_is_before_jiffies(bfqq->wr_start_at_switch_to_srt + ++ bfq_wr_duration(bfqd))) ++ bfq_bfqq_end_wr(bfqq); ++ else { ++ /* switch back to interactive wr */ ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ bfqq->last_wr_start_finish = ++ bfqq->wr_start_at_switch_to_srt; ++ BUG_ON(time_is_after_jiffies( ++ bfqq->last_wr_start_finish)); ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "back to interactive wr"); ++ } ++ } ++ } ++ /* Update weight both if it must be raised and if it must be lowered */ ++ if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); ++} ++ ++/* ++ * Dispatch one request from bfqq, moving it to the request queue ++ * dispatch list. ++ */ ++static int bfq_dispatch_request(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ struct request *rq; ++ unsigned long service_to_charge; ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Follow expired path, else get first next available. */ ++ rq = bfq_check_fifo(bfqq); ++ if (!rq) ++ rq = bfqq->next_rq; ++ service_to_charge = bfq_serv_to_charge(rq, bfqq); ++ ++ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { ++ /* ++ * This may happen if the next rq is chosen in fifo order ++ * instead of sector order. The budget is properly ++ * dimensioned to be always sufficient to serve the next ++ * request only if it is chosen in sector order. The reason ++ * is that it would be quite inefficient and little useful ++ * to always make sure that the budget is large enough to ++ * serve even the possible next rq in fifo order. ++ * In fact, requests are seldom served in fifo order. ++ * ++ * Expire the queue for budget exhaustion, and make sure ++ * that the next act_budget is enough to serve the next ++ * request, even if it comes from the fifo expired path. ++ */ ++ bfqq->next_rq = rq; ++ /* ++ * Since this dispatch is failed, make sure that ++ * a new one will be performed ++ */ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ goto expire; ++ } ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ /* Finally, insert request into driver dispatch list. */ ++ bfq_bfqq_served(bfqq, service_to_charge); ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ bfq_dispatch_insert(bfqd->queue, rq); ++ ++ /* ++ * If weight raising has to terminate for bfqq, then next ++ * function causes an immediate update of bfqq's weight, ++ * without waiting for next activation. As a consequence, on ++ * expiration, bfqq will be timestamped as if has never been ++ * weight-raised during this service slot, even if it has ++ * received part or even most of the service as a ++ * weight-raised queue. This inflates bfqq's timestamps, which ++ * is beneficial, as bfqq is then more willing to leave the ++ * device immediately to possible other weight-raised queues. ++ */ ++ bfq_update_wr_data(bfqd, bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "dispatched %u sec req (%llu), budg left %d", ++ blk_rq_sectors(rq), ++ (unsigned long long) blk_rq_pos(rq), ++ bfq_bfqq_budget_left(bfqq)); ++ ++ dispatched++; ++ ++ if (!bfqd->in_service_bic) { ++ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); ++ bfqd->in_service_bic = RQ_BIC(rq); ++ } ++ ++ if (bfqd->busy_queues > 1 && bfq_class_idle(bfqq)) ++ goto expire; ++ ++ return dispatched; ++ ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, false, BFQ_BFQQ_BUDGET_EXHAUSTED); ++ return dispatched; ++} ++ ++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ ++ while (bfqq->next_rq) { ++ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); ++ dispatched++; ++ } ++ ++ BUG_ON(!list_empty(&bfqq->fifo)); ++ return dispatched; ++} ++ ++/* ++ * Drain our current requests. ++ * Used for barriers and when switching io schedulers on-the-fly. ++ */ ++static int bfq_forced_dispatch(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *n; ++ struct bfq_service_tree *st; ++ int dispatched = 0; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq) ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ /* ++ * Loop through classes, and be careful to leave the scheduler ++ * in a consistent state, as feedback mechanisms and vtime ++ * updates cannot be disabled during the process. ++ */ ++ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { ++ st = bfq_entity_service_tree(&bfqq->entity); ++ ++ dispatched += __bfq_forced_dispatch_bfqq(bfqq); ++ ++ bfqq->max_budget = bfq_max_budget(bfqd); ++ bfq_forget_idle(st); ++ } ++ ++ BUG_ON(bfqd->busy_queues != 0); ++ ++ return dispatched; ++} ++ ++static int bfq_dispatch_requests(struct request_queue *q, int force) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq; ++ ++ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); ++ ++ if (bfqd->busy_queues == 0) ++ return 0; ++ ++ if (unlikely(force)) ++ return bfq_forced_dispatch(bfqd); ++ ++ /* ++ * Force device to serve one request at a time if ++ * strict_guarantees is true. Forcing this service scheme is ++ * currently the ONLY way to guarantee that the request ++ * service order enforced by the scheduler is respected by a ++ * queueing device. Otherwise the device is free even to make ++ * some unlucky request wait for as long as the device ++ * wishes. ++ * ++ * Of course, serving one request at at time may cause loss of ++ * throughput. ++ */ ++ if (bfqd->strict_guarantees && bfqd->rq_in_driver > 0) ++ return 0; ++ ++ bfqq = bfq_select_queue(bfqd); ++ if (!bfqq) ++ return 0; ++ ++ BUG_ON(bfqq->entity.budget < bfqq->entity.service); ++ ++ BUG_ON(bfq_bfqq_wait_request(bfqq)); ++ ++ if (!bfq_dispatch_request(bfqd, bfqq)) ++ return 0; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dispatched %s request", ++ bfq_bfqq_sync(bfqq) ? "sync" : "async"); ++ ++ BUG_ON(bfqq->next_rq == NULL && ++ bfqq->entity.budget < bfqq->entity.service); ++ return 1; ++} ++ ++/* ++ * Task holds one reference to the queue, dropped when task exits. Each rq ++ * in-flight on this queue also holds a reference, dropped when rq is freed. ++ * ++ * Queue lock must be held here. ++ */ ++static void bfq_put_queue(struct bfq_queue *bfqq) ++{ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_group *bfqg = bfqq_group(bfqq); ++#endif ++ ++ BUG_ON(bfqq->ref <= 0); ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref); ++ bfqq->ref--; ++ if (bfqq->ref) ++ return; ++ ++ BUG_ON(rb_first(&bfqq->sort_list)); ++ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); ++ BUG_ON(bfqq->entity.tree); ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq->bfqd->in_service_queue == bfqq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ /* ++ * The fact that this queue is being destroyed does not ++ * invalidate the fact that this queue may have been ++ * activated during the current burst. As a consequence, ++ * although the queue does not exist anymore, and hence ++ * needs to be removed from the burst list if there, ++ * the burst size has not to be decremented. ++ */ ++ hlist_del_init(&bfqq->burst_list_node); ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p freed", bfqq); ++ ++ kmem_cache_free(bfq_pool, bfqq); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ bfqg_put(bfqg); ++#endif ++} ++ ++static void bfq_put_cooperator(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *__bfqq, *next; ++ ++ /* ++ * If this queue was scheduled to merge with another queue, be ++ * sure to drop the reference taken on that queue (and others in ++ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. ++ */ ++ __bfqq = bfqq->new_bfqq; ++ while (__bfqq) { ++ if (__bfqq == bfqq) ++ break; ++ next = __bfqq->new_bfqq; ++ bfq_put_queue(__bfqq); ++ __bfqq = next; ++ } ++} ++ ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ if (bfqq == bfqd->in_service_queue) { ++ __bfq_bfqq_expire(bfqd, bfqq); ++ bfq_schedule_dispatch(bfqd); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, bfqq->ref); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++} ++ ++static void bfq_init_icq(struct io_cq *icq) ++{ ++ icq_to_bic(icq)->ttime.last_end_request = ktime_get_ns() - (1ULL<<32); ++} ++ ++static void bfq_exit_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ if (bic_to_bfqq(bic, false)) { ++ bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, false)); ++ bic_set_bfqq(bic, NULL, false); ++ } ++ ++ if (bic_to_bfqq(bic, true)) { ++ /* ++ * If the bic is using a shared queue, put the reference ++ * taken on the io_context when the bic started using a ++ * shared bfq_queue. ++ */ ++ if (bfq_bfqq_coop(bic_to_bfqq(bic, true))) ++ put_io_context(icq->ioc); ++ bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, true)); ++ bic_set_bfqq(bic, NULL, true); ++ } ++} ++ ++/* ++ * Update the entity prio values; note that the new values will not ++ * be used until the next (re)activation. ++ */ ++static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ struct task_struct *tsk = current; ++ int ioprio_class; ++ ++ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ switch (ioprio_class) { ++ default: ++ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, ++ "bfq: bad prio class %d\n", ioprio_class); ++ case IOPRIO_CLASS_NONE: ++ /* ++ * No prio set, inherit CPU scheduling settings. ++ */ ++ bfqq->new_ioprio = task_nice_ioprio(tsk); ++ bfqq->new_ioprio_class = task_nice_ioclass(tsk); ++ break; ++ case IOPRIO_CLASS_RT: ++ bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->new_ioprio_class = IOPRIO_CLASS_RT; ++ break; ++ case IOPRIO_CLASS_BE: ++ bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->new_ioprio_class = IOPRIO_CLASS_BE; ++ break; ++ case IOPRIO_CLASS_IDLE: ++ bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE; ++ bfqq->new_ioprio = 7; ++ bfq_clear_bfqq_idle_window(bfqq); ++ break; ++ } ++ ++ if (bfqq->new_ioprio >= IOPRIO_BE_NR) { ++ pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n", ++ bfqq->new_ioprio); ++ BUG(); ++ } ++ ++ bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio); ++ bfqq->entity.prio_changed = 1; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "set_next_ioprio_data: bic_class %d prio %d class %d", ++ ioprio_class, bfqq->new_ioprio, bfqq->new_ioprio_class); ++} ++ ++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_queue *bfqq; ++ unsigned long uninitialized_var(flags); ++ int ioprio = bic->icq.ioc->ioprio; ++ ++ /* ++ * This condition may trigger on a newly created bic, be sure to ++ * drop the lock before returning. ++ */ ++ if (unlikely(!bfqd) || likely(bic->ioprio == ioprio)) ++ return; ++ ++ bic->ioprio = ioprio; ++ ++ bfqq = bic_to_bfqq(bic, false); ++ if (bfqq) { ++ bfq_put_queue(bfqq); ++ bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic); ++ bic_set_bfqq(bic, bfqq, false); ++ bfq_log_bfqq(bfqd, bfqq, ++ "check_ioprio_change: bfqq %p %d", ++ bfqq, bfqq->ref); ++ } ++ ++ bfqq = bic_to_bfqq(bic, true); ++ if (bfqq) ++ bfq_set_next_ioprio_data(bfqq, bic); ++} ++ ++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic, pid_t pid, int is_sync) ++{ ++ RB_CLEAR_NODE(&bfqq->entity.rb_node); ++ INIT_LIST_HEAD(&bfqq->fifo); ++ INIT_HLIST_NODE(&bfqq->burst_list_node); ++ BUG_ON(!hlist_unhashed(&bfqq->burst_list_node)); ++ ++ bfqq->ref = 0; ++ bfqq->bfqd = bfqd; ++ ++ if (bic) ++ bfq_set_next_ioprio_data(bfqq, bic); ++ ++ if (is_sync) { ++ if (!bfq_class_idle(bfqq)) ++ bfq_mark_bfqq_idle_window(bfqq); ++ bfq_mark_bfqq_sync(bfqq); ++ bfq_mark_bfqq_just_created(bfqq); ++ } else ++ bfq_clear_bfqq_sync(bfqq); ++ bfq_mark_bfqq_IO_bound(bfqq); ++ ++ /* Tentative initial value to trade off between thr and lat */ ++ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; ++ bfqq->pid = pid; ++ ++ bfqq->wr_coeff = 1; ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->wr_start_at_switch_to_srt = bfq_smallest_from_now(); ++ bfqq->budget_timeout = bfq_smallest_from_now(); ++ bfqq->split_time = bfq_smallest_from_now(); ++ ++ /* ++ * Set to the value for which bfqq will not be deemed as ++ * soft rt when it becomes backlogged. ++ */ ++ bfqq->soft_rt_next_start = bfq_greatest_from_now(); ++ ++ /* first request is almost certainly seeky */ ++ bfqq->seek_history = 1; ++} ++ ++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int ioprio_class, int ioprio) ++{ ++ switch (ioprio_class) { ++ case IOPRIO_CLASS_RT: ++ return &bfqg->async_bfqq[0][ioprio]; ++ case IOPRIO_CLASS_NONE: ++ ioprio = IOPRIO_NORM; ++ /* fall through */ ++ case IOPRIO_CLASS_BE: ++ return &bfqg->async_bfqq[1][ioprio]; ++ case IOPRIO_CLASS_IDLE: ++ return &bfqg->async_idle_bfqq; ++ default: ++ BUG(); ++ } ++} ++ ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bio *bio, bool is_sync, ++ struct bfq_io_cq *bic) ++{ ++ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ struct bfq_queue **async_bfqq = NULL; ++ struct bfq_queue *bfqq; ++ struct bfq_group *bfqg; ++ ++ rcu_read_lock(); ++ ++ bfqg = bfq_find_set_group(bfqd, bio_blkcg(bio)); ++ if (!bfqg) { ++ bfqq = &bfqd->oom_bfqq; ++ goto out; ++ } ++ ++ if (!is_sync) { ++ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ++ ioprio); ++ bfqq = *async_bfqq; ++ if (bfqq) ++ goto out; ++ } ++ ++ bfqq = kmem_cache_alloc_node(bfq_pool, GFP_NOWAIT | __GFP_ZERO, ++ bfqd->queue->node); ++ ++ if (bfqq) { ++ bfq_init_bfqq(bfqd, bfqq, bic, current->pid, ++ is_sync); ++ bfq_init_entity(&bfqq->entity, bfqg); ++ bfq_log_bfqq(bfqd, bfqq, "allocated"); ++ } else { ++ bfqq = &bfqd->oom_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); ++ goto out; ++ } ++ ++ /* ++ * Pin the queue now that it's allocated, scheduler exit will ++ * prune it. ++ */ ++ if (async_bfqq) { ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", ++ bfqq, bfqq->ref); ++ *async_bfqq = bfqq; ++ } ++ ++out: ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref); ++ rcu_read_unlock(); ++ return bfqq; ++} ++ ++static void bfq_update_io_thinktime(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic) ++{ ++ struct bfq_ttime *ttime = &bic->ttime; ++ u64 elapsed = ktime_get_ns() - bic->ttime.last_end_request; ++ ++ elapsed = min_t(u64, elapsed, 2 * bfqd->bfq_slice_idle); ++ ++ ttime->ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; ++ ttime->ttime_total = div_u64(7*ttime->ttime_total + 256*elapsed, 8); ++ ttime->ttime_mean = div64_ul(ttime->ttime_total + 128, ++ ttime->ttime_samples); ++} ++ ++static void ++bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ bfqq->seek_history <<= 1; ++ bfqq->seek_history |= ++ get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR; ++} ++ ++/* ++ * Disable idle window if the process thinks too long or seeks so much that ++ * it doesn't matter. ++ */ ++static void bfq_update_idle_window(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ int enable_idle; ++ ++ /* Don't idle for async or idle io prio class. */ ++ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) ++ return; ++ ++ /* Idle window just restored, statistics are meaningless. */ ++ if (time_is_after_eq_jiffies(bfqq->split_time + ++ bfqd->bfq_wr_min_idle_time)) ++ return; ++ ++ enable_idle = bfq_bfqq_idle_window(bfqq); ++ ++ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || ++ bfqd->bfq_slice_idle == 0 || ++ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && ++ bfqq->wr_coeff == 1)) ++ enable_idle = 0; ++ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { ++ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && ++ bfqq->wr_coeff == 1) ++ enable_idle = 0; ++ else ++ enable_idle = 1; ++ } ++ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", ++ enable_idle); ++ ++ if (enable_idle) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++} ++ ++/* ++ * Called when a new fs request (rq) is added to bfqq. Check if there's ++ * something we should do about it. ++ */ ++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ struct bfq_io_cq *bic = RQ_BIC(rq); ++ ++ if (rq->cmd_flags & REQ_META) ++ bfqq->meta_pending++; ++ ++ bfq_update_io_thinktime(bfqd, bic); ++ bfq_update_io_seektime(bfqd, bfqq, rq); ++ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || ++ !BFQQ_SEEKY(bfqq)) ++ bfq_update_idle_window(bfqd, bfqq, bic); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "rq_enqueued: idle_window=%d (seeky %d)", ++ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq)); ++ ++ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ ++ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { ++ bool small_req = bfqq->queued[rq_is_sync(rq)] == 1 && ++ blk_rq_sectors(rq) < 32; ++ bool budget_timeout = bfq_bfqq_budget_timeout(bfqq); ++ ++ /* ++ * There is just this request queued: if the request ++ * is small and the queue is not to be expired, then ++ * just exit. ++ * ++ * In this way, if the device is being idled to wait ++ * for a new request from the in-service queue, we ++ * avoid unplugging the device and committing the ++ * device to serve just a small request. On the ++ * contrary, we wait for the block layer to decide ++ * when to unplug the device: hopefully, new requests ++ * will be merged to this one quickly, then the device ++ * will be unplugged and larger requests will be ++ * dispatched. ++ */ ++ if (small_req && !budget_timeout) ++ return; ++ ++ /* ++ * A large enough request arrived, or the queue is to ++ * be expired: in both cases disk idling is to be ++ * stopped, so clear wait_request flag and reset ++ * timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqg_stats_update_idle_time(bfqq_group(bfqq)); ++ ++ /* ++ * The queue is not empty, because a new request just ++ * arrived. Hence we can safely expire the queue, in ++ * case of budget timeout, without risking that the ++ * timestamps of the queue are not updated correctly. ++ * See [1] for more details. ++ */ ++ if (budget_timeout) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_BUDGET_TIMEOUT); ++ ++ /* ++ * Let the request rip immediately, or let a new queue be ++ * selected if bfqq has just been expired. ++ */ ++ __blk_run_queue(bfqd->queue); ++ } ++} ++ ++static void bfq_insert_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ /* ++ * An unplug may trigger a requeue of a request from the device ++ * driver: make sure we are in process context while trying to ++ * merge two bfq_queues. ++ */ ++ if (!in_interrupt()) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); ++ if (new_bfqq) { ++ if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) ++ new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); ++ /* ++ * Release the request's reference to the old bfqq ++ * and make sure one is taken to the shared queue. ++ */ ++ new_bfqq->allocated[rq_data_dir(rq)]++; ++ bfqq->allocated[rq_data_dir(rq)]--; ++ new_bfqq->ref++; ++ bfq_clear_bfqq_just_created(bfqq); ++ bfq_put_queue(bfqq); ++ if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) ++ bfq_merge_bfqqs(bfqd, RQ_BIC(rq), ++ bfqq, new_bfqq); ++ rq->elv.priv[1] = new_bfqq; ++ bfqq = new_bfqq; ++ } ++ } ++ ++ bfq_add_request(rq); ++ ++ rq->fifo_time = ktime_get_ns() + ++ jiffies_to_nsecs(bfqd->bfq_fifo_expire[rq_is_sync(rq)]); ++ list_add_tail(&rq->queuelist, &bfqq->fifo); ++ ++ bfq_rq_enqueued(bfqd, bfqq, rq); ++} ++ ++static void bfq_update_hw_tag(struct bfq_data *bfqd) ++{ ++ bfqd->max_rq_in_driver = max_t(int, bfqd->max_rq_in_driver, ++ bfqd->rq_in_driver); ++ ++ if (bfqd->hw_tag == 1) ++ return; ++ ++ /* ++ * This sample is valid if the number of outstanding requests ++ * is large enough to allow a queueing behavior. Note that the ++ * sum is not exact, as it's not taking into account deactivated ++ * requests. ++ */ ++ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) ++ return; ++ ++ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) ++ return; ++ ++ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; ++ bfqd->max_rq_in_driver = 0; ++ bfqd->hw_tag_samples = 0; ++} ++ ++static void bfq_completed_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ u64 now_ns; ++ u32 delta_us; ++ ++ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left", ++ blk_rq_sectors(rq)); ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ bfq_update_hw_tag(bfqd); ++ ++ BUG_ON(!bfqd->rq_in_driver); ++ BUG_ON(!bfqq->dispatched); ++ bfqd->rq_in_driver--; ++ bfqq->dispatched--; ++ bfqg_stats_update_completion(bfqq_group(bfqq), ++ rq_start_time_ns(rq), ++ rq_io_start_time_ns(rq), req_op(rq), ++ rq->cmd_flags); ++ ++ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ /* ++ * Set budget_timeout (which we overload to store the ++ * time at which the queue remains with no backlog and ++ * no outstanding request; used by the weight-raising ++ * mechanism). ++ */ ++ bfqq->budget_timeout = jiffies; ++ ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ } ++ ++ now_ns = ktime_get_ns(); ++ ++ RQ_BIC(rq)->ttime.last_end_request = now_ns; ++ ++ /* ++ * Using us instead of ns, to get a reasonable precision in ++ * computing rate in next check. ++ */ ++ delta_us = div_u64(now_ns - bfqd->last_completion, NSEC_PER_USEC); ++ ++ bfq_log(bfqd, "rq_completed: delta %uus/%luus max_size %u rate %llu/%llu", ++ delta_us, BFQ_MIN_TT/NSEC_PER_USEC, bfqd->last_rq_max_size, ++ (USEC_PER_SEC* ++ (u64)((bfqd->last_rq_max_size<>BFQ_RATE_SHIFT, ++ (USEC_PER_SEC*(u64)(1UL<<(BFQ_RATE_SHIFT-10)))>>BFQ_RATE_SHIFT); ++ ++ /* ++ * If the request took rather long to complete, and, according ++ * to the maximum request size recorded, this completion latency ++ * implies that the request was certainly served at a very low ++ * rate (less than 1M sectors/sec), then the whole observation ++ * interval that lasts up to this time instant cannot be a ++ * valid time interval for computing a new peak rate. Invoke ++ * bfq_update_rate_reset to have the following three steps ++ * taken: ++ * - close the observation interval at the last (previous) ++ * request dispatch or completion ++ * - compute rate, if possible, for that observation interval ++ * - reset to zero samples, which will trigger a proper ++ * re-initialization of the observation interval on next ++ * dispatch ++ */ ++ if (delta_us > BFQ_MIN_TT/NSEC_PER_USEC && ++ (bfqd->last_rq_max_size<last_completion = now_ns; ++ ++ /* ++ * If we are waiting to discover whether the request pattern ++ * of the task associated with the queue is actually ++ * isochronous, and both requisites for this condition to hold ++ * are now satisfied, then compute soft_rt_next_start (see the ++ * comments on the function bfq_bfqq_softrt_next_start()). We ++ * schedule this delayed check when bfqq expires, if it still ++ * has in-flight requests. ++ */ ++ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ ++ /* ++ * If this is the in-service queue, check if it needs to be expired, ++ * or if we want to idle in case it has no pending requests. ++ */ ++ if (bfqd->in_service_queue == bfqq) { ++ if (bfqq->dispatched == 0 && bfq_bfqq_must_idle(bfqq)) { ++ bfq_arm_slice_timer(bfqd); ++ goto out; ++ } else if (bfq_may_expire_for_budg_timeout(bfqq)) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_BUDGET_TIMEOUT); ++ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && ++ (bfqq->dispatched == 0 || ++ !bfq_bfqq_may_idle(bfqq))) ++ bfq_bfqq_expire(bfqd, bfqq, false, ++ BFQ_BFQQ_NO_MORE_REQUESTS); ++ } ++ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ ++out: ++ return; ++} ++ ++static int __bfq_may_queue(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { ++ bfq_clear_bfqq_must_alloc(bfqq); ++ return ELV_MQUEUE_MUST; ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++static int bfq_may_queue(struct request_queue *q, int op, int op_flags) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Don't force setup of a queue from here, as a call to may_queue ++ * does not necessarily imply that a request actually will be ++ * queued. So just lookup a possibly existing queue, or return ++ * 'may queue' if that fails. ++ */ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (!bic) ++ return ELV_MQUEUE_MAY; ++ ++ bfqq = bic_to_bfqq(bic, rw_is_sync(op, op_flags)); ++ if (bfqq) ++ return __bfq_may_queue(bfqq); ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++/* ++ * Queue lock held here. ++ */ ++static void bfq_put_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ if (bfqq) { ++ const int rw = rq_data_dir(rq); ++ ++ BUG_ON(!bfqq->allocated[rw]); ++ bfqq->allocated[rw]--; ++ ++ rq->elv.priv[0] = NULL; ++ rq->elv.priv[1] = NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/* ++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this ++ * was the last process referring to that bfqq. ++ */ ++static struct bfq_queue * ++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ ++ put_io_context(bic->icq.ioc); ++ ++ if (bfqq_process_refs(bfqq) == 1) { ++ bfqq->pid = current->pid; ++ bfq_clear_bfqq_coop(bfqq); ++ bfq_clear_bfqq_split_coop(bfqq); ++ return bfqq; ++ } ++ ++ bic_set_bfqq(bic, NULL, 1); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++ return NULL; ++} ++ ++/* ++ * Allocate bfq data structures associated with this request. ++ */ ++static int bfq_set_request(struct request_queue *q, struct request *rq, ++ struct bio *bio, gfp_t gfp_mask) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); ++ const int rw = rq_data_dir(rq); ++ const int is_sync = rq_is_sync(rq); ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ bool split = false; ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ bfq_check_ioprio_change(bic, bio); ++ ++ if (!bic) ++ goto queue_fail; ++ ++ bfq_bic_update_cgroup(bic, bio); ++ ++new_queue: ++ bfqq = bic_to_bfqq(bic, is_sync); ++ if (!bfqq || bfqq == &bfqd->oom_bfqq) { ++ if (bfqq) ++ bfq_put_queue(bfqq); ++ bfqq = bfq_get_queue(bfqd, bio, is_sync, bic); ++ BUG_ON(!hlist_unhashed(&bfqq->burst_list_node)); ++ ++ bic_set_bfqq(bic, bfqq, is_sync); ++ if (split && is_sync) { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: was_in_list %d " ++ "was_in_large_burst %d " ++ "large burst in progress %d", ++ bic->was_in_burst_list, ++ bic->saved_in_large_burst, ++ bfqd->large_burst); ++ ++ if ((bic->was_in_burst_list && bfqd->large_burst) || ++ bic->saved_in_large_burst) { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: marking in " ++ "large burst"); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ } else { ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_request: clearing in " ++ "large burst"); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ if (bic->was_in_burst_list) ++ hlist_add_head(&bfqq->burst_list_node, ++ &bfqd->burst_list); ++ } ++ bfqq->split_time = jiffies; ++ } ++ } else { ++ /* If the queue was seeky for too long, break it apart. */ ++ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { ++ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); ++ ++ /* Update bic before losing reference to bfqq */ ++ if (bfq_bfqq_in_large_burst(bfqq)) ++ bic->saved_in_large_burst = true; ++ ++ bfqq = bfq_split_bfqq(bic, bfqq); ++ split = true; ++ if (!bfqq) ++ goto new_queue; ++ } ++ } ++ ++ bfqq->allocated[rw]++; ++ bfqq->ref++; ++ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, bfqq->ref); ++ ++ rq->elv.priv[0] = bic; ++ rq->elv.priv[1] = bfqq; ++ ++ /* ++ * If a bfq_queue has only one process reference, it is owned ++ * by only one bfq_io_cq: we can set the bic field of the ++ * bfq_queue to the address of that structure. Also, if the ++ * queue has just been split, mark a flag so that the ++ * information is available to the other scheduler hooks. ++ */ ++ if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { ++ bfqq->bic = bic; ++ if (split) { ++ /* ++ * If the queue has just been split from a shared ++ * queue, restore the idle window and the possible ++ * weight raising period. ++ */ ++ bfq_bfqq_resume_state(bfqq, bic); ++ } ++ } ++ ++ if (unlikely(bfq_bfqq_just_created(bfqq))) ++ bfq_handle_burst(bfqd, bfqq); ++ ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 0; ++ ++queue_fail: ++ bfq_schedule_dispatch(bfqd); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 1; ++} ++ ++static void bfq_kick_queue(struct work_struct *work) ++{ ++ struct bfq_data *bfqd = ++ container_of(work, struct bfq_data, unplug_work); ++ struct request_queue *q = bfqd->queue; ++ ++ spin_lock_irq(q->queue_lock); ++ __blk_run_queue(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++/* ++ * Handler of the expiration of the timer running if the in-service queue ++ * is idling inside its time slice. ++ */ ++static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer) ++{ ++ struct bfq_data *bfqd = container_of(timer, struct bfq_data, ++ idle_slice_timer); ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ enum bfqq_expiration reason; ++ ++ spin_lock_irqsave(bfqd->queue->queue_lock, flags); ++ ++ bfqq = bfqd->in_service_queue; ++ /* ++ * Theoretical race here: the in-service queue can be NULL or ++ * different from the queue that was idling if the timer handler ++ * spins on the queue_lock and a new request arrives for the ++ * current queue and there is a full dispatch cycle that changes ++ * the in-service queue. This can hardly happen, but in the worst ++ * case we just expire a queue too early. ++ */ ++ if (bfqq) { ++ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); ++ bfq_clear_bfqq_wait_request(bfqq); ++ ++ if (bfq_bfqq_budget_timeout(bfqq)) ++ /* ++ * Also here the queue can be safely expired ++ * for budget timeout without wasting ++ * guarantees ++ */ ++ reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) ++ /* ++ * The queue may not be empty upon timer expiration, ++ * because we may not disable the timer when the ++ * first request of the in-service queue arrives ++ * during disk idling. ++ */ ++ reason = BFQ_BFQQ_TOO_IDLE; ++ else ++ goto schedule_dispatch; ++ ++ bfq_bfqq_expire(bfqd, bfqq, true, reason); ++ } ++ ++schedule_dispatch: ++ bfq_schedule_dispatch(bfqd); ++ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); ++ return HRTIMER_NORESTART; ++} ++ ++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) ++{ ++ hrtimer_cancel(&bfqd->idle_slice_timer); ++ cancel_work_sync(&bfqd->unplug_work); ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void __bfq_put_async_bfqq(struct bfq_data *bfqd, ++ struct bfq_queue **bfqq_ptr) ++{ ++ struct bfq_group *root_group = bfqd->root_group; ++ struct bfq_queue *bfqq = *bfqq_ptr; ++ ++ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); ++ if (bfqq) { ++ bfq_bfqq_move(bfqd, bfqq, root_group); ++ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ *bfqq_ptr = NULL; ++ } ++} ++ ++/* ++ * Release all the bfqg references to its async queues. If we are ++ * deallocating the group these queues may still contain requests, so ++ * we reparent them to the root cgroup (i.e., the only one that will ++ * exist for sure until all the requests on a device are gone). ++ */ ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); ++ ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); ++} ++#endif ++ ++static void bfq_exit_queue(struct elevator_queue *e) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ struct request_queue *q = bfqd->queue; ++ struct bfq_queue *bfqq, *n; ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ spin_lock_irq(q->queue_lock); ++ ++ BUG_ON(bfqd->in_service_queue); ++ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ ++ spin_unlock_irq(q->queue_lock); ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ BUG_ON(hrtimer_active(&bfqd->idle_slice_timer)); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_deactivate_policy(q, &blkcg_policy_bfq); ++#else ++ kfree(bfqd->root_group); ++#endif ++ ++ kfree(bfqd); ++} ++ ++static void bfq_init_root_group(struct bfq_group *root_group, ++ struct bfq_data *bfqd) ++{ ++ int i; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ root_group->entity.parent = NULL; ++ root_group->my_entity = NULL; ++ root_group->bfqd = bfqd; ++#endif ++ root_group->rq_pos_tree = RB_ROOT; ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ root_group->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++} ++ ++static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) ++{ ++ struct bfq_data *bfqd; ++ struct elevator_queue *eq; ++ ++ eq = elevator_alloc(q, e); ++ if (!eq) ++ return -ENOMEM; ++ ++ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); ++ if (!bfqd) { ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ eq->elevator_data = bfqd; ++ ++ /* ++ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. ++ * Grab a permanent reference to it, so that the normal code flow ++ * will not attempt to free it. ++ */ ++ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0); ++ bfqd->oom_bfqq.ref++; ++ bfqd->oom_bfqq.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; ++ bfqd->oom_bfqq.new_ioprio_class = IOPRIO_CLASS_BE; ++ bfqd->oom_bfqq.entity.new_weight = ++ bfq_ioprio_to_weight(bfqd->oom_bfqq.new_ioprio); ++ ++ /* oom_bfqq does not participate to bursts */ ++ bfq_clear_bfqq_just_created(&bfqd->oom_bfqq); ++ /* ++ * Trigger weight initialization, according to ioprio, at the ++ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio ++ * class won't be changed any more. ++ */ ++ bfqd->oom_bfqq.entity.prio_changed = 1; ++ ++ bfqd->queue = q; ++ ++ spin_lock_irq(q->queue_lock); ++ q->elevator = eq; ++ spin_unlock_irq(q->queue_lock); ++ ++ bfqd->root_group = bfq_create_group_hierarchy(bfqd, q->node); ++ if (!bfqd->root_group) ++ goto out_free; ++ bfq_init_root_group(bfqd->root_group, bfqd); ++ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); ++ ++ hrtimer_init(&bfqd->idle_slice_timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); ++ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; ++ ++ bfqd->queue_weights_tree = RB_ROOT; ++ bfqd->group_weights_tree = RB_ROOT; ++ ++ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); ++ ++ INIT_LIST_HEAD(&bfqd->active_list); ++ INIT_LIST_HEAD(&bfqd->idle_list); ++ INIT_HLIST_HEAD(&bfqd->burst_list); ++ ++ bfqd->hw_tag = -1; ++ ++ bfqd->bfq_max_budget = bfq_default_max_budget; ++ ++ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; ++ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; ++ bfqd->bfq_back_max = bfq_back_max; ++ bfqd->bfq_back_penalty = bfq_back_penalty; ++ bfqd->bfq_slice_idle = bfq_slice_idle; ++ bfqd->bfq_class_idle_last_service = 0; ++ bfqd->bfq_timeout = bfq_timeout; ++ ++ bfqd->bfq_requests_within_timer = 120; ++ ++ bfqd->bfq_large_burst_thresh = 8; ++ bfqd->bfq_burst_interval = msecs_to_jiffies(180); ++ ++ bfqd->low_latency = true; ++ ++ /* ++ * Trade-off between responsiveness and fairness. ++ */ ++ bfqd->bfq_wr_coeff = 30; ++ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); ++ bfqd->bfq_wr_max_time = 0; ++ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); ++ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); ++ bfqd->bfq_wr_max_softrt_rate = 7000; /* ++ * Approximate rate required ++ * to playback or record a ++ * high-definition compressed ++ * video. ++ */ ++ bfqd->wr_busy_queues = 0; ++ ++ /* ++ * Begin by assuming, optimistically, that the device is a ++ * high-speed one, and that its peak rate is equal to 2/3 of ++ * the highest reference rate. ++ */ ++ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * ++ T_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)] * 2 / 3; ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ ++ return 0; ++ ++out_free: ++ kfree(bfqd); ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++} ++ ++static void bfq_slab_kill(void) ++{ ++ kmem_cache_destroy(bfq_pool); ++} ++ ++static int __init bfq_slab_setup(void) ++{ ++ bfq_pool = KMEM_CACHE(bfq_queue, 0); ++ if (!bfq_pool) ++ return -ENOMEM; ++ return 0; ++} ++ ++static ssize_t bfq_var_show(unsigned int var, char *page) ++{ ++ return sprintf(page, "%u\n", var); ++} ++ ++static ssize_t bfq_var_store(unsigned long *var, const char *page, ++ size_t count) ++{ ++ unsigned long new_val; ++ int ret = kstrtoul(page, 10, &new_val); ++ ++ if (ret == 0) ++ *var = new_val; ++ ++ return count; ++} ++ ++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ ++ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? ++ jiffies_to_msecs(bfqd->bfq_wr_max_time) : ++ jiffies_to_msecs(bfq_wr_duration(bfqd))); ++} ++ ++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_queue *bfqq; ++ struct bfq_data *bfqd = e->elevator_data; ++ ssize_t num_char = 0; ++ ++ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", ++ bfqd->queued); ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ num_char += sprintf(page + num_char, "Active:\n"); ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, nr_queued %d %d, ", ++ bfqq->pid, ++ bfqq->entity.weight, ++ bfqq->queued[0], ++ bfqq->queued[1]); ++ num_char += sprintf(page + num_char, ++ "dur %d/%u\n", ++ jiffies_to_msecs( ++ jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ num_char += sprintf(page + num_char, "Idle:\n"); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ ++ return num_char; ++} ++ ++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ u64 __data = __VAR; \ ++ if (__CONV == 1) \ ++ __data = jiffies_to_msecs(__data); \ ++ else if (__CONV == 2) \ ++ __data = div_u64(__data, NSEC_PER_MSEC); \ ++ return bfq_var_show(__data, (page)); \ ++} ++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 2); ++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 2); ++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); ++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); ++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 2); ++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); ++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout, 1); ++SHOW_FUNCTION(bfq_strict_guarantees_show, bfqd->strict_guarantees, 0); ++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); ++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); ++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); ++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); ++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, ++ 1); ++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); ++#undef SHOW_FUNCTION ++ ++#define USEC_SHOW_FUNCTION(__FUNC, __VAR) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ u64 __data = __VAR; \ ++ __data = div_u64(__data, NSEC_PER_USEC); \ ++ return bfq_var_show(__data, (page)); \ ++} ++USEC_SHOW_FUNCTION(bfq_slice_idle_us_show, bfqd->bfq_slice_idle); ++#undef USEC_SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ ++static ssize_t \ ++__FUNC(struct elevator_queue *e, const char *page, size_t count) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long uninitialized_var(__data); \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ if (__CONV == 1) \ ++ *(__PTR) = msecs_to_jiffies(__data); \ ++ else if (__CONV == 2) \ ++ *(__PTR) = (u64)__data * NSEC_PER_MSEC; \ ++ else \ ++ *(__PTR) = __data; \ ++ return ret; \ ++} ++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, ++ INT_MAX, 2); ++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, ++ INT_MAX, 2); ++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); ++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, ++ INT_MAX, 0); ++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 2); ++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, ++ 1); ++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, ++ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, ++ INT_MAX, 0); ++#undef STORE_FUNCTION ++ ++#define USEC_STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \ ++static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long __data; \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ *(__PTR) = (u64)__data * NSEC_PER_USEC; \ ++ return ret; \ ++} ++USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0, ++ UINT_MAX); ++#undef USEC_STORE_FUNCTION ++ ++/* do nothing for the moment */ ++static ssize_t bfq_weights_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ return count; ++} ++ ++static ssize_t bfq_max_budget_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data == 0) ++ bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); ++ else { ++ if (__data > INT_MAX) ++ __data = INT_MAX; ++ bfqd->bfq_max_budget = __data; ++ } ++ ++ bfqd->bfq_user_max_budget = __data; ++ ++ return ret; ++} ++ ++/* ++ * Leaving this name to preserve name compatibility with cfq ++ * parameters, but this timeout is used for both sync and async. ++ */ ++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data < 1) ++ __data = 1; ++ else if (__data > INT_MAX) ++ __data = INT_MAX; ++ ++ bfqd->bfq_timeout = msecs_to_jiffies(__data); ++ if (bfqd->bfq_user_max_budget == 0) ++ bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); ++ ++ return ret; ++} ++ ++static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (!bfqd->strict_guarantees && __data == 1 ++ && bfqd->bfq_slice_idle < 8 * NSEC_PER_MSEC) ++ bfqd->bfq_slice_idle = 8 * NSEC_PER_MSEC; ++ ++ bfqd->strict_guarantees = __data; ++ ++ return ret; ++} ++ ++static ssize_t bfq_low_latency_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (__data == 0 && bfqd->low_latency != 0) ++ bfq_end_wr(bfqd); ++ bfqd->low_latency = __data; ++ ++ return ret; ++} ++ ++#define BFQ_ATTR(name) \ ++ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) ++ ++static struct elv_fs_entry bfq_attrs[] = { ++ BFQ_ATTR(fifo_expire_sync), ++ BFQ_ATTR(fifo_expire_async), ++ BFQ_ATTR(back_seek_max), ++ BFQ_ATTR(back_seek_penalty), ++ BFQ_ATTR(slice_idle), ++ BFQ_ATTR(slice_idle_us), ++ BFQ_ATTR(max_budget), ++ BFQ_ATTR(timeout_sync), ++ BFQ_ATTR(strict_guarantees), ++ BFQ_ATTR(low_latency), ++ BFQ_ATTR(wr_coeff), ++ BFQ_ATTR(wr_max_time), ++ BFQ_ATTR(wr_rt_max_time), ++ BFQ_ATTR(wr_min_idle_time), ++ BFQ_ATTR(wr_min_inter_arr_async), ++ BFQ_ATTR(wr_max_softrt_rate), ++ BFQ_ATTR(weights), ++ __ATTR_NULL ++}; ++ ++static struct elevator_type iosched_bfq = { ++ .ops = { ++ .elevator_merge_fn = bfq_merge, ++ .elevator_merged_fn = bfq_merged_request, ++ .elevator_merge_req_fn = bfq_merged_requests, ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ .elevator_bio_merged_fn = bfq_bio_merged, ++#endif ++ .elevator_allow_bio_merge_fn = bfq_allow_bio_merge, ++ .elevator_allow_rq_merge_fn = bfq_allow_rq_merge, ++ .elevator_dispatch_fn = bfq_dispatch_requests, ++ .elevator_add_req_fn = bfq_insert_request, ++ .elevator_activate_req_fn = bfq_activate_request, ++ .elevator_deactivate_req_fn = bfq_deactivate_request, ++ .elevator_completed_req_fn = bfq_completed_request, ++ .elevator_former_req_fn = elv_rb_former_request, ++ .elevator_latter_req_fn = elv_rb_latter_request, ++ .elevator_init_icq_fn = bfq_init_icq, ++ .elevator_exit_icq_fn = bfq_exit_icq, ++ .elevator_set_req_fn = bfq_set_request, ++ .elevator_put_req_fn = bfq_put_request, ++ .elevator_may_queue_fn = bfq_may_queue, ++ .elevator_init_fn = bfq_init_queue, ++ .elevator_exit_fn = bfq_exit_queue, ++ }, ++ .icq_size = sizeof(struct bfq_io_cq), ++ .icq_align = __alignof__(struct bfq_io_cq), ++ .elevator_attrs = bfq_attrs, ++ .elevator_name = "bfq", ++ .elevator_owner = THIS_MODULE, ++}; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static struct blkcg_policy blkcg_policy_bfq = { ++ .dfl_cftypes = bfq_blkg_files, ++ .legacy_cftypes = bfq_blkcg_legacy_files, ++ ++ .cpd_alloc_fn = bfq_cpd_alloc, ++ .cpd_init_fn = bfq_cpd_init, ++ .cpd_bind_fn = bfq_cpd_init, ++ .cpd_free_fn = bfq_cpd_free, ++ ++ .pd_alloc_fn = bfq_pd_alloc, ++ .pd_init_fn = bfq_pd_init, ++ .pd_offline_fn = bfq_pd_offline, ++ .pd_free_fn = bfq_pd_free, ++ .pd_reset_stats_fn = bfq_pd_reset_stats, ++}; ++#endif ++ ++static int __init bfq_init(void) ++{ ++ int ret; ++ char msg[50] = "BFQ I/O-scheduler: v8r4"; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ ret = blkcg_policy_register(&blkcg_policy_bfq); ++ if (ret) ++ return ret; ++#endif ++ ++ ret = -ENOMEM; ++ if (bfq_slab_setup()) ++ goto err_pol_unreg; ++ ++ /* ++ * Times to load large popular applications for the typical ++ * systems installed on the reference devices (see the ++ * comments before the definitions of the next two ++ * arrays). Actually, we use slightly slower values, as the ++ * estimated peak rate tends to be smaller than the actual ++ * peak rate. The reason for this last fact is that estimates ++ * are computed over much shorter time intervals than the long ++ * intervals typically used for benchmarking. Why? First, to ++ * adapt more quickly to variations. Second, because an I/O ++ * scheduler cannot rely on a peak-rate-evaluation workload to ++ * be run for a long time. ++ */ ++ T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */ ++ T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */ ++ T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */ ++ T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */ ++ ++ /* ++ * Thresholds that determine the switch between speed classes ++ * (see the comments before the definition of the array ++ * device_speed_thresh). These thresholds are biased towards ++ * transitions to the fast class. This is safer than the ++ * opposite bias. In fact, a wrong transition to the slow ++ * class results in short weight-raising periods, because the ++ * speed of the device then tends to be higher that the ++ * reference peak rate. On the opposite end, a wrong ++ * transition to the fast class tends to increase ++ * weight-raising periods, because of the opposite reason. ++ */ ++ device_speed_thresh[0] = (4 * R_slow[0]) / 3; ++ device_speed_thresh[1] = (4 * R_slow[1]) / 3; ++ ++ ret = elv_register(&iosched_bfq); ++ if (ret) ++ goto err_pol_unreg; ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ strcat(msg, " (with cgroups support)"); ++#endif ++ pr_info("%s", msg); ++ ++ return 0; ++ ++err_pol_unreg: ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_policy_unregister(&blkcg_policy_bfq); ++#endif ++ return ret; ++} ++ ++static void __exit bfq_exit(void) ++{ ++ elv_unregister(&iosched_bfq); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ blkcg_policy_unregister(&blkcg_policy_bfq); ++#endif ++ bfq_slab_kill(); ++} ++ ++module_init(bfq_init); ++module_exit(bfq_exit); ++ ++MODULE_AUTHOR("Arianna Avanzini, Fabio Checconi, Paolo Valente"); ++MODULE_LICENSE("GPL"); +diff -w -uNr '--exclude=.git' linux-4.8/block/bfq-sched.c linux-4.8-bfq/block/bfq-sched.c +--- linux-4.8/block/bfq-sched.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.8-bfq/block/bfq-sched.c 2016-10-18 12:57:57.691164881 +0200 +@@ -0,0 +1,1501 @@ ++/* ++ * BFQ: Hierarchical B-WF2Q+ scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente ++ */ ++ ++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++#define for_each_entity(entity) \ ++ for (; entity ; entity = entity->parent) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) ++ ++ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd); ++ ++static void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++ struct bfq_entity *bfqg_entity; ++ struct bfq_group *bfqg; ++ struct bfq_sched_data *group_sd; ++ ++ BUG_ON(!next_in_service); ++ ++ group_sd = next_in_service->sched_data; ++ ++ bfqg = container_of(group_sd, struct bfq_group, sched_data); ++ /* ++ * bfq_group's my_entity field is not NULL only if the group ++ * is not the root group. We must not touch the root entity ++ * as it must never become an in-service entity. ++ */ ++ bfqg_entity = bfqg->my_entity; ++ if (bfqg_entity) ++ bfqg_entity->budget = next_in_service->budget; ++} ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ struct bfq_entity *next_in_service; ++ struct bfq_queue *bfqq; ++ ++ if (sd->in_service_entity) ++ /* will update/requeue at the end of service */ ++ return 0; ++ ++ /* ++ * NOTE: this can be improved in many ways, such as returning ++ * 1 (and thus propagating upwards the update) only when the ++ * budget changes, or caching the bfqq that will be scheduled ++ * next from this subtree. By now we worry more about ++ * correctness than about performance... ++ */ ++ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); ++ sd->next_in_service = next_in_service; ++ ++ if (next_in_service) ++ bfq_update_budget(next_in_service); ++ else ++ goto exit; ++ ++ bfqq = bfq_entity_to_bfqq(next_in_service); ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_next_in_service: chosen this queue"); ++ else { ++ struct bfq_group *bfqg = ++ container_of(next_in_service, ++ struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_next_in_service: chosen this entity"); ++ } ++exit: ++ return 1; ++} ++ ++static void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++ WARN_ON(sd->next_in_service != entity); ++} ++#else ++#define for_each_entity(entity) \ ++ for (; entity ; entity = NULL) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (parent = NULL; entity ; entity = parent) ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ return 0; ++} ++ ++static void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++} ++ ++static void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++} ++#endif ++ ++/* ++ * Shift for timestamp calculations. This actually limits the maximum ++ * service allowed in one timestamp delta (small shift values increase it), ++ * the maximum total weight that can be used for the queues in the system ++ * (big shift values increase it), and the period of virtual time ++ * wraparounds. ++ */ ++#define WFQ_SERVICE_SHIFT 22 ++ ++/** ++ * bfq_gt - compare two timestamps. ++ * @a: first ts. ++ * @b: second ts. ++ * ++ * Return @a > @b, dealing with wrapping correctly. ++ */ ++static int bfq_gt(u64 a, u64 b) ++{ ++ return (s64)(a - b) > 0; ++} ++ ++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = NULL; ++ ++ BUG_ON(!entity); ++ ++ if (!entity->my_sched_data) ++ bfqq = container_of(entity, struct bfq_queue, entity); ++ ++ return bfqq; ++} ++ ++ ++/** ++ * bfq_delta - map service into the virtual time domain. ++ * @service: amount of service. ++ * @weight: scale factor (weight of an entity or weight sum). ++ */ ++static u64 bfq_delta(unsigned long service, unsigned long weight) ++{ ++ u64 d = (u64)service << WFQ_SERVICE_SHIFT; ++ ++ do_div(d, weight); ++ return d; ++} ++ ++/** ++ * bfq_calc_finish - assign the finish time to an entity. ++ * @entity: the entity to act upon. ++ * @service: the service to be charged to the entity. ++ */ ++static void bfq_calc_finish(struct bfq_entity *entity, unsigned long service) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned long long start, finish, delta; ++ ++ BUG_ON(entity->weight == 0); ++ ++ entity->finish = entity->start + ++ bfq_delta(service, entity->weight); ++ ++ start = ((entity->start>>10)*1000)>>12; ++ finish = ((entity->finish>>10)*1000)>>12; ++ delta = ((bfq_delta(service, entity->weight)>>10)*1000)>>12; ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: start %llu, finish %llu, delta %llu", ++ start, finish, delta); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "calc_finish group: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "calc_finish group: start %llu, finish %llu, delta %llu", ++ start, finish, delta); ++#endif ++ } ++} ++ ++/** ++ * bfq_entity_of - get an entity from a node. ++ * @node: the node field of the entity. ++ * ++ * Convert a node pointer to the relative entity. This is used only ++ * to simplify the logic of some functions and not as the generic ++ * conversion mechanism because, e.g., in the tree walking functions, ++ * the check for a %NULL value would be redundant. ++ */ ++static struct bfq_entity *bfq_entity_of(struct rb_node *node) ++{ ++ struct bfq_entity *entity = NULL; ++ ++ if (node) ++ entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ return entity; ++} ++ ++/** ++ * bfq_extract - remove an entity from a tree. ++ * @root: the tree root. ++ * @entity: the entity to remove. ++ */ ++static void bfq_extract(struct rb_root *root, struct bfq_entity *entity) ++{ ++ BUG_ON(entity->tree != root); ++ ++ entity->tree = NULL; ++ rb_erase(&entity->rb_node, root); ++} ++ ++/** ++ * bfq_idle_extract - extract an entity from the idle tree. ++ * @st: the service tree of the owning @entity. ++ * @entity: the entity being removed. ++ */ ++static void bfq_idle_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *next; ++ ++ BUG_ON(entity->tree != &st->idle); ++ ++ if (entity == st->first_idle) { ++ next = rb_next(&entity->rb_node); ++ st->first_idle = bfq_entity_of(next); ++ } ++ ++ if (entity == st->last_idle) { ++ next = rb_prev(&entity->rb_node); ++ st->last_idle = bfq_entity_of(next); ++ } ++ ++ bfq_extract(&st->idle, entity); ++ ++ if (bfqq) ++ list_del(&bfqq->bfqq_list); ++} ++ ++/** ++ * bfq_insert - generic tree insertion. ++ * @root: tree root. ++ * @entity: entity to insert. ++ * ++ * This is used for the idle and the active tree, since they are both ++ * ordered by finish time. ++ */ ++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) ++{ ++ struct bfq_entity *entry; ++ struct rb_node **node = &root->rb_node; ++ struct rb_node *parent = NULL; ++ ++ BUG_ON(entity->tree); ++ ++ while (*node) { ++ parent = *node; ++ entry = rb_entry(parent, struct bfq_entity, rb_node); ++ ++ if (bfq_gt(entry->finish, entity->finish)) ++ node = &parent->rb_left; ++ else ++ node = &parent->rb_right; ++ } ++ ++ rb_link_node(&entity->rb_node, parent, node); ++ rb_insert_color(&entity->rb_node, root); ++ ++ entity->tree = root; ++} ++ ++/** ++ * bfq_update_min - update the min_start field of a entity. ++ * @entity: the entity to update. ++ * @node: one of its children. ++ * ++ * This function is called when @entity may store an invalid value for ++ * min_start due to updates to the active tree. The function assumes ++ * that the subtree rooted at @node (which may be its left or its right ++ * child) has a valid min_start value. ++ */ ++static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node) ++{ ++ struct bfq_entity *child; ++ ++ if (node) { ++ child = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entity->min_start, child->min_start)) ++ entity->min_start = child->min_start; ++ } ++} ++ ++/** ++ * bfq_update_active_node - recalculate min_start. ++ * @node: the node to update. ++ * ++ * @node may have changed position or one of its children may have moved, ++ * this function updates its min_start value. The left and right subtrees ++ * are assumed to hold a correct min_start value. ++ */ ++static void bfq_update_active_node(struct rb_node *node) ++{ ++ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ entity->min_start = entity->start; ++ bfq_update_min(entity, node->rb_right); ++ bfq_update_min(entity, node->rb_left); ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_active_node: new min_start %llu", ++ ((entity->min_start>>10)*1000)>>12); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_active_node: new min_start %llu", ++ ((entity->min_start>>10)*1000)>>12); ++#endif ++ } ++} ++ ++/** ++ * bfq_update_active_tree - update min_start for the whole active tree. ++ * @node: the starting node. ++ * ++ * @node must be the deepest modified node after an update. This function ++ * updates its min_start using the values held by its children, assuming ++ * that they did not change, and then updates all the nodes that may have ++ * changed in the path to the root. The only nodes that may have changed ++ * are the ones in the path or their siblings. ++ */ ++static void bfq_update_active_tree(struct rb_node *node) ++{ ++ struct rb_node *parent; ++ ++up: ++ bfq_update_active_node(node); ++ ++ parent = rb_parent(node); ++ if (!parent) ++ return; ++ ++ if (node == parent->rb_left && parent->rb_right) ++ bfq_update_active_node(parent->rb_right); ++ else if (parent->rb_left) ++ bfq_update_active_node(parent->rb_left); ++ ++ node = parent; ++ goto up; ++} ++ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++ ++/** ++ * bfq_active_insert - insert an entity in the active tree of its ++ * group/device. ++ * @st: the service tree of the entity. ++ * @entity: the entity being inserted. ++ * ++ * The active tree is ordered by finish time, but an extra key is kept ++ * per each node, containing the minimum value for the start times of ++ * its children (and the node itself), so it's possible to search for ++ * the eligible node with the lowest finish time in logarithmic time. ++ */ ++static void bfq_active_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node = &entity->rb_node; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ bfq_insert(&st->active, entity); ++ ++ if (node->rb_left) ++ node = node->rb_left; ++ else if (node->rb_right) ++ node = node->rb_right; ++ ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ bfqg->active_entities++; ++ } ++#endif ++} ++ ++/** ++ * bfq_ioprio_to_weight - calc a weight from an ioprio. ++ * @ioprio: the ioprio value to convert. ++ */ ++static unsigned short bfq_ioprio_to_weight(int ioprio) ++{ ++ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); ++ return (IOPRIO_BE_NR - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF; ++} ++ ++/** ++ * bfq_weight_to_ioprio - calc an ioprio from a weight. ++ * @weight: the weight value to convert. ++ * ++ * To preserve as much as possible the old only-ioprio user interface, ++ * 0 is used as an escape ioprio value for weights (numerically) equal or ++ * larger than IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF. ++ */ ++static unsigned short bfq_weight_to_ioprio(int weight) ++{ ++ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); ++ return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight < 0 ? ++ 0 : IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight; ++} ++ ++static void bfq_get_entity(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) { ++ bfqq->ref++; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", ++ bfqq, bfqq->ref); ++ } ++} ++ ++/** ++ * bfq_find_deepest - find the deepest node that an extraction can modify. ++ * @node: the node being removed. ++ * ++ * Do the first step of an extraction in an rb tree, looking for the ++ * node that will replace @node, and returning the deepest node that ++ * the following modifications to the tree can touch. If @node is the ++ * last node in the tree return %NULL. ++ */ ++static struct rb_node *bfq_find_deepest(struct rb_node *node) ++{ ++ struct rb_node *deepest; ++ ++ if (!node->rb_right && !node->rb_left) ++ deepest = rb_parent(node); ++ else if (!node->rb_right) ++ deepest = node->rb_left; ++ else if (!node->rb_left) ++ deepest = node->rb_right; ++ else { ++ deepest = rb_next(node); ++ if (deepest->rb_right) ++ deepest = deepest->rb_right; ++ else if (rb_parent(deepest) != node) ++ deepest = rb_parent(deepest); ++ } ++ ++ return deepest; ++} ++ ++/** ++ * bfq_active_extract - remove an entity from the active tree. ++ * @st: the service_tree containing the tree. ++ * @entity: the entity being removed. ++ */ ++static void bfq_active_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ node = bfq_find_deepest(&entity->rb_node); ++ bfq_extract(&st->active, entity); ++ ++ if (node) ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq) ++ list_del(&bfqq->bfqq_list); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_remove(bfqd, entity, ++ &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ BUG_ON(!bfqg->active_entities); ++ bfqg->active_entities--; ++ } ++#endif ++} ++ ++/** ++ * bfq_idle_insert - insert an entity into the idle tree. ++ * @st: the service tree containing the tree. ++ * @entity: the entity to insert. ++ */ ++static void bfq_idle_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (!first_idle || bfq_gt(first_idle->finish, entity->finish)) ++ st->first_idle = entity; ++ if (!last_idle || bfq_gt(entity->finish, last_idle->finish)) ++ st->last_idle = entity; ++ ++ bfq_insert(&st->idle, entity); ++ ++ if (bfqq) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); ++} ++ ++/** ++ * bfq_forget_entity - remove an entity from the wfq trees. ++ * @st: the service tree. ++ * @entity: the entity being removed. ++ * ++ * Update the device status and forget everything about @entity, putting ++ * the device reference to it, if it is a queue. Entities belonging to ++ * groups are not refcounted. ++ */ ++static void bfq_forget_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(!entity->on_st); ++ ++ entity->on_st = 0; ++ st->wsum -= entity->weight; ++ if (bfqq) { ++ sd = entity->sched_data; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", ++ bfqq, bfqq->ref); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/** ++ * bfq_put_idle_entity - release the idle tree ref of an entity. ++ * @st: service tree for the entity. ++ * @entity: the entity being released. ++ */ ++static void bfq_put_idle_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ bfq_idle_extract(st, entity); ++ bfq_forget_entity(st, entity); ++} ++ ++/** ++ * bfq_forget_idle - update the idle tree if necessary. ++ * @st: the service tree to act upon. ++ * ++ * To preserve the global O(log N) complexity we only remove one entry here; ++ * as the idle tree will not grow indefinitely this can be done safely. ++ */ ++static void bfq_forget_idle(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (RB_EMPTY_ROOT(&st->active) && last_idle && ++ !bfq_gt(last_idle->finish, st->vtime)) { ++ /* ++ * Forget the whole idle tree, increasing the vtime past ++ * the last finish time of idle entities. ++ */ ++ st->vtime = last_idle->finish; ++ } ++ ++ if (first_idle && !bfq_gt(first_idle->finish, st->vtime)) ++ bfq_put_idle_entity(st, first_idle); ++} ++ ++static struct bfq_service_tree * ++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_service_tree *new_st = old_st; ++ ++ if (entity->prio_changed) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned int prev_weight, new_weight; ++ struct bfq_data *bfqd = NULL; ++ struct rb_root *root; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ struct bfq_sched_data *sd; ++ struct bfq_group *bfqg; ++#endif ++ ++ if (bfqq) ++ bfqd = bfqq->bfqd; ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ sd = entity->my_sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++ BUG_ON(!bfqd); ++ } ++#endif ++ ++ BUG_ON(old_st->wsum < entity->weight); ++ old_st->wsum -= entity->weight; ++ ++ if (entity->new_weight != entity->orig_weight) { ++ if (entity->new_weight < BFQ_MIN_WEIGHT || ++ entity->new_weight > BFQ_MAX_WEIGHT) { ++ pr_crit("update_weight_prio: new_weight %d\n", ++ entity->new_weight); ++ if (entity->new_weight < BFQ_MIN_WEIGHT) ++ entity->new_weight = BFQ_MIN_WEIGHT; ++ else ++ entity->new_weight = BFQ_MAX_WEIGHT; ++ } ++ entity->orig_weight = entity->new_weight; ++ if (bfqq) ++ bfqq->ioprio = ++ bfq_weight_to_ioprio(entity->orig_weight); ++ } ++ ++ if (bfqq) ++ bfqq->ioprio_class = bfqq->new_ioprio_class; ++ entity->prio_changed = 0; ++ ++ /* ++ * NOTE: here we may be changing the weight too early, ++ * this will cause unfairness. The correct approach ++ * would have required additional complexity to defer ++ * weight changes to the proper time instants (i.e., ++ * when entity->finish <= old_st->vtime). ++ */ ++ new_st = bfq_entity_service_tree(entity); ++ ++ prev_weight = entity->weight; ++ new_weight = entity->orig_weight * ++ (bfqq ? bfqq->wr_coeff : 1); ++ /* ++ * If the weight of the entity changes, remove the entity ++ * from its old weight counter (if there is a counter ++ * associated with the entity), and add it to the counter ++ * associated with its new weight. ++ */ ++ if (prev_weight != new_weight) { ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "weight changed %d %d(%d %d)", ++ prev_weight, new_weight, ++ entity->orig_weight, ++ bfqq->wr_coeff); ++ ++ root = bfqq ? &bfqd->queue_weights_tree : ++ &bfqd->group_weights_tree; ++ bfq_weights_tree_remove(bfqd, entity, root); ++ } ++ entity->weight = new_weight; ++ /* ++ * Add the entity to its weights tree only if it is ++ * not associated with a weight-raised queue. ++ */ ++ if (prev_weight != new_weight && ++ (bfqq ? bfqq->wr_coeff == 1 : 1)) ++ /* If we get here, root has been initialized. */ ++ bfq_weights_tree_add(bfqd, entity, root); ++ ++ new_st->wsum += entity->weight; ++ ++ if (new_st != old_st) ++ entity->start = new_st->vtime; ++ } ++ ++ return new_st; ++} ++ ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg); ++#endif ++ ++/** ++ * bfq_bfqq_served - update the scheduler status after selection for ++ * service. ++ * @bfqq: the queue being served. ++ * @served: bytes to transfer. ++ * ++ * NOTE: this can be optimized, as the timestamps of upper level entities ++ * are synchronized every time a new bfqq is selected for service. By now, ++ * we keep it to better check consistency. ++ */ ++static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st; ++ ++ for_each_entity(entity) { ++ st = bfq_entity_service_tree(entity); ++ ++ entity->service += served; ++ ++ BUG_ON(st->wsum == 0); ++ ++ st->vtime += bfq_delta(served, st->wsum); ++ bfq_forget_idle(st); ++ } ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ bfqg_stats_set_start_empty_time(bfqq_group(bfqq)); ++#endif ++ st = bfq_entity_service_tree(&bfqq->entity); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs, vtime %llu on %p", ++ served, ((st->vtime>>10)*1000)>>12, st); ++} ++ ++/** ++ * bfq_bfqq_charge_time - charge an amount of service equivalent to the length ++ * of the time interval during which bfqq has been in ++ * service. ++ * @bfqd: the device ++ * @bfqq: the queue that needs a service update. ++ * @time_ms: the amount of time during which the queue has received service ++ * ++ * If a queue does not consume its budget fast enough, then providing ++ * the queue with service fairness may impair throughput, more or less ++ * severely. For this reason, queues that consume their budget slowly ++ * are provided with time fairness instead of service fairness. This ++ * goal is achieved through the BFQ scheduling engine, even if such an ++ * engine works in the service, and not in the time domain. The trick ++ * is charging these queues with an inflated amount of service, equal ++ * to the amount of service that they would have received during their ++ * service slot if they had been fast, i.e., if their requests had ++ * been dispatched at a rate equal to the estimated peak rate. ++ * ++ * It is worth noting that time fairness can cause important ++ * distortions in terms of bandwidth distribution, on devices with ++ * internal queueing. The reason is that I/O requests dispatched ++ * during the service slot of a queue may be served after that service ++ * slot is finished, and may have a total processing time loosely ++ * correlated with the duration of the service slot. This is ++ * especially true for short service slots. ++ */ ++static void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ unsigned long time_ms) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ int tot_serv_to_charge = entity->service; ++ unsigned int timeout_ms = jiffies_to_msecs(bfq_timeout); ++ ++ if (time_ms > 0 && time_ms < timeout_ms) ++ tot_serv_to_charge = ++ (bfqd->bfq_max_budget * time_ms) / timeout_ms; ++ ++ if (tot_serv_to_charge < entity->service) ++ tot_serv_to_charge = entity->service; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "charge_time: %lu/%u ms, %d/%d/%d sectors", ++ time_ms, timeout_ms, entity->service, ++ tot_serv_to_charge, entity->budget); ++ ++ /* Increase budget to avoid inconsistencies */ ++ if (tot_serv_to_charge > entity->budget) ++ entity->budget = tot_serv_to_charge; ++ ++ bfq_bfqq_served(bfqq, ++ max_t(int, 0, tot_serv_to_charge - entity->service)); ++} ++ ++/** ++ * __bfq_activate_entity - activate an entity. ++ * @entity: the entity being activated. ++ * @non_blocking_wait_rq: true if this entity was waiting for a request ++ * ++ * Called whenever an entity is activated, i.e., it is not active and one ++ * of its children receives a new request, or has to be reactivated due to ++ * budget exhaustion. It uses the current budget of the entity (and the ++ * service received if @entity is active) of the queue to calculate its ++ * timestamps. ++ */ ++static void __bfq_activate_entity(struct bfq_entity *entity, ++ bool non_blocking_wait_rq) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ bool backshifted = false; ++ ++ BUG_ON(!sd); ++ BUG_ON(!st); ++ if (entity == sd->in_service_entity) { ++ BUG_ON(entity->tree); ++ /* ++ * If we are requeueing the current entity we have ++ * to take care of not charging to it service it has ++ * not received. ++ */ ++ bfq_calc_finish(entity, entity->service); ++ entity->start = entity->finish; ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) { ++ /* ++ * Requeueing an entity due to a change of some ++ * next_in_service entity below it. We reuse the ++ * old start time. ++ */ ++ bfq_active_extract(st, entity); ++ } else { ++ unsigned long long min_vstart; ++ ++ /* See comments on bfq_fqq_update_budg_for_activation */ ++ if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) { ++ backshifted = true; ++ min_vstart = entity->finish; ++ } else ++ min_vstart = st->vtime; ++ ++ if (entity->tree == &st->idle) { ++ /* ++ * Must be on the idle tree, bfq_idle_extract() will ++ * check for that. ++ */ ++ bfq_idle_extract(st, entity); ++ entity->start = bfq_gt(min_vstart, entity->finish) ? ++ min_vstart : entity->finish; ++ } else { ++ /* ++ * The finish time of the entity may be invalid, and ++ * it is in the past for sure, otherwise the queue ++ * would have been on the idle tree. ++ */ ++ entity->start = min_vstart; ++ st->wsum += entity->weight; ++ bfq_get_entity(entity); ++ ++ BUG_ON(entity->on_st); ++ entity->on_st = 1; ++ } ++ } ++ ++ st = __bfq_entity_update_weight_prio(st, entity); ++ bfq_calc_finish(entity, entity->budget); ++ ++ /* ++ * If some queues enjoy backshifting for a while, then their ++ * (virtual) finish timestamps may happen to become lower and ++ * lower than the system virtual time. In particular, if ++ * these queues often happen to be idle for short time ++ * periods, and during such time periods other queues with ++ * higher timestamps happen to be busy, then the backshifted ++ * timestamps of the former queues can become much lower than ++ * the system virtual time. In fact, to serve the queues with ++ * higher timestamps while the ones with lower timestamps are ++ * idle, the system virtual time may be pushed-up to much ++ * higher values than the finish timestamps of the idle ++ * queues. As a consequence, the finish timestamps of all new ++ * or newly activated queues may end up being much larger than ++ * those of lucky queues with backshifted timestamps. The ++ * latter queues may then monopolize the device for a lot of ++ * time. This would simply break service guarantees. ++ * ++ * To reduce this problem, push up a little bit the ++ * backshifted timestamps of the queue associated with this ++ * entity (only a queue can happen to have the backshifted ++ * flag set): just enough to let the finish timestamp of the ++ * queue be equal to the current value of the system virtual ++ * time. This may introduce a little unfairness among queues ++ * with backshifted timestamps, but it does not break ++ * worst-case fairness guarantees. ++ * ++ * As a special case, if bfqq is weight-raised, push up ++ * timestamps much less, to keep very low the probability that ++ * this push up causes the backshifted finish timestamps of ++ * weight-raised queues to become higher than the backshifted ++ * finish timestamps of non weight-raised queues. ++ */ ++ if (backshifted && bfq_gt(st->vtime, entity->finish)) { ++ unsigned long delta = st->vtime - entity->finish; ++ ++ if (bfqq) ++ delta /= bfqq->wr_coeff; ++ ++ entity->start += delta; ++ entity->finish += delta; ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__activate_entity: new queue finish %llu", ++ ((entity->finish>>10)*1000)>>12); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__activate_entity: new group finish %llu", ++ ((entity->finish>>10)*1000)>>12); ++#endif ++ } ++ } ++ ++ bfq_active_insert(st, entity); ++ ++ if (bfqq) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__activate_entity: queue %seligible in st %p", ++ entity->start <= st->vtime ? "" : "non ", st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ } else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__activate_entity: group %seligible in st %p", ++ entity->start <= st->vtime ? "" : "non ", st); ++#endif ++ } ++} ++ ++/** ++ * bfq_activate_entity - activate an entity and its ancestors if necessary. ++ * @entity: the entity to activate. ++ * @non_blocking_wait_rq: true if this entity was waiting for a request ++ * ++ * Activate @entity and all the entities on the path from it to the root. ++ */ ++static void bfq_activate_entity(struct bfq_entity *entity, ++ bool non_blocking_wait_rq) ++{ ++ struct bfq_sched_data *sd; ++ ++ for_each_entity(entity) { ++ BUG_ON(!entity); ++ __bfq_activate_entity(entity, non_blocking_wait_rq); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ /* ++ * No need to propagate the activation to the ++ * upper entities, as they will be updated when ++ * the in-service entity is rescheduled. ++ */ ++ break; ++ } ++} ++ ++/** ++ * __bfq_deactivate_entity - deactivate an entity from its service tree. ++ * @entity: the entity to deactivate. ++ * @requeue: if false, the entity will not be put into the idle tree. ++ * ++ * Deactivate an entity, independently from its previous state. If the ++ * entity was not on a service tree just return, otherwise if it is on ++ * any scheduler tree, extract it from that tree, and if necessary ++ * and if the caller did not specify @requeue, put it on the idle tree. ++ * ++ * Return %1 if the caller should update the entity hierarchy, i.e., ++ * if the entity was in service or if it was the next_in_service for ++ * its sched_data; return %0 otherwise. ++ */ ++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st; ++ int was_in_service; ++ int ret = 0; ++ ++ if (sd == NULL || !entity->on_st) /* never activated, or inactive */ ++ return 0; ++ ++ st = bfq_entity_service_tree(entity); ++ was_in_service = entity == sd->in_service_entity; ++ ++ BUG_ON(was_in_service && entity->tree); ++ ++ if (was_in_service) { ++ bfq_calc_finish(entity, entity->service); ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) ++ bfq_active_extract(st, entity); ++ else if (entity->tree == &st->idle) ++ bfq_idle_extract(st, entity); ++ else if (entity->tree) ++ BUG(); ++ ++ if (was_in_service || sd->next_in_service == entity) ++ ret = bfq_update_next_in_service(sd); ++ ++ if (!requeue || !bfq_gt(entity->finish, st->vtime)) ++ bfq_forget_entity(st, entity); ++ else ++ bfq_idle_insert(st, entity); ++ ++ BUG_ON(sd->in_service_entity == entity); ++ BUG_ON(sd->next_in_service == entity); ++ ++ return ret; ++} ++ ++/** ++ * bfq_deactivate_entity - deactivate an entity. ++ * @entity: the entity to deactivate. ++ * @requeue: true if the entity can be put on the idle tree ++ */ ++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd; ++ struct bfq_entity *parent; ++ ++ for_each_entity_safe(entity, parent) { ++ sd = entity->sched_data; ++ ++ if (!__bfq_deactivate_entity(entity, requeue)) ++ /* ++ * next_in_service has not been changed, so ++ * no upwards update is needed ++ */ ++ break; ++ ++ if (sd->next_in_service) ++ /* ++ * The parent entity is still backlogged, ++ * because next_in_service is not NULL, and ++ * next_in_service has been updated (see ++ * comment on the body of the above if): ++ * upwards update of the schedule is needed. ++ */ ++ goto update; ++ ++ /* ++ * If we get here, then the parent is no more backlogged and ++ * we want to propagate the deactivation upwards. ++ */ ++ requeue = 1; ++ } ++ ++ return; ++ ++update: ++ entity = parent; ++ for_each_entity(entity) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ __bfq_activate_entity(entity, false); ++ ++ sd = entity->sched_data; ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "invoking udpdate_next for this queue"); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, ++ struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "invoking udpdate_next for this entity"); ++ } ++#endif ++ if (!bfq_update_next_in_service(sd)) ++ break; ++ } ++} ++ ++/** ++ * bfq_update_vtime - update vtime if necessary. ++ * @st: the service tree to act upon. ++ * ++ * If necessary update the service tree vtime to have at least one ++ * eligible entity, skipping to its start time. Assumes that the ++ * active tree of the device is not empty. ++ * ++ * NOTE: this hierarchical implementation updates vtimes quite often, ++ * we may end up with reactivated processes getting timestamps after a ++ * vtime skip done because we needed a ->first_active entity on some ++ * intermediate node. ++ */ ++static void bfq_update_vtime(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry; ++ struct rb_node *node = st->active.rb_node; ++ ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entry->min_start, st->vtime)) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entry); ++ st->vtime = entry->min_start; ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "update_vtime: new vtime %llu %p", ++ ((st->vtime>>10)*1000)>>12, st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entry, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "update_vtime: new vtime %llu %p", ++ ((st->vtime>>10)*1000)>>12, st); ++ } ++#endif ++ bfq_forget_idle(st); ++ } ++} ++ ++/** ++ * bfq_first_active_entity - find the eligible entity with ++ * the smallest finish time ++ * @st: the service tree to select from. ++ * ++ * This function searches the first schedulable entity, starting from the ++ * root of the tree and going on the left every time on this side there is ++ * a subtree with at least one eligible (start >= vtime) entity. The path on ++ * the right is followed only if a) the left subtree contains no eligible ++ * entities and b) no eligible entity has been found yet. ++ */ ++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry, *first = NULL; ++ struct rb_node *node = st->active.rb_node; ++ ++ while (node) { ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++left: ++ if (!bfq_gt(entry->start, st->vtime)) ++ first = entry; ++ ++ BUG_ON(bfq_gt(entry->min_start, st->vtime)); ++ ++ if (node->rb_left) { ++ entry = rb_entry(node->rb_left, ++ struct bfq_entity, rb_node); ++ if (!bfq_gt(entry->min_start, st->vtime)) { ++ node = node->rb_left; ++ goto left; ++ } ++ } ++ if (first) ++ break; ++ node = node->rb_right; ++ } ++ ++ BUG_ON(!first && !RB_EMPTY_ROOT(&st->active)); ++ return first; ++} ++ ++/** ++ * __bfq_lookup_next_entity - return the first eligible entity in @st. ++ * @st: the service tree. ++ * ++ * Update the virtual time in @st and return the first eligible entity ++ * it contains. ++ */ ++static struct bfq_entity * ++__bfq_lookup_next_entity(struct bfq_service_tree *st, bool force) ++{ ++ struct bfq_entity *entity, *new_next_in_service = NULL; ++ struct bfq_queue *bfqq; ++ ++ if (RB_EMPTY_ROOT(&st->active)) ++ return NULL; ++ ++ bfq_update_vtime(st); ++ entity = bfq_first_active_entity(st); ++ BUG_ON(bfq_gt(entity->start, st->vtime)); ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ if (bfqq) ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "__lookup_next: start %llu vtime %llu st %p", ++ ((entity->start>>10)*1000)>>12, ++ ((st->vtime>>10)*1000)>>12, st); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, ++ "__lookup_next: start %llu vtime %llu st %p", ++ ((entity->start>>10)*1000)>>12, ++ ((st->vtime>>10)*1000)>>12, st); ++ } ++#endif ++ ++ /* ++ * If the chosen entity does not match with the sched_data's ++ * next_in_service and we are forcedly serving the IDLE priority ++ * class tree, bubble up budget update. ++ */ ++ if (unlikely(force && entity != entity->sched_data->next_in_service)) { ++ new_next_in_service = entity; ++ for_each_entity(new_next_in_service) ++ bfq_update_budget(new_next_in_service); ++ } ++ ++ return entity; ++} ++ ++/** ++ * bfq_lookup_next_entity - return the first eligible entity in @sd. ++ * @sd: the sched_data. ++ * @extract: if true the returned entity will be also extracted from @sd. ++ * ++ * NOTE: since we cache the next_in_service entity at each level of the ++ * hierarchy, the complexity of the lookup can be decreased with ++ * absolutely no effort just returning the cached next_in_service value; ++ * we prefer to do full lookups to test the consistency of * the data ++ * structures. ++ */ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_service_tree *st = sd->service_tree; ++ struct bfq_entity *entity; ++ int i = 0; ++ ++ BUG_ON(sd->in_service_entity); ++ ++ /* ++ * Choose from idle class, if needed to guarantee a minimum ++ * bandwidth to this class. This should also mitigate ++ * priority-inversion problems in case a low priority task is ++ * holding file system resources. ++ */ ++ if (bfqd && ++ jiffies - bfqd->bfq_class_idle_last_service > ++ BFQ_CL_IDLE_TIMEOUT) { ++ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, ++ true); ++ if (entity) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "idle chosen from st %p %d", ++ st + BFQ_IOPRIO_CLASSES - 1, ++ BFQ_IOPRIO_CLASSES - 1); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "idle chosen from st %p %d", ++ st + BFQ_IOPRIO_CLASSES - 1, ++ BFQ_IOPRIO_CLASSES - 1); ++ } ++#endif ++ i = BFQ_IOPRIO_CLASSES - 1; ++ bfqd->bfq_class_idle_last_service = jiffies; ++ sd->next_in_service = entity; ++ } ++ } ++ for (; i < BFQ_IOPRIO_CLASSES; i++) { ++ entity = __bfq_lookup_next_entity(st + i, false); ++ if (entity) { ++ if (bfqd != NULL) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "chosen from st %p %d", ++ st + i, i); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "chosen from st %p %d", ++ st + i, i); ++ } ++#endif ++ } ++ ++ if (extract) { ++ bfq_check_next_in_service(sd, entity); ++ bfq_active_extract(st + i, entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ } ++ break; ++ } ++ } ++ ++ return entity; ++} ++ ++static bool next_queue_may_preempt(struct bfq_data *bfqd) ++{ ++ struct bfq_sched_data *sd = &bfqd->root_group->sched_data; ++ ++ return sd->next_in_service != sd->in_service_entity; ++} ++ ++/* ++ * Get next queue for service. ++ */ ++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_entity *entity = NULL; ++ struct bfq_sched_data *sd; ++ struct bfq_queue *bfqq; ++ ++ BUG_ON(bfqd->in_service_queue); ++ ++ if (bfqd->busy_queues == 0) ++ return NULL; ++ ++ sd = &bfqd->root_group->sched_data; ++ for (; sd ; sd = entity->my_sched_data) { ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ if (entity) { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "get_next_queue: lookup in this group"); ++ } else ++ bfq_log_bfqg(bfqd, bfqd->root_group, ++ "get_next_queue: lookup in root group"); ++#endif ++ ++ entity = bfq_lookup_next_entity(sd, 1, bfqd); ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ if (bfqq) ++ bfq_log_bfqq(bfqd, bfqq, ++ "get_next_queue: this queue, finish %llu", ++ (((entity->finish>>10)*1000)>>10)>>2); ++#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ else { ++ struct bfq_group *bfqg = ++ container_of(entity, struct bfq_group, entity); ++ ++ bfq_log_bfqg(bfqd, bfqg, ++ "get_next_queue: this entity, finish %llu", ++ (((entity->finish>>10)*1000)>>10)>>2); ++ } ++#endif ++ ++ BUG_ON(!entity); ++ entity->service = 0; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ BUG_ON(!bfqq); ++ ++ return bfqq; ++} ++ ++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) ++{ ++ if (bfqd->in_service_bic) { ++ put_io_context(bfqd->in_service_bic->icq.ioc); ++ bfqd->in_service_bic = NULL; ++ } ++ ++ bfq_clear_bfqq_wait_request(bfqd->in_service_queue); ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); ++ bfqd->in_service_queue = NULL; ++} ++ ++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ bfq_deactivate_entity(entity, requeue); ++} ++ ++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_activate_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq)); ++ bfq_clear_bfqq_non_blocking_wait_rq(bfqq); ++} ++ ++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg); ++ ++/* ++ * Called when the bfqq no longer has requests pending, remove it from ++ * the service tree. ++ */ ++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "del from busy"); ++ ++ bfq_clear_bfqq_busy(bfqq); ++ ++ BUG_ON(bfqd->busy_queues == 0); ++ bfqd->busy_queues--; ++ ++ if (!bfqq->dispatched) ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues--; ++ ++ bfqg_stats_update_dequeue(bfqq_group(bfqq)); ++ ++ BUG_ON(bfqq->entity.budget < 0); ++ ++ bfq_deactivate_bfqq(bfqd, bfqq, requeue); ++ ++ BUG_ON(bfqq->entity.budget < 0); ++} ++ ++/* ++ * Called when an inactive queue receives a new request. ++ */ ++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "add to busy"); ++ ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ bfq_mark_bfqq_busy(bfqq); ++ bfqd->busy_queues++; ++ ++ if (!bfqq->dispatched) ++ if (bfqq->wr_coeff == 1) ++ bfq_weights_tree_add(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues++; ++} +diff -w -uNr '--exclude=.git' linux-4.8/block/Kconfig.iosched linux-4.8-bfq/block/Kconfig.iosched +--- linux-4.8/block/Kconfig.iosched 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/block/Kconfig.iosched 2016-10-18 12:57:57.691164881 +0200 +@@ -39,6 +39,25 @@ + ---help--- + Enable group IO scheduling in CFQ. + ++config IOSCHED_BFQ ++ tristate "BFQ I/O scheduler" ++ default n ++ ---help--- ++ The BFQ I/O scheduler tries to distribute bandwidth among ++ all processes according to their weights. ++ It aims at distributing the bandwidth as desired, independently of ++ the disk parameters and with any workload. It also tries to ++ guarantee low latency to interactive and soft real-time ++ applications. If compiled built-in (saying Y here), BFQ can ++ be configured to support hierarchical scheduling. ++ ++config BFQ_GROUP_IOSCHED ++ bool "BFQ hierarchical scheduling support" ++ depends on IOSCHED_BFQ && BLK_CGROUP ++ default n ++ ---help--- ++ Enable hierarchical scheduling in BFQ, using the blkio controller. ++ + choice + prompt "Default I/O scheduler" + default DEFAULT_CFQ +@@ -52,6 +71,16 @@ + config DEFAULT_CFQ + bool "CFQ" if IOSCHED_CFQ=y + ++ config DEFAULT_BFQ ++ bool "BFQ" if IOSCHED_BFQ=y ++ help ++ Selects BFQ as the default I/O scheduler which will be ++ used by default for all block devices. ++ The BFQ I/O scheduler aims at distributing the bandwidth ++ as desired, independently of the disk parameters and with ++ any workload. It also tries to guarantee low latency to ++ interactive and soft real-time applications. ++ + config DEFAULT_NOOP + bool "No-op" + +@@ -61,6 +90,7 @@ + string + default "deadline" if DEFAULT_DEADLINE + default "cfq" if DEFAULT_CFQ ++ default "bfq" if DEFAULT_BFQ + default "noop" if DEFAULT_NOOP + + endmenu +diff -w -uNr '--exclude=.git' linux-4.8/block/Makefile linux-4.8-bfq/block/Makefile +--- linux-4.8/block/Makefile 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/block/Makefile 2016-10-18 12:57:57.691164881 +0200 +@@ -18,6 +18,7 @@ + obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o + obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o + obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o ++obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o + + obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o + obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o +diff -w -uNr '--exclude=.git' linux-4.8/include/linux/blkdev.h linux-4.8-bfq/include/linux/blkdev.h +--- linux-4.8/include/linux/blkdev.h 2016-10-03 01:24:33.000000000 +0200 ++++ linux-4.8-bfq/include/linux/blkdev.h 2016-10-18 12:57:59.951179412 +0200 +@@ -45,7 +45,7 @@ + * Maximum number of blkcg policies allowed to be registered concurrently. + * Defined here to simplify include dependency. + */ +-#define BLKCG_MAX_POLS 2 ++#define BLKCG_MAX_POLS 3 + + typedef void (rq_end_io_fn)(struct request *, int); + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-add-recursion-limit-to-GRO.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-add-recursion-limit-to-GRO.patch new file mode 100644 index 00000000..a3e3aa52 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-add-recursion-limit-to-GRO.patch @@ -0,0 +1,242 @@ +From fcd91dd449867c6bfe56a81cabba76b829fd05cd Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Thu, 20 Oct 2016 15:58:02 +0200 +Subject: [PATCH] net: add recursion limit to GRO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, GRO can do unlimited recursion through the gro_receive +handlers. This was fixed for tunneling protocols by limiting tunnel GRO +to one level with encap_mark, but both VLAN and TEB still have this +problem. Thus, the kernel is vulnerable to a stack overflow, if we +receive a packet composed entirely of VLAN headers. + +This patch adds a recursion counter to the GRO layer to prevent stack +overflow. When a gro_receive function hits the recursion limit, GRO is +aborted for this skb and it is processed normally. This recursion +counter is put in the GRO CB, but could be turned into a percpu counter +if we run out of space in the CB. + +Thanks to Vladimír Beneš for the initial bug report. + +Fixes: CVE-2016-7039 +Fixes: 9b174d88c257 ("net: Add Transparent Ethernet Bridging GRO support.") +Fixes: 66e5133f19e9 ("vlan: Add GRO support for non hardware accelerated vlan") +Signed-off-by: Sabrina Dubroca +Reviewed-by: Jiri Benc +Acked-by: Hannes Frederic Sowa +Acked-by: Tom Herbert +Signed-off-by: David S. Miller +--- + drivers/net/geneve.c | 2 +- + drivers/net/vxlan.c | 2 +- + include/linux/netdevice.h | 39 ++++++++++++++++++++++++++++++++++++++- + net/8021q/vlan.c | 2 +- + net/core/dev.c | 1 + + net/ethernet/eth.c | 2 +- + net/ipv4/af_inet.c | 2 +- + net/ipv4/fou.c | 4 ++-- + net/ipv4/gre_offload.c | 2 +- + net/ipv4/udp_offload.c | 2 +- + net/ipv6/ip6_offload.c | 2 +- + 11 files changed, 49 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 3c20e87..16af1ce 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk, + + skb_gro_pull(skb, gh_len); + skb_gro_postpull_rcsum(skb, gh, gh_len); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index e7d1668..c1639a3 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -583,7 +583,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk, + } + } + +- pp = eth_gro_receive(head, skb); ++ pp = call_gro_receive(eth_gro_receive, head, skb); + flush = 0; + + out: +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 465e128..91ee364 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2169,7 +2169,10 @@ struct napi_gro_cb { + /* Used to determine if flush_id can be ignored */ + u8 is_atomic:1; + +- /* 5 bit hole */ ++ /* Number of gro_receive callbacks this packet already went through */ ++ u8 recursion_counter:4; ++ ++ /* 1 bit hole */ + + /* used to support CHECKSUM_COMPLETE for tunneling protocols */ + __wsum csum; +@@ -2180,6 +2183,40 @@ struct napi_gro_cb { + + #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) + ++#define GRO_RECURSION_LIMIT 15 ++static inline int gro_recursion_inc_test(struct sk_buff *skb) ++{ ++ return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT; ++} ++ ++typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *); ++static inline struct sk_buff **call_gro_receive(gro_receive_t cb, ++ struct sk_buff **head, ++ struct sk_buff *skb) ++{ ++ if (unlikely(gro_recursion_inc_test(skb))) { ++ NAPI_GRO_CB(skb)->flush |= 1; ++ return NULL; ++ } ++ ++ return cb(head, skb); ++} ++ ++typedef struct sk_buff **(*gro_receive_sk_t)(struct sock *, struct sk_buff **, ++ struct sk_buff *); ++static inline struct sk_buff **call_gro_receive_sk(gro_receive_sk_t cb, ++ struct sock *sk, ++ struct sk_buff **head, ++ struct sk_buff *skb) ++{ ++ if (unlikely(gro_recursion_inc_test(skb))) { ++ NAPI_GRO_CB(skb)->flush |= 1; ++ return NULL; ++ } ++ ++ return cb(sk, head, skb); ++} ++ + struct packet_type { + __be16 type; /* This is really htons(ether_type). */ + struct net_device *dev; /* NULL is wildcarded here */ +diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c +index 8de138d..f2531ad 100644 +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -664,7 +664,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head, + + skb_gro_pull(skb, sizeof(*vhdr)); + skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr)); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/core/dev.c b/net/core/dev.c +index b09ac57..dbc8713 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4511,6 +4511,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff + NAPI_GRO_CB(skb)->flush = 0; + NAPI_GRO_CB(skb)->free = 0; + NAPI_GRO_CB(skb)->encap_mark = 0; ++ NAPI_GRO_CB(skb)->recursion_counter = 0; + NAPI_GRO_CB(skb)->is_fou = 0; + NAPI_GRO_CB(skb)->is_atomic = 1; + NAPI_GRO_CB(skb)->gro_remcsum_start = 0; +diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c +index 66dff5e..02acfff 100644 +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -439,7 +439,7 @@ struct sk_buff **eth_gro_receive(struct sk_buff **head, + + skb_gro_pull(skb, sizeof(*eh)); + skb_gro_postpull_rcsum(skb, eh, sizeof(*eh)); +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 1effc98..9648c97 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1391,7 +1391,7 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb) + skb_gro_pull(skb, sizeof(*iph)); + skb_set_transport_header(skb, skb_gro_offset(skb)); + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c +index cf50f7e..030d153 100644 +--- a/net/ipv4/fou.c ++++ b/net/ipv4/fou.c +@@ -249,7 +249,7 @@ static struct sk_buff **fou_gro_receive(struct sock *sk, + if (!ops || !ops->callbacks.gro_receive) + goto out_unlock; + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +@@ -441,7 +441,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk, + if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + goto out_unlock; + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c +index 96e0efe..d5cac99 100644 +--- a/net/ipv4/gre_offload.c ++++ b/net/ipv4/gre_offload.c +@@ -229,7 +229,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head, + /* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/ + skb_gro_postpull_rcsum(skb, greh, grehlen); + +- pp = ptype->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + flush = 0; + + out_unlock: +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index f9333c9..b2be1d9 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -295,7 +295,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb, + + skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */ + skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); +- pp = udp_sk(sk)->gro_receive(sk, head, skb); ++ pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb); + + out_unlock: + rcu_read_unlock(); +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index e7bfd55..1fcf61f 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -246,7 +246,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, + + skb_gro_postpull_rcsum(skb, iph, nlen); + +- pp = ops->callbacks.gro_receive(head, skb); ++ pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + + out_unlock: + rcu_read_unlock(); +-- +2.10.1 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch new file mode 100644 index 00000000..c251e081 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch @@ -0,0 +1,429 @@ +From cf4747d7535a936105f0abe8d8109d3fe339162b Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Wed, 12 Oct 2016 13:54:04 -0500 +Subject: [PATCH] rtlwifi: Fix regression caused by commit d86e64768859 + +In commit d86e64768859 ("rtlwifi: rtl818x: constify local structures"), +the configuration struct for most of the drivers was changed to be +constant. The problem is that five of the modified drivers need to be +able to update the firmware name based on the exact model of the card. +As the file names were stored in one of the members of that struct, +these drivers would fail with a kernel BUG splat when they tried to +update the firmware name. + +Rather than reverting the previous commit, I used a suggestion by +Johannes Berg and made the firmware file name pointers be local to +the routines that update the software variables. + +The configuration struct of rtl8192cu, which was not touched in the +previous patch, is now constantfied. + +Fixes: d86e64768859 ("rtlwifi: rtl818x: constify local structures") +Suggested-by: Johannes Berg +Signed-off-by: Larry Finger +Cc: Stable # 4.8 +Cc: Julia Lawall +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 2 +- + drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 8 ++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c | 13 +++++-------- + drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c | 12 ++++++------ + drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c | 6 +++--- + drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c | 8 ++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c | 9 +++++---- + drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c | 12 +++++------- + drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c | 6 +++--- + drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 18 +++++++++--------- + drivers/net/wireless/realtek/rtlwifi/wifi.h | 2 -- + 11 files changed, 45 insertions(+), 51 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c +index f95760c..8e7f23c 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -111,7 +111,7 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, + if (!err) + goto found_alt; + } +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); ++ pr_err("Selected firmware is not available\n"); + rtlpriv->max_fw_size = 0; + return; + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c +index e7b11b4..f361808 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c +@@ -86,6 +86,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tid; ++ char *fw_name; + + rtl8188ee_bt_reg_init(hw); + rtlpriv->dm.dm_initialgain_enable = 1; +@@ -169,10 +170,10 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8188efw.bin"; ++ fw_name = "rtlwifi/rtl8188efw.bin"; + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -284,7 +285,6 @@ static const struct rtl_hal_cfg rtl88ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl88e_pci", +- .fw_name = "rtlwifi/rtl8188efw.bin", + .ops = &rtl8188ee_hal_ops, + .mod_params = &rtl88ee_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +index 87aa209..8b6e37c 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +@@ -96,6 +96,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ char *fw_name = "rtlwifi/rtl8192cfwU.bin"; + + rtl8192ce_bt_reg_init(hw); + +@@ -167,15 +168,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) + } + + /* request fw */ +- if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && +- !IS_92C_SERIAL(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; +- else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; ++ if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) ++ fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + + rtlpriv->max_fw_size = 0x4000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -262,7 +260,6 @@ static const struct rtl_hal_cfg rtl92ce_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92c_pci", +- .fw_name = "rtlwifi/rtl8192cfw.bin", + .ops = &rtl8192ce_hal_ops, + .mod_params = &rtl92ce_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +index 7c6f7f0..f953320 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +@@ -59,6 +59,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; ++ char *fw_name; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -77,18 +78,18 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) + } + if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && + !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_A.bin"; + } else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_B.bin"; + } else { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; ++ fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; + } + /* provide name of alternative file */ + rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin"; +- pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); ++ pr_info("Loading firmware %s\n", fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, +- rtlpriv->cfg->fw_name, rtlpriv->io.dev, ++ fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + return err; + } +@@ -187,7 +188,6 @@ static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { + + static struct rtl_hal_cfg rtl92cu_hal_cfg = { + .name = "rtl92c_usb", +- .fw_name = "rtlwifi/rtl8192cufw.bin", + .ops = &rtl8192cu_hal_ops, + .mod_params = &rtl92cu_mod_params, + .usb_interface_cfg = &rtl92cu_interface_cfg, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +index 0538a4d..1ebfee1 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +@@ -92,6 +92,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) + u8 tid; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); ++ char *fw_name = "rtlwifi/rtl8192defw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -181,10 +182,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) + + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); +- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); ++ pr_info("Loading firmware file %s\n", fw_name); + + /* request fw */ +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -266,7 +267,6 @@ static const struct rtl_hal_cfg rtl92de_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8192de", +- .fw_name = "rtlwifi/rtl8192defw.bin", + .ops = &rtl8192de_hal_ops, + .mod_params = &rtl92de_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c +index ac299cb..46b605de3 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c +@@ -91,6 +91,7 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; ++ char *fw_name; + + rtl92ee_bt_reg_init(hw); + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; +@@ -170,11 +171,11 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) + } + + /* request fw */ +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8192eefw.bin"; ++ fw_name = "rtlwifi/rtl8192eefw.bin"; + + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -266,7 +267,6 @@ static const struct rtl_hal_cfg rtl92ee_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl92ee_pci", +- .fw_name = "rtlwifi/rtl8192eefw.bin", + .ops = &rtl8192ee_hal_ops, + .mod_params = &rtl92ee_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +index 5e8e02d..3e1eaea 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -89,12 +89,13 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_firmware *pfirmware = NULL; ++ char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { +- pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); ++ pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; + return; + } +@@ -117,6 +118,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int err = 0; + u16 earlyrxthreshold = 7; ++ char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + rtlpriv->dm.dm_initialgain_enable = true; + rtlpriv->dm.dm_flag = 0; +@@ -214,9 +216,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) + rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 + + sizeof(struct fw_hdr); + pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" +- "Loading firmware %s\n", rtlpriv->cfg->fw_name); ++ "Loading firmware %s\n", fw_name); + /* request fw */ +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); + if (err) { +@@ -310,7 +312,6 @@ static const struct rtl_hal_cfg rtl92se_hal_cfg = { + .bar_id = 1, + .write_readback = false, + .name = "rtl92s_pci", +- .fw_name = "rtlwifi/rtl8192sefw.bin", + .ops = &rtl8192se_hal_ops, + .mod_params = &rtl92se_mod_params, + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c +index 89c828a..c51a9e8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c +@@ -94,6 +94,7 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int err = 0; ++ char *fw_name = "rtlwifi/rtl8723fw.bin"; + + rtl8723e_bt_reg_init(hw); + +@@ -176,14 +177,12 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + +- if (IS_VENDOR_8723_A_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin"; +- else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin"; ++ if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) ++ fw_name = "rtlwifi/rtl8723fw_B.bin"; + + rtlpriv->max_fw_size = 0x6000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -280,7 +279,6 @@ static const struct rtl_hal_cfg rtl8723e_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723e_pci", +- .fw_name = "rtlwifi/rtl8723efw.bin", + .ops = &rtl8723e_hal_ops, + .mod_params = &rtl8723e_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c +index 20b53f0..847644d 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c +@@ -91,6 +91,7 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); ++ char *fw_name = "rtlwifi/rtl8723befw.bin"; + + rtl8723be_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); +@@ -184,8 +185,8 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) + } + + rtlpriv->max_fw_size = 0x8000; +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -280,7 +281,6 @@ static const struct rtl_hal_cfg rtl8723be_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8723be_pci", +- .fw_name = "rtlwifi/rtl8723befw.bin", + .ops = &rtl8723be_hal_ops, + .mod_params = &rtl8723be_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +index 22f687b1..297938e 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +@@ -93,6 +93,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ char *fw_name, *wowlan_fw_name; + + rtl8821ae_bt_reg_init(hw); + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); +@@ -203,17 +204,17 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + } + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin"; +- rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin"; ++ fw_name = "rtlwifi/rtl8812aefw.bin"; ++ wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin"; + } else { +- rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin"; +- rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin"; ++ fw_name = "rtlwifi/rtl8821aefw.bin"; ++ wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin"; + } + + rtlpriv->max_fw_size = 0x8000; + /*load normal firmware*/ +- pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +- err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, ++ pr_info("Using firmware %s\n", fw_name); ++ err = request_firmware_nowait(THIS_MODULE, 1, fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); + if (err) { +@@ -222,9 +223,9 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) + return 1; + } + /*load wowlan firmware*/ +- pr_info("Using firmware %s\n", rtlpriv->cfg->wowlan_fw_name); ++ pr_info("Using firmware %s\n", wowlan_fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, +- rtlpriv->cfg->wowlan_fw_name, ++ wowlan_fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_wowlan_fw_cb); + if (err) { +@@ -320,7 +321,6 @@ static const struct rtl_hal_cfg rtl8821ae_hal_cfg = { + .bar_id = 2, + .write_readback = true, + .name = "rtl8821ae_pci", +- .fw_name = "rtlwifi/rtl8821aefw.bin", + .ops = &rtl8821ae_hal_ops, + .mod_params = &rtl8821ae_mod_params, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 595f7d5..dafe486 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2278,9 +2278,7 @@ struct rtl_hal_cfg { + u8 bar_id; + bool write_readback; + char *name; +- char *fw_name; + char *alt_fw_name; +- char *wowlan_fw_name; + struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + struct rtl_hal_usbint_cfg *usb_interface_cfg; +-- +2.10.1 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch1-V4.patch b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch1-V4.patch new file mode 100644 index 00000000..9bcefef0 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch1-V4.patch @@ -0,0 +1,111 @@ +diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c +index e947e298a737..44009105f8c8 100644 +--- a/drivers/nvme/host/scsi.c ++++ b/drivers/nvme/host/scsi.c +@@ -72,15 +72,6 @@ static int sg_version_num = 30534; /* 2 digits for each component */ + #define ALL_LUNS_RETURNED 0x02 + #define ALL_WELL_KNOWN_LUNS_RETURNED 0x01 + #define RESTRICTED_LUNS_RETURNED 0x00 +-#define NVME_POWER_STATE_START_VALID 0x00 +-#define NVME_POWER_STATE_ACTIVE 0x01 +-#define NVME_POWER_STATE_IDLE 0x02 +-#define NVME_POWER_STATE_STANDBY 0x03 +-#define NVME_POWER_STATE_LU_CONTROL 0x07 +-#define POWER_STATE_0 0 +-#define POWER_STATE_1 1 +-#define POWER_STATE_2 2 +-#define POWER_STATE_3 3 + #define DOWNLOAD_SAVE_ACTIVATE 0x05 + #define DOWNLOAD_SAVE_DEFER_ACTIVATE 0x0E + #define ACTIVATE_DEFERRED_MICROCODE 0x0F +@@ -1229,64 +1220,6 @@ static void nvme_trans_fill_read_cap(u8 *response, struct nvme_id_ns *id_ns, + + /* Start Stop Unit Helper Functions */ + +-static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr, +- u8 pc, u8 pcmod, u8 start) +-{ +- int res; +- int nvme_sc; +- struct nvme_id_ctrl *id_ctrl; +- int lowest_pow_st; /* max npss = lowest power consumption */ +- unsigned ps_desired = 0; +- +- nvme_sc = nvme_identify_ctrl(ns->ctrl, &id_ctrl); +- res = nvme_trans_status_code(hdr, nvme_sc); +- if (res) +- return res; +- +- lowest_pow_st = max(POWER_STATE_0, (int)(id_ctrl->npss - 1)); +- kfree(id_ctrl); +- +- switch (pc) { +- case NVME_POWER_STATE_START_VALID: +- /* Action unspecified if POWER CONDITION MODIFIER != 0 */ +- if (pcmod == 0 && start == 0x1) +- ps_desired = POWER_STATE_0; +- if (pcmod == 0 && start == 0x0) +- ps_desired = lowest_pow_st; +- break; +- case NVME_POWER_STATE_ACTIVE: +- /* Action unspecified if POWER CONDITION MODIFIER != 0 */ +- if (pcmod == 0) +- ps_desired = POWER_STATE_0; +- break; +- case NVME_POWER_STATE_IDLE: +- /* Action unspecified if POWER CONDITION MODIFIER != [0,1,2] */ +- if (pcmod == 0x0) +- ps_desired = POWER_STATE_1; +- else if (pcmod == 0x1) +- ps_desired = POWER_STATE_2; +- else if (pcmod == 0x2) +- ps_desired = POWER_STATE_3; +- break; +- case NVME_POWER_STATE_STANDBY: +- /* Action unspecified if POWER CONDITION MODIFIER != [0,1] */ +- if (pcmod == 0x0) +- ps_desired = max(POWER_STATE_0, (lowest_pow_st - 2)); +- else if (pcmod == 0x1) +- ps_desired = max(POWER_STATE_0, (lowest_pow_st - 1)); +- break; +- case NVME_POWER_STATE_LU_CONTROL: +- default: +- res = nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, +- ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, +- SCSI_ASCQ_CAUSE_NOT_REPORTABLE); +- break; +- } +- nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_POWER_MGMT, ps_desired, 0, +- NULL); +- return nvme_trans_status_code(hdr, nvme_sc); +-} +- + static int nvme_trans_send_activate_fw_cmd(struct nvme_ns *ns, struct sg_io_hdr *hdr, + u8 buffer_id) + { +@@ -2235,11 +2168,10 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns, + static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, + u8 *cmd) + { +- u8 immed, pcmod, pc, no_flush, start; ++ u8 immed, pcmod, no_flush, start; + + immed = cmd[1] & 0x01; + pcmod = cmd[3] & 0x0f; +- pc = (cmd[4] & 0xf0) >> 4; + no_flush = cmd[4] & 0x04; + start = cmd[4] & 0x01; + +@@ -2254,8 +2186,8 @@ static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, + if (res) + return res; + } +- /* Setup the expected power state transition */ +- return nvme_trans_power_state(ns, hdr, pc, pcmod, start); ++ ++ return 0; + } + } + +-- +2.7.4 diff --git a/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch2-V4.patch b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch2-V4.patch new file mode 100644 index 00000000..454cb4a5 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch2-V4.patch @@ -0,0 +1,107 @@ +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 2feacc70bf61..b92a7f767bfc 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -597,7 +597,7 @@ int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid, + } + + int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, +- dma_addr_t dma_addr, u32 *result) ++ void *buffer, size_t buflen, u32 *result) + { + struct nvme_command c; + struct nvme_completion cqe; +@@ -606,10 +606,9 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, + memset(&c, 0, sizeof(c)); + c.features.opcode = nvme_admin_get_features; + c.features.nsid = cpu_to_le32(nsid); +- c.features.dptr.prp1 = cpu_to_le64(dma_addr); + c.features.fid = cpu_to_le32(fid); + +- ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, ++ ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, buffer, buflen, 0, + NVME_QID_ANY, 0, 0); + if (ret >= 0 && result) + *result = le32_to_cpu(cqe.result); +@@ -617,7 +616,7 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, + } + + int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, +- dma_addr_t dma_addr, u32 *result) ++ void *buffer, size_t buflen, u32 *result) + { + struct nvme_command c; + struct nvme_completion cqe; +@@ -625,12 +624,11 @@ int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + + memset(&c, 0, sizeof(c)); + c.features.opcode = nvme_admin_set_features; +- c.features.dptr.prp1 = cpu_to_le64(dma_addr); + c.features.fid = cpu_to_le32(fid); + c.features.dword11 = cpu_to_le32(dword11); + +- ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, NULL, 0, 0, +- NVME_QID_ANY, 0, 0); ++ ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &cqe, ++ buffer, buflen, 0, NVME_QID_ANY, 0, 0); + if (ret >= 0 && result) + *result = le32_to_cpu(cqe.result); + return ret; +@@ -664,7 +662,7 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) + u32 result; + int status, nr_io_queues; + +- status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, 0, ++ status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, + &result); + if (status < 0) + return status; +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index ab18b78102bf..c2151761ec5f 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -292,9 +292,9 @@ int nvme_identify_ns(struct nvme_ctrl *dev, unsigned nsid, + struct nvme_id_ns **id); + int nvme_get_log_page(struct nvme_ctrl *dev, struct nvme_smart_log **log); + int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned nsid, +- dma_addr_t dma_addr, u32 *result); ++ void *buffer, size_t buflen, u32 *result); + int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, +- dma_addr_t dma_addr, u32 *result); ++ void *buffer, size_t buflen, u32 *result); + int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); + void nvme_start_keep_alive(struct nvme_ctrl *ctrl); + void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); +diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c +index 44009105f8c8..c2a0a1c7d05d 100644 +--- a/drivers/nvme/host/scsi.c ++++ b/drivers/nvme/host/scsi.c +@@ -906,7 +906,7 @@ static int nvme_trans_log_temperature(struct nvme_ns *ns, struct sg_io_hdr *hdr, + kfree(smart_log); + + /* Get Features for Temp Threshold */ +- res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, 0, ++ res = nvme_get_features(ns->ctrl, NVME_FEAT_TEMP_THRESH, 0, NULL, 0, + &feature_resp); + if (res != NVME_SC_SUCCESS) + temp_c_thresh = LOG_TEMP_UNKNOWN; +@@ -1039,7 +1039,7 @@ static int nvme_trans_fill_caching_page(struct nvme_ns *ns, + if (len < MODE_PAGE_CACHING_LEN) + return -EINVAL; + +- nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, 0, ++ nvme_sc = nvme_get_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, 0, NULL, 0, + &feature_resp); + res = nvme_trans_status_code(hdr, nvme_sc); + if (res) +@@ -1328,7 +1328,7 @@ static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr, + case MODE_PAGE_CACHING: + dword11 = ((mode_page[2] & CACHING_MODE_PAGE_WCE_MASK) ? 1 : 0); + nvme_sc = nvme_set_features(ns->ctrl, NVME_FEAT_VOLATILE_WC, +- dword11, 0, NULL); ++ dword11, NULL, 0, NULL); + res = nvme_trans_status_code(hdr, nvme_sc); + break; + case MODE_PAGE_CONTROL: +-- +2.7.4 diff --git a/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch3-V4.patch b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch3-V4.patch new file mode 100644 index 00000000..797c4681 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/nvmepatch3-V4.patch @@ -0,0 +1,264 @@ +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index b92a7f767bfc..a143c72c3d0d 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -56,6 +56,11 @@ EXPORT_SYMBOL_GPL(nvme_max_retries); + static int nvme_char_major; + module_param(nvme_char_major, int, 0); + ++static unsigned long default_ps_max_latency_us = 25000; ++module_param(default_ps_max_latency_us, ulong, 0644); ++MODULE_PARM_DESC(ps_max_latency_us, ++ "default max power saving latency; overridden per device in sysfs"); ++ + static LIST_HEAD(nvme_ctrl_list); + static DEFINE_SPINLOCK(dev_list_lock); + +@@ -1205,6 +1210,98 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, + blk_queue_write_cache(q, vwc, vwc); + } + ++static void nvme_configure_apst(struct nvme_ctrl *ctrl) ++{ ++ /* ++ * APST (Autonomous Power State Transition) lets us program a ++ * table of power state transitions that the controller will ++ * perform automatically. We configure it with a simple ++ * heuristic: we are willing to spend at most 2% of the time ++ * transitioning between power states. Therefore, when running ++ * in any given state, we will enter the next lower-power ++ * non-operational state after waiting 100 * (enlat + exlat) ++ * microseconds, as long as that state's total latency is under ++ * the requested maximum latency. ++ * ++ * We will not autonomously enter any non-operational state for ++ * which the total latency exceeds ps_max_latency_us. Users ++ * can set ps_max_latency_us to zero to turn off APST. ++ */ ++ ++ unsigned apste; ++ struct nvme_feat_auto_pst *table; ++ int ret; ++ ++ if (!ctrl->apsta) ++ return; /* APST isn't supported. */ ++ ++ if (ctrl->npss > 31) { ++ dev_warn(ctrl->device, "NPSS is invalid; not using APST\n"); ++ return; ++ } ++ ++ table = kzalloc(sizeof(*table), GFP_KERNEL); ++ if (!table) ++ return; ++ ++ if (ctrl->ps_max_latency_us == 0) { ++ /* Turn off APST. */ ++ apste = 0; ++ } else { ++ __le64 target = cpu_to_le64(0); ++ int state; ++ ++ /* ++ * Walk through all states from lowest- to highest-power. ++ * According to the spec, lower-numbered states use more ++ * power. NPSS, despite the name, is the index of the ++ * lowest-power state, not the number of states. ++ */ ++ for (state = (int)ctrl->npss; state >= 0; state--) { ++ u64 total_latency_us, transition_ms; ++ ++ if (target) ++ table->entries[state] = target; ++ ++ /* ++ * Is this state a useful non-operational state for ++ * higher-power states to autonomously transition to? ++ */ ++ if (!(ctrl->psd[state].flags & 2)) ++ continue; /* It's an operational state. */ ++ ++ total_latency_us = ++ (u64)cpu_to_le32(ctrl->psd[state].entry_lat) + ++ + cpu_to_le32(ctrl->psd[state].exit_lat); ++ if (total_latency_us > ctrl->ps_max_latency_us) ++ continue; ++ ++ /* ++ * This state is good. Use it as the APST idle ++ * target for higher power states. ++ */ ++ transition_ms = total_latency_us + 19; ++ do_div(transition_ms, 20); ++ if (transition_ms >= (1 << 24)) ++ transition_ms = (1 << 24); ++ ++ target = cpu_to_le64((state << 3) | ++ (transition_ms << 8)); ++ } ++ ++ apste = 1; ++ } ++ ++ ret = nvme_set_features(ctrl, NVME_FEAT_AUTO_PST, apste, ++ table, sizeof(*table), NULL); ++ if (ret) ++ dev_err(ctrl->device, "failed to set APST feature (%d)\n", ret); ++ ++ kfree(table); ++} ++ ++static struct attribute_group nvme_dev_dynamic_attrs_group; ++ + /* + * Initialize the cached copies of the Identify data and various controller + * register in our nvme_ctrl structure. This should be called as soon as +@@ -1271,6 +1368,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) + ctrl->sgls = le32_to_cpu(id->sgls); + ctrl->kas = le16_to_cpu(id->kas); + ++ ctrl->npss = id->npss; ++ ctrl->apsta = id->apsta; ++ memcpy(ctrl->psd, id->psd, sizeof(ctrl->psd)); ++ + if (ctrl->ops->is_fabrics) { + ctrl->icdoff = le16_to_cpu(id->icdoff); + ctrl->ioccsz = le32_to_cpu(id->ioccsz); +@@ -1294,6 +1395,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) + } + + kfree(id); ++ ++ nvme_configure_apst(ctrl); ++ ++ sysfs_update_group(&ctrl->device->kobj, &nvme_dev_dynamic_attrs_group); + return ret; + } + EXPORT_SYMBOL_GPL(nvme_init_identify); +@@ -1564,6 +1669,41 @@ static ssize_t nvme_sysfs_show_address(struct device *dev, + } + static DEVICE_ATTR(address, S_IRUGO, nvme_sysfs_show_address, NULL); + ++static ssize_t nvme_sysfs_show_ps_max_latency_us( ++ struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ ++ return snprintf(buf, PAGE_SIZE, "%llu\n", ctrl->ps_max_latency_us); ++} ++ ++static ssize_t nvme_sysfs_store_ps_max_latency_us( ++ struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ int ret; ++ u64 val; ++ ++ ret = kstrtoull(buf, 10, &val); ++ if (ret) ++ return ret; ++ ++ if (ctrl->ps_max_latency_us != val) { ++ ctrl->ps_max_latency_us = val; ++ nvme_configure_apst(ctrl); ++ } ++ ++ return size; ++} ++ ++static DEVICE_ATTR(ps_max_latency_us, 0644, ++ nvme_sysfs_show_ps_max_latency_us, ++ nvme_sysfs_store_ps_max_latency_us); ++ + static struct attribute *nvme_dev_attrs[] = { + &dev_attr_reset_controller.attr, + &dev_attr_rescan_controller.attr, +@@ -1605,8 +1745,33 @@ static struct attribute_group nvme_dev_attrs_group = { + .is_visible = nvme_dev_attrs_are_visible, + }; + ++static struct attribute *nvme_dev_dynamic_attrs[] = { ++ &dev_attr_ps_max_latency_us.attr, ++ NULL ++}; ++ ++static umode_t nvme_dev_dynamic_attrs_are_visible(struct kobject *kobj, ++ struct attribute *a, int n) ++{ ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct nvme_ctrl *ctrl = dev_get_drvdata(dev); ++ ++ if (a == &dev_attr_ps_max_latency_us.attr) { ++ if (!ctrl->apsta) ++ return 0; ++ } ++ ++ return a->mode; ++} ++ ++static struct attribute_group nvme_dev_dynamic_attrs_group = { ++ .attrs = nvme_dev_dynamic_attrs, ++ .is_visible = nvme_dev_dynamic_attrs_are_visible, ++}; ++ + static const struct attribute_group *nvme_dev_attr_groups[] = { + &nvme_dev_attrs_group, ++ &nvme_dev_dynamic_attrs_group, + NULL, + }; + +@@ -1991,6 +2156,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, + ctrl->quirks = quirks; + INIT_WORK(&ctrl->scan_work, nvme_scan_work); + INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); ++ ctrl->ps_max_latency_us = default_ps_max_latency_us; + + ret = nvme_set_instance(ctrl); + if (ret) +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index c2151761ec5f..16d51006afc0 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -129,13 +129,19 @@ struct nvme_ctrl { + u32 vs; + u32 sgls; + u16 kas; ++ u8 npss; ++ u8 apsta; + unsigned int kato; + bool subsystem; + unsigned long quirks; ++ struct nvme_id_power_state psd[32]; + struct work_struct scan_work; + struct work_struct async_event_work; + struct delayed_work ka_work; + ++ /* Power saving configuration */ ++ u64 ps_max_latency_us; ++ + /* Fabrics only */ + u16 sqsize; + u32 ioccsz; +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index d8b37bab2887..a76237dac4b0 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -543,6 +543,12 @@ struct nvme_dsm_range { + __le64 slba; + }; + ++/* Features */ ++ ++struct nvme_feat_auto_pst { ++ __le64 entries[32]; ++}; ++ + /* Admin commands */ + + enum nvme_admin_opcode { +-- +2.7.4 diff --git a/kernel/tools/cpupowertools/files/patches/mageia/series b/kernel/tools/cpupowertools/files/patches/mageia/series index 6452397c..e7a005b7 100644 --- a/kernel/tools/cpupowertools/files/patches/mageia/series +++ b/kernel/tools/cpupowertools/files/patches/mageia/series @@ -41,11 +41,19 @@ Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch # breaks nvidia304 Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch +# fix non-booting systems +x86-smpboot-Init-apic-mapping-before-usage.patch + ### ### Core ### base-cacheinfo-silence-DT-warnings.patch +# Patch for having the cpupower setting the governor +# (from https://bugzilla.kernel.org/show_bug.cgi?id=135391, same as +# https://bugzilla.redhat.com/show_bug.cgi?id=1374212) +kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch + ### ### i2c ### @@ -119,8 +127,20 @@ ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch # Nice SSD speedup block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch -# ahci ids -ahci-add-new-Intel-device-IDs.patch +# Include new BFQ I/O scheduler +# (See http://algo.ing.unimo.it/people/paolo/disk_sched) +# +# Release of BFQ I/O scheduler v8r4 (rediffed from git https://github.com/linusw/linux-bfq) +linux-BFQ-v8r4.patch + +# Let NVME drives enter in power state +# (see https://github.com/damige/linux-nvme/tree/master/src) +nvmepatch1-V4.patch +nvmepatch2-V4.patch +nvmepatch3-V4.patch + +# fix feature check, reported on dev@ ml +dm-raid-fix-compat_features-validation.patch ### ### Char @@ -134,9 +154,8 @@ Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch ### # aufs from: http://aufs.sourceforge.net/ (mga#8314) -fs-aufs-4.7.patch -fs-aufs-4.7-modular.patch -fs-aufs-4.7-ver-fix.patch +fs-aufs-4.8.patch +fs-aufs-4.8-modular.patch ### ### FireWire @@ -171,6 +190,14 @@ gpu-drm-mach64-linux-3.14-buildfix.patch gpu-drm-mach64-3.17-buildfix.patch gpu-drm-mach64-3.18-buildfix.patch +# Attempt to fix FIFO underrun problems: +# (from https://patchwork.freedesktop.org/patch/113642/ and +# also from https://bugs.freedesktop.org/attachment.cgi?id=127264, first reference from +# https://bugs.freedesktop.org/show_bug.cgi?id=97450). Does not completely resolve the +# issues but reduce. +# now in drm-next: https://cgit.freedesktop.org/~airlied/linux/commit?h=drm-next&id=5a920b85f2c6e3fd7d9dd9bb3f3345e9085e2360 +gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch + ### ### Hardware Monitoring ### @@ -222,6 +249,12 @@ net-netfilter-psd.patch net-netfilter-psd-mdv.patch net-netfilter-psd-2.6.35-buildfix.patch +# rtlwifi regression +net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch + +# CVE-2016-7039 +net-add-recursion-limit-to-GRO.patch + ### ### Platform drivers ### @@ -232,10 +265,6 @@ platform-x86-add-shuttle-wmi-driver.patch platform-x86-shuttle-wmi-drop-devinit-exit.patch platform-x86-shuttle-wmi-4.2-buildfix.patch -# -intel_th-Fix-a-deadlock-in-modprobing.patch -intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch - ### ### RTC ### @@ -331,6 +360,7 @@ video-mageia-logo.patch # add rtl8723bs support (mga#15874) 3rd-rtl8723bs.patch 3rd-rtl8723bs-4.7-buildfix.patch +3rd-rtl8723bs-4.8-buildfix.patch ### ### Security @@ -348,10 +378,6 @@ video-mageia-logo.patch ### ARM ### -# RPi2 support -# Read MAC address from DT -arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch - ### ### IA64 ### @@ -360,6 +386,11 @@ arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch ### Tools ### +# wipe powerpc refrence so we can nuke dangling symlinks (mga#17676) +tools-testing-selftest-Makefile-remove-powerpc-reference.patch + ### ### UAPI ### +# breaks linux-arm build +Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch diff --git a/kernel/tools/cpupowertools/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch b/kernel/tools/cpupowertools/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch new file mode 100644 index 00000000..677e97df --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch @@ -0,0 +1,10 @@ +--- linux/tools/testing/selftests/Makefile.orig ++++ linux/tools/testing/selftests/Makefile +@@ -15,7 +15,6 @@ TARGETS += memory-hotplug + TARGETS += mount + TARGETS += mqueue + TARGETS += net +-TARGETS += powerpc + TARGETS += pstore + TARGETS += ptrace + TARGETS += seccomp diff --git a/kernel/tools/cpupowertools/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch b/kernel/tools/cpupowertools/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch new file mode 100644 index 00000000..6c2e766a --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch @@ -0,0 +1,61 @@ +From 1e90a13d0c3dc94512af1ccb2b6563e8297838fa Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Sat, 29 Oct 2016 13:42:42 +0200 +Subject: [PATCH] x86/smpboot: Init apic mapping before usage + +The recent changes, which forced the registration of the boot cpu on UP +systems, which do not have ACPI tables, have been fixed for systems w/o +local APIC, but left a wreckage for systems which have neither ACPI nor +mptables, but the CPU has an APIC, e.g. virtualbox. + +The boot process crashes in prefill_possible_map() as it wants to register +the boot cpu, which needs to access the local apic, but the local APIC is +not yet mapped. + +There is no reason why init_apic_mapping() can't be invoked before +prefill_possible_map(). So instead of playing another silly early mapping +game, as the ACPI/mptables code does, we just move init_apic_mapping() +before the call to prefill_possible_map(). + +In hindsight, I should have noticed that combination earlier. + +Sorry for the churn (also in stable)! + +Fixes: ff8560512b8d ("x86/boot/smp: Don't try to poke disabled/non-existent APIC") +Reported-and-debugged-by: Michal Necasek +Reported-and-tested-by: Wolfgang Bauer +Cc: prarit@redhat.com +Cc: ville.syrjala@linux.intel.com +Cc: michael.thayer@oracle.com +Cc: knut.osmundsen@oracle.com +Cc: frank.mehnert@oracle.com +Cc: Borislav Petkov +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1610282114380.5053@nanos +Signed-off-by: Thomas Gleixner +--- + arch/x86/kernel/setup.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index bbfbca5..9c337b0 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1222,11 +1222,16 @@ void __init setup_arch(char **cmdline_p) + if (smp_found_config) + get_smp_config(); + ++ /* ++ * Systems w/o ACPI and mptables might not have it mapped the local ++ * APIC yet, but prefill_possible_map() might need to access it. ++ */ ++ init_apic_mappings(); ++ + prefill_possible_map(); + + init_cpu_to_node(); + +- init_apic_mappings(); + io_apic_init_mappings(); + + kvm_guest_init(); diff --git a/kernel/tools/cpupowertools/pspec.xml b/kernel/tools/cpupowertools/pspec.xml index 3115b317..dc701efa 100644 --- a/kernel/tools/cpupowertools/pspec.xml +++ b/kernel/tools/cpupowertools/pspec.xml @@ -12,14 +12,14 @@ app:console CPU power management tools cpupowertools contains utilities to manage power management and frequency scaling policies of modern CPUs. - https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.7.tar.gz + https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.tar.gz pciutils-devel - - - patches/linux/patch-4.7.2.xz - + + + patches/linux/patch-4.8.6.xz + patches/mageia/Revert-ipmi-Start-the-timer-and-thread-on-internal-m.patch @@ -27,9 +27,11 @@ patches/mageia/x86-boot-video-80x25-if-break.patch patches/mageia/x86-default_poweroff_up_machines.patch patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch - patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch + patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch + patches/mageia/x86-smpboot-Init-apic-mapping-before-usage.patch patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch patches/mageia/base-cacheinfo-silence-DT-warnings.patch + patches/mageia/kernel-governor-cpupower-Correct-return-type-of-cpu_power_is_cpu_onl.patch patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch patches/mageia/pci-quirks-drop-devinit-exit.patch patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch @@ -48,9 +50,13 @@ patches/mageia/block-floppy-disable-pnp-modalias.patch patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch - patches/mageia/fs-aufs-4.7.patch - patches/mageia/fs-aufs-4.7-modular.patch - patches/mageia/fs-aufs-4.7-ver-fix.patch + patches/mageia/linux-BFQ-v8r4.patch + patches/mageia/nvmepatch1-V4.patch + patches/mageia/nvmepatch2-V4.patch + patches/mageia/nvmepatch3-V4.patch + patches/mageia/dm-raid-fix-compat_features-validation.patch + patches/mageia/fs-aufs-4.8.patch + patches/mageia/fs-aufs-4.8-modular.patch patches/mageia/firewire-ieee1394-module-aliases.patch patches/mageia/char-agp-intel-new-Q57-id.patch @@ -71,6 +77,7 @@ patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch patches/mageia/gpu-drm-mach64-3.17-buildfix.patch patches/mageia/gpu-drm-mach64-3.18-buildfix.patch + patches/mageia/gpu-drm-i915-gen9-fix-DDB-partitioning-for-multi-screen-cases.patch patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch patches/mageia/net-sis190-fix-list-usage.patch patches/mageia/net-netfilter-IFWLOG.patch @@ -83,11 +90,11 @@ patches/mageia/net-netfilter-psd.patch patches/mageia/net-netfilter-psd-mdv.patch patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch + patches/mageia/net-wireless-rtlwifi-Fix-regression-caused-by-commit-d86e64768859.patch + patches/mageia/net-add-recursion-limit-to-GRO.patch patches/mageia/platform-x86-add-shuttle-wmi-driver.patch patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch - patches/mageia/intel_th-Fix-a-deadlock-in-modprobing.patch - patches/mageia/intel_th-pci-Add-Kaby-Lake-PCH-H-support.patch patches/mageia/include-kbuild-export-pci_ids.patch patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch patches/mageia/usb-storage-unusual_devs-add-id.patch @@ -120,9 +127,10 @@ patches/mageia/3rd-viahss-3.0-buildfix.patch patches/mageia/3rd-rtl8723bs.patch patches/mageia/3rd-rtl8723bs-4.7-buildfix.patch - patches/mageia/ahci-add-new-Intel-device-IDs.patch - patches/mageia/arm-0001-ARM-bcm2835-dt-Add-the-ethernet-to-the-device-trees.patch - + patches/mageia/3rd-rtl8723bs-4.8-buildfix.patch + patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch + patches/mageia/Revert-include-uapi-linux-atm_zatm.h-include-linux-t.patch +

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 z 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 mbP1a`OeNYJt|bSIwN_&Er9HJX%lG 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