From 5510415b5122e5e06e71e8f4a12fcd5548e6b0fc Mon Sep 17 00:00:00 2001 From: Sangbum Kim Date: Tue, 6 Dec 2016 14:23:25 +0900 Subject: [PATCH] =?UTF-8?q?macbook=20pro=EC=A4=80=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + PKGBUILD | 6 +- config.saved.x86_64 | 1633 ++++++++--- linux-spica.install | 26 +- ...nfig-build-bits-for-BFQ-v7r11-4.8.0.patch} | 10 +- ...he-BFQ-v7r11-I-O-sched-to-be-ported.patch} | 179 +- ...ly-Queue-Merge-EQM-to-BFQ-v7r11-to-.patch} | 96 +- ...n-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch} | 2376 ++++++++++++----- patches/BLD-4.7.patch | 9 - ...izations_for_gcc_v4.9+_kernel_v3.15+.patch | 10 +- patches/hid-apple-patched.patch | 115 + ...v4.7.patch => uksm-0.1.2.5-for-v4.8.patch} | 166 +- 12 files changed, 3300 insertions(+), 1327 deletions(-) rename patches/{0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch => 0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.0.patch} (96%) rename patches/{0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch => 0002-block-introduce-the-BFQ-v7r11-I-O-sched-to-be-ported.patch} (98%) rename patches/{0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch => 0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-to-.patch} (92%) rename patches/{0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch => 0004-Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch} (77%) create mode 100644 patches/hid-apple-patched.patch rename patches/{uksm-0.1.2.5-for-v4.7.patch => uksm-0.1.2.5-for-v4.8.patch} (97%) diff --git a/.gitignore b/.gitignore index 60f3fa7..4b38b18 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ # Linux trash folder which might appear on any partition or disk .Trash-* +/linux-spica/ diff --git a/PKGBUILD b/PKGBUILD index f522bb0..d5c39db 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -7,9 +7,9 @@ pkgname=$pkgbase # comment the following line to build a single package containing the kernel and the headers (( 1 )) && pkgname=("$pkgbase" "$pkgbase-headers" "$pkgbase-docs") pkgdesc="The Linux Kernel and modules from Linus' git tree" -depends=('coreutils' 'linux-firmware-git' 'mkinitcpio') +depends=('coreutils' 'linux-firmware' 'mkinitcpio') -pkgver=4.8.rc8 +pkgver=4.9.rc7 pkgrel=1 url="http://www.kernel.org/" arch=(i686 x86_64) @@ -24,7 +24,7 @@ sha256sums=('SKIP') # set _gitrev to a git revision (man gitrevisions) like a tag, a commit sha1 # hash or a branch name to build from this tree instead of master -_gitrev="v4.7.5" +_gitrev="v4.8.12" #################################################################### # KERNEL CONFIG FILES diff --git a/config.saved.x86_64 b/config.saved.x86_64 index 198fda5..b386474 100644 --- a/config.saved.x86_64 +++ b/config.saved.x86_64 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 4.7.5 Kernel Configuration +# Linux/x86 4.8.12 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -17,11 +17,9 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y @@ -37,9 +35,7 @@ CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y 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 @@ -69,7 +65,7 @@ CONFIG_HAVE_KERNEL_LZ4=y # CONFIG_KERNEL_XZ is not set # CONFIG_KERNEL_LZO is not set CONFIG_KERNEL_LZ4=y -CONFIG_DEFAULT_HOSTNAME="core.amuz.es" +CONFIG_DEFAULT_HOSTNAME="ari" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -91,6 +87,7 @@ CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y CONFIG_CLOCKSOURCE_WATCHDOG=y @@ -121,10 +118,7 @@ CONFIG_TICK_CPU_ACCOUNTING=y # CONFIG_IRQ_TIME_ACCOUNTING is not set CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_TASKSTATS is not set # # RCU Subsystem @@ -147,12 +141,9 @@ CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_CGROUPS=y -CONFIG_PAGE_COUNTER=y -CONFIG_MEMCG=y -# CONFIG_MEMCG_SWAP is not set +# CONFIG_MEMCG is not set CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set -CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_CFS_BANDWIDTH is not set @@ -164,7 +155,7 @@ CONFIG_CPUSETS=y # CONFIG_PROC_PID_CPUSET is not set CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y -# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_PERF=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CHECKPOINT_RESTORE=y CONFIG_NAMESPACES=y @@ -175,7 +166,7 @@ CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_SCHED_AUTOGROUP=y # CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set +CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y @@ -228,9 +219,11 @@ CONFIG_VM_EVENT_COUNTERS=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +CONFIG_SLAB_FREELIST_RANDOM=y CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y CONFIG_JUMP_LABEL=y @@ -265,11 +258,14 @@ CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=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=y # CONFIG_CC_STACKPROTECTOR_NONE is not set # CONFIG_CC_STACKPROTECTOR_REGULAR is not set CONFIG_CC_STACKPROTECTOR_STRONG=y +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 @@ -291,6 +287,7 @@ CONFIG_HAVE_STACK_VALIDATION=y # # GCOV-based kernel profiling # +# CONFIG_GCOV_KERNEL is not set CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_RT_MUTEXES=y @@ -366,13 +363,13 @@ CONFIG_ZONE_DMA=y CONFIG_SMP=y CONFIG_X86_FEATURE_NAMES=y CONFIG_X86_FAST_FEATURE_TESTS=y -CONFIG_X86_X2APIC=y CONFIG_X86_MPPARSE=y # CONFIG_GOLDFISH is not set # CONFIG_X86_EXTENDED_PLATFORM is not set CONFIG_X86_INTEL_LPSS=y # CONFIG_X86_AMD_PLATFORM_DEVICE is not set CONFIG_IOSF_MBI=y +# CONFIG_IOSF_MBI_DEBUG is not set CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_HYPERVISOR_GUEST is not set @@ -422,8 +419,8 @@ CONFIG_IOMMU_HELPER=y CONFIG_NR_CPUS=16 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y @@ -470,7 +467,6 @@ CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_ARCH_DISCARD_MEMBLOCK=y -CONFIG_MEMORY_ISOLATION=y # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set # CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 @@ -487,11 +483,11 @@ CONFIG_UKSM=y # CONFIG_KSM_LEGACY is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_MEMORY_FAILURE=y -CONFIG_HWPOISON_INJECT=y +# CONFIG_MEMORY_FAILURE is not set 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 @@ -506,10 +502,10 @@ CONFIG_PGTABLE_MAPPING=y CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y # CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_HAS_PKEYS=y -CONFIG_X86_PMEM_LEGACY_DEVICE=y -CONFIG_X86_PMEM_LEGACY=y +# CONFIG_X86_PMEM_LEGACY is not set # CONFIG_X86_CHECK_BIOS_CORRUPTION is not set CONFIG_X86_RESERVE_LOW=64 CONFIG_MTRR=y @@ -540,6 +536,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=0x0 CONFIG_HOTPLUG_CPU=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set @@ -554,10 +552,13 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # # Power management and ACPI options # +CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_SUSPEND_SKIP_SYNC is not set -# CONFIG_HIBERNATION is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_PM_AUTOSLEEP=y @@ -576,19 +577,22 @@ CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y -# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_EC_DEBUGFS=y CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_VIDEO=y 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_HOTPLUG_CPU=y CONFIG_ACPI_PROCESSOR_AGGREGATOR=y CONFIG_ACPI_THERMAL=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 @@ -597,18 +601,17 @@ CONFIG_ACPI_CONTAINER=y CONFIG_ACPI_HOTPLUG_IOAPIC=y CONFIG_ACPI_SBS=y CONFIG_ACPI_HED=y +# CONFIG_ACPI_CUSTOM_METHOD is not set CONFIG_ACPI_BGRT=y CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y CONFIG_ACPI_NFIT=y CONFIG_HAVE_ACPI_APEI=y CONFIG_HAVE_ACPI_APEI_NMI=y -CONFIG_ACPI_APEI=y -CONFIG_ACPI_APEI_GHES=y -CONFIG_ACPI_APEI_PCIEAER=y -CONFIG_ACPI_APEI_MEMORY_FAILURE=y -# CONFIG_ACPI_APEI_ERST_DEBUG is not set +# CONFIG_ACPI_APEI is not set +CONFIG_DPTF_POWER=y CONFIG_ACPI_EXTLOG=y CONFIG_PMIC_OPREGION=y +CONFIG_ACPI_CONFIGFS=y # CONFIG_SFI is not set # @@ -617,7 +620,8 @@ CONFIG_PMIC_OPREGION=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 is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set @@ -634,8 +638,8 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # # CPU frequency scaling drivers # -CONFIG_X86_INTEL_PSTATE=y -CONFIG_X86_PCC_CPUFREQ=y +# CONFIG_X86_INTEL_PSTATE is not set +# CONFIG_X86_PCC_CPUFREQ is not set CONFIG_X86_ACPI_CPUFREQ=y # CONFIG_X86_POWERNOW_K8 is not set # CONFIG_X86_SPEEDSTEP_CENTRINO is not set @@ -676,8 +680,8 @@ CONFIG_PCIE_ECRC=y CONFIG_PCIEAER_INJECT=y CONFIG_PCIEASPM=y # CONFIG_PCIEASPM_DEBUG is not set -# CONFIG_PCIEASPM_DEFAULT is not set -CONFIG_PCIEASPM_POWERSAVE=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set # CONFIG_PCIEASPM_PERFORMANCE is not set CONFIG_PCIE_PME=y # CONFIG_PCIE_DPC is not set @@ -697,14 +701,14 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set +CONFIG_HOTPLUG_PCI_SHPC=y # # PCI host controller drivers # # CONFIG_PCIE_DW_PLAT is not set # CONFIG_ISA_BUS is not set -CONFIG_ISA_DMA_API=y +# CONFIG_ISA_DMA_API is not set # CONFIG_PCCARD is not set # CONFIG_RAPIDIO is not set CONFIG_X86_SYSFB=y @@ -764,12 +768,12 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_UDP_TUNNEL=y CONFIG_NET_FOU=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_DIAG is not set @@ -781,6 +785,7 @@ CONFIG_TCP_CONG_CUBIC=y # CONFIG_TCP_CONG_HSTCP is not set # CONFIG_TCP_CONG_HYBLA is not set # CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_NV is not set # CONFIG_TCP_CONG_SCALABLE is not set CONFIG_TCP_CONG_LP=y # CONFIG_TCP_CONG_VENO is not set @@ -800,7 +805,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y -# CONFIG_IPV6_ILA is not set +CONFIG_IPV6_ILA=y CONFIG_INET6_XFRM_TUNNEL=y CONFIG_INET6_TUNNEL=y CONFIG_INET6_XFRM_MODE_TRANSPORT=y @@ -829,7 +834,6 @@ CONFIG_BRIDGE_NETFILTER=y # Core Netfilter Configuration # CONFIG_NETFILTER_INGRESS=y -CONFIG_NETFILTER_NETLINK=y # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set # CONFIG_NETFILTER_NETLINK_LOG is not set @@ -842,7 +846,6 @@ CONFIG_NETFILTER_XTABLES=y # Xtables combined modules # # CONFIG_NETFILTER_XT_MARK is not set -CONFIG_NETFILTER_XT_SET=y # # Xtables targets @@ -853,6 +856,7 @@ CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y CONFIG_NETFILTER_XT_TARGET_HL=y # CONFIG_NETFILTER_XT_TARGET_HMARK is not set # CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set CONFIG_NETFILTER_XT_TARGET_LOG=y # CONFIG_NETFILTER_XT_TARGET_MARK is not set # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set @@ -874,7 +878,7 @@ CONFIG_NETFILTER_XT_MATCH_CGROUP=y # CONFIG_NETFILTER_XT_MATCH_DCCP is not set # CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set # CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ECN is not set +CONFIG_NETFILTER_XT_MATCH_ECN=y # CONFIG_NETFILTER_XT_MATCH_ESP is not set # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set CONFIG_NETFILTER_XT_MATCH_HL=y @@ -887,7 +891,6 @@ CONFIG_NETFILTER_XT_MATCH_MAC=y # CONFIG_NETFILTER_XT_MATCH_MARK is not set CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y # CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set CONFIG_NETFILTER_XT_MATCH_OWNER=y # CONFIG_NETFILTER_XT_MATCH_POLICY is not set # CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set @@ -903,23 +906,7 @@ CONFIG_NETFILTER_XT_MATCH_STRING=y CONFIG_NETFILTER_XT_MATCH_TCPMSS=y CONFIG_NETFILTER_XT_MATCH_TIME=y # CONFIG_NETFILTER_XT_MATCH_U32 is not set -CONFIG_IP_SET=y -CONFIG_IP_SET_MAX=256 -CONFIG_IP_SET_BITMAP_IP=y -CONFIG_IP_SET_BITMAP_IPMAC=y -CONFIG_IP_SET_BITMAP_PORT=y -CONFIG_IP_SET_HASH_IP=y -CONFIG_IP_SET_HASH_IPMARK=y -CONFIG_IP_SET_HASH_IPPORT=y -CONFIG_IP_SET_HASH_IPPORTIP=y -CONFIG_IP_SET_HASH_IPPORTNET=y -CONFIG_IP_SET_HASH_MAC=y -CONFIG_IP_SET_HASH_NETPORTNET=y -CONFIG_IP_SET_HASH_NET=y -CONFIG_IP_SET_HASH_NETNET=y -CONFIG_IP_SET_HASH_NETPORT=y -CONFIG_IP_SET_HASH_NETIFACE=y -CONFIG_IP_SET_LIST_SET=y +# CONFIG_IP_SET is not set # CONFIG_IP_VS is not set # @@ -931,14 +918,14 @@ CONFIG_NF_LOG_ARP=y CONFIG_NF_LOG_IPV4=y CONFIG_NF_REJECT_IPV4=y CONFIG_IP_NF_IPTABLES=y -# CONFIG_IP_NF_MATCH_AH is not set -# CONFIG_IP_NF_MATCH_ECN is not set +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y CONFIG_IP_NF_MATCH_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y CONFIG_IP_NF_MANGLE=y -# CONFIG_IP_NF_TARGET_ECN is not set +CONFIG_IP_NF_TARGET_ECN=y CONFIG_IP_NF_TARGET_TTL=y # CONFIG_IP_NF_RAW is not set # CONFIG_IP_NF_ARPTABLES is not set @@ -977,7 +964,11 @@ CONFIG_SCTP_COOKIE_HMAC_MD5=y # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set -# CONFIG_L2TP is not set +CONFIG_L2TP=y +# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y CONFIG_STP=y CONFIG_GARP=y CONFIG_MRP=y @@ -1046,6 +1037,7 @@ CONFIG_NET_CLS_FLOW=y CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_BPF=y CONFIG_NET_CLS_FLOWER=y +# CONFIG_NET_CLS_MATCHALL is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=y @@ -1053,7 +1045,6 @@ CONFIG_NET_EMATCH_NBYTE=y CONFIG_NET_EMATCH_U32=y CONFIG_NET_EMATCH_META=y CONFIG_NET_EMATCH_TEXT=y -CONFIG_NET_EMATCH_IPSET=y CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=y CONFIG_NET_ACT_GACT=y @@ -1080,6 +1071,7 @@ CONFIG_NETLINK_DIAG=y # CONFIG_HSR is not set CONFIG_NET_SWITCHDEV=y # CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_NCSI is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y @@ -1094,23 +1086,77 @@ CONFIG_NET_FLOW_LIMIT=y # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set -# CONFIG_BT is not set +CONFIG_BT=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +CONFIG_BT_LEDS=y +# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTUSB_BCM=y +# CONFIG_BT_HCIBTUSB_RTL is not set +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIUART_3WIRE is not set +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIVHCI=y +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set # CONFIG_AF_RXRPC is not set CONFIG_AF_KCM=y CONFIG_FIB_RULES=y -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +# CONFIG_CFG80211_WEXT is not set +# CONFIG_LIB80211 is not set +# CONFIG_MAC80211 is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set CONFIG_LWTUNNEL=y CONFIG_DST_CACHE=y -CONFIG_NET_DEVLINK=y +# CONFIG_NET_DEVLINK is not set CONFIG_MAY_USE_DEVLINK=y CONFIG_HAVE_EBPF_JIT=y @@ -1138,6 +1184,7 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y CONFIG_DMA_SHARED_BUFFER=y # CONFIG_FENCE_TRACE is not set @@ -1159,7 +1206,6 @@ CONFIG_PNP=y CONFIG_PNPACPI=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_NULL_BLK is not set -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set # CONFIG_ZRAM is not set # CONFIG_BLK_CPQ_CISS_DA is not set @@ -1180,6 +1226,7 @@ CONFIG_BLK_DEV_NBD=y # CONFIG_BLK_DEV_RBD is not set # CONFIG_BLK_DEV_RSXX is not set # CONFIG_BLK_DEV_NVME is not set +# CONFIG_NVME_TARGET is not set # # Misc devices @@ -1198,13 +1245,15 @@ CONFIG_BLK_DEV_NBD=y # CONFIG_ISL29003 is not set # CONFIG_ISL29020 is not set # CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set # CONFIG_SENSORS_BH1770 is not set # CONFIG_SENSORS_APDS990X is not set # CONFIG_HMC6352 is not set # CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set # CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set # CONFIG_SRAM is not set # CONFIG_C2PORT is not set @@ -1212,9 +1261,11 @@ CONFIG_BLK_DEV_NBD=y # EEPROM support # # CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set # CONFIG_CB710_CORE is not set # @@ -1269,8 +1320,7 @@ CONFIG_INTEL_MEI_TXE=y # CONFIG_GENWQE is not set # 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 @@ -1385,17 +1435,16 @@ CONFIG_NET_CORE=y # CONFIG_NET_FC is not set # CONFIG_IFB is not set # CONFIG_NET_TEAM is not set -CONFIG_MACVLAN=y -CONFIG_MACVTAP=y -CONFIG_IPVLAN=y +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set # CONFIG_VXLAN is not set # CONFIG_GENEVE is not set # CONFIG_GTP is not set -CONFIG_MACSEC=y +# CONFIG_MACSEC is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_TUN is not set +CONFIG_TUN=y # CONFIG_TUN_VNET_CROSS_LE is not set # CONFIG_VETH is not set # CONFIG_NLMON is not set @@ -1419,7 +1468,14 @@ CONFIG_ETHERNET=y # CONFIG_NET_VENDOR_ATHEROS is not set # CONFIG_NET_VENDOR_AURORA is not set # CONFIG_NET_CADENCE is not set -# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_TIGON3=y +# CONFIG_BNX2X is not set +# CONFIG_BNXT is not set # CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_CAVIUM is not set # CONFIG_NET_VENDOR_CHELSIO is not set @@ -1432,25 +1488,12 @@ CONFIG_ETHERNET=y # CONFIG_NET_VENDOR_EZCHIP is not set # CONFIG_NET_VENDOR_EXAR is not set # CONFIG_NET_VENDOR_HP is not set -CONFIG_NET_VENDOR_INTEL=y -# CONFIG_E100 is not set -# CONFIG_E1000 is not set -CONFIG_E1000E=y -CONFIG_E1000E_HWTS=y -CONFIG_IGB=y -CONFIG_IGB_HWMON=y -# CONFIG_IGBVF is not set -# CONFIG_IXGB is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGBEVF is not set -# CONFIG_I40E is not set -# CONFIG_I40EVF is not set -# CONFIG_FM10K is not set -# CONFIG_NET_VENDOR_I825XX is not set +# CONFIG_NET_VENDOR_INTEL is not set # CONFIG_JME is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MELLANOX is not set # CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set # CONFIG_NET_VENDOR_MYRI is not set # CONFIG_FEALNX is not set # CONFIG_NET_VENDOR_NATSEMI is not set @@ -1461,10 +1504,7 @@ CONFIG_IGB_HWMON=y # CONFIG_NET_PACKET_ENGINE is not set # CONFIG_NET_VENDOR_QLOGIC is not set # CONFIG_NET_VENDOR_QUALCOMM is not set -CONFIG_NET_VENDOR_REALTEK=y -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -CONFIG_R8169=y +# CONFIG_NET_VENDOR_REALTEK is not set # CONFIG_NET_VENDOR_RENESAS is not set # CONFIG_NET_VENDOR_RDC is not set # CONFIG_NET_VENDOR_ROCKER is not set @@ -1484,11 +1524,122 @@ CONFIG_R8169=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_NET_SB1000 is not set -# CONFIG_PHYLIB is not set -# CONFIG_PPP is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_THUNDER is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y # CONFIG_SLIP is not set -# CONFIG_USB_NET_DRIVERS is not set -# CONFIG_WLAN is not set +CONFIG_SLHC=y +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=y +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_AX88179_178A is not set +CONFIG_USB_NET_CDCETHER=y +CONFIG_USB_NET_CDC_EEM=y +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +CONFIG_USB_NET_CDC_SUBSET_ENABLE=y +CONFIG_USB_NET_CDC_SUBSET=y +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +CONFIG_USB_NET_KALMIA=y +CONFIG_USB_NET_QMI_WWAN=y +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +CONFIG_USB_IPHETH=y +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_BRCMUTIL=y +CONFIG_BRCMFMAC=y +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_WLAN_VENDOR_INTERSIL is not set +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +# CONFIG_WLAN_VENDOR_RALINK is not set +# CONFIG_WLAN_VENDOR_REALTEK is not set +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -1503,8 +1654,9 @@ CONFIG_R8169=y # Input device support # CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set +CONFIG_INPUT_POLLDEV=y # CONFIG_INPUT_SPARSEKMAP is not set # CONFIG_INPUT_MATRIXKMAP is not set @@ -1512,7 +1664,7 @@ CONFIG_INPUT=y # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set @@ -1522,44 +1674,12 @@ CONFIG_INPUT_EVDEV=y # # Input Device Drivers # -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_KEYBOARD is not set CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_PS2_ALPS is not set -# CONFIG_MOUSE_PS2_BYD is not set -# CONFIG_MOUSE_PS2_LOGIPS2PP is not set -# CONFIG_MOUSE_PS2_SYNAPTICS is not set -# CONFIG_MOUSE_PS2_CYPRESS is not set -# CONFIG_MOUSE_PS2_LIFEBOOK is not set -# CONFIG_MOUSE_PS2_TRACKPOINT is not set -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_PS2_FOCALTECH is not set +# CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_BCM5974=y # CONFIG_MOUSE_CYAPA is not set # CONFIG_MOUSE_ELAN_I2C is not set # CONFIG_MOUSE_VSXXXAA is not set @@ -1576,6 +1696,7 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=y # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_APANEL is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set # CONFIG_INPUT_GPIO_TILT_POLLED is not set @@ -1590,8 +1711,8 @@ CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set @@ -1600,18 +1721,8 @@ CONFIG_INPUT_UINPUT=y # # Hardware I/O ports # -CONFIG_SERIO=y +# CONFIG_SERIO is not set CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=y -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set # @@ -1636,45 +1747,25 @@ CONFIG_UNIX98_PTYS=y # # Serial drivers # -CONFIG_SERIAL_EARLYCON=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_PNP=y -# CONFIG_SERIAL_8250_FINTEK is not set -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_FSL is not set -# CONFIG_SERIAL_8250_DW is not set -# CONFIG_SERIAL_8250_RT288X is not set -# CONFIG_SERIAL_8250_MID is not set -# CONFIG_SERIAL_8250_MOXA is not set +# CONFIG_SERIAL_8250 is not set # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set # CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_SC16IS7XX is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set # CONFIG_SERIAL_ARC is not set # CONFIG_SERIAL_RP2 is not set # CONFIG_SERIAL_FSL_LPUART is not set # CONFIG_TTY_PRINTK is not set -CONFIG_IPMI_HANDLER=y -CONFIG_IPMI_PANIC_EVENT=y -CONFIG_IPMI_PANIC_STRING=y -CONFIG_IPMI_DEVICE_INTERFACE=y -# CONFIG_IPMI_SI is not set -CONFIG_IPMI_SSIF=y -CONFIG_IPMI_WATCHDOG=y -CONFIG_IPMI_POWEROFF=y +# CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y # CONFIG_R3964 is not set @@ -1686,7 +1777,20 @@ CONFIG_HPET=y CONFIG_HPET_MMAP=y CONFIG_HPET_MMAP_DEFAULT=y # CONFIG_HANGCHECK_TIMER is not set -# CONFIG_TCG_TPM is not set +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_CORE=y +CONFIG_TCG_TIS=y +# CONFIG_TCG_TIS_SPI is not set +# CONFIG_TCG_TIS_I2C_ATMEL is not set +# CONFIG_TCG_TIS_I2C_INFINEON is not set +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_INFINEON is not set +# CONFIG_TCG_CRB is not set +# CONFIG_TCG_VTPM_PROXY is not set +# CONFIG_TCG_TIS_ST33ZP24_I2C is not set +# CONFIG_TCG_TIS_ST33ZP24_SPI is not set # CONFIG_TELCLOCK is not set CONFIG_DEVPORT=y # CONFIG_XILLYBUS is not set @@ -1697,10 +1801,20 @@ CONFIG_DEVPORT=y CONFIG_I2C=y CONFIG_ACPI_I2C_OPREGION=y CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y +# CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_MUX is not set +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=y CONFIG_I2C_ALGOBIT=y # @@ -1761,7 +1875,33 @@ CONFIG_I2C_SCMI=y # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +CONFIG_SPI_PXA2XX=y +CONFIG_SPI_PXA2XX_PCI=y +# CONFIG_SPI_ROCKCHIP is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set # CONFIG_SPMI is not set # CONFIG_HSI is not set @@ -1802,23 +1942,20 @@ CONFIG_PINCTRL=y # CONFIG_PINCTRL_CHERRYVIEW is not set # CONFIG_PINCTRL_BROXTON is not set # CONFIG_PINCTRL_SUNRISEPOINT is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_DEVRES=y CONFIG_GPIO_ACPI=y -CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC=y # # Memory mapped GPIO drivers # # CONFIG_GPIO_AMDPT is not set # CONFIG_GPIO_DWAPB is not set -CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_ICH is not set -CONFIG_GPIO_LYNXPOINT=y +# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_ICH=y +# CONFIG_GPIO_LYNXPOINT is not set # CONFIG_GPIO_VX855 is not set # CONFIG_GPIO_ZX is not set @@ -1850,14 +1987,19 @@ CONFIG_GPIO_LYNXPOINT=y # # CONFIG_GPIO_AMD8111 is not set # CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_INTEL_MID is not set # CONFIG_GPIO_ML_IOH is not set # CONFIG_GPIO_RDC321X is not set +# +# SPI GPIO expanders +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set + # # SPI or I2C GPIO expanders # -# CONFIG_GPIO_MCP23S08 is not set # # USB GPIO expanders @@ -1866,6 +2008,7 @@ CONFIG_GPIO_LYNXPOINT=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set # CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set # CONFIG_TEST_POWER is not set # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set @@ -1897,6 +2040,7 @@ CONFIG_HWMON=y # # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7314 is not set # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set @@ -1905,6 +2049,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set # CONFIG_SENSORS_ADT7410 is not set # CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set @@ -1913,7 +2058,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_K8TEMP is not set # CONFIG_SENSORS_K10TEMP is not set -# CONFIG_SENSORS_APPLESMC is not set +CONFIG_SENSORS_APPLESMC=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set @@ -1924,14 +2069,14 @@ CONFIG_HWMON=y # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_FTSTEUTATES is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_G762 is not set # CONFIG_SENSORS_GPIO_FAN is not set # CONFIG_SENSORS_HIH6130 is not set -# CONFIG_SENSORS_IBMAEM is not set -# CONFIG_SENSORS_IBMPEX is not set +# CONFIG_SENSORS_IIO_HWMON is not set # CONFIG_SENSORS_I5500 is not set CONFIG_SENSORS_CORETEMP=y # CONFIG_SENSORS_IT87 is not set @@ -1946,17 +2091,21 @@ CONFIG_SENSORS_JC42=y # CONFIG_SENSORS_LTC4245 is not set # CONFIG_SENSORS_LTC4260 is not set # CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX16065 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX1668 is not set # CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set # CONFIG_SENSORS_MAX6639 is not set # CONFIG_SENSORS_MAX6642 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_MAX6697 is not set # CONFIG_SENSORS_MAX31790 is not set # CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set @@ -1982,6 +2131,7 @@ CONFIG_SENSORS_JC42=y # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set # CONFIG_SENSORS_SHTC1 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_DME1737 is not set @@ -1998,9 +2148,11 @@ CONFIG_SENSORS_JC42=y # CONFIG_SENSORS_ADC128D818 is not set # CONFIG_SENSORS_ADS1015 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set # CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set @@ -2041,15 +2193,14 @@ CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y # CONFIG_THERMAL_EMULATION is not set CONFIG_INTEL_POWERCLAMP=y CONFIG_X86_PKG_TEMP_THERMAL=y -CONFIG_INTEL_SOC_DTS_IOSF_CORE=y # CONFIG_INTEL_SOC_DTS_THERMAL is not set # # ACPI INT340X thermal drivers # -CONFIG_INT340X_THERMAL=y -CONFIG_ACPI_THERMAL_REL=y +# CONFIG_INT340X_THERMAL is not set CONFIG_INTEL_PCH_THERMAL=y +# CONFIG_GENERIC_ADC_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -2133,12 +2284,14 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_AXP20X_I2C is not set # CONFIG_MFD_CROS_EC is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set # CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_I2CPLD is not set @@ -2162,6 +2315,7 @@ CONFIG_LPC_ICH=y # CONFIG_MFD_MAX8998 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set @@ -2170,7 +2324,6 @@ CONFIG_LPC_ICH=y # CONFIG_MFD_RT5033 is not set # CONFIG_MFD_RTSX_USB is not set # CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set @@ -2192,6 +2345,7 @@ CONFIG_LPC_ICH=y # CONFIG_MFD_TPS6586X is not set # CONFIG_MFD_TPS65910 is not set # CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set # CONFIG_MFD_TPS80031 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_TWL6040_CORE is not set @@ -2200,31 +2354,223 @@ CONFIG_LPC_ICH=y # CONFIG_MFD_TMIO is not set # CONFIG_MFD_VX855 is not set # CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_WM8994 is not set # CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_RC_SUPPORT is not set +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_VMALLOC=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_VIDEO_USBTV is not set + +# +# Webcam, TV (analog/digital) USB devices +# +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_MEDIA_PCI_SUPPORT is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_CAFE_CCIC is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_SR030PC30 is not set + +# +# Flash devices +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Audio/Video compression chips +# +# CONFIG_VIDEO_SAA6752HS is not set + +# +# Miscellaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set + +# +# Sensors used on soc_camera driver +# + +# +# soc_camera sensor drivers +# +# CONFIG_SOC_CAMERA_IMX074 is not set +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_OV2640 is not set +# CONFIG_SOC_CAMERA_OV5642 is not set +# CONFIG_SOC_CAMERA_OV6650 is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set +# CONFIG_SOC_CAMERA_OV9740 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set + +# +# Customise DVB Frontends +# +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set # # Graphics support # # CONFIG_AGP is not set +CONFIG_INTEL_GTT=y # CONFIG_VGA_ARB is not set # CONFIG_VGA_SWITCHEROO is not set CONFIG_DRM=y +CONFIG_DRM_MIPI_DSI=y CONFIG_DRM_DP_AUX_CHARDEV=y CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -CONFIG_DRM_TTM=y # # I2C encoder or helper chips # -# CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_I2C_CH7006 is not set # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_I2C_NXP_TDA998X is not set @@ -2237,7 +2583,16 @@ CONFIG_DRM_TTM=y # ACP (Audio CoProcessor) Configuration # # CONFIG_DRM_NOUVEAU is not set -# CONFIG_DRM_I915 is not set +CONFIG_DRM_I915=y +CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT=y +CONFIG_DRM_I915_USERPTR=y +# CONFIG_DRM_I915_GVT is not set + +# +# drm/i915 Debugging +# +# CONFIG_DRM_I915_WERROR is not set +# CONFIG_DRM_I915_DEBUG is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_VIA is not set # CONFIG_DRM_SAVAGE is not set @@ -2245,11 +2600,16 @@ CONFIG_DRM_TTM=y # CONFIG_DRM_VMWGFX is not set # CONFIG_DRM_GMA500 is not set # CONFIG_DRM_UDL is not set -CONFIG_DRM_AST=y +# CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set # CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_QXL is not set # CONFIG_DRM_BOCHS is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# CONFIG_DRM_BRIDGE=y # @@ -2279,8 +2639,8 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set # # Frame buffer hardware drivers @@ -2330,7 +2690,19 @@ CONFIG_FB_EFI=y # CONFIG_FB_AUO_K190X is not set # CONFIG_FB_SIMPLE is not set # CONFIG_FB_SM712 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_APPLE=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_VGASTATE is not set CONFIG_HDMI=y @@ -2347,7 +2719,132 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_LOGO is not set -# CONFIG_SOUND is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_DMA_SGBUF=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ASIHPI is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SE6X is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# HD-Audio +# +CONFIG_SND_HDA=y +CONFIG_SND_HDA_INTEL=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=1 +CONFIG_SND_HDA_PATCH_LOADER=y +# CONFIG_SND_HDA_CODEC_REALTEK is not set +# CONFIG_SND_HDA_CODEC_ANALOG is not set +# CONFIG_SND_HDA_CODEC_SIGMATEL is not set +# CONFIG_SND_HDA_CODEC_VIA is not set +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +# CONFIG_SND_HDA_CODEC_CONEXANT is not set +# CONFIG_SND_HDA_CODEC_CA0110 is not set +# CONFIG_SND_HDA_CODEC_CA0132 is not set +# CONFIG_SND_HDA_CODEC_CMEDIA is not set +# CONFIG_SND_HDA_CODEC_SI3054 is not set +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=5 +CONFIG_SND_HDA_CORE=y +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set # # HID support @@ -2363,13 +2860,15 @@ CONFIG_HID_GENERIC=y # # CONFIG_HID_A4TECH is not set # CONFIG_HID_ACRUX is not set -# CONFIG_HID_APPLE is not set +CONFIG_HID_APPLE=y # CONFIG_HID_APPLEIR is not set # CONFIG_HID_AUREAL is not set # CONFIG_HID_BELKIN is not set # CONFIG_HID_BETOP_FF is not set # CONFIG_HID_CHERRY is not set # CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_PRODIKEYS is not set # CONFIG_HID_CMEDIA is not set # CONFIG_HID_CP2112 is not set # CONFIG_HID_CYPRESS is not set @@ -2381,6 +2880,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_GEMBIRD is not set # CONFIG_HID_GFRM is not set # CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set # CONFIG_HID_UCLOGIC is not set @@ -2388,11 +2888,12 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_GYRATION is not set # CONFIG_HID_ICADE is not set # CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_KENSINGTON=y # CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LED is not set # CONFIG_HID_LENOVO is not set # CONFIG_HID_LOGITECH is not set -# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MAGICMOUSE=y # CONFIG_HID_MICROSOFT is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_MULTITOUCH is not set @@ -2407,6 +2908,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_ROCCAT is not set # CONFIG_HID_SAITEK is not set # CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set # CONFIG_HID_SPEEDLINK is not set # CONFIG_HID_STEELSERIES is not set # CONFIG_HID_SUNPLUS is not set @@ -2415,12 +2917,15 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_SMARTJOYPLUS is not set # CONFIG_HID_TIVO is not set # CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set # CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_WACOM is not set +CONFIG_HID_WACOM=y +# CONFIG_HID_WIIMOTE is not set # CONFIG_HID_XINMO is not set # CONFIG_HID_ZEROPLUS is not set # CONFIG_HID_ZYDACRON is not set # CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set # # USB HID support @@ -2460,15 +2965,12 @@ CONFIG_USB_ULPI_BUS=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y # CONFIG_USB_XHCI_PLATFORM is not set -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -CONFIG_USB_EHCI_PCI=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set # CONFIG_USB_OHCI_HCD is not set # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -2478,9 +2980,9 @@ CONFIG_USB_EHCI_PCI=y # # USB Device Class drivers # -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set +CONFIG_USB_ACM=y +CONFIG_USB_PRINTER=y +CONFIG_USB_WDM=y # CONFIG_USB_TMC is not set # @@ -2492,26 +2994,27 @@ CONFIG_USB_EHCI_PCI=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_UAS is not set +CONFIG_USB_STORAGE_REALTEK=y +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_STORAGE_ENE_UB6250=y +CONFIG_USB_UAS=y # # USB Imaging devices # -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MDC800=y +CONFIG_USB_MICROTEK=y # CONFIG_USBIP_CORE is not set # CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_DWC3 is not set @@ -2533,25 +3036,23 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set +CONFIG_USB_LCD=y # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set +CONFIG_USB_APPLEDISPLAY=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_ISIGHTFW=y # CONFIG_USB_YUREX is not set # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_LINK_LAYER_TEST is not set -# CONFIG_UCSI is not set +CONFIG_UCSI=y # # USB Physical Layer drivers @@ -2560,33 +3061,152 @@ CONFIG_USB_STORAGE=y # CONFIG_NOP_USB_XCEIV is not set # CONFIG_USB_GPIO_VBUS is not set # CONFIG_USB_ISP1301 is not set -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +CONFIG_USB_BDC_UDC=y + +# +# Platform Support +# +CONFIG_USB_BDC_PCI=y +# CONFIG_USB_AMD5536UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_USB_GOKU is not set +# CONFIG_USB_EG20T is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_U_ETHER=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_RNDIS=y +CONFIG_USB_F_MASS_STORAGE=y +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +CONFIG_USB_G_MULTI=y +CONFIG_USB_G_MULTI_RNDIS=y +CONFIG_USB_G_MULTI_CDC=y +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set +CONFIG_USB_LED_TRIG=y # CONFIG_UWB is not set -# CONFIG_MMC is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PCI=y +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=y +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +CONFIG_MMC_USHC=y +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_MTK is not set # CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_DISK is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_CPU is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_LEDS_TRIGGER_PANIC is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y -CONFIG_EDAC=y -# CONFIG_EDAC_LEGACY_SYSFS is not set -# CONFIG_EDAC_DEBUG is not set -CONFIG_EDAC_MM_EDAC=y -# CONFIG_EDAC_GHES is not set -# CONFIG_EDAC_E752X is not set -# CONFIG_EDAC_I82975X is not set -# CONFIG_EDAC_I3000 is not set -# CONFIG_EDAC_I3200 is not set -CONFIG_EDAC_IE31200=y -# CONFIG_EDAC_X38 is not set -# CONFIG_EDAC_I5400 is not set -# CONFIG_EDAC_I7CORE is not set -# CONFIG_EDAC_I5000 is not set -# CONFIG_EDAC_I5100 is not set -# CONFIG_EDAC_I7300 is not set -CONFIG_EDAC_SBRIDGE=y +# CONFIG_EDAC 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" @@ -2634,6 +3254,21 @@ CONFIG_RTC_INTF_DEV=y # # SPI RTC drivers # +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set CONFIG_RTC_I2C_AND_SPI=y # @@ -2670,7 +3305,27 @@ CONFIG_RTC_DRV_CMOS=y # HID Sensor RTC drivers # # CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -# CONFIG_DMADEVICES is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ACPI=y +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_INTEL_IOATDMA is not set +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +CONFIG_DW_DMAC_CORE=y +# CONFIG_DW_DMAC is not set +CONFIG_DW_DMAC_PCI=y + +# +# DMA Clients +# +CONFIG_ASYNC_TX_DMA=y +# CONFIG_DMATEST is not set # # DMABUF options @@ -2678,7 +3333,6 @@ CONFIG_RTC_DRV_CMOS=y CONFIG_SYNC_FILE=y # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set -# CONFIG_VFIO is not set # CONFIG_VIRT_DRIVERS is not set # @@ -2690,55 +3344,43 @@ CONFIG_SYNC_FILE=y # # Microsoft Hyper-V guest support # -CONFIG_STAGING=y -# CONFIG_SLICOSS is not set -# CONFIG_RTS5208 is not set -# CONFIG_FB_SM750 is not set -# CONFIG_FB_XGI is not set - -# -# Speakup console speech -# -# CONFIG_SPEAKUP is not set -# CONFIG_STAGING_MEDIA is not set - -# -# Android -# -# CONFIG_DGNC is not set -# CONFIG_GS_FPGABOOT is not set -# CONFIG_CRYPTO_SKEIN is not set -# CONFIG_UNISYSSPAR is not set -# CONFIG_MOST is not set +# CONFIG_STAGING is not set CONFIG_X86_PLATFORM_DEVICES=y # CONFIG_ACERHDF is not set -# CONFIG_DELL_WMI_AIO is not set +# CONFIG_ASUS_LAPTOP is not set # CONFIG_DELL_SMO8800 is not set +# CONFIG_DELL_RBTN is not set +# CONFIG_FUJITSU_LAPTOP is not set # CONFIG_FUJITSU_TABLET is not set -# CONFIG_HP_ACCEL is not set # CONFIG_HP_WIRELESS is not set -# CONFIG_HP_WMI is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_INTEL_MENLOW is not set +# CONFIG_EEEPC_LAPTOP is not set # CONFIG_ASUS_WIRELESS is not set -CONFIG_ACPI_WMI=y +# CONFIG_ACPI_WMI is not set # CONFIG_TOPSTAR_LAPTOP is not set # CONFIG_TOSHIBA_BT_RFKILL is not set # CONFIG_TOSHIBA_HAPS is not set -# CONFIG_TOSHIBA_WMI is not set # CONFIG_ACPI_CMPC is not set # CONFIG_INTEL_HID_EVENT is not set +# CONFIG_INTEL_VBTN is not set CONFIG_INTEL_IPS=y CONFIG_INTEL_PMC_CORE=y # CONFIG_IBM_RTL is not set -# CONFIG_MXM_WMI is not set +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_INTEL_OAKTRAIL is not set # CONFIG_SAMSUNG_Q10 is not set +CONFIG_APPLE_GMUX=y CONFIG_INTEL_RST=y CONFIG_INTEL_SMARTCONNECT=y # CONFIG_PVPANIC is not set # CONFIG_INTEL_PMC_IPC is not set # CONFIG_SURFACE_PRO3_BUTTON is not set -CONFIG_INTEL_PUNIT_IPC=y +# CONFIG_INTEL_PUNIT_IPC is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y @@ -2753,7 +3395,7 @@ CONFIG_COMMON_CLK=y # CONFIG_COMMON_CLK_NXP is not set # 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 @@ -2771,20 +3413,7 @@ CONFIG_CLKBLD_I8253=y # CONFIG_SH_TIMER_TMU is not set # CONFIG_EM_TIMER_STI is not set # CONFIG_MAILBOX is not set -CONFIG_IOMMU_API=y -CONFIG_IOMMU_SUPPORT=y - -# -# Generic IOMMU Pagetable Support -# -CONFIG_IOMMU_IOVA=y -# CONFIG_AMD_IOMMU is not set -CONFIG_DMAR_TABLE=y -CONFIG_INTEL_IOMMU=y -CONFIG_INTEL_IOMMU_SVM=y -CONFIG_INTEL_IOMMU_DEFAULT_ON=y -CONFIG_INTEL_IOMMU_FLOPPY_WA=y -CONFIG_IRQ_REMAP=y +# CONFIG_IOMMU_SUPPORT is not set # # Remoteproc drivers @@ -2798,19 +3427,283 @@ CONFIG_IRQ_REMAP=y # # SOC (System On Chip) specific Drivers # + +# +# Broadcom SoC drivers +# # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set # CONFIG_EXTCON is not set # CONFIG_MEMORY is not set -# CONFIG_IIO is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +# CONFIG_IIO_BUFFER_CB is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGERED_BUFFER=y +# CONFIG_IIO_CONFIGFS is not set +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 +# CONFIG_IIO_SW_DEVICE is not set +# CONFIG_IIO_SW_TRIGGER is not set + +# +# Accelerometers +# +# CONFIG_BMA180 is not set +# CONFIG_BMA220 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MMA7455_I2C is not set +# CONFIG_MMA7455_SPI is not set +# CONFIG_MMA7660 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_MXC6255 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD799X is not set +# CONFIG_HI8435 is not set +# CONFIG_INA2XX_ADC is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_NAU7802 is not set +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC0832 is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_TI_ADS1015 is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Chemical Sensors +# +# CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_IAQCORE is not set +# CONFIG_VZ89X is not set + +# +# Hid Sensor IIO Common +# + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5592R is not set +# CONFIG_AD5593R is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5761 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7303 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set + +# +# IIO dummy driver +# + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set + +# +# Health Sensors +# + +# +# Heart Rate Monitors +# +# CONFIG_AFE4403 is not set +# CONFIG_AFE4404 is not set +# CONFIG_MAX30100 is not set + +# +# Humidity sensors +# +# CONFIG_AM2315 is not set +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_I2C is not set +# CONFIG_INV_MPU6050_SPI is not set + +# +# Light sensors +# +CONFIG_ACPI_ALS=y +# CONFIG_ADJD_S311 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_ISL29125 is not set +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +# CONFIG_MAX44000 is not set +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_STK3310 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set +# CONFIG_VEML6070 is not set + +# +# Magnetometer sensors +# +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN_I2C is not set +# CONFIG_BMC150_MAGN_SPI is not set +# CONFIG_MAG3110 is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set + +# +# Inclinometer sensors +# + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y + +# +# Digital potentiometers +# +# CONFIG_DS1803 is not set +# CONFIG_MAX5487 is not set +# CONFIG_MCP4131 is not set +# CONFIG_MCP4531 is not set +# CONFIG_TPL0102 is not set + +# +# Pressure sensors +# +# CONFIG_BMP280 is not set +# CONFIG_HP03 is not set +# CONFIG_MPL115_I2C is not set +# CONFIG_MPL115_SPI is not set +# CONFIG_MPL3115 is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set +# CONFIG_HP206C is not set + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set + +# +# Proximity sensors +# +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_SX9500 is not set + +# +# Temperature sensors +# +# CONFIG_MLX90614 is not set +# CONFIG_TMP006 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set # CONFIG_PWM is not set CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_IPACK_BUS is not set # CONFIG_RESET_CONTROLLER is not set -# CONFIG_FMC is not set +CONFIG_FMC=y +# CONFIG_FMC_FAKEDEV is not set +# CONFIG_FMC_TRIVIAL is not set +# CONFIG_FMC_WRITE_EEPROM is not set +# CONFIG_FMC_CHARDEV is not set # # PHY Subsystem @@ -2828,7 +3721,7 @@ CONFIG_INTEL_RAPL=y # Performance monitor support # CONFIG_RAS=y -# CONFIG_THUNDERBOLT is not set +CONFIG_THUNDERBOLT=y # # Android @@ -2840,7 +3733,7 @@ CONFIG_ND_BLK=y CONFIG_ND_CLAIM=y CONFIG_ND_BTT=y CONFIG_BTT=y -CONFIG_DEV_DAX=y +# CONFIG_DEV_DAX is not set # CONFIG_NVMEM is not set # CONFIG_STM is not set # CONFIG_INTEL_TH is not set @@ -2906,6 +3799,7 @@ CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_ASSERT is not set # CONFIG_NILFS2_FS is not set CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y CONFIG_F2FS_FS_XATTR=y CONFIG_F2FS_FS_POSIX_ACL=y # CONFIG_F2FS_FS_SECURITY is not set @@ -2915,6 +3809,7 @@ CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y +CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y # CONFIG_MANDATORY_FILE_LOCKING is not set CONFIG_FS_ENCRYPTION=y @@ -2925,7 +3820,8 @@ CONFIG_FANOTIFY=y # CONFIG_QUOTA is not set # CONFIG_QUOTACTL is not set CONFIG_AUTOFS4_FS=y -# CONFIG_FUSE_FS is not set +CONFIG_FUSE_FS=y +CONFIG_CUSE=y CONFIG_OVERLAY_FS=y # @@ -3001,6 +3897,9 @@ CONFIG_HFSPLUS_FS_POSIX_ACL=y # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_PSTORE=y +# CONFIG_PSTORE_ZLIB_COMPRESS is not set +# CONFIG_PSTORE_LZO_COMPRESS is not set +CONFIG_PSTORE_LZ4_COMPRESS=y # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set # CONFIG_PSTORE_RAM is not set @@ -3010,7 +3909,19 @@ CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_SMB2=y +CONFIG_CIFS_SMB311=y +CONFIG_CIFS_FSCACHE=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -3040,7 +3951,7 @@ CONFIG_NLS_CODEPAGE_949=y # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -3079,19 +3990,20 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_DYNAMIC_DEBUG is not set # # Compile-time checks and compiler options # # CONFIG_DEBUG_INFO is not set -CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=2048 CONFIG_STRIP_ASM_SYMS=y # CONFIG_READABLE_ASM is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_PAGE_OWNER is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y @@ -3109,6 +4021,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_PAGE_REF is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y @@ -3123,6 +4036,7 @@ CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_ARCH_KMEMCHECK=y # CONFIG_KMEMCHECK is not set CONFIG_HAVE_ARCH_KASAN=y +# CONFIG_KASAN is not set CONFIG_ARCH_HAS_KCOV=y # CONFIG_KCOV is not set # CONFIG_DEBUG_SHIRQ is not set @@ -3142,9 +4056,9 @@ CONFIG_WQ_WATCHDOG=y CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=15 # CONFIG_SCHED_DEBUG is not set -CONFIG_SCHED_INFO=y +# CONFIG_SCHED_INFO is not set # CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_SCHED_STACK_END_CHECK=y # CONFIG_DEBUG_TIMEKEEPING is not set CONFIG_TIMER_STATS=y @@ -3161,7 +4075,7 @@ CONFIG_TIMER_STATS=y # CONFIG_DEBUG_ATOMIC_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set -# CONFIG_STACKTRACE is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_LIST is not set @@ -3187,9 +4101,8 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=21 # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set -CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y -# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y @@ -3199,12 +4112,39 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_FENTRY=y CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y -# CONFIG_FTRACE is not set +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENT is not set +# CONFIG_PROBE_EVENTS is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_MMIOTRACE is not set +# CONFIG_HIST_TRIGGERS is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_TRACE_ENUM_MAP_FILE is not set +# CONFIG_TRACING_EVENTS_GPIO is not set # # Runtime Testing # +# CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set @@ -3251,6 +4191,7 @@ CONFIG_IO_DELAY_TYPE_NONE=3 # CONFIG_IO_DELAY_UDELAY is not set CONFIG_IO_DELAY_NONE=y CONFIG_DEFAULT_IO_DELAY_TYPE=3 +# CONFIG_DEBUG_BOOT_PARAMS is not set # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_ENTRY is not set @@ -3264,12 +4205,16 @@ CONFIG_OPTIMIZE_INLINING=y CONFIG_KEYS=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_BIG_KEYS=y +# CONFIG_TRUSTED_KEYS is not set CONFIG_ENCRYPTED_KEYS=y -# CONFIG_KEY_DH_OPERATIONS is not set +CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY_DMESG_RESTRICT=y # CONFIG_SECURITY is not set CONFIG_SECURITYFS=y -# CONFIG_INTEL_TXT is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_PAGESPAN=y CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" CONFIG_XOR_BLOCKS=y @@ -3296,7 +4241,11 @@ CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=y -# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=y @@ -3365,8 +4314,11 @@ CONFIG_CRYPTO_SHA1_SSSE3=y CONFIG_CRYPTO_SHA256_SSSE3=y CONFIG_CRYPTO_SHA512_SSSE3=y CONFIG_CRYPTO_SHA1_MB=y +CONFIG_CRYPTO_SHA256_MB=y +CONFIG_CRYPTO_SHA512_MB=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=y CONFIG_CRYPTO_TGR192=y CONFIG_CRYPTO_WP512=y CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y @@ -3398,7 +4350,7 @@ CONFIG_CRYPTO_KHAZAD=y CONFIG_CRYPTO_SALSA20=y CONFIG_CRYPTO_SALSA20_X86_64=y CONFIG_CRYPTO_CHACHA20=y -# CONFIG_CRYPTO_CHACHA20_X86_64 is not set +CONFIG_CRYPTO_CHACHA20_X86_64=y CONFIG_CRYPTO_SEED=y CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y @@ -3423,27 +4375,19 @@ CONFIG_CRYPTO_LZ4HC=y # # Random Number Generation # -# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_HASH=y CONFIG_CRYPTO_DRBG_CTR=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -# CONFIG_CRYPTO_USER_API_RNG is not set -# CONFIG_CRYPTO_USER_API_AEAD is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_PADLOCK is not set -# CONFIG_CRYPTO_DEV_CCP is not set -CONFIG_CRYPTO_DEV_QAT=y -CONFIG_CRYPTO_DEV_QAT_DH895xCC=y -# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set -# CONFIG_CRYPTO_DEV_QAT_C62X is not set -CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=y -# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set -# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=y +CONFIG_CRYPTO_USER_API_AEAD=y +# CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set # @@ -3451,7 +4395,7 @@ CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=y # CONFIG_HAVE_KVM=y # CONFIG_VIRTUALIZATION is not set -# CONFIG_BINARY_PRINTF is not set +CONFIG_BINARY_PRINTF=y # # Library routines @@ -3509,6 +4453,7 @@ CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=y CONFIG_TEXTSEARCH_BM=y CONFIG_TEXTSEARCH_FSM=y +CONFIG_INTERVAL_TREE=y CONFIG_RADIX_TREE_MULTIORDER=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y @@ -3521,9 +4466,11 @@ CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_CLZ_TAB=y CONFIG_CORDIC=y CONFIG_DDR=y # CONFIG_IRQ_POLL is not set +CONFIG_MPILIB=y CONFIG_UCS2_STRING=y CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set diff --git a/linux-spica.install b/linux-spica.install index 60e8431..56e4ca8 100644 --- a/linux-spica.install +++ b/linux-spica.install @@ -1,5 +1,5 @@ pkgname=linux-spica -kernver=4.7.5-1spica-dirty +kernver=4.8.12-1spica-dirty #bootdevice="BOOT_IMAGE=/boot/vmlinuz-$pkgname root=UUID=d670564f-2cb3-4981-9d51-6ed9c1327d47" #option="rw quiet clocksource=hpet initrd=EFI/spi-ca/initrd intel_iommu=on pci-stub.ids=1002:683f,1002:aab0 vfio_iommu_type1.allow_unsafe_interrupts=1,kvm.ignore_msrs=1" #option="rw quiet clocksource=hpet initrd=EFI/spi-ca/initrd quiet intremap=no_x2apic_optout zswap.enabled=1 zswap.max_pool_percent=25 zswap.compressor=lz4" @@ -12,19 +12,19 @@ post_install () { echo "> Generating initramfs, using mkinitcpio. Please wait..." echo ">" mkinitcpio -p $pkgname - echo "> Modifing efibootmgr..." - efibootmgr|awk 'match($0,/^Boot([0-9a-fA-F]{4})\* spi-ca_v(.+)$/,m){printf "efibootmgr -b %s -B;echo \">> remove entry : %s\";",m[1],m[2]}'|sh - echo "> Copy efistub from boot" - cp -fv "boot/vmlinuz-$pkgname" "boot/efi/EFI/spi-ca/kernel.efi" - cp -fv "boot/initramfs-$pkgname.img" "boot/efi/EFI/spi-ca/initrd" - echo "> Registering efistub " +# echo "> Modifing efibootmgr..." +# efibootmgr|awk 'match($0,/^Boot([0-9a-fA-F]{4})\* spi-ca_v(.+)$/,m){printf "efibootmgr -b %s -B;echo \">> remove entry : %s\";",m[1],m[2]}'|sh +# echo "> Copy efistub from boot" +# cp -fv "boot/vmlinuz-$pkgname" "boot/efi/EFI/spi-ca/kernel.efi" +# cp -fv "boot/initramfs-$pkgname.img" "boot/efi/EFI/spi-ca/initrd" +# echo "> Registering efistub " #echo 'efibootmgr -c -g -d /dev/sda -p 1 -L "spi-ca_v$kernver" -l "\EFI\spi-ca\kernel.efi" #-u "$bootdevice $option"' - efibootmgr -c -g -d /dev/sde -p 1 -L "spi-ca_v$kernver" -l "\EFI\spi-ca\kernel" # -u "$bootdevice $option" - echo "> Reordering Bootorder..." - newentry=`efibootmgr|awk 'match($0,/^Boot([0-9a-fA-F]{4})\* spi-ca_v(.+)$/,m){print m[1]}'` - prebootorder=`efibootmgr |grep BootOrder |cut -d : -f 2 |tr -d ' '` - efibootmgr -O - efibootmgr -o ${newentry},${prebootorder} +# efibootmgr -c -g -d /dev/sde -p 1 -L "spi-ca_v$kernver" -l "\EFI\spi-ca\kernel" # -u "$bootdevice $option" +# echo "> Reordering Bootorder..." +# newentry=`efibootmgr|awk 'match($0,/^Boot([0-9a-fA-F]{4})\* spi-ca_v(.+)$/,m){print m[1]}'` +# prebootorder=`efibootmgr |grep BootOrder |cut -d : -f 2 |tr -d ' '` +# efibootmgr -O +# efibootmgr -o ${newentry},${prebootorder} echo "> OK!" } diff --git a/patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch b/patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.0.patch similarity index 96% rename from patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch rename to patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.0.patch index ff75a8b..35cd1ce 100644 --- a/patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.7.0.patch +++ b/patches/0001-block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.0.patch @@ -1,7 +1,7 @@ -From 22ee35ec82fa543b65c1b6d516a086a21f723846 Mon Sep 17 00:00:00 2001 +From f2ebe596e7d72e96e0fb2be87be90f0b96e6f1b3 Mon Sep 17 00:00:00 2001 From: Paolo Valente Date: Tue, 7 Apr 2015 13:39:12 +0200 -Subject: [PATCH 1/4] block: cgroups, kconfig, build bits for BFQ-v7r11-4.7.0 +Subject: [PATCH 1/4] block: cgroups, kconfig, build bits for BFQ-v7r11-4.8.0 Update Kconfig.iosched and do the related Makefile changes to include kernel configuration options for BFQ. Also increase the number of @@ -86,7 +86,7 @@ index 9eda232..4a36683 100644 obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 3d9cf32..8d862a0 100644 +index e79055c..931ff1e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -45,7 +45,7 @@ struct pr_ops; @@ -96,8 +96,8 @@ index 3d9cf32..8d862a0 100644 -#define BLKCG_MAX_POLS 2 +#define BLKCG_MAX_POLS 3 - struct request; typedef void (rq_end_io_fn)(struct request *, int); + -- -1.9.1 +2.7.4 (Apple Git-66) diff --git a/patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch b/patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-to-be-ported.patch similarity index 98% rename from patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch rename to patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-to-be-ported.patch index 368a4ff..7cc8ce1 100644 --- a/patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-for-4.7.0.patch +++ b/patches/0002-block-introduce-the-BFQ-v7r11-I-O-sched-to-be-ported.patch @@ -1,7 +1,8 @@ -From 2aae32be2a18a7d0da104ae42c08cb9bce9d9c7c Mon Sep 17 00:00:00 2001 +From d9af6fcc4167cbb8433b10bbf3663c8297487f52 Mon Sep 17 00:00:00 2001 From: Paolo Valente Date: Thu, 9 May 2013 19:10:02 +0200 -Subject: [PATCH 2/4] block: introduce the BFQ-v7r11 I/O sched for 4.7.0 +Subject: [PATCH 2/4] block: introduce the BFQ-v7r11 I/O sched, to be ported to + 4.8.0 The general structure is borrowed from CFQ, as much of the code for handling I/O contexts. Over time, several useful features have been @@ -56,12 +57,12 @@ Signed-off-by: Paolo Valente Signed-off-by: Arianna Avanzini --- block/Kconfig.iosched | 6 +- - block/bfq-cgroup.c | 1182 ++++++++++++++++ + block/bfq-cgroup.c | 1186 ++++++++++++++++ block/bfq-ioc.c | 36 + - block/bfq-iosched.c | 3754 +++++++++++++++++++++++++++++++++++++++++++++++++ - block/bfq-sched.c | 1200 ++++++++++++++++ + block/bfq-iosched.c | 3763 +++++++++++++++++++++++++++++++++++++++++++++++++ + block/bfq-sched.c | 1199 ++++++++++++++++ block/bfq.h | 801 +++++++++++ - 6 files changed, 6975 insertions(+), 4 deletions(-) + 6 files changed, 6987 insertions(+), 4 deletions(-) create mode 100644 block/bfq-cgroup.c create mode 100644 block/bfq-ioc.c create mode 100644 block/bfq-iosched.c @@ -91,10 +92,10 @@ index 0ee5f0f..f78cd1a 100644 prompt "Default I/O scheduler" diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c new file mode 100644 -index 0000000..8610cd6 +index 0000000..8b08a57 --- /dev/null +++ b/block/bfq-cgroup.c -@@ -0,0 +1,1182 @@ +@@ -0,0 +1,1186 @@ +/* + * BFQ: CGROUPS support. + * @@ -259,7 +260,9 @@ index 0000000..8610cd6 +static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg) +{ + struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq); ++ + BUG_ON(!pd); ++ + return pd_to_bfqg(pd); +} + @@ -379,7 +382,8 @@ index 0000000..8610cd6 + blkg_stat_add_aux(&from->time, &from->time); + blkg_stat_add_aux(&to->unaccounted_time, &from->unaccounted_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->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); @@ -471,9 +475,9 @@ index 0000000..8610cd6 +} + +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) +{ @@ -562,8 +566,8 @@ index 0000000..8610cd6 +} + +/* to be used by recursive prfill, sums live and dead rwstats recursively */ -+static struct blkg_rwstat bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, -+ int off) ++static struct blkg_rwstat ++bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, int off) +{ + struct blkg_rwstat a, b; + @@ -776,7 +780,6 @@ index 0000000..8610cd6 + + BUG_ON(!bfqq); + bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); -+ return; +} + +/** @@ -804,8 +807,6 @@ index 0000000..8610cd6 + if (bfqg->sched_data.in_service_entity) + bfq_reparent_leaf_entity(bfqd, + bfqg->sched_data.in_service_entity); -+ -+ return; +} + +/** @@ -930,6 +931,7 @@ index 0000000..8610cd6 + 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; + /* @@ -1043,7 +1045,8 @@ index 0000000..8610cd6 + return 0; +} + -+static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) +{ + int ret; + @@ -1051,22 +1054,22 @@ index 0000000..8610cd6 + if (ret) + return NULL; + -+ return blkg_to_bfqg(bfqd->queue->root_blkg); ++ return blkg_to_bfqg(bfqd->queue->root_blkg); +} + +static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp) +{ -+ struct bfq_group_data *bgd; ++ struct bfq_group_data *bgd; + -+ bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); -+ if (!bgd) -+ return NULL; -+ return &bgd->pd; ++ bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); ++ if (!bgd) ++ return NULL; ++ return &bgd->pd; +} + +static void bfq_cpd_free(struct blkcg_policy_data *cpd) +{ -+ kfree(cpd_to_bfqgd(cpd)); ++ kfree(cpd_to_bfqgd(cpd)); +} + +static struct cftype bfqio_files_dfl[] = { @@ -1201,20 +1204,19 @@ index 0000000..8610cd6 +}; + +static struct blkcg_policy blkcg_policy_bfq = { -+ .dfl_cftypes = bfqio_files_dfl, -+ .legacy_cftypes = bfqio_files, ++ .dfl_cftypes = bfqio_files_dfl, ++ .legacy_cftypes = bfqio_files, + -+ .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, -+ -+ .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, + ++ .cpd_alloc_fn = bfq_cpd_alloc, ++ .cpd_init_fn = bfq_cpd_init, ++ .cpd_bind_fn = bfq_cpd_init, ++ .cpd_free_fn = bfq_cpd_free, +}; + +#else @@ -1223,6 +1225,7 @@ index 0000000..8610cd6 + 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) { @@ -1236,6 +1239,7 @@ index 0000000..8610cd6 +bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) +{ + struct bfq_data *bfqd = bic_to_bfqd(bic); ++ + return bfqd->root_group; +} + @@ -1257,12 +1261,13 @@ index 0000000..8610cd6 +} + +static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, -+ struct blkcg *blkcg) ++ struct blkcg *blkcg) +{ + return bfqd->root_group; +} + -+static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) ++static struct bfq_group * ++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) +{ + struct bfq_group *bfqg; + int i; @@ -1321,10 +1326,10 @@ index 0000000..fb7bb8f +} diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c new file mode 100644 -index 0000000..f9787a6 +index 0000000..85e2169 --- /dev/null +++ b/block/bfq-iosched.c -@@ -0,0 +1,3754 @@ +@@ -0,0 +1,3763 @@ +/* + * Budget Fair Queueing (BFQ) disk scheduler. + * @@ -1542,7 +1547,7 @@ index 0000000..f9787a6 + unsigned long back_max; +#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ +#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ -+ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ ++ unsigned int wrap = 0; /* bit mask: requests behind the disk head? */ + + if (!rq1 || rq1 == rq2) + return rq2; @@ -1597,12 +1602,11 @@ index 0000000..f9787a6 + return rq1; + else if (d2 < d1) + return rq2; -+ else { -+ if (s1 >= s2) -+ return rq1; -+ else -+ return rq2; -+ } ++ ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; + + case BFQ_RQ2_WRAP: + return rq1; @@ -1889,7 +1893,7 @@ index 0000000..f9787a6 + */ + hlist_for_each_entry(bfqq_item, &bfqd->burst_list, + burst_list_node) -+ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_mark_bfqq_in_large_burst(bfqq_item); + bfq_mark_bfqq_in_large_burst(bfqq); + + /* @@ -2288,7 +2292,7 @@ index 0000000..f9787a6 + bfqd->rq_in_driver++; + bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); + bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", -+ (long long unsigned)bfqd->last_position); ++ (unsigned long long) bfqd->last_position); +} + +static void bfq_deactivate_request(struct request_queue *q, struct request *rq) @@ -2595,6 +2599,7 @@ index 0000000..f9787a6 +{ + struct bfq_queue *bfqq = bfqd->in_service_queue; + unsigned int timeout_coeff; ++ + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) + timeout_coeff = 1; + else @@ -2667,6 +2672,7 @@ index 0000000..f9787a6 +static int bfq_bfqq_budget_left(struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; ++ + return entity->budget - entity->service; +} + @@ -2906,6 +2912,7 @@ index 0000000..f9787a6 + if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && + update) { + int dev_type = blk_queue_nonrot(bfqd->queue); ++ + if (bfqd->bfq_user_max_budget == 0) { + bfqd->bfq_max_budget = + bfq_calc_max_budget(bfqd->peak_rate, @@ -3065,6 +3072,7 @@ index 0000000..f9787a6 + enum bfqq_expiration reason) +{ + bool slow; ++ + BUG_ON(bfqq != bfqd->in_service_queue); + + /* @@ -3098,7 +3106,7 @@ index 0000000..f9787a6 + } + + if (reason == BFQ_BFQQ_TOO_IDLE && -+ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) ++ bfqq->entity.service <= 2 * bfqq->entity.budget / 10) + bfq_clear_bfqq_IO_bound(bfqq); + + if (bfqd->low_latency && bfqq->wr_coeff == 1) @@ -3244,7 +3252,7 @@ index 0000000..f9787a6 + */ + idling_boosts_thr = !bfqd->hw_tag || + (!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && -+ bfq_bfqq_idle_window(bfqq)) ; ++ bfq_bfqq_idle_window(bfqq)); + + /* + * The value of the next variable, @@ -3356,7 +3364,7 @@ index 0000000..f9787a6 + * (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). ++ * (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 @@ -3553,6 +3561,7 @@ index 0000000..f9787a6 +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 */ + bfq_log_bfqq(bfqd, bfqq, + "raising period dur %u/%u msec, old coeff %u, w %d(%d)", @@ -3643,7 +3652,7 @@ index 0000000..f9787a6 + bfq_log_bfqq(bfqd, bfqq, + "dispatched %u sec req (%llu), budg left %d", + blk_rq_sectors(rq), -+ (long long unsigned)blk_rq_pos(rq), ++ (unsigned long long) blk_rq_pos(rq), + bfq_bfqq_budget_left(bfqq)); + + dispatched++; @@ -3841,7 +3850,8 @@ index 0000000..f9787a6 + * 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) ++static void ++bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) +{ + struct task_struct *tsk = current; + int ioprio_class; @@ -3874,8 +3884,8 @@ index 0000000..f9787a6 + } + + if (bfqq->new_ioprio < 0 || bfqq->new_ioprio >= IOPRIO_BE_NR) { -+ printk(KERN_CRIT "bfq_set_next_ioprio_data: new_ioprio %d\n", -+ bfqq->new_ioprio); ++ pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n", ++ bfqq->new_ioprio); + BUG(); + } + @@ -3999,7 +4009,7 @@ index 0000000..f9787a6 + + if (bfqq) { + bfq_init_bfqq(bfqd, bfqq, bic, current->pid, -+ is_sync); ++ is_sync); + bfq_init_entity(&bfqq->entity, bfqg); + bfq_log_bfqq(bfqd, bfqq, "allocated"); + } else { @@ -4187,7 +4197,7 @@ index 0000000..f9787a6 + bfq_log_bfqq(bfqd, bfqq, + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", + bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), -+ (long long unsigned)bfqq->seek_mean); ++ (unsigned long long) bfqq->seek_mean); + + bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); + @@ -4738,8 +4748,7 @@ index 0000000..f9787a6 + +static void bfq_slab_kill(void) +{ -+ if (bfq_pool) -+ kmem_cache_destroy(bfq_pool); ++ kmem_cache_destroy(bfq_pool); +} + +static int __init bfq_slab_setup(void) @@ -4770,6 +4779,7 @@ index 0000000..f9787a6 +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))); @@ -4788,25 +4798,29 @@ index 0000000..f9787a6 + + 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, dur %d/%u\n", -+ bfqq->pid, -+ bfqq->entity.weight, -+ bfqq->queued[0], -+ bfqq->queued[1], -+ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), -+ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ 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)); ++ 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); @@ -5081,10 +5095,10 @@ index 0000000..f9787a6 +MODULE_LICENSE("GPL"); diff --git a/block/bfq-sched.c b/block/bfq-sched.c new file mode 100644 -index 0000000..a64fec1 +index 0000000..a5ed694 --- /dev/null +++ b/block/bfq-sched.c -@@ -0,0 +1,1200 @@ +@@ -0,0 +1,1199 @@ +/* + * BFQ: Hierarchical B-WF2Q+ scheduler. + * @@ -5715,8 +5729,7 @@ index 0000000..a64fec1 + if (entity->new_weight != entity->orig_weight) { + if (entity->new_weight < BFQ_MIN_WEIGHT || + entity->new_weight > BFQ_MAX_WEIGHT) { -+ printk(KERN_CRIT "update_weight_prio: " -+ "new_weight %d\n", ++ pr_crit("update_weight_prio: new_weight %d\n", + entity->new_weight); + BUG(); + } @@ -6287,7 +6300,7 @@ index 0000000..a64fec1 +} diff --git a/block/bfq.h b/block/bfq.h new file mode 100644 -index 0000000..485d0c9 +index 0000000..2bf54ae --- /dev/null +++ b/block/bfq.h @@ -0,0 +1,801 @@ @@ -6722,10 +6735,10 @@ index 0000000..485d0c9 + * @last_ins_in_burst. + * @burst_size: number of queues in the current burst of queue activations. + * @bfq_large_burst_thresh: maximum burst size above which the current -+ * queue-activation burst is deemed as 'large'. ++ * queue-activation burst is deemed as 'large'. + * @large_burst: true if a large queue-activation burst is in progress. + * @burst_list: head of the burst list (as for the above fields, more details -+ * in the comments to the function bfq_handle_burst). ++ * in the comments to the function bfq_handle_burst). + * @low_latency: if set to true, low-latency heuristics are enabled. + * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised + * queue is multiplied. @@ -7093,5 +7106,5 @@ index 0000000..485d0c9 + +#endif /* _BFQ_H */ -- -1.9.1 +2.7.4 (Apple Git-66) diff --git a/patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch b/patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-to-.patch similarity index 92% rename from patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch rename to patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-to-.patch index a9876aa..2a53175 100644 --- a/patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch +++ b/patches/0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-to-.patch @@ -1,8 +1,8 @@ -From 47de1e46ef5f462e9694e5b0607aec6ad658f1e0 Mon Sep 17 00:00:00 2001 +From 409e62551360d2802992b0175062237352793a2a Mon Sep 17 00:00:00 2001 From: Mauro Andreolini Date: Sun, 6 Sep 2015 16:09:05 +0200 -Subject: [PATCH 3/4] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r11 for - 4.7.0 +Subject: [PATCH 3/4] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r11, to + port to 4.8.0 A set of processes may happen to perform interleaved reads, i.e.,requests whose union would give rise to a sequential read pattern. There are two @@ -35,16 +35,16 @@ Signed-off-by: Arianna Avanzini Signed-off-by: Paolo Valente Signed-off-by: Linus Walleij --- - block/bfq-cgroup.c | 4 + - block/bfq-iosched.c | 687 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + block/bfq-cgroup.c | 5 + + block/bfq-iosched.c | 685 +++++++++++++++++++++++++++++++++++++++++++++++++++- block/bfq.h | 66 +++++ - 3 files changed, 743 insertions(+), 14 deletions(-) + 3 files changed, 743 insertions(+), 13 deletions(-) diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -index 8610cd6..5ee99ec 100644 +index 8b08a57..0367996 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c -@@ -437,6 +437,7 @@ static void bfq_pd_init(struct blkg_policy_data *pd) +@@ -440,6 +440,7 @@ static void bfq_pd_init(struct blkg_policy_data *pd) */ bfqg->bfqd = bfqd; bfqg->active_entities = 0; @@ -52,16 +52,17 @@ index 8610cd6..5ee99ec 100644 } static void bfq_pd_free(struct blkg_policy_data *pd) -@@ -530,6 +531,8 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, +@@ -533,6 +534,9 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, return bfqg; } -+static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq); + /** * bfq_bfqq_move - migrate @bfqq to @bfqg. * @bfqd: queue descriptor. -@@ -577,6 +580,7 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -580,6 +584,7 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, bfqg_get(bfqg); if (busy) { @@ -70,10 +71,10 @@ index 8610cd6..5ee99ec 100644 bfq_activate_bfqq(bfqd, bfqq); } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index f9787a6..d1f648d 100644 +index 85e2169..cf3e9b1 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c -@@ -296,6 +296,72 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd, +@@ -295,6 +295,72 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd, } } @@ -112,7 +113,7 @@ index f9787a6..d1f648d 100644 + *rb_link = p; + + bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", -+ (long long unsigned)sector, ++ (unsigned long long) sector, + bfqq ? bfqq->pid : 0); + + return bfqq; @@ -146,11 +147,11 @@ index f9787a6..d1f648d 100644 /* * Tell whether there are active queues or groups with differentiated weights. */ -@@ -528,6 +594,57 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd) +@@ -527,6 +593,57 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd) return dur; } -+static unsigned bfq_bfqq_cooperations(struct bfq_queue *bfqq) ++static unsigned int bfq_bfqq_cooperations(struct bfq_queue *bfqq) +{ + return bfqq->bic ? bfqq->bic->cooperations : 0; +} @@ -204,7 +205,7 @@ index f9787a6..d1f648d 100644 /* 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) { -@@ -764,8 +881,14 @@ static void bfq_add_request(struct request *rq) +@@ -763,8 +880,14 @@ static void bfq_add_request(struct request *rq) BUG_ON(!next_rq); bfqq->next_rq = next_rq; @@ -220,7 +221,7 @@ index f9787a6..d1f648d 100644 idle_for_long_time = time_is_before_jiffies( bfqq->budget_timeout + bfqd->bfq_wr_min_idle_time); -@@ -793,11 +916,12 @@ static void bfq_add_request(struct request *rq) +@@ -792,11 +915,12 @@ static void bfq_add_request(struct request *rq) bfqd->last_ins_in_burst = jiffies; } @@ -236,7 +237,7 @@ index f9787a6..d1f648d 100644 entity->budget = max_t(unsigned long, bfqq->max_budget, bfq_serv_to_charge(next_rq, bfqq)); -@@ -816,6 +940,9 @@ static void bfq_add_request(struct request *rq) +@@ -815,6 +939,9 @@ static void bfq_add_request(struct request *rq) if (!bfqd->low_latency) goto add_bfqq_busy; @@ -246,7 +247,7 @@ index f9787a6..d1f648d 100644 /* * If the queue: * - is not being boosted, -@@ -840,7 +967,7 @@ static void bfq_add_request(struct request *rq) +@@ -839,7 +966,7 @@ static void bfq_add_request(struct request *rq) } else if (old_wr_coeff > 1) { if (interactive) bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); @@ -255,7 +256,7 @@ index f9787a6..d1f648d 100644 (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time && !soft_rt)) { -@@ -905,6 +1032,7 @@ static void bfq_add_request(struct request *rq) +@@ -904,6 +1031,7 @@ static void bfq_add_request(struct request *rq) bfqd->bfq_wr_rt_max_time; } } @@ -263,7 +264,7 @@ index f9787a6..d1f648d 100644 if (old_wr_coeff != bfqq->wr_coeff) entity->prio_changed = 1; add_bfqq_busy: -@@ -1047,6 +1175,15 @@ static void bfq_merged_request(struct request_queue *q, struct request *req, +@@ -1046,6 +1174,15 @@ static void bfq_merged_request(struct request_queue *q, struct request *req, bfqd->last_position); BUG_ON(!next_rq); bfqq->next_rq = next_rq; @@ -279,7 +280,7 @@ index f9787a6..d1f648d 100644 } } -@@ -1129,11 +1266,346 @@ static void bfq_end_wr(struct bfq_data *bfqd) +@@ -1128,11 +1265,346 @@ static void bfq_end_wr(struct bfq_data *bfqd) spin_unlock_irq(bfqd->queue->queue_lock); } @@ -572,7 +573,7 @@ index f9787a6..d1f648d 100644 + struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +{ + bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", -+ (long unsigned)new_bfqq->pid); ++ (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); @@ -626,7 +627,7 @@ index f9787a6..d1f648d 100644 /* * Disallow merge of a sync bio into an async request. -@@ -1150,7 +1622,26 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, +@@ -1149,7 +1621,26 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, if (!bic) return 0; @@ -654,7 +655,7 @@ index f9787a6..d1f648d 100644 } static void __bfq_set_in_service_queue(struct bfq_data *bfqd, -@@ -1349,6 +1840,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -1350,6 +1841,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) __bfq_bfqd_reset_in_service(bfqd); @@ -670,7 +671,7 @@ index f9787a6..d1f648d 100644 if (RB_EMPTY_ROOT(&bfqq->sort_list)) { /* * Overloading budget_timeout field to store the time -@@ -1357,8 +1857,13 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -1358,8 +1858,13 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) */ bfqq->budget_timeout = jiffies; bfq_del_bfqq_busy(bfqd, bfqq, 1); @@ -685,7 +686,7 @@ index f9787a6..d1f648d 100644 } /** -@@ -2242,10 +2747,12 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -2246,10 +2751,12 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) /* * If the queue was activated in a burst, or * too much time has elapsed from the beginning @@ -700,7 +701,7 @@ index f9787a6..d1f648d 100644 time_is_before_jiffies(bfqq->last_wr_start_finish + bfqq->wr_cur_max_time)) { bfqq->last_wr_start_finish = jiffies; -@@ -2474,6 +2981,25 @@ static void bfq_put_queue(struct bfq_queue *bfqq) +@@ -2478,6 +2985,25 @@ static void bfq_put_queue(struct bfq_queue *bfqq) #endif } @@ -726,7 +727,7 @@ index f9787a6..d1f648d 100644 static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) { if (bfqq == bfqd->in_service_queue) { -@@ -2484,6 +3010,8 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -2488,6 +3014,8 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, atomic_read(&bfqq->ref)); @@ -735,7 +736,7 @@ index f9787a6..d1f648d 100644 bfq_put_queue(bfqq); } -@@ -2492,6 +3020,25 @@ static void bfq_init_icq(struct io_cq *icq) +@@ -2496,6 +3024,25 @@ static void bfq_init_icq(struct io_cq *icq) struct bfq_io_cq *bic = icq_to_bic(icq); bic->ttime.last_end_request = jiffies; @@ -761,7 +762,7 @@ index f9787a6..d1f648d 100644 } static void bfq_exit_icq(struct io_cq *icq) -@@ -2505,6 +3052,13 @@ static void bfq_exit_icq(struct io_cq *icq) +@@ -2509,6 +3056,13 @@ static void bfq_exit_icq(struct io_cq *icq) } if (bic->bfqq[BLK_RW_SYNC]) { @@ -775,7 +776,7 @@ index f9787a6..d1f648d 100644 bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); bic->bfqq[BLK_RW_SYNC] = NULL; } -@@ -2809,6 +3363,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, +@@ -2814,6 +3368,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) return; @@ -786,7 +787,7 @@ index f9787a6..d1f648d 100644 enable_idle = bfq_bfqq_idle_window(bfqq); if (atomic_read(&bic->icq.ioc->active_ref) == 0 || -@@ -2856,6 +3414,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -2861,6 +3419,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || !BFQQ_SEEKY(bfqq)) bfq_update_idle_window(bfqd, bfqq, bic); @@ -794,7 +795,7 @@ index f9787a6..d1f648d 100644 bfq_log_bfqq(bfqd, bfqq, "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", -@@ -2920,12 +3479,47 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -2925,12 +3484,47 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, static void bfq_insert_request(struct request_queue *q, struct request *rq) { struct bfq_data *bfqd = q->elevator->elevator_data; @@ -843,7 +844,7 @@ index f9787a6..d1f648d 100644 rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; list_add_tail(&rq->queuelist, &bfqq->fifo); -@@ -3094,6 +3688,32 @@ static void bfq_put_request(struct request *rq) +@@ -3099,6 +3693,32 @@ static void bfq_put_request(struct request *rq) } /* @@ -876,7 +877,7 @@ index f9787a6..d1f648d 100644 * Allocate bfq data structures associated with this request. */ static int bfq_set_request(struct request_queue *q, struct request *rq, -@@ -3105,6 +3725,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, +@@ -3110,6 +3730,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, const int is_sync = rq_is_sync(rq); struct bfq_queue *bfqq; unsigned long flags; @@ -884,7 +885,7 @@ index f9787a6..d1f648d 100644 might_sleep_if(gfpflags_allow_blocking(gfp_mask)); -@@ -3117,15 +3738,30 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, +@@ -3122,15 +3743,30 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, bfq_bic_update_cgroup(bic, bio); @@ -900,12 +901,11 @@ index f9787a6..d1f648d 100644 + bic->saved_in_large_burst) bfq_mark_bfqq_in_large_burst(bfqq); - else -- bfq_clear_bfqq_in_large_burst(bfqq); + else { -+ bfq_clear_bfqq_in_large_burst(bfqq); -+ if (bic->was_in_burst_list) -+ hlist_add_head(&bfqq->burst_list_node, -+ &bfqd->burst_list); + bfq_clear_bfqq_in_large_burst(bfqq); ++ if (bic->was_in_burst_list) ++ hlist_add_head(&bfqq->burst_list_node, ++ &bfqd->burst_list); + } + } + } else { @@ -919,7 +919,7 @@ index f9787a6..d1f648d 100644 } } -@@ -3137,6 +3773,26 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, +@@ -3142,6 +3778,26 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, rq->elv.priv[0] = bic; rq->elv.priv[1] = bfqq; @@ -946,7 +946,7 @@ index f9787a6..d1f648d 100644 spin_unlock_irqrestore(q->queue_lock, flags); return 0; -@@ -3290,6 +3946,7 @@ static void bfq_init_root_group(struct bfq_group *root_group, +@@ -3295,6 +3951,7 @@ static void bfq_init_root_group(struct bfq_group *root_group, root_group->my_entity = NULL; root_group->bfqd = bfqd; #endif @@ -954,7 +954,7 @@ index f9787a6..d1f648d 100644 for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) root_group->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; } -@@ -3370,6 +4027,8 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) +@@ -3375,6 +4032,8 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; @@ -964,7 +964,7 @@ index f9787a6..d1f648d 100644 bfqd->bfq_large_burst_thresh = 11; diff --git a/block/bfq.h b/block/bfq.h -index 485d0c9..f73c942 100644 +index 2bf54ae..fcce855 100644 --- a/block/bfq.h +++ b/block/bfq.h @@ -183,6 +183,8 @@ struct bfq_group; @@ -1097,5 +1097,5 @@ index 485d0c9..f73c942 100644 static void bfq_put_queue(struct bfq_queue *bfqq); static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); -- -1.9.1 +2.7.4 (Apple Git-66) diff --git a/patches/0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch b/patches/0004-Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch similarity index 77% rename from patches/0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch rename to patches/0004-Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch index bf56ac7..62cdd1a 100644 --- a/patches/0004-block-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8r3-for.patch +++ b/patches/0004-Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch @@ -1,16 +1,16 @@ -From d384ccf796a992e27691b7359ce54534db57e74c Mon Sep 17 00:00:00 2001 +From ec8981e245dfe24bc6a80207e832ca9be18fd39d Mon Sep 17 00:00:00 2001 From: Paolo Valente Date: Tue, 17 May 2016 08:28:04 +0200 -Subject: [PATCH 4/4] block, bfq: turn BFQ-v7r11 for 4.7.0 into BFQ-v8r3 for - 4.7.0 +Subject: [PATCH 4/4] Turn BFQ-v7r11 into BFQ-v8r4 for 4.8.0 +Signed-off-by: Paolo Valente --- block/Kconfig.iosched | 2 +- - block/bfq-cgroup.c | 480 +++++---- - block/bfq-iosched.c | 2602 +++++++++++++++++++++++++++++-------------------- - block/bfq-sched.c | 441 +++++++-- - block/bfq.h | 708 +++++++------- - 5 files changed, 2484 insertions(+), 1749 deletions(-) + block/bfq-cgroup.c | 495 ++++---- + block/bfq-iosched.c | 3230 +++++++++++++++++++++++++++++++------------------ + block/bfq-sched.c | 480 ++++++-- + block/bfq.h | 747 ++++++------ + 5 files changed, 3073 insertions(+), 1881 deletions(-) diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched index f78cd1a..6d92579 100644 @@ -26,33 +26,85 @@ index f78cd1a..6d92579 100644 ---help--- Enable hierarchical scheduling in BFQ, using the blkio controller. diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -index 5ee99ec..c83d90c 100644 +index 0367996..b50ae8e 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c -@@ -162,7 +162,6 @@ static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg) - static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg) +@@ -7,7 +7,9 @@ + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * +- * Copyright (C) 2010 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. +@@ -163,8 +165,6 @@ static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg) { struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq); + - BUG_ON(!pd); +- return pd_to_bfqg(pd); } -@@ -224,14 +223,6 @@ static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw) - blkg_rwstat_add(&bfqg->stats.merged, rw, 1); +@@ -208,59 +208,49 @@ static void bfqg_put(struct bfq_group *bfqg) + + static void bfqg_stats_update_io_add(struct bfq_group *bfqg, + struct bfq_queue *bfqq, +- int rw) ++ int op, int op_flags) + { +- blkg_rwstat_add(&bfqg->stats.queued, rw, 1); ++ 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 rw) +-{ +- blkg_rwstat_add(&bfqg->stats.queued, rw, -1); +-} +- +-static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw) ++static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, ++ int op_flags) + { +- blkg_rwstat_add(&bfqg->stats.merged, rw, 1); ++ blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, -1); } -static void bfqg_stats_update_dispatch(struct bfq_group *bfqg, - uint64_t bytes, int rw) --{ ++static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, ++ int op_flags) + { - blkg_stat_add(&bfqg->stats.sectors, bytes >> 9); - blkg_rwstat_add(&bfqg->stats.serviced, rw, 1); - blkg_rwstat_add(&bfqg->stats.service_bytes, rw, bytes); --} -- ++ 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 rw) +- uint64_t start_time, uint64_t io_start_time, int rw) ++ uint64_t start_time, uint64_t io_start_time, int op, ++ int op_flags) { -@@ -248,17 +239,11 @@ static void bfqg_stats_update_completion(struct bfq_group *bfqg, + 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, rw, 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, rw, ++ 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) { @@ -70,7 +122,7 @@ index 5ee99ec..c83d90c 100644 blkg_stat_reset(&stats->avg_queue_size_sum); blkg_stat_reset(&stats->avg_queue_size_samples); blkg_stat_reset(&stats->dequeue); -@@ -268,21 +253,19 @@ static void bfqg_stats_reset(struct bfqg_stats *stats) +@@ -270,19 +260,16 @@ static void bfqg_stats_reset(struct bfqg_stats *stats) } /* @to += @from */ @@ -89,13 +141,9 @@ index 5ee99ec..c83d90c 100644 blkg_stat_add_aux(&from->time, &from->time); - blkg_stat_add_aux(&to->unaccounted_time, &from->unaccounted_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->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); -@@ -308,10 +291,8 @@ static void bfqg_stats_xfer_dead(struct bfq_group *bfqg) + blkg_stat_add_aux(&to->avg_queue_size_samples, + &from->avg_queue_size_samples); +@@ -311,10 +298,8 @@ static void bfqg_stats_xfer_dead(struct bfq_group *bfqg) if (unlikely(!parent)) return; @@ -107,7 +155,7 @@ index 5ee99ec..c83d90c 100644 } static void bfq_init_entity(struct bfq_entity *entity, -@@ -332,15 +313,11 @@ static void bfq_init_entity(struct bfq_entity *entity, +@@ -335,15 +320,11 @@ static void bfq_init_entity(struct bfq_entity *entity, static void bfqg_stats_exit(struct bfqg_stats *stats) { @@ -123,7 +171,7 @@ index 5ee99ec..c83d90c 100644 blkg_stat_exit(&stats->avg_queue_size_sum); blkg_stat_exit(&stats->avg_queue_size_samples); blkg_stat_exit(&stats->dequeue); -@@ -351,15 +328,11 @@ static void bfqg_stats_exit(struct bfqg_stats *stats) +@@ -354,15 +335,11 @@ static void bfqg_stats_exit(struct bfqg_stats *stats) static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp) { @@ -140,18 +188,7 @@ index 5ee99ec..c83d90c 100644 blkg_stat_init(&stats->avg_queue_size_sum, gfp) || blkg_stat_init(&stats->avg_queue_size_samples, gfp) || blkg_stat_init(&stats->dequeue, gfp) || -@@ -374,20 +347,36 @@ static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp) - } - - 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) - { +@@ -386,11 +363,27 @@ static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg) return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq)); } @@ -180,7 +217,7 @@ index 5ee99ec..c83d90c 100644 } static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) -@@ -398,8 +387,7 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) +@@ -401,8 +394,7 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) if (!bfqg) return NULL; @@ -190,7 +227,7 @@ index 5ee99ec..c83d90c 100644 kfree(bfqg); return NULL; } -@@ -407,27 +395,20 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) +@@ -410,27 +402,20 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node) return &bfqg->pd; } @@ -228,7 +265,7 @@ index 5ee99ec..c83d90c 100644 entity->orig_weight = entity->weight = entity->new_weight = d->weight; entity->my_sched_data = &bfqg->sched_data; -@@ -445,70 +426,53 @@ static void bfq_pd_free(struct blkg_policy_data *pd) +@@ -448,70 +433,53 @@ static void bfq_pd_free(struct blkg_policy_data *pd) struct bfq_group *bfqg = pd_to_bfqg(pd); bfqg_stats_exit(&bfqg->stats); @@ -256,23 +293,23 @@ index 5ee99ec..c83d90c 100644 } -/* to be used by recursive prfill, sums live and dead rwstats recursively */ --static struct blkg_rwstat bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, -- int off) +-static struct blkg_rwstat +-bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, int off) +static void bfq_group_set_parent(struct bfq_group *bfqg, + struct bfq_group *parent) { - struct blkg_rwstat a, b; + struct bfq_entity *entity; -+ -+ BUG_ON(!parent); -+ BUG_ON(!bfqg); -+ BUG_ON(bfqg == parent); - a = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, off); - b = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, - off + dead_stats_off_delta); - blkg_rwstat_add_aux(&a, &b); - return a; ++ BUG_ON(!parent); ++ BUG_ON(!bfqg); ++ BUG_ON(bfqg == parent); ++ + entity = &bfqg->entity; + entity->parent = parent->my_entity; + entity->sched_data = &parent->sched_data; @@ -326,19 +363,15 @@ index 5ee99ec..c83d90c 100644 /* * Update chain of bfq_groups as we might be handling a leaf group -@@ -531,13 +495,18 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, - return bfqg; - } +@@ -537,11 +505,15 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, + static void bfq_pos_tree_add_move(struct bfq_data *bfqd, + struct bfq_queue *bfqq); --static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq); -+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. @@ -347,7 +380,7 @@ index 5ee99ec..c83d90c 100644 * @bfqg: the group to move to. * * Move @bfqq to @bfqg, deactivating it from its old group and reactivating -@@ -548,26 +517,40 @@ static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -552,26 +524,40 @@ static void bfq_pos_tree_add_move(struct bfq_data *bfqd, * rcu_read_lock()). */ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, @@ -368,7 +401,9 @@ index 5ee99ec..c83d90c 100644 + && entity->on_st && bfqq != bfqd->in_service_queue); + BUG_ON(!bfq_bfqq_busy(bfqq) && bfqq == bfqd->in_service_queue); -+ + +- if (busy) { +- BUG_ON(atomic_read(&bfqq->ref) < 2); + /* 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 @@ -382,9 +417,7 @@ index 5ee99ec..c83d90c 100644 + BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq) + && &bfq_entity_service_tree(entity)->idle != + entity->tree); - -- if (busy) { -- BUG_ON(atomic_read(&bfqq->ref) < 2); ++ + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); - if (!resume) @@ -402,7 +435,7 @@ index 5ee99ec..c83d90c 100644 bfqg_put(bfqq_group(bfqq)); /* -@@ -579,14 +562,17 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -583,14 +569,17 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, entity->sched_data = &bfqg->sched_data; bfqg_get(bfqg); @@ -423,16 +456,20 @@ index 5ee99ec..c83d90c 100644 } /** -@@ -613,7 +599,7 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, +@@ -617,7 +606,11 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, lockdep_assert_held(bfqd->queue->queue_lock); - bfqg = bfq_find_alloc_group(bfqd, blkcg); + bfqg = bfq_find_set_group(bfqd, blkcg); ++ ++ if (unlikely(!bfqg)) ++ bfqg = bfqd->root_group; ++ if (async_bfqq) { entity = &async_bfqq->entity; -@@ -621,7 +607,8 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, +@@ -625,7 +618,8 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, bic_set_bfqq(bic, NULL, 0); bfq_log_bfqq(bfqd, async_bfqq, "bic_change_group: %p %d", @@ -442,7 +479,7 @@ index 5ee99ec..c83d90c 100644 bfq_put_queue(async_bfqq); } } -@@ -629,7 +616,7 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, +@@ -633,7 +627,7 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, if (sync_bfqq) { entity = &sync_bfqq->entity; if (entity->sched_data != &bfqg->sched_data) @@ -451,7 +488,7 @@ index 5ee99ec..c83d90c 100644 } return bfqg; -@@ -638,25 +625,23 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, +@@ -642,25 +636,23 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) { struct bfq_data *bfqd = bic_to_bfqd(bic); @@ -485,22 +522,16 @@ index 5ee99ec..c83d90c 100644 } /** -@@ -682,8 +667,7 @@ static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, +@@ -686,7 +678,7 @@ static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); BUG_ON(!bfqq); - bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); -- return; + bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); } /** -@@ -711,16 +695,15 @@ static void bfq_reparent_active_entities(struct bfq_data *bfqd, - if (bfqg->sched_data.in_service_entity) - bfq_reparent_leaf_entity(bfqd, - bfqg->sched_data.in_service_entity); -- -- return; +@@ -717,11 +709,12 @@ static void bfq_reparent_active_entities(struct bfq_data *bfqd, } /** @@ -517,7 +548,7 @@ index 5ee99ec..c83d90c 100644 */ static void bfq_pd_offline(struct blkg_policy_data *pd) { -@@ -779,6 +762,12 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) +@@ -780,6 +773,12 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) bfq_put_async_queues(bfqd, bfqg); BUG_ON(entity->tree); @@ -530,7 +561,7 @@ index 5ee99ec..c83d90c 100644 bfqg_stats_xfer_dead(bfqg); } -@@ -788,46 +777,35 @@ static void bfq_end_wr_async(struct bfq_data *bfqd) +@@ -789,46 +788,35 @@ static void bfq_end_wr_async(struct bfq_data *bfqd) list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) { struct bfq_group *bfqg = blkg_to_bfqg(blkg); @@ -588,15 +619,7 @@ index 5ee99ec..c83d90c 100644 if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT) return ret; -@@ -837,6 +815,7 @@ static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css, - 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; - /* -@@ -871,13 +850,18 @@ static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css, +@@ -873,13 +861,18 @@ static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css, return ret; } @@ -620,7 +643,7 @@ index 5ee99ec..c83d90c 100644 } static int bfqg_print_stat(struct seq_file *sf, void *v) -@@ -897,16 +881,17 @@ static int bfqg_print_rwstat(struct seq_file *sf, void *v) +@@ -899,16 +892,17 @@ static int bfqg_print_rwstat(struct seq_file *sf, void *v) static u64 bfqg_prfill_stat_recursive(struct seq_file *sf, struct blkg_policy_data *pd, int off) { @@ -642,7 +665,7 @@ index 5ee99ec..c83d90c 100644 return __blkg_prfill_rwstat(sf, pd, &sum); } -@@ -926,6 +911,41 @@ static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v) +@@ -928,6 +922,41 @@ static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v) return 0; } @@ -684,37 +707,23 @@ index 5ee99ec..c83d90c 100644 static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf, struct blkg_policy_data *pd, int off) { -@@ -950,7 +970,8 @@ static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v) - return 0; - } - --static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) -+static struct bfq_group * -+bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) - { - int ret; - -@@ -958,41 +979,18 @@ static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int n - if (ret) - return NULL; - -- return blkg_to_bfqg(bfqd->queue->root_blkg); -+ return blkg_to_bfqg(bfqd->queue->root_blkg); +@@ -964,38 +993,15 @@ bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) + return blkg_to_bfqg(bfqd->queue->root_blkg); } -static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp) -{ -- struct bfq_group_data *bgd; +- struct bfq_group_data *bgd; - -- bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); -- if (!bgd) -- return NULL; -- return &bgd->pd; +- bgd = kzalloc(sizeof(*bgd), GFP_KERNEL); +- if (!bgd) +- return NULL; +- return &bgd->pd; -} - -static void bfq_cpd_free(struct blkcg_policy_data *cpd) -{ -- kfree(cpd_to_bfqgd(cpd)); +- kfree(cpd_to_bfqgd(cpd)); -} - -static struct cftype bfqio_files_dfl[] = { @@ -742,7 +751,7 @@ index 5ee99ec..c83d90c 100644 { .name = "bfq.time", .private = offsetof(struct bfq_group, stats.time), -@@ -1000,18 +998,17 @@ static struct cftype bfqio_files[] = { +@@ -1003,18 +1009,17 @@ static struct cftype bfqio_files[] = { }, { .name = "bfq.sectors", @@ -766,7 +775,7 @@ index 5ee99ec..c83d90c 100644 }, { .name = "bfq.io_service_time", -@@ -1042,18 +1039,17 @@ static struct cftype bfqio_files[] = { +@@ -1045,18 +1050,17 @@ static struct cftype bfqio_files[] = { }, { .name = "bfq.sectors_recursive", @@ -790,7 +799,7 @@ index 5ee99ec..c83d90c 100644 }, { .name = "bfq.io_service_time_recursive", -@@ -1099,32 +1095,35 @@ static struct cftype bfqio_files[] = { +@@ -1102,31 +1106,39 @@ static struct cftype bfqio_files[] = { .private = offsetof(struct bfq_group, stats.dequeue), .seq_show = bfqg_print_stat, }, @@ -803,20 +812,19 @@ index 5ee99ec..c83d90c 100644 }; -static struct blkcg_policy blkcg_policy_bfq = { -- .dfl_cftypes = bfqio_files_dfl, -- .legacy_cftypes = bfqio_files, +- .dfl_cftypes = bfqio_files_dfl, +- .legacy_cftypes = bfqio_files, - -- .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, -- -- .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, - +- .cpd_alloc_fn = bfq_cpd_alloc, +- .cpd_init_fn = bfq_cpd_init, +- .cpd_bind_fn = bfq_cpd_init, +- .cpd_free_fn = bfq_cpd_free, +static struct cftype bfq_blkg_files[] = { + { + .name = "bfq.weight", @@ -831,13 +839,17 @@ index 5ee99ec..c83d90c 100644 +#else /* CONFIG_BFQ_GROUP_IOSCHED */ + +static inline void bfqg_stats_update_io_add(struct bfq_group *bfqg, -+ struct bfq_queue *bfqq, int rw) { } -+static inline void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int rw) { } -+static inline void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw) { } ++ 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 rw) { } -+static inline void bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg, -+struct bfq_group *curr_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) { } @@ -847,7 +859,7 @@ index 5ee99ec..c83d90c 100644 static void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg) -@@ -1146,27 +1145,20 @@ bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) +@@ -1150,27 +1162,20 @@ bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) return bfqd->root_group; } @@ -865,31 +877,33 @@ index 5ee99ec..c83d90c 100644 -static void bfq_disconnect_groups(struct bfq_data *bfqd) +static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, -+ struct blkcg *blkcg) ++ struct blkcg *blkcg) { - bfq_put_async_queues(bfqd, bfqd->root_group); + return bfqd->root_group; } -static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, -- struct blkcg *blkcg) +- struct blkcg *blkcg) +static struct bfq_group *bfqq_group(struct bfq_queue *bfqq) { - return bfqd->root_group; + return bfqq->bfqd->root_group; } - static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) + static struct bfq_group * diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index d1f648d..3bc1f8b 100644 +index cf3e9b1..eef6ff4 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c -@@ -7,25 +7,26 @@ +@@ -7,25 +7,28 @@ * Copyright (C) 2008 Fabio Checconi * Paolo Valente * - * Copyright (C) 2010 Paolo Valente -+ * Copyright (C) 2016 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. @@ -926,7 +940,28 @@ index d1f648d..3bc1f8b 100644 * * 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 -@@ -87,7 +88,6 @@ static const int bfq_stats_min_budgets = 194; +@@ -70,8 +73,8 @@ + #include "bfq.h" + #include "blk.h" + +-/* Expiration time of sync (0) and async (1) requests, in jiffies. */ +-static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; ++/* 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; +@@ -79,15 +82,14 @@ 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 jiffies. */ +-static int bfq_slice_idle = HZ / 125; ++/* 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; @@ -934,7 +969,7 @@ index d1f648d..3bc1f8b 100644 /* * Async to sync throughput distribution is controlled as follows: -@@ -97,8 +97,7 @@ static const int bfq_max_budget_async_rq = 4; +@@ -97,23 +99,27 @@ static const int bfq_max_budget_async_rq = 4; static const int bfq_async_charge_factor = 10; /* Default timeout values, in jiffies, approximating CFQ defaults. */ @@ -944,19 +979,33 @@ index d1f648d..3bc1f8b 100644 struct kmem_cache *bfq_pool; -@@ -109,8 +108,9 @@ struct kmem_cache *bfq_pool; +-/* Below this threshold (in ms), we consider thinktime immediate. */ +-#define BFQ_MIN_TT 2 ++/* 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 * 1024) -#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) -+#define BFQQ_SEEK_THR (sector_t)(8 * 100) ++#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 samples used for peak rate estimation (for autotuning). */ - #define BFQ_PEAK_RATE_SAMPLES 32 -@@ -141,16 +141,24 @@ struct kmem_cache *bfq_pool; +-/* Min samples used for peak rate estimation (for autotuning). */ +-#define BFQ_PEAK_RATE_SAMPLES 32 ++/* 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 +@@ -141,16 +147,24 @@ struct kmem_cache *bfq_pool; * The device's speed class is dynamically (re)detected in * bfq_update_peak_rate() every time the estimated peak rate is updated. * @@ -988,7 +1037,19 @@ index d1f648d..3bc1f8b 100644 /* * To improve readability, a conversion function is used to initialize the * following arrays, which entails that they can be initialized only in a -@@ -410,11 +418,7 @@ static bool bfq_differentiated_weights(struct bfq_data *bfqd) +@@ -183,10 +197,7 @@ static void bfq_schedule_dispatch(struct bfq_data *bfqd); + */ + static int bfq_bio_sync(struct bio *bio) + { +- if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) +- return 1; +- +- return 0; ++ return bio_data_dir(bio) == READ || (bio->bi_opf & REQ_SYNC); + } + + /* +@@ -409,11 +420,7 @@ static bool bfq_differentiated_weights(struct bfq_data *bfqd) */ static bool bfq_symmetric_scenario(struct bfq_data *bfqd) { @@ -1001,7 +1062,7 @@ index d1f648d..3bc1f8b 100644 } /* -@@ -534,9 +538,19 @@ static struct request *bfq_find_next_rq(struct bfq_data *bfqd, +@@ -533,9 +540,19 @@ static struct request *bfq_find_next_rq(struct bfq_data *bfqd, static unsigned long bfq_serv_to_charge(struct request *rq, struct bfq_queue *bfqq) { @@ -1024,7 +1085,7 @@ index d1f648d..3bc1f8b 100644 } /** -@@ -591,12 +605,23 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd) +@@ -590,12 +607,23 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd) dur = bfqd->RT_prod; do_div(dur, bfqd->peak_rate); @@ -1046,14 +1107,14 @@ index d1f648d..3bc1f8b 100644 + else if (dur < msecs_to_jiffies(3000)) + dur = msecs_to_jiffies(3000); --static unsigned bfq_bfqq_cooperations(struct bfq_queue *bfqq) +-static unsigned int bfq_bfqq_cooperations(struct bfq_queue *bfqq) -{ - return bfqq->bic ? bfqq->bic->cooperations : 0; + return dur; } static void -@@ -606,31 +631,11 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) +@@ -605,31 +633,28 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) bfq_mark_bfqq_idle_window(bfqq); else bfq_clear_bfqq_idle_window(bfqq); @@ -1076,17 +1137,33 @@ index d1f648d..3bc1f8b 100644 - bfqq->wr_cur_max_time = bic->wr_time_left; - bfqq->last_wr_start_finish = jiffies; - bfqq->entity.prio_changed = 1; -- } ++ ++ 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; + } - /* - * Clear wr_time_left to prevent bfq_bfqq_save_state() from - * getting confused about the queue's need of a weight-raising - * period. - */ - bic->wr_time_left = 0; ++ /* make sure weight will be updated, however we got here */ ++ bfqq->entity.prio_changed = 1; } static int bfqq_process_refs(struct bfq_queue *bfqq) -@@ -640,7 +645,7 @@ static int bfqq_process_refs(struct bfq_queue *bfqq) +@@ -639,7 +664,7 @@ static int bfqq_process_refs(struct bfq_queue *bfqq) lockdep_assert_held(bfqq->bfqd->queue->queue_lock); io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; @@ -1095,7 +1172,7 @@ index d1f648d..3bc1f8b 100644 BUG_ON(process_refs < 0); return process_refs; } -@@ -655,6 +660,7 @@ static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -654,6 +679,7 @@ static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) hlist_del_init(&item->burst_list_node); hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); bfqd->burst_size = 1; @@ -1103,7 +1180,7 @@ index d1f648d..3bc1f8b 100644 } /* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ -@@ -663,6 +669,10 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -662,6 +688,10 @@ 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++; @@ -1114,7 +1191,7 @@ index d1f648d..3bc1f8b 100644 if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { struct bfq_queue *pos, *bfqq_item; struct hlist_node *n; -@@ -672,15 +682,19 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -671,15 +701,19 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) * other to consider this burst as large. */ bfqd->large_burst = true; @@ -1127,7 +1204,7 @@ index d1f648d..3bc1f8b 100644 hlist_for_each_entry(bfqq_item, &bfqd->burst_list, - burst_list_node) + burst_list_node) { - bfq_mark_bfqq_in_large_burst(bfqq_item); + 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); @@ -1135,7 +1212,7 @@ index d1f648d..3bc1f8b 100644 /* * From now on, and until the current burst finishes, any -@@ -692,67 +706,79 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -691,67 +725,79 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, burst_list_node) hlist_del_init(&pos->burst_list_node); @@ -1249,7 +1326,8 @@ index d1f648d..3bc1f8b 100644 + * 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. -+ * + * +- * . when the very first queue is activated, the queue is inserted into the + * 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 @@ -1258,13 +1336,12 @@ index d1f648d..3bc1f8b 100644 + * 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 activated, the queue is inserted into the ++ * + * . 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 -@@ -773,13 +799,13 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -772,13 +818,13 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) * * . the device enters a large-burst mode * @@ -1280,7 +1357,7 @@ index d1f648d..3bc1f8b 100644 * 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: -@@ -792,52 +818,44 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -791,52 +837,44 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) * in a possible new burst (then the burst list contains just Q * after this step). */ @@ -1357,7 +1434,7 @@ index d1f648d..3bc1f8b 100644 } /* -@@ -846,8 +864,9 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -845,8 +883,9 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, * bfqq as belonging to this large burst immediately. */ if (bfqd->large_burst) { @@ -1368,7 +1445,7 @@ index d1f648d..3bc1f8b 100644 } /* -@@ -856,25 +875,498 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -855,25 +894,491 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, * queue. Then we add bfqq to the burst. */ bfq_add_to_burst(bfqd, bfqq); @@ -1388,6 +1465,7 @@ index d1f648d..3bc1f8b 100644 +static int bfq_bfqq_budget_left(struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; ++ + return entity->budget - entity->service; +} + @@ -1550,6 +1628,7 @@ index d1f648d..3bc1f8b 100644 + * 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); @@ -1558,8 +1637,9 @@ index d1f648d..3bc1f8b 100644 + 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)); ++ bfq_serv_to_charge(bfqq->next_rq, bfqq)); + BUG_ON(entity->budget < 0); + + bfq_clear_bfqq_non_blocking_wait_rq(bfqq); @@ -1580,6 +1660,7 @@ index d1f648d..3bc1f8b 100644 + 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 = @@ -1613,32 +1694,13 @@ index d1f648d..3bc1f8b 100644 + jiffies, + jiffies_to_msecs(bfqq-> + wr_cur_max_time)); -+ } else if (time_before( -+ bfqq->last_wr_start_finish + -+ bfqq->wr_cur_max_time, -+ jiffies + -+ bfqd->bfq_wr_rt_max_time) && -+ soft_rt) { ++ } else if (soft_rt) { + /* -+ * The remaining weight-raising time is lower -+ * than bfqd->bfq_wr_rt_max_time, which means -+ * that the application is enjoying weight -+ * raising either because deemed soft-rt in -+ * the near past, or because deemed interactive -+ * a long ago. -+ * In both cases, resetting now the current -+ * remaining weight-raising time for the -+ * application to the weight-raising duration -+ * for soft rt applications would not cause any -+ * latency increase for the application (as the -+ * new duration would be higher than the -+ * remaining time). -+ * -+ * In addition, the application is now meeting -+ * the requirements for being deemed soft rt. -+ * In the end we can correctly and safely -+ * (re)charge the weight-raising duration for -+ * the application with the weight-raising ++ * 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., @@ -1662,14 +1724,22 @@ index d1f648d..3bc1f8b 100644 + * 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; -+ 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, or " -+ " just moving forward duration"); + } + } +} @@ -1697,9 +1767,9 @@ index d1f648d..3bc1f8b 100644 + * bfq_bfqq_update_budg_for_activation for + * details on the usage of the next variable. + */ -+ arrived_in_time = time_is_after_jiffies( ++ arrived_in_time = ktime_get_ns() <= + RQ_BIC(rq)->ttime.last_end_request + -+ bfqd->bfq_slice_idle * 3); ++ bfqd->bfq_slice_idle * 3; + + bfq_log_bfqq(bfqd, bfqq, + "bfq_add_request non-busy: " @@ -1714,7 +1784,7 @@ index d1f648d..3bc1f8b 100644 + + BUG_ON(bfqq == bfqd->in_service_queue); + bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq, -+ rq->cmd_flags); ++ req_op(rq), rq->cmd_flags); + + /* + * bfqq deserves to be weight-raised if: @@ -1871,7 +1941,7 @@ index d1f648d..3bc1f8b 100644 */ prev = bfqq->next_rq; next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); -@@ -887,160 +1379,10 @@ static void bfq_add_request(struct request *rq) +@@ -886,160 +1391,10 @@ static void bfq_add_request(struct request *rq) if (prev != bfqq->next_rq) bfq_pos_tree_add_move(bfqd, bfqq); @@ -2036,7 +2106,7 @@ index d1f648d..3bc1f8b 100644 if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && time_is_before_jiffies( bfqq->last_wr_start_finish + -@@ -1049,16 +1391,43 @@ add_bfqq_busy: +@@ -1048,16 +1403,43 @@ add_bfqq_busy: bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); bfqd->wr_busy_queues++; @@ -2084,7 +2154,36 @@ index d1f648d..3bc1f8b 100644 if (bfqd->low_latency && (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) bfqq->last_wr_start_finish = jiffies; -@@ -1106,6 +1475,9 @@ static void bfq_remove_request(struct request *rq) +@@ -1081,14 +1463,24 @@ static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, + 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++; +- bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); +- bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", +- (unsigned long long) bfqd->last_position); + } + + static void bfq_deactivate_request(struct request_queue *q, struct request *rq) +@@ -1105,6 +1497,9 @@ static void bfq_remove_request(struct request *rq) struct bfq_data *bfqd = bfqq->bfqd; const int sync = rq_is_sync(rq); @@ -2094,7 +2193,7 @@ index d1f648d..3bc1f8b 100644 if (bfqq->next_rq == rq) { bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); bfq_updated_next_req(bfqd, bfqq); -@@ -1119,8 +1491,25 @@ static void bfq_remove_request(struct request *rq) +@@ -1118,8 +1513,25 @@ static void bfq_remove_request(struct request *rq) elv_rb_del(&bfqq->sort_list, rq); if (RB_EMPTY_ROOT(&bfqq->sort_list)) { @@ -2121,23 +2220,55 @@ index d1f648d..3bc1f8b 100644 /* * Remove queue from request-position tree as it is empty. */ -@@ -1134,9 +1523,7 @@ static void bfq_remove_request(struct request *rq) +@@ -1133,9 +1545,8 @@ static void bfq_remove_request(struct request *rq) BUG_ON(bfqq->meta_pending == 0); bfqq->meta_pending--; } -#ifdef CONFIG_BFQ_GROUP_IOSCHED - bfqg_stats_update_io_remove(bfqq_group(bfqq), rq->cmd_flags); +- bfqg_stats_update_io_remove(bfqq_group(bfqq), rq->cmd_flags); -#endif ++ 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, -@@ -1221,21 +1608,25 @@ static void bfq_merged_requests(struct request_queue *q, struct request *rq, +@@ -1145,7 +1556,7 @@ static int bfq_merge(struct request_queue *q, struct request **req, + struct request *__rq; + + __rq = bfq_find_rq_fmerge(bfqd, bio); +- if (__rq && elv_rq_merge_ok(__rq, bio)) { ++ if (__rq && elv_bio_merge_ok(__rq, bio)) { + *req = __rq; + return ELEVATOR_FRONT_MERGE; + } +@@ -1190,7 +1601,8 @@ static void bfq_merged_request(struct request_queue *q, struct request *req, + 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->bi_rw); ++ bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio_op(bio), ++ bio->bi_opf); + } + #endif + +@@ -1210,7 +1622,7 @@ static void bfq_merged_requests(struct request_queue *q, struct request *rq, + */ + if (bfqq == next_bfqq && + !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && +- time_before(next->fifo_time, rq->fifo_time)) { ++ next->fifo_time < rq->fifo_time) { + list_del_init(&rq->queuelist); + list_replace_init(&next->queuelist, &rq->queuelist); + rq->fifo_time = next->fifo_time; +@@ -1220,21 +1632,31 @@ static void bfq_merged_requests(struct request_queue *q, struct request *rq, bfqq->next_rq = rq; bfq_remove_request(next); -#ifdef CONFIG_BFQ_GROUP_IOSCHED - bfqg_stats_update_io_merged(bfqq_group(bfqq), next->cmd_flags); +- bfqg_stats_update_io_merged(bfqq_group(bfqq), next->cmd_flags); -#endif ++ bfqg_stats_update_io_merged(bfqq_group(bfqq), req_op(next), ++ next->cmd_flags); } /* Must be called with bfqq != NULL */ @@ -2150,17 +2281,22 @@ index d1f648d..3bc1f8b 100644 bfqq->wr_coeff = 1; bfqq->wr_cur_max_time = 0; - /* Trigger a weight change on the next activation of the queue */ ++ 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, -@@ -1278,7 +1669,7 @@ static int bfq_rq_close_to_sector(void *io_struct, bool request, +@@ -1277,7 +1699,7 @@ 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) <= @@ -2169,7 +2305,7 @@ index d1f648d..3bc1f8b 100644 } static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd, -@@ -1400,7 +1791,7 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +@@ -1399,7 +1821,7 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) * throughput. */ bfqq->new_bfqq = new_bfqq; @@ -2178,7 +2314,7 @@ index d1f648d..3bc1f8b 100644 return new_bfqq; } -@@ -1431,9 +1822,23 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, +@@ -1430,9 +1852,23 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, } /* @@ -2205,7 +2341,7 @@ index d1f648d..3bc1f8b 100644 * structure otherwise. * * The OOM queue is not allowed to participate to cooperation: in fact, since -@@ -1442,6 +1847,18 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, +@@ -1441,6 +1877,18 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq, * 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. @@ -2224,7 +2360,7 @@ index d1f648d..3bc1f8b 100644 */ static struct bfq_queue * bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, -@@ -1451,16 +1868,32 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -1450,16 +1898,32 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, if (bfqq->new_bfqq) return bfqq->new_bfqq; @@ -2260,7 +2396,7 @@ index d1f648d..3bc1f8b 100644 unlikely(in_service_bfqq == &bfqd->oom_bfqq)) goto check_scheduled; -@@ -1482,7 +1915,15 @@ check_scheduled: +@@ -1481,7 +1945,15 @@ check_scheduled: BUG_ON(new_bfqq && bfqq->entity.parent != new_bfqq->entity.parent); @@ -2277,9 +2413,19 @@ index d1f648d..3bc1f8b 100644 bfq_may_be_close_cooperator(bfqq, new_bfqq)) return bfq_setup_merge(bfqq, new_bfqq); -@@ -1498,46 +1939,11 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq) +@@ -1490,53 +1962,24 @@ check_scheduled: + + 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 (!bfqq->bic) +- if (!bfqq->bic) ++ if (!bic) return; - if (bfqq->bic->wr_time_left) - /* @@ -2315,17 +2461,25 @@ index d1f648d..3bc1f8b 100644 - bfq_bfqq_end_wr(bfqq); - } else - bfqq->bic->wr_time_left = 0; -+ - bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); - bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); - bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); - bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); +- bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); +- bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); +- bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); +- bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); - bfqq->bic->cooperations++; - bfqq->bic->failed_cooperations = 0; ++ ++ 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) -@@ -1562,6 +1968,40 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, +@@ -1561,6 +2004,40 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, if (bfq_bfqq_IO_bound(bfqq)) bfq_mark_bfqq_IO_bound(new_bfqq); bfq_clear_bfqq_IO_bound(bfqq); @@ -2343,12 +2497,12 @@ index d1f648d..3bc1f8b 100644 + 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++; ++ bfqd->wr_busy_queues++; + new_bfqq->entity.prio_changed = 1; + bfq_log_bfqq(bfqd, new_bfqq, -+ "wr starting after merge with %d, " -+ "rais_max_time %u", ++ "wr start after merge with %d, rais_max_time %u", + bfqq->pid, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + } @@ -2366,7 +2520,7 @@ index d1f648d..3bc1f8b 100644 /* * Grab a reference to the bic, to prevent it from being destroyed * before being possibly touched by a bfq_split_bfqq(). -@@ -1588,18 +2028,6 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, +@@ -1587,20 +2064,8 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, bfq_put_queue(bfqq); } @@ -2382,10 +2536,32 @@ index d1f648d..3bc1f8b 100644 - } -} - - static int bfq_allow_merge(struct request_queue *q, struct request *rq, - struct bio *bio) +-static int bfq_allow_merge(struct request_queue *q, struct request *rq, +- struct bio *bio) ++static int bfq_allow_bio_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) { -@@ -1637,30 +2065,86 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_io_cq *bic; +@@ -1610,7 +2075,7 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, + * Disallow merge of a sync bio into an async request. + */ + if (bfq_bio_sync(bio) && !rq_is_sync(rq)) +- return 0; ++ return false; + + /* + * Lookup the bfqq that this bio will be queued with. Allow +@@ -1619,7 +2084,7 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, + */ + bic = bfq_bic_lookup(bfqd, current->io_context); + if (!bic) +- return 0; ++ return false; + + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); + /* +@@ -1636,30 +2101,107 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq, * to decide whether bio and rq can be merged. */ bfqq = new_bfqq; @@ -2397,6 +2573,12 @@ index d1f648d..3bc1f8b 100644 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. @@ -2407,6 +2589,7 @@ index d1f648d..3bc1f8b 100644 + struct bfq_queue *bfqq) +{ + unsigned int timeout_coeff; ++ + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) + timeout_coeff = 1; + else @@ -2437,9 +2620,10 @@ index d1f648d..3bc1f8b 100644 + BUG_ON(bfqq == bfqd->in_service_queue); + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); + -+ if (bfqq->wr_coeff > 1 && ++ 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)) { ++ time_is_before_jiffies(bfqq->budget_timeout)) { + /* + * For soft real-time queues, move the start + * of the weight-raising period forward by the @@ -2465,7 +2649,20 @@ index d1f648d..3bc1f8b 100644 + * request. + */ + bfqq->last_wr_start_finish += jiffies - -+ bfqq->budget_timeout; ++ 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); @@ -2478,7 +2675,7 @@ index d1f648d..3bc1f8b 100644 bfqd->in_service_queue = bfqq; } -@@ -1676,31 +2160,6 @@ static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) +@@ -1675,36 +2217,11 @@ static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) return bfqq; } @@ -2510,58 +2707,19 @@ index d1f648d..3bc1f8b 100644 static void bfq_arm_slice_timer(struct bfq_data *bfqd) { struct bfq_queue *bfqq = bfqd->in_service_queue; -@@ -1725,62 +2184,34 @@ static void bfq_arm_slice_timer(struct bfq_data *bfqd) - * 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 + struct bfq_io_cq *bic; +- unsigned long sl; ++ u32 sl; + + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); + +@@ -1728,59 +2245,343 @@ static void bfq_arm_slice_timer(struct bfq_data *bfqd) + 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 either - * has been seeky for long enough or has already proved to be - * constantly seeky. -- */ -- if (bfq_sample_valid(bfqq->seek_samples) && -- ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > -- bfq_max_budget(bfqq->bfqd) / 8) || -- bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 && -- bfq_symmetric_scenario(bfqd)) -- sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); -- else if (bfqq->wr_coeff > 1) -- sl = sl * 3; -- bfqd->last_idling_start = ktime_get(); -- mod_timer(&bfqd->idle_slice_timer, jiffies + sl); --#ifdef CONFIG_BFQ_GROUP_IOSCHED -- bfqg_stats_set_start_idle_time(bfqq_group(bfqq)); --#endif -- bfq_log(bfqd, "arm idle: %u/%u ms", -- jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); --} -- --/* -- * Set the maximum time for the in-service queue to consume its -- * budget. This prevents seeky processes from lowering the disk -- * throughput (always guaranteed with a time slice scheme as in CFQ). -- */ --static void bfq_set_budget_timeout(struct bfq_data *bfqd) --{ -- struct bfq_queue *bfqq = bfqd->in_service_queue; -- 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(); -- -- bfq_clear_bfqq_budget_new(bfqq); -- bfqq->budget_timeout = jiffies + -- bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; -+ */ -+ 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, @@ -2569,19 +2727,357 @@ index d1f648d..3bc1f8b 100644 + * its reserved share of the throughput (in particular, it is + * needed if the queue has a higher weight than some other + * queue). -+ */ + */ +- if (bfq_sample_valid(bfqq->seek_samples) && +- ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > +- bfq_max_budget(bfqq->bfqd) / 8) || +- bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 && + if (BFQQ_SEEKY(bfqq) && bfqq->wr_coeff == 1 && -+ bfq_symmetric_scenario(bfqd)) -+ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); + bfq_symmetric_scenario(bfqd)) +- sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); +- else if (bfqq->wr_coeff > 1) +- sl = sl * 3; ++ sl = min_t(u32, sl, BFQ_MIN_TT); ++ + bfqd->last_idling_start = ktime_get(); +- mod_timer(&bfqd->idle_slice_timer, jiffies + sl); +-#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ hrtimer_start(&bfqd->idle_slice_timer, ns_to_ktime(sl), ++ HRTIMER_MODE_REL); + bfqg_stats_set_start_idle_time(bfqq_group(bfqq)); +-#endif +- bfq_log(bfqd, "arm idle: %u/%u ms", +- jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); ++ bfq_log(bfqd, "arm idle: %ld/%ld ms", ++ sl / NSEC_PER_MSEC, bfqd->bfq_slice_idle / NSEC_PER_MSEC); + } + + /* +- * Set the maximum time for the in-service queue to consume its +- * budget. This prevents seeky processes from lowering the disk +- * throughput (always guaranteed with a time slice scheme as in CFQ). ++ * 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 void bfq_set_budget_timeout(struct bfq_data *bfqd) ++static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd) + { +- struct bfq_queue *bfqq = bfqd->in_service_queue; +- unsigned int timeout_coeff; ++ return (u64)bfqd->peak_rate * USEC_PER_MSEC * ++ jiffies_to_msecs(bfqd->bfq_timeout)>>BFQ_RATE_SHIFT; ++} + +- if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) +- timeout_coeff = 1; ++/* ++ * 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 +- timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ bfqd->last_rq_max_size = blk_rq_sectors(rq); + +- bfqd->last_budget_start = ktime_get(); ++ bfqd->delta_from_first = now_ns - bfqd->first_dispatch; + +- bfq_clear_bfqq_budget_new(bfqq); +- bfqq->budget_timeout = jiffies + +- bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; ++ 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); - bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", - jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * - timeout_coeff)); -+ bfqd->last_idling_start = ktime_get(); -+ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); -+ bfqg_stats_set_start_idle_time(bfqq_group(bfqq)); -+ bfq_log(bfqd, "arm idle: %u/%u ms", -+ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); ++ /* 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); } /* @@ -2594,10 +3090,11 @@ index d1f648d..3bc1f8b 100644 struct bfq_queue *bfqq = RQ_BFQQ(rq); /* -@@ -1794,15 +2225,9 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) +@@ -1794,15 +2595,10 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) * incrementing bfqq->dispatched. */ bfqq->dispatched++; ++ bfq_update_peak_rate(q->elevator->elevator_data, rq); + bfq_remove_request(rq); elv_dispatch_sort(q, rq); @@ -2611,12 +3108,12 @@ index d1f648d..3bc1f8b 100644 } /* -@@ -1822,18 +2247,12 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq) +@@ -1822,19 +2618,12 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq) rq = rq_entry_fifo(bfqq->fifo.next); - if (time_before(jiffies, rq->fifo_time)) -+ if (time_is_after_jiffies(rq->fifo_time)) ++ if (ktime_get_ns() < rq->fifo_time) return NULL; return rq; @@ -2625,13 +3122,14 @@ index d1f648d..3bc1f8b 100644 -static int bfq_bfqq_budget_left(struct bfq_queue *bfqq) -{ - struct bfq_entity *entity = &bfqq->entity; +- - return entity->budget - entity->service; -} - static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) { BUG_ON(bfqq != bfqd->in_service_queue); -@@ -1850,12 +2269,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -1851,12 +2640,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_mark_bfqq_split_coop(bfqq); if (RB_EMPTY_ROOT(&bfqq->sort_list)) { @@ -2653,7 +3151,7 @@ index d1f648d..3bc1f8b 100644 bfq_del_bfqq_busy(bfqd, bfqq, 1); } else { bfq_activate_bfqq(bfqd, bfqq); -@@ -1882,10 +2304,19 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, +@@ -1883,10 +2675,19 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, struct request *next_rq; int budget, min_budget; @@ -2675,7 +3173,7 @@ index d1f648d..3bc1f8b 100644 bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %d, budg left %d", bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); -@@ -1894,7 +2325,7 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, +@@ -1895,7 +2696,7 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); @@ -2684,7 +3182,7 @@ index d1f648d..3bc1f8b 100644 switch (reason) { /* * Caveat: in all the following cases we trade latency -@@ -1936,14 +2367,10 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, +@@ -1937,14 +2738,10 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, break; case BFQ_BFQQ_BUDGET_TIMEOUT: /* @@ -2703,7 +3201,7 @@ index d1f648d..3bc1f8b 100644 */ budget = min(budget * 2, bfqd->bfq_max_budget); break; -@@ -1960,17 +2387,49 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, +@@ -1961,17 +2758,49 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, budget = min(budget * 4, bfqd->bfq_max_budget); break; case BFQ_BFQQ_NO_MORE_REQUESTS: @@ -2760,7 +3258,7 @@ index d1f648d..3bc1f8b 100644 */ budget = bfqd->bfq_max_budget; -@@ -1981,65 +2440,105 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, +@@ -1982,160 +2811,120 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, bfqq->max_budget = min(bfqq->max_budget, bfqd->bfq_max_budget); /* @@ -2795,39 +3293,34 @@ index d1f648d..3bc1f8b 100644 } -static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) -+static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd) - { +-{ - unsigned long max_budget; - - /* - * The max_budget calculated when autotuning is equal to the +- /* +- * The max_budget calculated when autotuning is equal to the - * amount of sectors transfered in timeout_sync at the -+ * amount of sectors transfered in timeout at the - * estimated peak rate. - */ +- * estimated peak rate. +- */ - max_budget = (unsigned long)(peak_rate * 1000 * - timeout >> BFQ_RATE_SHIFT); - - return max_budget; -+ return bfqd->peak_rate * 1000 * jiffies_to_msecs(bfqd->bfq_timeout) >> -+ BFQ_RATE_SHIFT; - } - +-} +- /* - * In addition to updating the peak rate, checks whether the process - * is "slow", and returns 1 if so. This slow flag is used, in addition - * to the budget timeout, to reduce the amount of service provided to - * seeky processes, and hence reduce their chances to lower the - * throughput. See the code for more details. -+ * Update the read peak rate (quantity used for auto-tuning) as a -+ * function of the rate at which bfqq has been served, and check -+ * whether the process associated with bfqq is "slow". Return true if -+ * the process is slow. The slow flag is used, in addition to the -+ * budget timeout, to reduce the amount of service provided to seeky -+ * processes, and hence reduce their chances to lower the -+ * throughput. More details in the body of the function. ++ * 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: with devices with internal ++ * 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 @@ -2835,29 +3328,32 @@ index d1f648d..3bc1f8b 100644 + * 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, the device may be 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, -+ * as written above, this sum is the quantity used in this function to -+ * evaluate the peak rate. ++ * 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_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, +-static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, - bool compensate, enum bfqq_expiration reason) ++static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq, + bool compensate, enum bfqq_expiration reason, + unsigned long *delta_ms) { - u64 bw, usecs, expected, timeout; - ktime_t delta; -+ u64 bw, bwdiv10, delta_usecs, delta_ms_tmp; +- int update = 0; + ktime_t delta_ktime; - int update = 0; ++ u32 delta_usecs; + bool slow = BFQQ_SEEKY(bfqq); /* if delta too short, use seekyness */ - if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) @@ -2866,138 +3362,98 @@ index d1f648d..3bc1f8b 100644 if (compensate) - delta = bfqd->last_idling_start; -+ delta_ktime = bfqd->last_idling_start; - else +- else - delta = ktime_get(); - delta = ktime_sub(delta, bfqd->last_budget_start); - usecs = ktime_to_us(delta); -+ 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. */ +- +- /* Don't trust short/unrealistic values. */ - if (usecs < 100 || usecs >= LONG_MAX) - return false; -+ if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) { -+ if (blk_queue_nonrot(bfqd->queue)) -+ *delta_ms = BFQ_MIN_TT; /* give same worst-case -+ guarantees as -+ idling for seeky -+ */ -+ else /* Charge at least one seek */ -+ *delta_ms = jiffies_to_msecs(bfq_slice_idle); -+ return slow; -+ } -+ -+ delta_ms_tmp = delta_usecs; -+ do_div(delta_ms_tmp, 1000); -+ *delta_ms = delta_ms_tmp; - - /* - * Calculate the bandwidth for the last slice. We use a 64 bit -@@ -2048,32 +2547,51 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, - * and to avoid overflows. - */ - bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; +- +- /* +- * Calculate the bandwidth for the last slice. We use a 64 bit +- * value to store the peak rate, in sectors per usec in fixed +- * point math. We do so to have enough precision in the estimate +- * and to avoid overflows. +- */ +- bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; - do_div(bw, (unsigned long)usecs); - - timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); -+ do_div(bw, (unsigned long)delta_usecs); - -+ bfq_log(bfqd, "measured bw = %llu sects/sec", -+ (1000000*bw)>>BFQ_RATE_SHIFT); - /* - * Use only long (> 20ms) intervals to filter out spikes for - * the peak rate estimation. - */ +- +- /* +- * Use only long (> 20ms) intervals to filter out spikes for +- * the peak rate estimation. +- */ - if (usecs > 20000) { -+ if (delta_usecs > 20000) { -+ bool fully_sequential = bfqq->seek_history == 0; -+ /* -+ * Soft real-time queues are not good candidates for -+ * evaluating bw, as they are likely to be slow even -+ * if sequential. -+ */ -+ bool non_soft_rt = bfqq->wr_coeff == 1 || -+ bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time; -+ bool consumed_large_budget = -+ reason == BFQ_BFQQ_BUDGET_EXHAUSTED && -+ bfqq->entity.budget >= bfqd->bfq_max_budget * 2 / 3; -+ bool served_for_long_time = -+ reason == BFQ_BFQQ_BUDGET_TIMEOUT || -+ consumed_large_budget; -+ -+ BUG_ON(bfqq->seek_history == 0 && -+ hweight32(bfqq->seek_history) != 0); -+ - if (bw > bfqd->peak_rate || +- if (bw > bfqd->peak_rate || - (!BFQQ_SEEKY(bfqq) && - reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { - bfq_log(bfqd, "measured bw =%llu", bw); -+ (bfq_bfqq_sync(bfqq) && fully_sequential && non_soft_rt && -+ served_for_long_time)) { - /* - * To smooth oscillations use a low-pass filter with +- /* +- * To smooth oscillations use a low-pass filter with - * alpha=7/8, i.e., - * new_rate = (7/8) * old_rate + (1/8) * bw -+ * alpha=9/10, i.e., -+ * new_rate = (9/10) * old_rate + (1/10) * bw - */ +- */ - do_div(bw, 8); - if (bw == 0) - return 0; - bfqd->peak_rate *= 7; - do_div(bfqd->peak_rate, 8); - bfqd->peak_rate += bw; -+ bwdiv10 = bw; -+ do_div(bwdiv10, 10); -+ if (bwdiv10 == 0) -+ return false; /* bw too low to be used */ -+ bfqd->peak_rate *= 9; -+ do_div(bfqd->peak_rate, 10); -+ bfqd->peak_rate += bwdiv10; - update = 1; +- update = 1; - bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); -+ bfq_log(bfqd, "new peak_rate = %llu sects/sec", -+ (1000000*bfqd->peak_rate)>>BFQ_RATE_SHIFT); - } - - update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; -@@ -2086,9 +2604,8 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, - int dev_type = blk_queue_nonrot(bfqd->queue); - if (bfqd->bfq_user_max_budget == 0) { - bfqd->bfq_max_budget = +- } +- +- update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; +- +- if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) +- bfqd->peak_rate_samples++; +- +- if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && +- update) { +- int dev_type = blk_queue_nonrot(bfqd->queue); +- +- if (bfqd->bfq_user_max_budget == 0) { +- bfqd->bfq_max_budget = - bfq_calc_max_budget(bfqd->peak_rate, - timeout); - bfq_log(bfqd, "new max_budget=%d", -+ bfq_calc_max_budget(bfqd); -+ bfq_log(bfqd, "new max_budget = %d", - bfqd->bfq_max_budget); - } - if (bfqd->device_speed == BFQ_BFQD_FAST && -@@ -2102,38 +2619,35 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, - bfqd->RT_prod = R_fast[dev_type] * - T_fast[dev_type]; - } -+ bfq_log(bfqd, "dev_speed_class = %d (%d sects/sec), " -+ "thresh %d setcs/sec", -+ bfqd->device_speed, -+ bfqd->device_speed == BFQ_BFQD_FAST ? -+ (1000000*R_fast[dev_type])>>BFQ_RATE_SHIFT : -+ (1000000*R_slow[dev_type])>>BFQ_RATE_SHIFT, -+ (1000000*device_speed_thresh[dev_type])>> -+ BFQ_RATE_SHIFT); - } -+ /* -+ * Caveat: processes doing IO 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 bw has been lower than half -+ * of the estimated peak rate. -+ */ -+ slow = bw < bfqd->peak_rate / 2; +- 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]; +- } +- } ++ 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; } - /* @@ -3009,22 +3465,34 @@ index d1f648d..3bc1f8b 100644 - */ - if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) - return false; -- -- /* ++ *delta_ms = delta_usecs / USEC_PER_MSEC; + + /* - * A process is considered ``slow'' (i.e., seeky, so that we - * cannot treat it fairly in the service domain, as it would - * slow down too much the other processes) if, when a slice - * ends for whatever reason, it has received service at a - * rate that would not be high enough to complete the budget - * before the budget timeout expiration. -- */ ++ * Use only long (> 20ms) intervals to filter out excessive ++ * spikes in service rate estimation. + */ - expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; -+ bfq_log_bfqq(bfqd, bfqq, -+ "update_peak_rate: bw %llu sect/s, peak rate %llu, " -+ "slow %d", -+ (1000000*bw)>>BFQ_RATE_SHIFT, -+ (1000000*bfqd->peak_rate)>>BFQ_RATE_SHIFT, -+ bw < bfqd->peak_rate / 2); ++ 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); ++ } - /* - * Caveat: processes doing IO in the slower disk zones will @@ -3035,18 +3503,18 @@ index d1f648d..3bc1f8b 100644 - * process slow. - */ - return expected > (4 * bfqq->entity.budget) / 3; ++ bfq_log_bfqq(bfqd, bfqq, "bfq_bfqq_is_slow: slow %d", slow); ++ + return slow; } /* -@@ -2191,6 +2705,15 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -2193,20 +2982,35 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, 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", ++"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 / @@ -3055,22 +3523,23 @@ index d1f648d..3bc1f8b 100644 return max(bfqq->last_idle_bklogged + HZ * bfqq->service_from_backlogged / bfqd->bfq_wr_max_softrt_rate, -@@ -2198,13 +2721,21 @@ static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, - } - - /* -- * Return the largest-possible time instant such that, for as long as possible, -- * the current time will be lower than this time instant according to the macro -- * time_is_before_jiffies(). +- jiffies + bfqq->bfqd->bfq_slice_idle + 4); ++ 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 largest-possible time instant such that, for as long as possible, +- * the current time will be lower than this time instant according to the macro +- * time_is_before_jiffies(). + * Return the farthest past time instant according to jiffies + * macros. */ @@ -3082,7 +3551,7 @@ index d1f648d..3bc1f8b 100644 } /** -@@ -2214,28 +2745,24 @@ static unsigned long bfq_infinity_from_now(unsigned long now) +@@ -2216,28 +3020,24 @@ static unsigned long bfq_infinity_from_now(unsigned long now) * @compensate: if true, compensate for the time spent idling. * @reason: the reason causing the expiration. * @@ -3128,22 +3597,22 @@ index d1f648d..3bc1f8b 100644 */ static void bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq, -@@ -2243,40 +2770,53 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, +@@ -2245,41 +3045,52 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, enum bfqq_expiration reason) { bool slow; + unsigned long delta = 0; + struct bfq_entity *entity = &bfqq->entity; -+ + BUG_ON(bfqq != bfqd->in_service_queue); /* - * Update disk peak rate for autotuning and check whether the -+ * Update device peak rate for autotuning and check whether the - * process is slow (see bfq_update_peak_rate). +- * process is slow (see bfq_update_peak_rate). ++ * Check whether the process is slow (see bfq_bfqq_is_slow). */ - slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); -+ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason, &delta); ++ slow = bfq_bfqq_is_slow(bfqd, bfqq, compensate, reason, &delta); /* - * As above explained, 'punish' slow (i.e., seeky), timed-out @@ -3199,12 +3668,12 @@ index d1f648d..3bc1f8b 100644 + BUG_ON(bfqq->entity.budget < bfqq->entity.service); if (reason == BFQ_BFQQ_TOO_IDLE && -- bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) -+ entity->service <= 2 * entity->budget / 10 ) +- bfqq->entity.service <= 2 * bfqq->entity.budget / 10) ++ entity->service <= 2 * entity->budget / 10) bfq_clear_bfqq_IO_bound(bfqq); if (bfqd->low_latency && bfqq->wr_coeff == 1) -@@ -2285,19 +2825,23 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, +@@ -2288,19 +3099,23 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && RB_EMPTY_ROOT(&bfqq->sort_list)) { /* @@ -3236,7 +3705,7 @@ index d1f648d..3bc1f8b 100644 /* * The application is still waiting for the * completion of one or more requests: -@@ -2314,7 +2858,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, +@@ -2317,7 +3132,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, * happened to be in the past. */ bfqq->soft_rt_next_start = @@ -3245,7 +3714,7 @@ index d1f648d..3bc1f8b 100644 /* * Schedule an update of soft_rt_next_start to when * the task may be discovered to be isochronous. -@@ -2324,15 +2868,27 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, +@@ -2327,15 +3142,27 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, } bfq_log_bfqq(bfqd, bfqq, @@ -3275,7 +3744,7 @@ index d1f648d..3bc1f8b 100644 } /* -@@ -2342,20 +2898,17 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, +@@ -2345,20 +3172,17 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd, */ static bool bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) { @@ -3304,7 +3773,7 @@ index d1f648d..3bc1f8b 100644 static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) { bfq_log_bfqq(bfqq->bfqd, bfqq, -@@ -2397,10 +2950,12 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2400,10 +3224,12 @@ 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, @@ -3318,16 +3787,7 @@ index d1f648d..3bc1f8b 100644 /* * The next variable takes into account the cases where idling * boosts the throughput. -@@ -2422,7 +2977,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) - */ - idling_boosts_thr = !bfqd->hw_tag || - (!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) && -- bfq_bfqq_idle_window(bfqq)) ; -+ bfq_bfqq_idle_window(bfqq)); - - /* - * The value of the next variable, -@@ -2463,74 +3018,27 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2466,74 +3292,27 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) bfqd->wr_busy_queues == 0; /* @@ -3421,7 +3881,7 @@ index d1f648d..3bc1f8b 100644 * (i) each of these processes must get the same throughput as * the others; * (ii) all these processes have the same I/O pattern -@@ -2552,26 +3060,53 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2555,26 +3334,53 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) * 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 @@ -3495,7 +3955,7 @@ index d1f648d..3bc1f8b 100644 * * According to the above considerations, the next variable is * true (only) if sub-condition (i) holds. To compute the -@@ -2579,7 +3114,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2582,7 +3388,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) * the function bfq_symmetric_scenario(), but also check * whether bfqq is being weight-raised, because * bfq_symmetric_scenario() does not take into account also @@ -3504,7 +3964,7 @@ index d1f648d..3bc1f8b 100644 * bfq_weights_tree_add()). * * As a side note, it is worth considering that the above -@@ -2601,17 +3136,16 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2604,17 +3410,16 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) * 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 @@ -3527,13 +3987,15 @@ index d1f648d..3bc1f8b 100644 /* * We have now all the components we need to compute the return -@@ -2621,6 +3155,14 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2624,6 +3429,16 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) * 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 " -+ "wr_busy %d boosts %d IO-bound %d guar %d", -+ bfq_bfqq_sync(bfqq), idling_boosts_thr, ++ 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), @@ -3542,7 +4004,7 @@ index d1f648d..3bc1f8b 100644 return bfq_bfqq_sync(bfqq) && (idling_boosts_thr_without_issues || idling_needed_for_service_guarantees); -@@ -2632,7 +3174,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) +@@ -2635,7 +3450,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq) * 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. @@ -3551,17 +4013,57 @@ index d1f648d..3bc1f8b 100644 * why performing device idling is the best choice to boost the throughput * and preserve service guarantees when bfq_bfqq_may_idle itself * returns true. -@@ -2698,9 +3240,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) +@@ -2665,7 +3480,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); + + if (bfq_may_expire_for_budg_timeout(bfqq) && +- !timer_pending(&bfqd->idle_slice_timer) && ++ !hrtimer_active(&bfqd->idle_slice_timer) && + !bfq_bfqq_must_idle(bfqq)) + goto expire; + +@@ -2685,7 +3500,8 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + * not disable disk idling even when a new request + * arrives. + */ +- if (timer_pending(&bfqd->idle_slice_timer)) { ++ 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 +@@ -2700,10 +3516,8 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + * So we disable idling. */ bfq_clear_bfqq_wait_request(bfqq); - del_timer(&bfqd->idle_slice_timer); +- del_timer(&bfqd->idle_slice_timer); -#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); bfqg_stats_update_idle_time(bfqq_group(bfqq)); -#endif } goto keep_queue; } -@@ -2745,14 +3285,11 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -2714,7 +3528,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + * for a new request, or has requests waiting for a completion and + * may idle after their completion, then keep it anyway. + */ +- if (timer_pending(&bfqd->idle_slice_timer) || ++ if (hrtimer_active(&bfqd->idle_slice_timer) || + (bfqq->dispatched != 0 && bfq_bfqq_may_idle(bfqq))) { + bfqq = NULL; + goto keep_queue; +@@ -2736,6 +3550,9 @@ 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), +@@ -2749,22 +3566,30 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); /* @@ -3574,12 +4076,39 @@ index d1f648d..3bc1f8b 100644 + * time has elapsed from the beginning of this + * weight-raising period, then end weight raising. */ - if (bfq_bfqq_in_large_burst(bfqq) || +- if (bfq_bfqq_in_large_burst(bfqq) || - bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh || - time_is_before_jiffies(bfqq->last_wr_start_finish + - bfqq->wr_cur_max_time)) { - bfqq->last_wr_start_finish = jiffies; -@@ -2811,13 +3348,29 @@ static int bfq_dispatch_request(struct bfq_data *bfqd, +- time_is_before_jiffies(bfqq->last_wr_start_finish + +- bfqq->wr_cur_max_time)) { +- bfqq->last_wr_start_finish = jiffies; +- bfq_log_bfqq(bfqd, bfqq, +- "wrais ending at %lu, rais_max_time %u", +- bfqq->last_wr_start_finish, +- jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ 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 */ +@@ -2815,13 +3640,29 @@ static int bfq_dispatch_request(struct bfq_data *bfqd, */ if (!bfqd->rq_in_driver) bfq_schedule_dispatch(bfqd); @@ -3609,7 +4138,7 @@ index d1f648d..3bc1f8b 100644 bfq_update_wr_data(bfqd, bfqq); bfq_log_bfqq(bfqd, bfqq, -@@ -2833,9 +3386,7 @@ static int bfq_dispatch_request(struct bfq_data *bfqd, +@@ -2837,9 +3678,7 @@ static int bfq_dispatch_request(struct bfq_data *bfqd, bfqd->in_service_bic = RQ_BIC(rq); } @@ -3620,7 +4149,7 @@ index d1f648d..3bc1f8b 100644 goto expire; return dispatched; -@@ -2881,8 +3432,8 @@ static int bfq_forced_dispatch(struct bfq_data *bfqd) +@@ -2885,8 +3724,8 @@ static int bfq_forced_dispatch(struct bfq_data *bfqd) st = bfq_entity_service_tree(&bfqq->entity); dispatched += __bfq_forced_dispatch_bfqq(bfqq); @@ -3630,7 +4159,7 @@ index d1f648d..3bc1f8b 100644 bfq_forget_idle(st); } -@@ -2895,9 +3446,9 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) +@@ -2899,37 +3738,37 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) { struct bfq_data *bfqd = q->elevator->elevator_data; struct bfq_queue *bfqq; @@ -3641,7 +4170,25 @@ index d1f648d..3bc1f8b 100644 if (bfqd->busy_queues == 0) return 0; -@@ -2908,21 +3459,7 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) + 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; @@ -3662,9 +4209,13 @@ index d1f648d..3bc1f8b 100644 - return 0; + BUG_ON(bfqq->entity.budget < bfqq->entity.service); - bfq_clear_bfqq_wait_request(bfqq); - BUG_ON(timer_pending(&bfqd->idle_slice_timer)); -@@ -2933,6 +3470,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) +- bfq_clear_bfqq_wait_request(bfqq); +- BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ BUG_ON(bfq_bfqq_wait_request(bfqq)); + + if (!bfq_dispatch_request(bfqd, bfqq)) + return 0; +@@ -2937,6 +3776,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) bfq_log_bfqq(bfqd, bfqq, "dispatched %s request", bfq_bfqq_sync(bfqq) ? "sync" : "async"); @@ -3673,7 +4224,7 @@ index d1f648d..3bc1f8b 100644 return 1; } -@@ -2944,23 +3483,22 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) +@@ -2948,23 +3789,22 @@ static int bfq_dispatch_requests(struct request_queue *q, int force) */ static void bfq_put_queue(struct bfq_queue *bfqq) { @@ -3702,7 +4253,7 @@ index d1f648d..3bc1f8b 100644 if (bfq_bfqq_sync(bfqq)) /* -@@ -2973,7 +3511,7 @@ static void bfq_put_queue(struct bfq_queue *bfqq) +@@ -2977,7 +3817,7 @@ static void bfq_put_queue(struct bfq_queue *bfqq) */ hlist_del_init(&bfqq->burst_list_node); @@ -3711,7 +4262,7 @@ index d1f648d..3bc1f8b 100644 kmem_cache_free(bfq_pool, bfqq); #ifdef CONFIG_BFQ_GROUP_IOSCHED -@@ -3007,8 +3545,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -3011,8 +3851,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_schedule_dispatch(bfqd); } @@ -3721,10 +4272,12 @@ index d1f648d..3bc1f8b 100644 bfq_put_cooperator(bfqq); -@@ -3019,26 +3556,7 @@ static void bfq_init_icq(struct io_cq *icq) - { - struct bfq_io_cq *bic = icq_to_bic(icq); +@@ -3021,28 +3860,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) + static void bfq_init_icq(struct io_cq *icq) + { +- struct bfq_io_cq *bic = icq_to_bic(icq); +- - bic->ttime.last_end_request = jiffies; - /* - * A newly created bic indicates that the process has just @@ -3745,11 +4298,11 @@ index d1f648d..3bc1f8b 100644 - * as needing weight raising. - */ - bic->wr_time_left = 1; -+ bic->ttime.last_end_request = bfq_smallest_from_now(); ++ icq_to_bic(icq)->ttime.last_end_request = ktime_get_ns() - (1ULL<<32); } static void bfq_exit_icq(struct io_cq *icq) -@@ -3046,21 +3564,21 @@ static void bfq_exit_icq(struct io_cq *icq) +@@ -3050,21 +3868,21 @@ 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); @@ -3778,26 +4331,27 @@ index d1f648d..3bc1f8b 100644 } } -@@ -3068,7 +3586,8 @@ static void bfq_exit_icq(struct io_cq *icq) +@@ -3072,8 +3890,8 @@ static void bfq_exit_icq(struct io_cq *icq) * 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) +-static void +-bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) +static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, + struct bfq_io_cq *bic) { struct task_struct *tsk = current; int ioprio_class; -@@ -3100,7 +3619,7 @@ static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *b +@@ -3105,7 +3923,7 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) break; } - if (bfqq->new_ioprio < 0 || bfqq->new_ioprio >= IOPRIO_BE_NR) { + if (bfqq->new_ioprio >= IOPRIO_BE_NR) { - printk(KERN_CRIT "bfq_set_next_ioprio_data: new_ioprio %d\n", - bfqq->new_ioprio); + pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n", + bfqq->new_ioprio); BUG(); -@@ -3108,45 +3627,40 @@ static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *b +@@ -3113,45 +3931,40 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio); bfqq->entity.prio_changed = 1; @@ -3857,7 +4411,7 @@ index d1f648d..3bc1f8b 100644 } static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -@@ -3155,8 +3669,9 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3160,8 +3973,9 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, RB_CLEAR_NODE(&bfqq->entity.rb_node); INIT_LIST_HEAD(&bfqq->fifo); INIT_HLIST_NODE(&bfqq->burst_list_node); @@ -3868,7 +4422,7 @@ index d1f648d..3bc1f8b 100644 bfqq->bfqd = bfqd; if (bic) -@@ -3166,6 +3681,7 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3171,6 +3985,7 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, if (!bfq_class_idle(bfqq)) bfq_mark_bfqq_idle_window(bfqq); bfq_mark_bfqq_sync(bfqq); @@ -3876,14 +4430,16 @@ index d1f648d..3bc1f8b 100644 } else bfq_clear_bfqq_sync(bfqq); bfq_mark_bfqq_IO_bound(bfqq); -@@ -3175,72 +3691,17 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3180,72 +3995,19 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, bfqq->pid = pid; bfqq->wr_coeff = 1; - bfqq->last_wr_start_finish = 0; -+ bfqq->last_wr_start_finish = bfq_smallest_from_now(); ++ 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. @@ -3934,7 +4490,7 @@ index d1f648d..3bc1f8b 100644 - - if (bfqq) { - bfq_init_bfqq(bfqd, bfqq, bic, current->pid, -- is_sync); +- is_sync); - bfq_init_entity(&bfqq->entity, bfqg); - bfq_log_bfqq(bfqd, bfqq, "allocated"); - } else { @@ -3955,7 +4511,7 @@ index d1f648d..3bc1f8b 100644 } static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, -@@ -3263,44 +3724,60 @@ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, +@@ -3268,90 +4030,84 @@ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, } static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, @@ -3976,7 +4532,7 @@ index d1f648d..3bc1f8b 100644 - struct bfq_group *bfqg; + rcu_read_lock(); + -+ bfqg = bfq_find_set_group(bfqd,bio_blkcg(bio)); ++ bfqg = bfq_find_set_group(bfqd, bio_blkcg(bio)); + if (!bfqg) { + bfqq = &bfqd->oom_bfqq; + goto out; @@ -4034,14 +4590,33 @@ index d1f648d..3bc1f8b 100644 return bfqq; } -@@ -3316,37 +3793,21 @@ static void bfq_update_io_thinktime(struct bfq_data *bfqd, - bic->ttime.ttime_samples; + static void bfq_update_io_thinktime(struct bfq_data *bfqd, + struct bfq_io_cq *bic) + { +- unsigned long elapsed = jiffies - bic->ttime.last_end_request; +- unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); ++ 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); + +- bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; +- bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; +- bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / +- bic->ttime.ttime_samples; ++ 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) --{ ++static void ++bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) + { - sector_t sdist; - u64 total; - @@ -4060,32 +4635,22 @@ index d1f648d..3bc1f8b 100644 - sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); - else - sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); - +- - bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; - bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; - total = bfqq->seek_total + (bfqq->seek_samples/2); - do_div(total, bfqq->seek_samples); - bfqq->seek_mean = (sector_t)total; -+static void -+bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ struct request *rq) -+{ -+ sector_t sdist = 0; -+ if (bfqq->last_request_pos) { -+ if (bfqq->last_request_pos < blk_rq_pos(rq)) -+ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; -+ else -+ sdist = bfqq->last_request_pos - blk_rq_pos(rq); -+ } - +- - bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, - (u64)bfqq->seek_mean); + bfqq->seek_history <<= 1; -+ bfqq->seek_history |= (sdist > BFQQ_SEEK_THR); ++ bfqq->seek_history |= ++ get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR; } /* -@@ -3364,7 +3825,8 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, +@@ -3369,7 +4125,8 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, return; /* Idle window just restored, statistics are meaningless. */ @@ -4095,7 +4660,7 @@ index d1f648d..3bc1f8b 100644 return; enable_idle = bfq_bfqq_idle_window(bfqq); -@@ -3404,22 +3866,13 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3409,22 +4166,13 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, bfq_update_io_thinktime(bfqd, bic); bfq_update_io_seektime(bfqd, bfqq, rq); @@ -4114,13 +4679,13 @@ index d1f648d..3bc1f8b 100644 bfq_log_bfqq(bfqd, bfqq, - "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", - bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), -- (long long unsigned)bfqq->seek_mean); +- (unsigned long long) bfqq->seek_mean); + "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); -@@ -3433,14 +3886,15 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3438,14 +4186,15 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, * is small and the queue is not to be expired, then * just exit. * @@ -4144,17 +4709,19 @@ index d1f648d..3bc1f8b 100644 */ if (small_req && !budget_timeout) return; -@@ -3453,9 +3907,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -3457,10 +4206,8 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + * timer. */ bfq_clear_bfqq_wait_request(bfqq); - del_timer(&bfqd->idle_slice_timer); +- del_timer(&bfqd->idle_slice_timer); -#ifdef CONFIG_BFQ_GROUP_IOSCHED ++ hrtimer_try_to_cancel(&bfqd->idle_slice_timer); bfqg_stats_update_idle_time(bfqq_group(bfqq)); -#endif /* * The queue is not empty, because a new request just -@@ -3499,27 +3951,19 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq) +@@ -3504,28 +4251,21 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq) */ new_bfqq->allocated[rq_data_dir(rq)]++; bfqq->allocated[rq_data_dir(rq)]--; @@ -4182,10 +4749,13 @@ index d1f648d..3bc1f8b 100644 - */ - if (bfqq->bic) - bfqq->bic->wr_time_left = 0; - rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; +- rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(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); -@@ -3528,8 +3972,8 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq) + bfq_rq_enqueued(bfqd, bfqq, rq); +@@ -3533,8 +4273,8 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq) static void bfq_update_hw_tag(struct bfq_data *bfqd) { @@ -4196,11 +4766,13 @@ index d1f648d..3bc1f8b 100644 if (bfqd->hw_tag == 1) return; -@@ -3555,48 +3999,45 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq) +@@ -3560,48 +4300,85 @@ 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; - bool sync = bfq_bfqq_sync(bfqq); ++ u64 now_ns; ++ u32 delta_us; - bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", - blk_rq_sectors(rq), sync); @@ -4217,8 +4789,10 @@ index d1f648d..3bc1f8b 100644 -#ifdef CONFIG_BFQ_GROUP_IOSCHED bfqg_stats_update_completion(bfqq_group(bfqq), rq_start_time_ns(rq), - rq_io_start_time_ns(rq), rq->cmd_flags); +- rq_io_start_time_ns(rq), rq->cmd_flags); -#endif ++ 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)); @@ -4247,7 +4821,44 @@ index d1f648d..3bc1f8b 100644 - bfqd->sync_flight--; - RQ_BIC(rq)->ttime.last_end_request = jiffies; - } -+ RQ_BIC(rq)->ttime.last_end_request = jiffies; ++ 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 @@ -4265,7 +4876,7 @@ index d1f648d..3bc1f8b 100644 */ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && RB_EMPTY_ROOT(&bfqq->sort_list)) -@@ -3608,10 +4049,7 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq) +@@ -3613,10 +4390,7 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq) * or if we want to idle in case it has no pending requests. */ if (bfqd->in_service_queue == bfqq) { @@ -4277,7 +4888,25 @@ index d1f648d..3bc1f8b 100644 bfq_arm_slice_timer(bfqd); goto out; } else if (bfq_may_expire_for_budg_timeout(bfqq)) -@@ -3682,14 +4120,14 @@ static void bfq_put_request(struct request *rq) +@@ -3646,7 +4420,7 @@ static int __bfq_may_queue(struct bfq_queue *bfqq) + return ELV_MQUEUE_MAY; + } + +-static int bfq_may_queue(struct request_queue *q, int rw) ++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; +@@ -3663,7 +4437,7 @@ static int bfq_may_queue(struct request_queue *q, int rw) + if (!bic) + return ELV_MQUEUE_MAY; + +- bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); ++ bfqq = bic_to_bfqq(bic, rw_is_sync(op, op_flags)); + if (bfqq) + return __bfq_may_queue(bfqq); + +@@ -3687,14 +4461,14 @@ static void bfq_put_request(struct request *rq) rq->elv.priv[1] = NULL; bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", @@ -4294,7 +4923,7 @@ index d1f648d..3bc1f8b 100644 */ static struct bfq_queue * bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) -@@ -3727,11 +4165,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, +@@ -3732,11 +4506,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, unsigned long flags; bool split = false; @@ -4307,7 +4936,7 @@ index d1f648d..3bc1f8b 100644 if (!bic) goto queue_fail; -@@ -3741,23 +4176,47 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, +@@ -3746,23 +4517,47 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, new_queue: bfqq = bic_to_bfqq(bic, is_sync); if (!bfqq || bfqq == &bfqd->oom_bfqq) { @@ -4335,18 +4964,14 @@ index d1f648d..3bc1f8b 100644 + "large burst"); bfq_mark_bfqq_in_large_burst(bfqq); - else { -- bfq_clear_bfqq_in_large_burst(bfqq); -- if (bic->was_in_burst_list) -- hlist_add_head(&bfqq->burst_list_node, -- &bfqd->burst_list); + } 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); + 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; } @@ -4362,7 +4987,7 @@ index d1f648d..3bc1f8b 100644 bfqq = bfq_split_bfqq(bic, bfqq); split = true; if (!bfqq) -@@ -3766,9 +4225,8 @@ new_queue: +@@ -3771,9 +4566,8 @@ new_queue: } bfqq->allocated[rw]++; @@ -4374,7 +4999,7 @@ index d1f648d..3bc1f8b 100644 rq->elv.priv[0] = bic; rq->elv.priv[1] = bfqq; -@@ -3783,7 +4241,6 @@ new_queue: +@@ -3788,7 +4582,6 @@ new_queue: if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { bfqq->bic = bic; if (split) { @@ -4382,7 +5007,7 @@ index d1f648d..3bc1f8b 100644 /* * If the queue has just been split from a shared * queue, restore the idle window and the possible -@@ -3793,6 +4250,9 @@ new_queue: +@@ -3798,6 +4591,9 @@ new_queue: } } @@ -4392,7 +5017,39 @@ index d1f648d..3bc1f8b 100644 spin_unlock_irqrestore(q->queue_lock, flags); return 0; -@@ -3872,6 +4332,7 @@ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) +@@ -3824,9 +4620,10 @@ static void bfq_kick_queue(struct work_struct *work) + * Handler of the expiration of the timer running if the in-service queue + * is idling inside its time slice. + */ +-static void bfq_idle_slice_timer(unsigned long data) ++static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer) + { +- struct bfq_data *bfqd = (struct bfq_data *)data; ++ struct bfq_data *bfqd = container_of(timer, struct bfq_data, ++ idle_slice_timer); + struct bfq_queue *bfqq; + unsigned long flags; + enum bfqq_expiration reason; +@@ -3844,6 +4641,8 @@ static void bfq_idle_slice_timer(unsigned long data) + */ + 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 +@@ -3869,14 +4668,16 @@ 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) + { +- del_timer_sync(&bfqd->idle_slice_timer); ++ hrtimer_cancel(&bfqd->idle_slice_timer); cancel_work_sync(&bfqd->unplug_work); } @@ -4400,7 +5057,7 @@ index d1f648d..3bc1f8b 100644 static void __bfq_put_async_bfqq(struct bfq_data *bfqd, struct bfq_queue **bfqq_ptr) { -@@ -3880,9 +4341,9 @@ static void __bfq_put_async_bfqq(struct bfq_data *bfqd, +@@ -3885,9 +4686,9 @@ static void __bfq_put_async_bfqq(struct bfq_data *bfqd, bfq_log(bfqd, "put_async_bfqq: %p", bfqq); if (bfqq) { @@ -4412,7 +5069,7 @@ index d1f648d..3bc1f8b 100644 bfq_put_queue(bfqq); *bfqq_ptr = NULL; } -@@ -3904,6 +4365,7 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) +@@ -3909,6 +4710,7 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); } @@ -4420,16 +5077,18 @@ index d1f648d..3bc1f8b 100644 static void bfq_exit_queue(struct elevator_queue *e) { -@@ -3923,8 +4385,6 @@ static void bfq_exit_queue(struct elevator_queue *e) +@@ -3928,9 +4730,7 @@ static void bfq_exit_queue(struct elevator_queue *e) bfq_shutdown_timer_wq(bfqd); - synchronize_rcu(); - - BUG_ON(timer_pending(&bfqd->idle_slice_timer)); +- BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ BUG_ON(hrtimer_active(&bfqd->idle_slice_timer)); #ifdef CONFIG_BFQ_GROUP_IOSCHED -@@ -3973,11 +4433,14 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) + blkcg_deactivate_policy(q, &blkcg_policy_bfq); +@@ -3978,11 +4778,14 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) * will not attempt to free it. */ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0); @@ -4445,7 +5104,7 @@ index d1f648d..3bc1f8b 100644 /* * Trigger weight initialization, according to ioprio, at the * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio -@@ -3996,9 +4459,6 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) +@@ -4001,13 +4804,10 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) goto out_free; bfq_init_root_group(bfqd->root_group, bfqd); bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); @@ -4453,9 +5112,15 @@ index d1f648d..3bc1f8b 100644 - bfqd->active_numerous_groups = 0; -#endif - init_timer(&bfqd->idle_slice_timer); +- init_timer(&bfqd->idle_slice_timer); ++ hrtimer_init(&bfqd->idle_slice_timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); bfqd->idle_slice_timer.function = bfq_idle_slice_timer; -@@ -4023,20 +4483,19 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) +- bfqd->idle_slice_timer.data = (unsigned long)bfqd; + + bfqd->queue_weights_tree = RB_ROOT; + bfqd->group_weights_tree = RB_ROOT; +@@ -4028,20 +4828,19 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) bfqd->bfq_back_penalty = bfq_back_penalty; bfqd->bfq_slice_idle = bfq_slice_idle; bfqd->bfq_class_idle_last_service = 0; @@ -4483,7 +5148,7 @@ index d1f648d..3bc1f8b 100644 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); -@@ -4048,16 +4507,15 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) +@@ -4053,16 +4852,15 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) * video. */ bfqd->wr_busy_queues = 0; @@ -4504,9 +5169,36 @@ index d1f648d..3bc1f8b 100644 bfqd->device_speed = BFQ_BFQD_FAST; return 0; -@@ -4161,10 +4619,8 @@ SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); +@@ -4088,7 +4886,7 @@ static int __init bfq_slab_setup(void) + + static ssize_t bfq_var_show(unsigned int var, char *page) + { +- return sprintf(page, "%d\n", var); ++ return sprintf(page, "%u\n", var); + } + + static ssize_t bfq_var_store(unsigned long *var, const char *page, +@@ -4159,21 +4957,21 @@ static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) + static ssize_t __FUNC(struct elevator_queue *e, char *page) \ + { \ + struct bfq_data *bfqd = e->elevator_data; \ +- unsigned int __data = __VAR; \ +- if (__CONV) \ ++ 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], 1); +-SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); ++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, 1); +-SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); ++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_max_budget_async_rq_show, - bfqd->bfq_max_budget_async_rq, 0); @@ -4517,52 +5209,129 @@ index d1f648d..3bc1f8b 100644 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); -@@ -4199,10 +4655,6 @@ STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); +@@ -4183,6 +4981,17 @@ SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, + 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) \ +@@ -4194,24 +5003,22 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count) \ + __data = (MIN); \ + else if (__data > (MAX)) \ + __data = (MAX); \ +- if (__CONV) \ ++ 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, 1); ++ INT_MAX, 2); + STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, +- INT_MAX, 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, 1); +-STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); -STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, - 1, INT_MAX, 0); -STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, - INT_MAX, 1); ++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, -@@ -4224,10 +4676,8 @@ static ssize_t bfq_weights_store(struct elevator_queue *e, +@@ -4224,6 +5031,23 @@ STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, + INT_MAX, 0); + #undef STORE_FUNCTION - static unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) - { ++#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) +@@ -4231,16 +5055,6 @@ static ssize_t bfq_weights_store(struct elevator_queue *e, + return count; + } + +-static unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) +-{ - u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); - - if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) +- if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) - return bfq_calc_max_budget(bfqd->peak_rate, timeout); -+ return bfq_calc_max_budget(bfqd); - else - return bfq_default_max_budget; - } -@@ -4252,6 +4702,10 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e, +- else +- return bfq_default_max_budget; +-} +- + static ssize_t bfq_max_budget_store(struct elevator_queue *e, + const char *page, size_t count) + { +@@ -4249,7 +5063,7 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e, + int ret = bfq_var_store(&__data, (page), count); + + if (__data == 0) +- bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd); + else { + if (__data > INT_MAX) + __data = INT_MAX; +@@ -4261,6 +5075,10 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e, 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) { -@@ -4264,13 +4718,31 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, +@@ -4273,9 +5091,27 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, else if (__data > INT_MAX) __data = INT_MAX; - bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); + bfqd->bfq_timeout = msecs_to_jiffies(__data); if (bfqd->bfq_user_max_budget == 0) - bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); - - return ret; - } - +- bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ 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) +{ @@ -4573,20 +5342,18 @@ index d1f648d..3bc1f8b 100644 + if (__data > 1) + __data = 1; + if (!bfqd->strict_guarantees && __data == 1 -+ && bfqd->bfq_slice_idle < msecs_to_jiffies(8)) -+ bfqd->bfq_slice_idle = msecs_to_jiffies(8); ++ && 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) - { -@@ -4297,9 +4769,8 @@ static struct elv_fs_entry bfq_attrs[] = { + + return ret; + } +@@ -4305,10 +5141,10 @@ static struct elv_fs_entry bfq_attrs[] = { + 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(max_budget_async_rq), BFQ_ATTR(timeout_sync), @@ -4595,7 +5362,17 @@ index d1f648d..3bc1f8b 100644 BFQ_ATTR(low_latency), BFQ_ATTR(wr_coeff), BFQ_ATTR(wr_max_time), -@@ -4342,9 +4813,28 @@ static struct elevator_type iosched_bfq = { +@@ -4328,7 +5164,8 @@ static struct elevator_type iosched_bfq = { + #ifdef CONFIG_BFQ_GROUP_IOSCHED + .elevator_bio_merged_fn = bfq_bio_merged, + #endif +- .elevator_allow_merge_fn = bfq_allow_merge, ++ .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, +@@ -4351,18 +5188,28 @@ static struct elevator_type iosched_bfq = { .elevator_owner = THIS_MODULE, }; @@ -4620,32 +5397,46 @@ index d1f648d..3bc1f8b 100644 static int __init bfq_init(void) { int ret; -+ char msg[50] = "BFQ I/O-scheduler: v8r3"; - - /* - * Can be 0 on HZ < 1000 setups. -@@ -4352,9 +4842,6 @@ static int __init bfq_init(void) - if (bfq_slice_idle == 0) - bfq_slice_idle = 1; - +- +- /* +- * Can be 0 on HZ < 1000 setups. +- */ +- if (bfq_slice_idle == 0) +- bfq_slice_idle = 1; +- - if (bfq_timeout_async == 0) - bfq_timeout_async = 1; -- ++ char msg[50] = "BFQ I/O-scheduler: v8r4"; + #ifdef CONFIG_BFQ_GROUP_IOSCHED ret = blkcg_policy_register(&blkcg_policy_bfq); - if (ret) -@@ -4370,23 +4857,34 @@ static int __init bfq_init(void) - * installed on the reference devices (see the comments before the - * definitions of the two arrays). +@@ -4375,27 +5222,46 @@ static int __init bfq_init(void) + 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 two arrays). ++ * 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(2600); - T_slow[1] = msecs_to_jiffies(1000); - T_fast[0] = msecs_to_jiffies(5500); - T_fast[1] = msecs_to_jiffies(2000); -+ T_slow[0] = msecs_to_jiffies(3500); -+ T_slow[1] = msecs_to_jiffies(1500); -+ T_fast[0] = msecs_to_jiffies(8000); -+ T_fast[1] = msecs_to_jiffies(3000); ++ 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 @@ -4679,15 +5470,17 @@ index d1f648d..3bc1f8b 100644 return 0; diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index a64fec1..7d73b9d 100644 +index a5ed694..45d63d3 100644 --- a/block/bfq-sched.c +++ b/block/bfq-sched.c -@@ -7,9 +7,11 @@ +@@ -7,9 +7,13 @@ * Copyright (C) 2008 Fabio Checconi * Paolo Valente * - * Copyright (C) 2010 Paolo Valente -+ * Copyright (C) 2016 Paolo Valente ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente */ +static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); @@ -4695,7 +5488,7 @@ index a64fec1..7d73b9d 100644 #ifdef CONFIG_BFQ_GROUP_IOSCHED #define for_each_entity(entity) \ for (; entity ; entity = entity->parent) -@@ -22,8 +24,6 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, +@@ -22,8 +26,6 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, int extract, struct bfq_data *bfqd); @@ -4704,7 +5497,7 @@ index a64fec1..7d73b9d 100644 static void bfq_update_budget(struct bfq_entity *next_in_service) { struct bfq_entity *bfqg_entity; -@@ -48,6 +48,7 @@ static void bfq_update_budget(struct bfq_entity *next_in_service) +@@ -48,6 +50,7 @@ static void bfq_update_budget(struct bfq_entity *next_in_service) static int bfq_update_next_in_service(struct bfq_sched_data *sd) { struct bfq_entity *next_in_service; @@ -4712,13 +5505,13 @@ index a64fec1..7d73b9d 100644 if (sd->in_service_entity) /* will update/requeue at the end of service */ -@@ -65,14 +66,29 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd) +@@ -65,14 +68,29 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd) 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, @@ -4727,7 +5520,7 @@ index a64fec1..7d73b9d 100644 + 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"); + } @@ -4743,12 +5536,12 @@ index a64fec1..7d73b9d 100644 } #else #define for_each_entity(entity) \ -@@ -151,20 +167,35 @@ static u64 bfq_delta(unsigned long service, unsigned long weight) +@@ -151,20 +169,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight) 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 ; ++ unsigned long long start, finish, delta; + BUG_ON(entity->weight == 0); entity->finish = entity->start + @@ -4782,7 +5575,34 @@ index a64fec1..7d73b9d 100644 } } -@@ -386,8 +417,6 @@ static void bfq_active_insert(struct bfq_service_tree *st, +@@ -293,10 +327,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node) + 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 ++ } + } + + /** +@@ -386,8 +436,6 @@ static void bfq_active_insert(struct bfq_service_tree *st, BUG_ON(!bfqg); BUG_ON(!bfqd); bfqg->active_entities++; @@ -4791,16 +5611,16 @@ index a64fec1..7d73b9d 100644 } #endif } -@@ -399,7 +428,7 @@ static void bfq_active_insert(struct bfq_service_tree *st, +@@ -399,7 +447,7 @@ static void bfq_active_insert(struct bfq_service_tree *st, static unsigned short bfq_ioprio_to_weight(int ioprio) { BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); - return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - ioprio; -+ return (IOPRIO_BE_NR - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF ; ++ return (IOPRIO_BE_NR - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF; } /** -@@ -422,9 +451,9 @@ static void bfq_get_entity(struct bfq_entity *entity) +@@ -422,9 +470,9 @@ static void bfq_get_entity(struct bfq_entity *entity) struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); if (bfqq) { @@ -4812,7 +5632,7 @@ index a64fec1..7d73b9d 100644 } } -@@ -499,10 +528,6 @@ static void bfq_active_extract(struct bfq_service_tree *st, +@@ -499,10 +547,6 @@ static void bfq_active_extract(struct bfq_service_tree *st, BUG_ON(!bfqd); BUG_ON(!bfqg->active_entities); bfqg->active_entities--; @@ -4823,7 +5643,7 @@ index a64fec1..7d73b9d 100644 } #endif } -@@ -552,7 +577,7 @@ static void bfq_forget_entity(struct bfq_service_tree *st, +@@ -552,7 +596,7 @@ static void bfq_forget_entity(struct bfq_service_tree *st, if (bfqq) { sd = entity->sched_data; bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", @@ -4832,7 +5652,7 @@ index a64fec1..7d73b9d 100644 bfq_put_queue(bfqq); } } -@@ -602,7 +627,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, +@@ -602,7 +646,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, if (entity->prio_changed) { struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); @@ -4841,13 +5661,9 @@ index a64fec1..7d73b9d 100644 struct bfq_data *bfqd = NULL; struct rb_root *root; #ifdef CONFIG_BFQ_GROUP_IOSCHED -@@ -628,12 +653,14 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, - if (entity->new_weight != entity->orig_weight) { - if (entity->new_weight < BFQ_MIN_WEIGHT || +@@ -630,7 +674,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, entity->new_weight > BFQ_MAX_WEIGHT) { -- printk(KERN_CRIT "update_weight_prio: " -- "new_weight %d\n", -+ pr_crit("update_weight_prio: new_weight %d\n", + pr_crit("update_weight_prio: new_weight %d\n", entity->new_weight); - BUG(); + if (entity->new_weight < BFQ_MIN_WEIGHT) @@ -4855,12 +5671,9 @@ index a64fec1..7d73b9d 100644 + else + entity->new_weight = BFQ_MAX_WEIGHT; } -- entity->orig_weight = entity->new_weight; -+ entity->orig_weight = entity->new_weight; + entity->orig_weight = entity->new_weight; if (bfqq) - bfqq->ioprio = - bfq_weight_to_ioprio(entity->orig_weight); -@@ -662,6 +689,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, +@@ -661,6 +708,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, * associated with its new weight. */ if (prev_weight != new_weight) { @@ -4874,7 +5687,7 @@ index a64fec1..7d73b9d 100644 root = bfqq ? &bfqd->queue_weights_tree : &bfqd->group_weights_tree; bfq_weights_tree_remove(bfqd, entity, root); -@@ -708,7 +742,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) +@@ -707,7 +761,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) st = bfq_entity_service_tree(entity); entity->service += served; @@ -4883,7 +5696,7 @@ index a64fec1..7d73b9d 100644 BUG_ON(st->wsum == 0); st->vtime += bfq_delta(served, st->wsum); -@@ -717,31 +751,69 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) +@@ -716,31 +770,69 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served) #ifdef CONFIG_BFQ_GROUP_IOSCHED bfqg_stats_set_start_empty_time(bfqq_group(bfqq)); #endif @@ -4901,7 +5714,12 @@ index a64fec1..7d73b9d 100644 + * @bfqd: the device * @bfqq: the queue that needs a service update. + * @time_ms: the amount of time during which the queue has received service -+ * + * +- * When it's not possible to be fair in the service domain, because +- * a queue is not consuming its budget fast enough (the meaning of +- * fast depends on the timeout parameter), we charge it a full +- * budget. In this way we should obtain a sort of time-domain +- * fairness among all the seeky/slow queues. + * 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 @@ -4912,12 +5730,7 @@ index a64fec1..7d73b9d 100644 + * 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. - * -- * When it's not possible to be fair in the service domain, because -- * a queue is not consuming its budget fast enough (the meaning of -- * fast depends on the timeout parameter), we charge it a full -- * budget. In this way we should obtain a sort of time-domain -- * fairness among all the seeky/slow queues. ++ * + * 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 @@ -4937,17 +5750,17 @@ index a64fec1..7d73b9d 100644 + if (time_ms > 0 && time_ms < timeout_ms) + tot_serv_to_charge = + (bfqd->bfq_max_budget * time_ms) / timeout_ms; -+ + +- bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); + if (tot_serv_to_charge < entity->service) + tot_serv_to_charge = entity->service; -- bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); +- bfq_bfqq_served(bfqq, entity->budget - 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); - -- bfq_bfqq_served(bfqq, entity->budget - entity->service); ++ + /* Increase budget to avoid inconsistencies */ + if (tot_serv_to_charge > entity->budget) + entity->budget = tot_serv_to_charge; @@ -4963,7 +5776,7 @@ index a64fec1..7d73b9d 100644 * * 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 -@@ -749,11 +821,16 @@ static void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) +@@ -748,11 +840,16 @@ static void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) * service received if @entity is active) of the queue to calculate its * timestamps. */ @@ -4981,7 +5794,7 @@ index a64fec1..7d73b9d 100644 if (entity == sd->in_service_entity) { BUG_ON(entity->tree); /* -@@ -771,45 +848,133 @@ static void __bfq_activate_entity(struct bfq_entity *entity) +@@ -770,45 +867,133 @@ static void __bfq_activate_entity(struct bfq_entity *entity) * old start time. */ bfq_active_extract(st, entity); @@ -5003,9 +5816,7 @@ index a64fec1..7d73b9d 100644 - st->wsum += entity->weight; - bfq_get_entity(entity); + unsigned long long min_vstart; - -- BUG_ON(entity->on_st); -- entity->on_st = 1; ++ + /* See comments on bfq_fqq_update_budg_for_activation */ + if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) { + backshifted = true; @@ -5030,7 +5841,9 @@ index a64fec1..7d73b9d 100644 + entity->start = min_vstart; + st->wsum += entity->weight; + bfq_get_entity(entity); -+ + +- BUG_ON(entity->on_st); +- entity->on_st = 1; + BUG_ON(entity->on_st); + entity->on_st = 1; + } @@ -5135,7 +5948,7 @@ index a64fec1..7d73b9d 100644 sd = entity->sched_data; if (!bfq_update_next_in_service(sd)) -@@ -890,23 +1055,24 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) +@@ -889,23 +1074,24 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) if (!__bfq_deactivate_entity(entity, requeue)) /* @@ -5168,7 +5981,7 @@ index a64fec1..7d73b9d 100644 */ requeue = 1; } -@@ -916,9 +1082,23 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) +@@ -915,9 +1101,23 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) update: entity = parent; for_each_entity(entity) { @@ -5193,7 +6006,31 @@ index a64fec1..7d73b9d 100644 if (!bfq_update_next_in_service(sd)) break; } -@@ -997,10 +1177,11 @@ left: +@@ -943,7 +1143,23 @@ static void bfq_update_vtime(struct bfq_service_tree *st) + + 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); + } + } +@@ -996,10 +1212,11 @@ left: * Update the virtual time in @st and return the first eligible entity * it contains. */ @@ -5207,7 +6044,7 @@ index a64fec1..7d73b9d 100644 if (RB_EMPTY_ROOT(&st->active)) return NULL; -@@ -1009,6 +1190,24 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, +@@ -1008,6 +1225,24 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, entity = bfq_first_active_entity(st); BUG_ON(bfq_gt(entity->start, st->vtime)); @@ -5232,9 +6069,16 @@ index a64fec1..7d73b9d 100644 /* * If the chosen entity does not match with the sched_data's * next_in_service and we are forcedly serving the IDLE priority -@@ -1045,10 +1244,28 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, +@@ -1043,11 +1278,36 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, + 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) { + jiffies - bfqd->bfq_class_idle_last_service > @@ -5243,11 +6087,12 @@ index a64fec1..7d73b9d 100644 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) ; ++ BFQ_IOPRIO_CLASSES - 1); +#ifdef CONFIG_BFQ_GROUP_IOSCHED + else { + struct bfq_group *bfqg = @@ -5256,22 +6101,23 @@ index a64fec1..7d73b9d 100644 + bfq_log_bfqg(bfqd, bfqg, + "idle chosen from st %p %d", + st + BFQ_IOPRIO_CLASSES - 1, -+ 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; -@@ -1057,6 +1274,24 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, +@@ -1056,6 +1316,25 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, 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) ; ++ st + i, i); +#ifdef CONFIG_BFQ_GROUP_IOSCHED + else { + struct bfq_group *bfqg = @@ -5279,7 +6125,7 @@ index a64fec1..7d73b9d 100644 + + bfq_log_bfqg(bfqd, bfqg, + "chosen from st %p %d", -+ st + i, i) ; ++ st + i, i); + } +#endif + } @@ -5287,7 +6133,7 @@ index a64fec1..7d73b9d 100644 if (extract) { bfq_check_next_in_service(sd, entity); bfq_active_extract(st + i, entity); -@@ -1070,6 +1305,13 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, +@@ -1069,6 +1348,13 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, return entity; } @@ -5301,7 +6147,7 @@ index a64fec1..7d73b9d 100644 /* * Get next queue for service. */ -@@ -1086,7 +1328,36 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) +@@ -1085,7 +1371,36 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) sd = &bfqd->root_group->sched_data; for (; sd ; sd = entity->my_sched_data) { @@ -5338,7 +6184,18 @@ index a64fec1..7d73b9d 100644 BUG_ON(!entity); entity->service = 0; } -@@ -1113,9 +1384,7 @@ static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -1103,8 +1418,9 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) + 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; +- del_timer(&bfqd->idle_slice_timer); + } + + static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -1112,9 +1428,7 @@ static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, { struct bfq_entity *entity = &bfqq->entity; @@ -5349,7 +6206,7 @@ index a64fec1..7d73b9d 100644 bfq_deactivate_entity(entity, requeue); } -@@ -1123,12 +1392,11 @@ static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -1122,12 +1436,11 @@ static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) { struct bfq_entity *entity = &bfqq->entity; @@ -5364,7 +6221,7 @@ index a64fec1..7d73b9d 100644 /* * Called when the bfqq no longer has requests pending, remove it from -@@ -1139,6 +1407,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -1138,6 +1451,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, { BUG_ON(!bfq_bfqq_busy(bfqq)); BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); @@ -5372,7 +6229,7 @@ index a64fec1..7d73b9d 100644 bfq_log_bfqq(bfqd, bfqq, "del from busy"); -@@ -1147,27 +1416,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, +@@ -1146,27 +1460,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, BUG_ON(bfqd->busy_queues == 0); bfqd->busy_queues--; @@ -5397,16 +6254,16 @@ index a64fec1..7d73b9d 100644 -#ifdef CONFIG_BFQ_GROUP_IOSCHED bfqg_stats_update_dequeue(bfqq_group(bfqq)); -#endif - ++ + BUG_ON(bfqq->entity.budget < 0); -+ + bfq_deactivate_bfqq(bfqd, bfqq, requeue); + + BUG_ON(bfqq->entity.budget < 0); } /* -@@ -1185,16 +1447,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) +@@ -1184,16 +1491,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) bfq_mark_bfqq_busy(bfqq); bfqd->busy_queues++; @@ -5426,17 +6283,28 @@ index a64fec1..7d73b9d 100644 bfqd->wr_busy_queues++; } diff --git a/block/bfq.h b/block/bfq.h -index f73c942..49d28b9 100644 +index fcce855..ea1e7d8 100644 --- a/block/bfq.h +++ b/block/bfq.h @@ -1,5 +1,5 @@ /* - * BFQ-v7r11 for 4.5.0: data structures and common functions prototypes. -+ * BFQ-v8r3 for 4.7.0: data structures and common functions prototypes. ++ * BFQ-v8r4 for 4.8.0: data structures and common functions prototypes. * * Based on ideas and code from CFQ: * Copyright (C) 2003 Jens Axboe -@@ -28,20 +28,21 @@ +@@ -7,7 +7,9 @@ + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * +- * Copyright (C) 2010 Paolo Valente ++ * Copyright (C) 2015 Paolo Valente ++ * ++ * Copyright (C) 2016 Paolo Valente + */ + + #ifndef _BFQ_H +@@ -28,20 +30,21 @@ #define BFQ_DEFAULT_QUEUE_IOPRIO 4 @@ -5465,7 +6333,7 @@ index f73c942..49d28b9 100644 * * Each service tree represents a B-WF2Q+ scheduler on its own. Each * ioprio_class has its own independent scheduler, and so its own -@@ -49,27 +50,28 @@ struct bfq_entity; +@@ -49,27 +52,28 @@ struct bfq_entity; * of the containing bfqd. */ struct bfq_service_tree { @@ -5476,8 +6344,8 @@ index f73c942..49d28b9 100644 - struct bfq_entity *first_idle; - struct bfq_entity *last_idle; -+ struct bfq_entity *first_idle; /* idle entity with minimum F_i */ -+ struct bfq_entity *last_idle; /* idle entity with maximum F_i */ ++ struct bfq_entity *first_idle; /* idle entity with minimum F_i */ ++ struct bfq_entity *last_idle; /* idle entity with maximum F_i */ - u64 vtime; + u64 vtime; /* scheduler virtual time */ @@ -5504,7 +6372,7 @@ index f73c942..49d28b9 100644 * * The supported ioprio_classes are the same as in CFQ, in descending * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. -@@ -79,48 +81,29 @@ struct bfq_service_tree { +@@ -79,48 +83,29 @@ struct bfq_service_tree { * All the fields are protected by the queue lock of the containing bfqd. */ struct bfq_sched_data { @@ -5562,7 +6430,7 @@ index f73c942..49d28b9 100644 * * 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 -@@ -147,27 +130,52 @@ struct bfq_weight_counter { +@@ -147,27 +132,52 @@ struct bfq_weight_counter { * containing bfqd. */ struct bfq_entity { @@ -5600,7 +6468,7 @@ index f73c942..49d28b9 100644 + /* budget, used also to calculate F_i: F_i = S_i + @budget / @weight */ + int budget; + -+ unsigned int weight; /* weight of the queue */ ++ 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 */ @@ -5621,7 +6489,7 @@ index f73c942..49d28b9 100644 int prio_changed; }; -@@ -175,56 +183,6 @@ struct bfq_group; +@@ -175,56 +185,6 @@ struct bfq_group; /** * struct bfq_queue - leaf schedulable entity. @@ -5678,7 +6546,7 @@ index f73c942..49d28b9 100644 * * 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 -@@ -235,117 +193,163 @@ struct bfq_group; +@@ -235,117 +195,174 @@ struct bfq_group; * All the fields are protected by the queue lock of the containing bfqd. */ struct bfq_queue { @@ -5794,6 +6662,10 @@ index f73c942..49d28b9 100644 + * 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 */ }; @@ -5806,11 +6678,11 @@ index f73c942..49d28b9 100644 */ struct bfq_ttime { - unsigned long last_end_request; -+ unsigned long last_end_request; /* completion time of last request */ ++ u64 last_end_request; /* completion time of last request */ + -+ unsigned long ttime_total; /* total process thinktime */ ++ u64 ttime_total; /* total process thinktime */ + unsigned long ttime_samples; /* number of thinktime samples */ -+ unsigned long ttime_mean; /* average process thinktime */ ++ u64 ttime_mean; /* average process thinktime */ - unsigned long ttime_total; - unsigned long ttime_samples; @@ -5883,13 +6755,19 @@ index f73c942..49d28b9 100644 + * with another cooperating queue. + */ bool was_in_burst_list; -- + - unsigned int cooperations; - unsigned int failed_cooperations; ++ /* ++ * 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 { -@@ -354,224 +358,216 @@ enum bfq_device_speed { +@@ -354,224 +371,234 @@ enum bfq_device_speed { }; /** @@ -6000,10 +6878,10 @@ index f73c942..49d28b9 100644 - * @last_ins_in_burst. - * @burst_size: number of queues in the current burst of queue activations. - * @bfq_large_burst_thresh: maximum burst size above which the current -- * queue-activation burst is deemed as 'large'. +- * queue-activation burst is deemed as 'large'. - * @large_burst: true if a large queue-activation burst is in progress. - * @burst_list: head of the burst list (as for the above fields, more details -- * in the comments to the function bfq_handle_burst). +- * in the comments to the function bfq_handle_burst). - * @low_latency: if set to true, low-latency heuristics are enabled. - * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised - * queue is multiplied. @@ -6083,11 +6961,12 @@ index f73c942..49d28b9 100644 + /* number of budgets assigned */ int budgets_assigned; +- struct timer_list idle_slice_timer; + /* + * Timer set when idling (waiting) for the next request from + * the queue in service. + */ - struct timer_list idle_slice_timer; ++ struct hrtimer idle_slice_timer; + /* delayed work to restart dispatching on the request queue */ struct work_struct unplug_work; @@ -6099,14 +6978,33 @@ index f73c942..49d28b9 100644 + /* 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 used to calculate @peak_rate */ ++ ++ /* number of samples in current observation interval */ int peak_rate_samples; -+ /* peak transfer rate observed for a budget */ - u64 peak_rate; +- u64 peak_rate; ++ /* 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; @@ -6115,17 +7013,19 @@ index f73c942..49d28b9 100644 + /* list of all the bfq_queues idle on the device */ struct list_head idle_list; +- unsigned int bfq_fifo_expire[2]; + /* + * Timeout for async/sync requests; when it fires, requests + * are served in fifo order. + */ - unsigned int bfq_fifo_expire[2]; ++ 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; +- unsigned int bfq_slice_idle; + /* maximum idling time */ - unsigned int bfq_slice_idle; ++ u32 bfq_slice_idle; + /* last time CLASS_IDLE was served */ u64 bfq_class_idle_last_service; @@ -6250,7 +7150,7 @@ index f73c942..49d28b9 100644 BFQ_BFQQ_FLAG_IO_bound, /* * bfqq has timed-out at least once * having consumed at most 2/10 of -@@ -581,17 +577,12 @@ enum bfqq_state_flags { +@@ -581,17 +608,12 @@ enum bfqq_state_flags { * bfqq activated in a large burst, * see comments to bfq_handle_burst. */ @@ -6269,7 +7169,7 @@ index f73c942..49d28b9 100644 }; #define BFQ_BFQQ_FNS(name) \ -@@ -608,25 +599,53 @@ static int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ +@@ -608,25 +630,53 @@ static int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ } @@ -6328,7 +7228,7 @@ index f73c942..49d28b9 100644 #define bfq_log(bfqd, fmt, args...) \ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) -@@ -640,15 +659,12 @@ enum bfqq_expiration { +@@ -640,15 +690,12 @@ enum bfqq_expiration { 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 */ @@ -6346,7 +7246,7 @@ index f73c942..49d28b9 100644 /* number of ios merged */ struct blkg_rwstat merged; /* total time spent on device in ns, may not be accurate w/ queueing */ -@@ -657,12 +673,8 @@ struct bfqg_stats { +@@ -657,12 +704,8 @@ struct bfqg_stats { struct blkg_rwstat wait_time; /* number of IOs queued up */ struct blkg_rwstat queued; @@ -6359,7 +7259,7 @@ index f73c942..49d28b9 100644 /* sum of number of ios queued across all samples */ struct blkg_stat avg_queue_size_sum; /* count of samples taken for average */ -@@ -680,8 +692,10 @@ struct bfqg_stats { +@@ -680,8 +723,10 @@ struct bfqg_stats { uint64_t start_idle_time; uint64_t start_empty_time; uint16_t flags; @@ -6370,7 +7270,7 @@ index f73c942..49d28b9 100644 /* * struct bfq_group_data - per-blkcg storage for the blkio subsystem. * -@@ -692,7 +706,7 @@ struct bfq_group_data { +@@ -692,7 +737,7 @@ struct bfq_group_data { /* must be the first member */ struct blkcg_policy_data pd; @@ -6379,7 +7279,7 @@ index f73c942..49d28b9 100644 }; /** -@@ -712,7 +726,7 @@ struct bfq_group_data { +@@ -712,7 +757,7 @@ struct bfq_group_data { * 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 @@ -6388,7 +7288,7 @@ index f73c942..49d28b9 100644 * @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()). -@@ -745,7 +759,6 @@ struct bfq_group { +@@ -745,7 +790,6 @@ struct bfq_group { struct rb_root rq_pos_tree; struct bfqg_stats stats; @@ -6396,7 +7296,7 @@ index f73c942..49d28b9 100644 }; #else -@@ -767,11 +780,25 @@ bfq_entity_service_tree(struct bfq_entity *entity) +@@ -767,11 +811,25 @@ 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 : @@ -6409,7 +7309,7 @@ index f73c942..49d28b9 100644 + if (bfqq) + bfq_log_bfqq(bfqq->bfqd, bfqq, + "entity_service_tree %p %d", -+ sched_data->service_tree + idx, idx) ; ++ sched_data->service_tree + idx, idx); +#ifdef CONFIG_BFQ_GROUP_IOSCHED + else { + struct bfq_group *bfqg = @@ -6417,13 +7317,13 @@ index f73c942..49d28b9 100644 + + bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, + "entity_service_tree %p %d", -+ sched_data->service_tree + idx, idx) ; ++ sched_data->service_tree + idx, idx); + } +#endif return sched_data->service_tree + idx; } -@@ -791,47 +818,6 @@ static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) +@@ -791,47 +849,6 @@ static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) return bic->icq.q->elevator->elevator_data; } @@ -6471,7 +7371,7 @@ index f73c942..49d28b9 100644 #ifdef CONFIG_BFQ_GROUP_IOSCHED static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq) -@@ -857,11 +843,13 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio); +@@ -857,11 +874,13 @@ 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, @@ -6488,5 +7388,5 @@ index f73c942..49d28b9 100644 #endif /* _BFQ_H */ -- -1.9.1 +2.7.4 (Apple Git-66) diff --git a/patches/BLD-4.7.patch b/patches/BLD-4.7.patch index e252c45..987108b 100644 --- a/patches/BLD-4.7.patch +++ b/patches/BLD-4.7.patch @@ -347,15 +347,6 @@ index 97ee9ac..b2ddabc 100644 if (sched_feat(TTWU_QUEUE) && !cpus_share_cache(smp_processor_id(), cpu)) { sched_clock_cpu(cpu); /* sync clocks x-cpu */ ttwu_queue_remote(p, cpu, wake_flags); -@@ -2394,7 +2415,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) - * Silence PROVE_RCU. - */ - raw_spin_lock_irqsave(&p->pi_lock, flags); -- set_task_cpu(p, cpu); -+ __set_task_cpu(p, cpu); - raw_spin_unlock_irqrestore(&p->pi_lock, flags); - - #ifdef CONFIG_SCHED_INFO @@ -2941,7 +2962,14 @@ void sched_exec(void) int dest_cpu; diff --git a/patches/enable_additional_cpu_optimizations_for_gcc_v4.9+_kernel_v3.15+.patch b/patches/enable_additional_cpu_optimizations_for_gcc_v4.9+_kernel_v3.15+.patch index d9729b2..1c5200b 100644 --- a/patches/enable_additional_cpu_optimizations_for_gcc_v4.9+_kernel_v3.15+.patch +++ b/patches/enable_additional_cpu_optimizations_for_gcc_v4.9+_kernel_v3.15+.patch @@ -24,9 +24,13 @@ processors including: AMD K10-family, AMD Family 10h (Barcelona), AMD Family Family 15h (Steamroller), Family 16h (Jaguar), Intel 1st Gen Core i3/i5/i7 (Nehalem), Intel 1.5 Gen Core i3/i5/i7 (Westmere), Intel 2nd Gen Core i3/i5/i7 (Sandybridge), Intel 3rd Gen Core i3/i5/i7 (Ivybridge), Intel 4th Gen Core -i3/i5/i7 (Haswell), Intel 5th Gen Core i3/i5/i7 (Broadwell), and the low power -Silvermont series of Atom processors (Silvermont). It also offers the compiler -the 'native' flag. +i3/i5/i7 (Haswell), Intel 5th Gen Core i3/i5/i7 (Broadwell), Intel 6th Gen Core +i3/i5.i7 (Skylake), and the low power Silvermont series of Atom processors +(Silvermont). It also offers the compiler the 'native' flag. + +A warning to atom users: it is not recommended for you to compile with the +native option based on https://github.com/graysky2/kernel_gcc_patch/issues/15 +Instead, use the atom option. Small but real speed increases are measurable using a make endpoint comparing a generic kernel to one built with one of the respective microarchs. diff --git a/patches/hid-apple-patched.patch b/patches/hid-apple-patched.patch new file mode 100644 index 0000000..7a9210d --- /dev/null +++ b/patches/hid-apple-patched.patch @@ -0,0 +1,115 @@ +diff -urN a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +--- a/drivers/hid/hid-apple.c 2016-12-05 17:27:09.777555651 +0900 ++++ b/drivers/hid/hid-apple.c 2016-08-03 13:24:57.000000000 +0900 +@@ -52,6 +52,22 @@ + "(For people who want to keep Windows PC keyboard muscle memory. " + "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); + ++static unsigned int swap_fn_leftctrl; ++module_param(swap_fn_leftctrl, uint, 0644); ++MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " ++ "(For people who want to keep PC keyboard muscle memory. " ++ "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); ++ ++static unsigned int rightalt_as_rightctrl; ++module_param(rightalt_as_rightctrl, uint, 0644); ++MODULE_PARM_DESC(rightalt_as_rightctrl, "Use the right Alt key as a right Ctrl key. " ++ "[0] = as-is, Mac layout. 1 = Right Alt is right Ctrl"); ++ ++static unsigned int ejectcd_as_delete; ++module_param(ejectcd_as_delete, uint, 0644); ++MODULE_PARM_DESC(ejectcd_as_delete, "Use Eject-CD key as Delete key. " ++ "([0] = disabled, 1 = enabled)"); ++ + struct apple_sc { + unsigned long quirks; + unsigned int fn_on; +@@ -164,6 +180,21 @@ + { } + }; + ++static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { ++ { KEY_FN, KEY_LEFTCTRL }, ++ { } ++}; ++ ++static const struct apple_key_translation rightalt_as_rightctrl_keys[] = { ++ { KEY_RIGHTALT, KEY_RIGHTCTRL }, ++ { } ++}; ++ ++static const struct apple_key_translation ejectcd_as_delete_keys[] = { ++ { KEY_EJECTCD, KEY_DELETE }, ++ { } ++}; ++ + static const struct apple_key_translation *apple_find_translation( + const struct apple_key_translation *table, u16 from) + { +@@ -183,9 +214,11 @@ + struct apple_sc *asc = hid_get_drvdata(hid); + const struct apple_key_translation *trans, *table; + +- if (usage->code == KEY_FN) { ++ u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); ++ ++ if (usage->code == fn_keycode) { + asc->fn_on = !!value; +- input_event(input, usage->type, usage->code, value); ++ input_event(input, usage->type, KEY_FN, value); + return 1; + } + +@@ -264,6 +297,30 @@ + } + } + ++ if (swap_fn_leftctrl) { ++ trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code); ++ if (trans) { ++ input_event(input, usage->type, trans->to, value); ++ return 1; ++ } ++ } ++ ++ if (ejectcd_as_delete) { ++ trans = apple_find_translation(ejectcd_as_delete_keys, usage->code); ++ if (trans) { ++ input_event(input, usage->type, trans->to, value); ++ return 1; ++ } ++ } ++ ++ if (rightalt_as_rightctrl) { ++ trans = apple_find_translation(rightalt_as_rightctrl_keys, usage->code); ++ if (trans) { ++ input_event(input, usage->type, trans->to, value); ++ return 1; ++ } ++ } ++ + return 0; + } + +@@ -327,6 +384,21 @@ + + for (trans = apple_iso_keyboard; trans->from; trans++) + set_bit(trans->to, input->keybit); ++ ++ if (swap_fn_leftctrl) { ++ for (trans = swapped_fn_leftctrl_keys; trans->from; trans++) ++ set_bit(trans->to, input->keybit); ++ } ++ ++ if (ejectcd_as_delete) { ++ for (trans = ejectcd_as_delete_keys; trans->from; trans++) ++ set_bit(trans->to, input->keybit); ++ } ++ ++ if (rightalt_as_rightctrl) { ++ for (trans = rightalt_as_rightctrl_keys; trans->from; trans++) ++ set_bit(trans->to, input->keybit); ++ } + } + + static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, diff --git a/patches/uksm-0.1.2.5-for-v4.7.patch b/patches/uksm-0.1.2.5-for-v4.8.patch similarity index 97% rename from patches/uksm-0.1.2.5-for-v4.7.patch rename to patches/uksm-0.1.2.5-for-v4.8.patch index 4ba4cbb..d308f87 100644 --- a/patches/uksm-0.1.2.5-for-v4.7.patch +++ b/patches/uksm-0.1.2.5-for-v4.8.patch @@ -78,7 +78,7 @@ index 0000000..8fce86f +2015-04-22 UKSM 0.1.2.4 Fix a race condition that can sometimes trigger anonying warnings. +2016-09-10 UKSM 0.1.2.5 Fix a bug in dedup ratio calculation. diff --git a/fs/exec.c b/fs/exec.c -index 887c1c9..2bee16e 100644 +index 6fcfb3f..ef87e0f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -19,7 +19,7 @@ @@ -98,7 +98,7 @@ index 887c1c9..2bee16e 100644 #include #include -@@ -1273,6 +1274,7 @@ void setup_new_exec(struct linux_binprm * bprm) +@@ -1309,6 +1310,7 @@ void setup_new_exec(struct linux_binprm * bprm) /* An exec changes our domain. We are no longer part of the thread group */ current->self_exec_id++; @@ -107,7 +107,7 @@ index 887c1c9..2bee16e 100644 do_close_on_exec(current->files); } diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c -index 8372046..82aa2f4 100644 +index b9a8c81..9765269 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -89,6 +89,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) @@ -120,9 +120,9 @@ index 8372046..82aa2f4 100644 #ifdef CONFIG_QUICKLIST "Quicklists: %8lu kB\n" #endif -@@ -147,6 +150,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) +@@ -149,6 +152,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) K(global_page_state(NR_SLAB_UNRECLAIMABLE)), - global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024, + global_page_state(NR_KERNEL_STACK_KB), K(global_page_state(NR_PAGETABLE)), +#ifdef CONFIG_UKSM + K(global_page_state(NR_UKSM_ZERO_PAGES)), @@ -171,7 +171,7 @@ index d4458b6..172ceb9 100644 static inline unsigned long my_zero_pfn(unsigned long addr) diff --git a/include/linux/ksm.h b/include/linux/ksm.h -index 7ae216a..06861d8 100644 +index 481c8c4..5329b23 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h @@ -19,21 +19,6 @@ struct mem_cgroup; @@ -196,7 +196,7 @@ index 7ae216a..06861d8 100644 static inline struct stable_node *page_stable_node(struct page *page) { -@@ -64,6 +49,33 @@ struct page *ksm_might_need_to_copy(struct page *page, +@@ -63,6 +48,33 @@ struct page *ksm_might_need_to_copy(struct page *page, int rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc); void ksm_migrate_page(struct page *newpage, struct page *oldpage); @@ -230,7 +230,7 @@ index 7ae216a..06861d8 100644 #else /* !CONFIG_KSM */ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) -@@ -106,4 +118,6 @@ static inline void ksm_migrate_page(struct page *newpage, struct page *oldpage) +@@ -105,4 +117,6 @@ static inline void ksm_migrate_page(struct page *newpage, struct page *oldpage) #endif /* CONFIG_MMU */ #endif /* !CONFIG_KSM */ @@ -238,10 +238,10 @@ index 7ae216a..06861d8 100644 + #endif /* __LINUX_KSM_H */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index ca3e517..ae62e7d1 100644 +index 903200f..6c7d900 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -357,6 +357,9 @@ struct vm_area_struct { +@@ -358,6 +358,9 @@ struct vm_area_struct { struct mempolicy *vm_policy; /* NUMA policy for the VMA */ #endif struct vm_userfaultfd_ctx vm_userfaultfd_ctx; @@ -252,20 +252,20 @@ index ca3e517..ae62e7d1 100644 struct core_thread { diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index 02069c2..f7cce50 100644 +index 7f2ae99..89f7dd8 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h -@@ -153,6 +153,9 @@ enum zone_stat_item { - WORKINGSET_NODERECLAIM, - NR_ANON_TRANSPARENT_HUGEPAGES, +@@ -138,6 +138,9 @@ enum zone_stat_item { + NUMA_OTHER, /* allocation from other node */ + #endif NR_FREE_CMA_PAGES, +#ifdef CONFIG_UKSM + NR_UKSM_ZERO_PAGES, +#endif NR_VM_ZONE_STAT_ITEMS }; - /* -@@ -817,7 +820,7 @@ static inline int is_highmem_idx(enum zone_type idx) + enum node_stat_item { +@@ -869,7 +872,7 @@ static inline int is_highmem_idx(enum zone_type idx) } /** @@ -513,10 +513,10 @@ index 0000000..825f05e +#endif /* !CONFIG_UKSM */ +#endif /* __LINUX_UKSM_H */ diff --git a/kernel/fork.c b/kernel/fork.c -index aea4f4d..f93e114 100644 +index beb3172..569893a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -459,7 +459,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -457,7 +457,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) goto fail_nomem; charge = len; } @@ -525,7 +525,7 @@ index aea4f4d..f93e114 100644 if (!tmp) goto fail_nomem; *tmp = *mpnt; -@@ -512,7 +512,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -510,7 +510,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) __vma_link_rb(mm, tmp, rb_link, rb_parent); rb_link = &tmp->vm_rb.rb_right; rb_parent = &tmp->vm_rb; @@ -535,17 +535,17 @@ index aea4f4d..f93e114 100644 retval = copy_page_range(mm, oldmm, mpnt); diff --git a/lib/Makefile b/lib/Makefile -index ff6a7a6..ac0bb55 100644 +index 5dc77a8..b63a823 100644 --- a/lib/Makefile +++ b/lib/Makefile -@@ -20,7 +20,7 @@ KCOV_INSTRUMENT_dynamic_debug.o := n - KCOV_INSTRUMENT_hweight.o := n +@@ -17,7 +17,7 @@ KCOV_INSTRUMENT_debugobjects.o := n + KCOV_INSTRUMENT_dynamic_debug.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ - rbtree.o radix-tree.o dump_stack.o timerqueue.o\ + rbtree.o radix-tree.o sradix-tree.o dump_stack.o timerqueue.o\ idr.o int_sqrt.o extable.o \ - sha1.o md5.o irq_regs.o argv_split.o \ + sha1.o chacha20.o md5.o irq_regs.o argv_split.o \ flex_proportions.o ratelimit.o show_mem.o \ diff --git a/lib/sradix-tree.c b/lib/sradix-tree.c new file mode 100644 @@ -1030,10 +1030,10 @@ index 0000000..8d06329 + return 0; +} diff --git a/mm/Kconfig b/mm/Kconfig -index 3e2daef..165b60e 100644 +index be0ee11..64fd3bc 100644 --- a/mm/Kconfig +++ b/mm/Kconfig -@@ -332,6 +332,32 @@ config KSM +@@ -340,6 +340,32 @@ config KSM See Documentation/vm/ksm.txt for more information: KSM is inactive until a program has madvised that an area is MADV_MERGEABLE, and root has set /sys/kernel/mm/ksm/run to 1 (if CONFIG_SYSFS is set). @@ -1067,10 +1067,10 @@ index 3e2daef..165b60e 100644 config DEFAULT_MMAP_MIN_ADDR int "Low address space to protect from user allocation" diff --git a/mm/Makefile b/mm/Makefile -index 78c6f7d..7e7cd8a 100644 +index 2ca1faf..980c8dd 100644 --- a/mm/Makefile +++ b/mm/Makefile -@@ -63,7 +63,8 @@ obj-$(CONFIG_SPARSEMEM) += sparse.o +@@ -66,7 +66,8 @@ obj-$(CONFIG_SPARSEMEM) += sparse.o obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o obj-$(CONFIG_SLOB) += slob.o obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o @@ -1081,10 +1081,10 @@ index 78c6f7d..7e7cd8a 100644 obj-$(CONFIG_SLAB) += slab.o obj-$(CONFIG_SLUB) += slub.o diff --git a/mm/memory.c b/mm/memory.c -index 9e04681..02200d3 100644 +index 793fe0f..0464507 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -124,6 +124,28 @@ unsigned long highest_memmap_pfn __read_mostly; +@@ -124,6 +124,25 @@ unsigned long highest_memmap_pfn __read_mostly; EXPORT_SYMBOL(zero_pfn); @@ -1095,14 +1095,11 @@ index 9e04681..02200d3 100644 + +static int __init setup_uksm_zero_page(void) +{ -+ unsigned long addr; -+ addr = __get_free_pages(GFP_KERNEL | __GFP_ZERO, 0); -+ if (!addr) ++ empty_uksm_zero_page = alloc_pages(__GFP_ZERO & ~__GFP_MOVABLE, 0); ++ if (!empty_uksm_zero_page) + panic("Oh boy, that early out of memory?"); + -+ empty_uksm_zero_page = virt_to_page((void *) addr); + SetPageReserved(empty_uksm_zero_page); -+ + uksm_zero_pfn = page_to_pfn(empty_uksm_zero_page); + + return 0; @@ -1113,7 +1110,7 @@ index 9e04681..02200d3 100644 /* * CONFIG_MMU architectures set up ZERO_PAGE in their paging_init() */ -@@ -135,6 +157,7 @@ static int __init init_zero_pfn(void) +@@ -135,6 +154,7 @@ static int __init init_zero_pfn(void) core_initcall(init_zero_pfn); @@ -1121,7 +1118,7 @@ index 9e04681..02200d3 100644 #if defined(SPLIT_RSS_COUNTING) void sync_mm_rss(struct mm_struct *mm) -@@ -905,6 +928,11 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, +@@ -914,6 +934,11 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, get_page(page); page_dup_rmap(page, false); rss[mm_counter(page)]++; @@ -1133,7 +1130,7 @@ index 9e04681..02200d3 100644 } out_set_pte: -@@ -1138,8 +1166,10 @@ again: +@@ -1148,8 +1173,10 @@ again: ptent = ptep_get_and_clear_full(mm, addr, pte, tlb->fullmm); tlb_remove_tlb_entry(tlb, pte, addr); @@ -1145,7 +1142,7 @@ index 9e04681..02200d3 100644 if (!PageAnon(page)) { if (pte_dirty(ptent)) { -@@ -1995,8 +2025,10 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo +@@ -2010,8 +2037,10 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo clear_page(kaddr); kunmap_atomic(kaddr); flush_dcache_page(dst); @@ -1157,15 +1154,15 @@ index 9e04681..02200d3 100644 } static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma) -@@ -2141,6 +2173,7 @@ static int wp_page_copy(struct mm_struct *mm, struct vm_area_struct *vma, - new_page = alloc_zeroed_user_highpage_movable(vma, address); +@@ -2154,6 +2183,7 @@ static int wp_page_copy(struct fault_env *fe, pte_t orig_pte, + new_page = alloc_zeroed_user_highpage_movable(vma, fe->address); if (!new_page) goto oom; + uksm_cow_pte(vma, orig_pte); } else { - new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); - if (!new_page) -@@ -2166,7 +2199,9 @@ static int wp_page_copy(struct mm_struct *mm, struct vm_area_struct *vma, + new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, + fe->address); +@@ -2180,7 +2210,9 @@ static int wp_page_copy(struct fault_env *fe, pte_t orig_pte, mm_counter_file(old_page)); inc_mm_counter_fast(mm, MM_ANONPAGES); } @@ -1174,12 +1171,12 @@ index 9e04681..02200d3 100644 + uksm_unmap_zero_page(orig_pte); inc_mm_counter_fast(mm, MM_ANONPAGES); } - flush_cache_page(vma, address, pte_pfn(orig_pte)); + flush_cache_page(vma, fe->address, pte_pfn(orig_pte)); diff --git a/mm/mmap.c b/mm/mmap.c -index de2c176..ce60715 100644 +index ca9d91b..cf565b7 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -43,6 +43,7 @@ +@@ -44,6 +44,7 @@ #include #include #include @@ -1187,7 +1184,7 @@ index de2c176..ce60715 100644 #include #include -@@ -164,6 +165,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +@@ -165,6 +166,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) if (vma->vm_file) fput(vma->vm_file); mpol_put(vma_policy(vma)); @@ -1206,13 +1203,13 @@ index de2c176..ce60715 100644 + uksm_remove_vma(vma); + if (next && !insert) { - struct vm_area_struct *exporter = NULL; + struct vm_area_struct *exporter = NULL, *importer = NULL; + uksm_remove_vma(next); if (end >= next->vm_end) { /* * vma expands, overlapping all the next, and -@@ -725,6 +734,7 @@ again: remove_next = 1 + (end > next->vm_end); +@@ -733,6 +742,7 @@ again: end_changed = true; } vma->vm_pgoff = pgoff; @@ -1220,14 +1217,13 @@ index de2c176..ce60715 100644 if (adjust_next) { next->vm_start += adjust_next << PAGE_SHIFT; next->vm_pgoff += adjust_next; -@@ -795,16 +805,22 @@ again: remove_next = 1 + (end > next->vm_end); - * up the code too much to do both in one go. - */ - next = vma->vm_next; -- if (remove_next == 2) -+ if (remove_next == 2) { +@@ -806,16 +816,21 @@ again: + if (remove_next == 2) { + remove_next = 1; + end = next->vm_end; + uksm_remove_vma(next); goto again; +- } - else if (next) + } else if (next) { vma_gap_update(next); @@ -1246,7 +1242,7 @@ index de2c176..ce60715 100644 validate_mm(mm); return 0; -@@ -1196,6 +1212,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, +@@ -1207,6 +1222,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; @@ -1256,7 +1252,7 @@ index de2c176..ce60715 100644 if (flags & MAP_LOCKED) if (!can_do_mlock()) return -EPERM; -@@ -1534,6 +1553,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1545,6 +1563,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, allow_write_access(file); } file = vma->vm_file; @@ -1264,7 +1260,7 @@ index de2c176..ce60715 100644 out: perf_event_mmap(vma); -@@ -1575,6 +1595,7 @@ allow_write_and_free_vma: +@@ -1586,6 +1605,7 @@ allow_write_and_free_vma: if (vm_flags & VM_DENYWRITE) allow_write_access(file); free_vma: @@ -1272,7 +1268,7 @@ index de2c176..ce60715 100644 kmem_cache_free(vm_area_cachep, vma); unacct_error: if (charged) -@@ -2369,6 +2390,8 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2391,6 +2411,8 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -1281,7 +1277,7 @@ index de2c176..ce60715 100644 /* Success. */ if (!err) return 0; -@@ -2639,6 +2662,7 @@ static int do_brk(unsigned long addr, unsigned long len) +@@ -2669,6 +2691,7 @@ static int do_brk(unsigned long addr, unsigned long request) return 0; flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -1289,7 +1285,7 @@ index de2c176..ce60715 100644 error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED); if (offset_in_page(error)) -@@ -2696,6 +2720,7 @@ static int do_brk(unsigned long addr, unsigned long len) +@@ -2726,6 +2749,7 @@ static int do_brk(unsigned long addr, unsigned long request) vma->vm_flags = flags; vma->vm_page_prot = vm_get_page_prot(flags); vma_link(mm, vma, prev, rb_link, rb_parent); @@ -1297,7 +1293,7 @@ index de2c176..ce60715 100644 out: perf_event_mmap(vma); mm->total_vm += len >> PAGE_SHIFT; -@@ -2734,6 +2759,12 @@ void exit_mmap(struct mm_struct *mm) +@@ -2764,6 +2788,12 @@ void exit_mmap(struct mm_struct *mm) /* mm's last user has gone, and its about to be pulled down */ mmu_notifier_release(mm); @@ -1310,7 +1306,7 @@ index de2c176..ce60715 100644 if (mm->locked_vm) { vma = mm->mmap; while (vma) { -@@ -2769,6 +2800,11 @@ void exit_mmap(struct mm_struct *mm) +@@ -2799,6 +2829,11 @@ void exit_mmap(struct mm_struct *mm) vma = remove_vma(vma); } vm_unacct_memory(nr_accounted); @@ -1322,7 +1318,7 @@ index de2c176..ce60715 100644 } /* Insert vm structure into process list sorted by address -@@ -2878,6 +2914,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2908,6 +2943,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); *need_rmap_locks = false; @@ -1330,7 +1326,7 @@ index de2c176..ce60715 100644 } return new_vma; -@@ -3015,6 +3052,7 @@ static struct vm_area_struct *__install_special_mapping( +@@ -3055,6 +3091,7 @@ static struct vm_area_struct *__install_special_mapping( vm_stat_account(mm, vma->vm_flags, len >> PAGE_SHIFT); perf_event_mmap(vma); @@ -1339,7 +1335,7 @@ index de2c176..ce60715 100644 return vma; diff --git a/mm/rmap.c b/mm/rmap.c -index 701b93f..64ba784 100644 +index 1ef3640..1c40463 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1110,9 +1110,9 @@ void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma) @@ -1356,10 +1352,10 @@ index 701b93f..64ba784 100644 static void __page_set_anon_rmap(struct page *page, diff --git a/mm/uksm.c b/mm/uksm.c new file mode 100644 -index 0000000..039192f +index 0000000..56852a5 --- /dev/null +++ b/mm/uksm.c -@@ -0,0 +1,5518 @@ +@@ -0,0 +1,5524 @@ +/* + * Ultra KSM. Copyright (C) 2011-2012 Nai Xia + * @@ -1558,7 +1554,8 @@ index 0000000..039192f +static struct sradix_tree_node *slot_tree_node_alloc(void) +{ + struct slot_tree_node *p; -+ p = kmem_cache_zalloc(slot_tree_node_cachep, GFP_KERNEL); ++ p = kmem_cache_zalloc(slot_tree_node_cachep, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (!p) + return NULL; + @@ -2044,7 +2041,8 @@ index 0000000..039192f +static inline struct node_vma *alloc_node_vma(void) +{ + struct node_vma *node_vma; -+ node_vma = kmem_cache_zalloc(node_vma_cache, GFP_KERNEL); ++ node_vma = kmem_cache_zalloc(node_vma_cache, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (node_vma) { + INIT_HLIST_HEAD(&node_vma->rmap_hlist); + INIT_HLIST_NODE(&node_vma->hlist); @@ -2069,7 +2067,8 @@ index 0000000..039192f + if (!vma_slot_cache) + return NULL; + -+ slot = kmem_cache_zalloc(vma_slot_cache, GFP_KERNEL); ++ slot = kmem_cache_zalloc(vma_slot_cache, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (slot) { + INIT_LIST_HEAD(&slot->slot_list); + INIT_LIST_HEAD(&slot->dedup_list); @@ -2089,7 +2088,8 @@ index 0000000..039192f +{ + struct rmap_item *rmap_item; + -+ rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL); ++ rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (rmap_item) { + /* bug on lowest bit is not clear for flag use */ + BUG_ON(is_addr(rmap_item)); @@ -2106,7 +2106,8 @@ index 0000000..039192f +static inline struct stable_node *alloc_stable_node(void) +{ + struct stable_node *node; -+ node = kmem_cache_alloc(stable_node_cache, GFP_KERNEL | GFP_ATOMIC); ++ node = kmem_cache_alloc(stable_node_cache, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (!node) + return NULL; + @@ -2124,7 +2125,8 @@ index 0000000..039192f +static inline struct tree_node *alloc_tree_node(struct list_head *list) +{ + struct tree_node *node; -+ node = kmem_cache_zalloc(tree_node_cache, GFP_KERNEL | GFP_ATOMIC); ++ node = kmem_cache_zalloc(tree_node_cache, GFP_KERNEL | ++ __GFP_NORETRY | __GFP_NOWARN); + if (!node) + return NULL; + @@ -2241,8 +2243,8 @@ index 0000000..039192f + void *expected_mapping; + + page = pfn_to_page(stable_node->kpfn); -+ expected_mapping = (void *)stable_node + -+ (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); ++ expected_mapping = (void *)((unsigned long)stable_node | ++ PAGE_MAPPING_KSM); + rcu_read_lock(); + if (page->mapping != expected_mapping) + goto stale; @@ -2919,6 +2921,7 @@ index 0000000..039192f + (page_to_pfn(kpage) == zero_pfn)) { + entry = pte_mkspecial(entry); + dec_mm_counter(mm, MM_ANONPAGES); ++ inc_zone_page_state(page, NR_UKSM_ZERO_PAGES); + } else { + get_page(kpage); + page_add_anon_rmap(kpage, vma, addr, false); @@ -3986,7 +3989,7 @@ index 0000000..039192f + if (IS_ERR_OR_NULL(page)) + break; + if (PageKsm(page)) { -+ ret = handle_mm_fault(vma->vm_mm, vma, addr, ++ ret = handle_mm_fault(vma, addr, + FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE); + } else + ret = VM_FAULT_WRITE; @@ -4634,7 +4637,6 @@ index 0000000..039192f + if (find_zero_page_hash(hash_strength, *hash)) { + if (!cmp_and_merge_zero_page(slot->vma, page)) { + slot->pages_merged++; -+ inc_zone_page_state(page, NR_UKSM_ZERO_PAGES); + + /* For full-zero pages, no need to create rmap item */ + goto putpage; @@ -6879,12 +6881,12 @@ index 0000000..039192f +#endif + diff --git a/mm/vmstat.c b/mm/vmstat.c -index cb2a67b..912b86f 100644 +index 89cec42..188ce43 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c -@@ -733,6 +733,9 @@ const char * const vmstat_text[] = { - "nr_anon_transparent_hugepages", - "nr_free_cma", +@@ -974,6 +974,9 @@ const char * const vmstat_text[] = { + "nr_dirtied", + "nr_written", +#ifdef CONFIG_UKSM + "nr_uksm_zero_pages",