@@ -11,7 +11,7 @@
|
||||
<Summary>Kernel module allowing to switch dedicated graphics card on Optimus laptops</Summary>
|
||||
<Description>kernel module allowing to switch dedicated graphics card on Optimus laptops</Description>
|
||||
<BuildDependencies>
|
||||
<Dependency version="4.9.6">kernel-module-headers</Dependency>
|
||||
<Dependency version="4.9.35">kernel-module-headers</Dependency>
|
||||
</BuildDependencies>
|
||||
<Archive sha1sum="e282ee682d794e3962baa4dead01917c42571e78" type="targz">https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz</Archive>
|
||||
<Patches>
|
||||
@@ -20,7 +20,7 @@
|
||||
<Package>
|
||||
<Name>module-bbswitch</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency version="4.9.6">kernel</Dependency>
|
||||
<Dependency version="4.9.35">kernel</Dependency>
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
<Path fileType="library" permanent="true">/lib/modules</Path>
|
||||
@@ -34,6 +34,13 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="9">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>0.8</Version>
|
||||
<Comment>Rebuild for new kernel.</Comment>
|
||||
<Name>Kamil Atlı</Name>
|
||||
<Email>suvari@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="8">
|
||||
<Date>2017-02-01</Date>
|
||||
<Version>0.8</Version>
|
||||
@@ -91,4 +98,4 @@
|
||||
<Email>ertugrulerata@gmail.com</Email>
|
||||
</Update>
|
||||
</History>
|
||||
</PISI>
|
||||
</PISI>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<Archive sha1sum="8acbdbb4ab4ab4123d1773b616904798fbef9277" type="targz" target="i686">https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35-nodebug-pcoem-6_30_223_271.tar.gz</Archive>
|
||||
<Archive sha1sum="1f568bb989d175813c5631c6629d9479eae6f3be" type="targz" target="x86_64">https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz</Archive>
|
||||
<BuildDependencies>
|
||||
<Dependency version="4.9.6">kernel-module-headers</Dependency>
|
||||
<Dependency version="4.9.35">kernel-module-headers</Dependency>
|
||||
</BuildDependencies>
|
||||
<Patches>
|
||||
<Patch level="1">patch/license.patch</Patch>
|
||||
@@ -28,7 +28,7 @@
|
||||
<Package>
|
||||
<Name>module-broadcom-wl</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency version="4.9.6">kernel</Dependency>
|
||||
<Dependency version="4.9.35">kernel</Dependency>
|
||||
<Dependency release="current">module-broadcom-wl-userspace</Dependency>
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
@@ -57,6 +57,13 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="9">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>6.30.223.271</Version>
|
||||
<Comment>Rebuild for new kernel.</Comment>
|
||||
<Name>Kamil Atlı</Name>
|
||||
<Email>suvari@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="8">
|
||||
<Date>2017-02-01</Date>
|
||||
<Version>6.30.223.271</Version>
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
<Description>This package provides the kernel modules needed for mouse integration and shared folder support between VirtualBox host and guest systems.</Description>
|
||||
<Archive sha1sum="87b355193a306ed5516e8d348f7eb83854e08ac1" type="tarxz">https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-guest-5.1.14.tar.xz</Archive>
|
||||
<BuildDependencies>
|
||||
<Dependency version="4.9.6">kernel-module-headers</Dependency>
|
||||
<Dependency version="4.9.35">kernel-module-headers</Dependency>
|
||||
</BuildDependencies>
|
||||
</Source>
|
||||
|
||||
<Package>
|
||||
<Name>module-virtualbox-guest</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency version="4.9.6">kernel</Dependency>
|
||||
<Dependency version="4.9.35">kernel</Dependency>
|
||||
<Dependency>baselayout</Dependency>
|
||||
<Dependency version="current">module-virtualbox-guest-userspace</Dependency>
|
||||
</RuntimeDependencies>
|
||||
@@ -52,6 +52,13 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="15">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>5.1.14</Version>
|
||||
<Comment>Rebuild for new kernel.</Comment>
|
||||
<Name>Kamil Atlı</Name>
|
||||
<Email>suvari@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="14">
|
||||
<Date>2017-02-01</Date>
|
||||
<Version>5.1.14</Version>
|
||||
@@ -151,4 +158,4 @@
|
||||
<Email>ertugrulerata@gmail.com</Email>
|
||||
</Update>
|
||||
</History>
|
||||
</PISI>
|
||||
</PISI>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<Description>This package provides the kernel support for VirtualBox.</Description>
|
||||
<Archive sha1sum="7489ae3b501407d5ca2826e6ef1d5b2000e06154" type="tarxz">https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-5.1.14.tar.xz</Archive>
|
||||
<BuildDependencies>
|
||||
<Dependency version="4.9.6">kernel-module-headers</Dependency>
|
||||
<Dependency version="4.9.35">kernel-module-headers</Dependency>
|
||||
</BuildDependencies>
|
||||
<!--Patches>
|
||||
<Patch>vbox_linux-4.3.diff</Patch>
|
||||
@@ -24,7 +24,7 @@
|
||||
<Package>
|
||||
<Name>module-virtualbox</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency version="4.9.6">kernel</Dependency>
|
||||
<Dependency version="4.9.35">kernel</Dependency>
|
||||
<Dependency version="current">module-virtualbox-userspace</Dependency>
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
@@ -50,6 +50,13 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="15">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>5.1.14</Version>
|
||||
<Comment>Rebuild for new kernel.</Comment>
|
||||
<Name>Kamil Atlı</Name>
|
||||
<Email>suvari@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="14">
|
||||
<Date>2017-02-01</Date>
|
||||
<Version>5.1.14</Version>
|
||||
@@ -149,4 +156,4 @@
|
||||
<Email>ertugrulerata@gmail.com</Email>
|
||||
</Update>
|
||||
</History>
|
||||
</PISI>
|
||||
</PISI>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<Description>module-ndiswrapper allows you to use Windows XP drivers for WLAN cards without proper Linux drivers.</Description>
|
||||
<Archive sha1sum="20998237cf6d37b86391dc8736c10031110db578" type="targz">http://download.sourceforge.net/ndiswrapper/ndiswrapper-1.60.tar.gz</Archive>
|
||||
<BuildDependencies>
|
||||
<Dependency version="4.9.6">kernel-module-headers</Dependency>
|
||||
<Dependency version="4.9.35">kernel-module-headers</Dependency>
|
||||
</BuildDependencies>
|
||||
<Patches>
|
||||
<Patch>upstream.patch</Patch>
|
||||
@@ -25,7 +25,7 @@
|
||||
<Package>
|
||||
<Name>ndiswrapper</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency version="4.9.6">kernel</Dependency>
|
||||
<Dependency version="4.9.35">kernel</Dependency>
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
<Path fileType="library" permanent="true">/lib/modules</Path>
|
||||
@@ -41,6 +41,13 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="8">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>1.60</Version>
|
||||
<Comment>Rebuild for new kernel.</Comment>
|
||||
<Name>PisiLinux Community</Name>
|
||||
<Email>admin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="7">
|
||||
<Date>2017-02-07</Date>
|
||||
<Version>1.60</Version>
|
||||
|
||||
@@ -34,27 +34,3 @@ def install():
|
||||
|
||||
# Generate some module lists to use within mkinitramfs
|
||||
shelltools.system("./generate-module-list %s/lib/modules/%s" % (get.installDIR(), kerneltools.__getSuffix()))
|
||||
|
||||
|
||||
|
||||
#mkinitcpio default config
|
||||
pisitools.dodir("/etc/mkinitcpio.d")
|
||||
shelltools.touch("linux.preset")
|
||||
|
||||
|
||||
shelltools.echo("linux.preset", "# mkinitcpio preset file for the 'linux' package\n" +
|
||||
|
||||
'ALL_config="/etc/mkinitcpio.conf"\n'+
|
||||
|
||||
'ALL_kver="/boot/kernel-%s"\n\n'% get.srcVERSION() +
|
||||
"PRESETS=('default' 'fallback') \n\n" +
|
||||
'#default_config="/etc/mkinitcpio.conf"\n' +
|
||||
|
||||
'default_image="/boot/initramfs-%s.img"\n'% get.srcVERSION() +
|
||||
|
||||
'#default_options=""\n\n' +
|
||||
'#fallback_config="/etc/mkinitcpio.conf"\n'+
|
||||
'fallback_image="/boot/initramfs-%s-fallback.img"\n'% get.srcVERSION() +
|
||||
'fallback_options="-S autodetect"\n')
|
||||
|
||||
pisitools.insinto("/etc/mkinitcpio.d", "linux.preset")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86_64 4.9.6 Kernel Configuration
|
||||
# Linux/x86_64 4.9.35 Kernel Configuration
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_X86_64=y
|
||||
@@ -373,8 +373,7 @@ CONFIG_IOSCHED_NOOP=y
|
||||
CONFIG_IOSCHED_DEADLINE=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_IOSCHED_BFQ=m
|
||||
# CONFIG_BFQ_GROUP_IOSCHED is not set
|
||||
# CONFIG_IOSCHED_BFQ is not set
|
||||
CONFIG_DEFAULT_DEADLINE=y
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
# CONFIG_DEFAULT_NOOP is not set
|
||||
@@ -6935,7 +6934,8 @@ CONFIG_SBITMAP=y
|
||||
#
|
||||
# Unofficial 3rd party kernel additions
|
||||
#
|
||||
CONFIG_NDISWRAPPER=m
|
||||
CONFIG_VIAHSS=m
|
||||
CONFIG_RTL8723BS=m
|
||||
CONFIG_WLAN_SDIO=y
|
||||
CONFIG_NDISWRAPPER=m
|
||||
CONFIG_VIAHSS=m
|
||||
# CONFIG_RTL8812AU is not set
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
diff -Nuar linux-4.9.orig/fs/aufs/posix_acl.c linux-4.9/fs/aufs/posix_acl.c
|
||||
--- linux-4.9.orig/fs/aufs/posix_acl.c 2017-04-09 09:33:00.155052337 +0300
|
||||
+++ linux-4.9/fs/aufs/posix_acl.c 2017-04-09 09:34:03.760053849 +0300
|
||||
@@ -1,5 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Junjiro R. Okajima
|
||||
+ *
|
||||
+ * This program, aufs is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -36,6 +49,8 @@
|
||||
|
||||
/* always topmost only */
|
||||
acl = get_acl(h_inode, type);
|
||||
+ if (!IS_ERR_OR_NULL(acl))
|
||||
+ set_cached_acl(inode, type, acl);
|
||||
|
||||
out:
|
||||
ii_read_unlock(inode);
|
||||
@@ -77,8 +92,10 @@
|
||||
ssz = au_sxattr(dentry, inode, &arg);
|
||||
dput(dentry);
|
||||
err = ssz;
|
||||
- if (ssz >= 0)
|
||||
+ if (ssz >= 0) {
|
||||
err = 0;
|
||||
+ set_cached_acl(inode, type, acl);
|
||||
+ }
|
||||
|
||||
out:
|
||||
return err;
|
||||
diff -Nuar linux-4.9.orig/fs/aufs/xattr.c linux-4.9/fs/aufs/xattr.c
|
||||
--- linux-4.9.orig/fs/aufs/xattr.c 2017-04-09 09:33:00.160052337 +0300
|
||||
+++ linux-4.9/fs/aufs/xattr.c 2017-04-09 09:34:08.757053967 +0300
|
||||
@@ -1,11 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Junjiro R. Okajima
|
||||
+ *
|
||||
+ * This program, aufs is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* handling xattr functions
|
||||
*/
|
||||
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/posix_acl_xattr.h>
|
||||
#include <linux/xattr.h>
|
||||
#include "aufs.h"
|
||||
|
||||
@@ -309,7 +324,11 @@
|
||||
};
|
||||
|
||||
static const struct xattr_handler *au_xattr_handlers[] = {
|
||||
- &au_xattr_handler,
|
||||
+#ifdef CONFIG_FS_POSIX_ACL
|
||||
+ &posix_acl_access_xattr_handler,
|
||||
+ &posix_acl_default_xattr_handler,
|
||||
+#endif
|
||||
+ &au_xattr_handler, /* must be last */
|
||||
NULL
|
||||
};
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
-70
@@ -1,70 +0,0 @@
|
||||
From ca45663819accf038291dbe2d67ed66dc48d714c Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Backlund <tmb@mageia.org>
|
||||
Date: Sun, 29 Nov 2015 14:44:22 +0200
|
||||
Subject: [PATCH] Revert "x86/mm/mtrr: Remove kernel internal MTRR interfaces:
|
||||
unexport mtrr_add() and mtrr_del()"
|
||||
|
||||
This reverts commit 2baa891e42d84159b693eadd44f6fe1486285bdc.
|
||||
|
||||
It currently breaks nvidia304 driver.
|
||||
|
||||
Signed-of-by: Thomas Backlund <tmb@mageia.org>
|
||||
---
|
||||
Documentation/x86/mtrr.txt | 20 ++++----------------
|
||||
arch/x86/kernel/cpu/mtrr/main.c | 2 ++
|
||||
2 files changed, 6 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/Documentation/x86/mtrr.txt b/Documentation/x86/mtrr.txt
|
||||
index dc3e703..860bc3a 100644
|
||||
--- a/Documentation/x86/mtrr.txt
|
||||
+++ b/Documentation/x86/mtrr.txt
|
||||
@@ -6,22 +6,10 @@ Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
|
||||
===============================================================================
|
||||
Phasing out MTRR use
|
||||
|
||||
-MTRR use is replaced on modern x86 hardware with PAT. Direct MTRR use by
|
||||
-drivers on Linux is now completely phased out, device drivers should use
|
||||
-arch_phys_wc_add() in combination with ioremap_wc() to make MTRR effective on
|
||||
-non-PAT systems while a no-op but equally effective on PAT enabled systems.
|
||||
-
|
||||
-Even if Linux does not use MTRRs directly, some x86 platform firmware may still
|
||||
-set up MTRRs early before booting the OS. They do this as some platform
|
||||
-firmware may still have implemented access to MTRRs which would be controlled
|
||||
-and handled by the platform firmware directly. An example of platform use of
|
||||
-MTRRs is through the use of SMI handlers, one case could be for fan control,
|
||||
-the platform code would need uncachable access to some of its fan control
|
||||
-registers. Such platform access does not need any Operating System MTRR code in
|
||||
-place other than mtrr_type_lookup() to ensure any OS specific mapping requests
|
||||
-are aligned with platform MTRR setup. If MTRRs are only set up by the platform
|
||||
-firmware code though and the OS does not make any specific MTRR mapping
|
||||
-requests mtrr_type_lookup() should always return MTRR_TYPE_INVALID.
|
||||
+MTRR use is replaced on modern x86 hardware with PAT. Over time the only type
|
||||
+of effective MTRR that is expected to be supported will be for write-combining.
|
||||
+As MTRR use is phased out device drivers should use arch_phys_wc_add() to make
|
||||
+MTRR effective on non-PAT systems while a no-op on PAT enabled systems.
|
||||
|
||||
For details refer to Documentation/x86/pat.txt.
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
|
||||
index f891b47..e7ed0d8 100644
|
||||
--- a/arch/x86/kernel/cpu/mtrr/main.c
|
||||
+++ b/arch/x86/kernel/cpu/mtrr/main.c
|
||||
@@ -448,6 +448,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
|
||||
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
|
||||
increment);
|
||||
}
|
||||
+EXPORT_SYMBOL(mtrr_add);
|
||||
|
||||
/**
|
||||
* mtrr_del_page - delete a memory type region
|
||||
@@ -536,6 +537,7 @@ int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
return -EINVAL;
|
||||
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
|
||||
}
|
||||
+EXPORT_SYMBOL(mtrr_del);
|
||||
|
||||
/**
|
||||
* arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable
|
||||
--
|
||||
2.3.10
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
From 760235cd6ca8ae0d7509055d75a0f1d8b3c60668 Mon Sep 17 00:00:00 2001
|
||||
From: Lv Zheng <lv.zheng@intel.com>
|
||||
Date: Wed, 30 Nov 2016 15:21:12 +0800
|
||||
Subject: [PATCH] ACPICA: Events: Fix acpi_ev_initialize_region() return value
|
||||
|
||||
ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8
|
||||
|
||||
This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST
|
||||
from it so that, not only in acpi_ds_load2_end_op(), but all places invoking
|
||||
this function won't emit exceptions. The exception can be seen in
|
||||
acpi_ds_initialize_objects() when certain table loading mode is chosen.
|
||||
|
||||
This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region()
|
||||
as this function will always be invoked with interpreter lock held now, and
|
||||
the lock granularity has been tuned to lock around _REG execution, thus it
|
||||
is now handled by acpi_ex_exit_interpreter(). Lv Zheng.
|
||||
|
||||
Link: https://github.com/acpica/acpica/commit/543342ab
|
||||
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
|
||||
Signed-off-by: Bob Moore <robert.moore@intel.com>
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
---
|
||||
drivers/acpi/acpica/acevents.h | 4 +--
|
||||
drivers/acpi/acpica/dsopcode.c | 2 +-
|
||||
drivers/acpi/acpica/dswload2.c | 13 +---------
|
||||
drivers/acpi/acpica/evrgnini.c | 59 +++++++++++++++++-------------------------
|
||||
4 files changed, 27 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
|
||||
index 92fa47c..8a0049d 100644
|
||||
--- a/drivers/acpi/acpica/acevents.h
|
||||
+++ b/drivers/acpi/acpica/acevents.h
|
||||
@@ -243,9 +243,7 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
u32 function,
|
||||
void *handler_context, void **region_context);
|
||||
|
||||
-acpi_status
|
||||
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
- u8 acpi_ns_locked);
|
||||
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
|
||||
|
||||
/*
|
||||
* evsci - SCI (System Control Interrupt) handling/dispatch
|
||||
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
|
||||
index 4cc9d98..77fd7c8 100644
|
||||
--- a/drivers/acpi/acpica/dsopcode.c
|
||||
+++ b/drivers/acpi/acpica/dsopcode.c
|
||||
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
|
||||
|
||||
/* Namespace is NOT locked */
|
||||
|
||||
- status = acpi_ev_initialize_region(obj_desc, FALSE);
|
||||
+ status = acpi_ev_initialize_region(obj_desc);
|
||||
return (status);
|
||||
}
|
||||
|
||||
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
|
||||
index e362182..651f35a 100644
|
||||
--- a/drivers/acpi/acpica/dswload2.c
|
||||
+++ b/drivers/acpi/acpica/dswload2.c
|
||||
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
|
||||
status =
|
||||
acpi_ev_initialize_region
|
||||
- (acpi_ns_get_attached_object(node), FALSE);
|
||||
-
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- /*
|
||||
- * If AE_NOT_EXIST is returned, it is not fatal
|
||||
- * because many regions get created before a handler
|
||||
- * is installed for said region.
|
||||
- */
|
||||
- if (AE_NOT_EXIST == status) {
|
||||
- status = AE_OK;
|
||||
- }
|
||||
- }
|
||||
+ (acpi_ns_get_attached_object(node));
|
||||
break;
|
||||
|
||||
case AML_NAME_OP:
|
||||
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
|
||||
index 75ddd16..a909225 100644
|
||||
--- a/drivers/acpi/acpica/evrgnini.c
|
||||
+++ b/drivers/acpi/acpica/evrgnini.c
|
||||
@@ -479,7 +479,6 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
* FUNCTION: acpi_ev_initialize_region
|
||||
*
|
||||
* PARAMETERS: region_obj - Region we are initializing
|
||||
- * acpi_ns_locked - Is namespace locked?
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
@@ -497,19 +496,28 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
* MUTEX: Interpreter should be unlocked, because we may run the _REG
|
||||
* method for this region.
|
||||
*
|
||||
+ * NOTE: Possible incompliance:
|
||||
+ * There is a behavior conflict in automatic _REG execution:
|
||||
+ * 1. When the interpreter is evaluating a method, we can only
|
||||
+ * automatically run _REG for the following case:
|
||||
+ * operation_region (OPR1, 0x80, 0x1000010, 0x4)
|
||||
+ * 2. When the interpreter is loading a table, we can also
|
||||
+ * automatically run _REG for the following case:
|
||||
+ * operation_region (OPR1, 0x80, 0x1000010, 0x4)
|
||||
+ * Though this may not be compliant to the de-facto standard, the
|
||||
+ * logic is kept in order not to trigger regressions. And keeping
|
||||
+ * this logic should be taken care by the caller of this function.
|
||||
+ *
|
||||
******************************************************************************/
|
||||
|
||||
-acpi_status
|
||||
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
- u8 acpi_ns_locked)
|
||||
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
|
||||
{
|
||||
union acpi_operand_object *handler_obj;
|
||||
union acpi_operand_object *obj_desc;
|
||||
acpi_adr_space_type space_id;
|
||||
struct acpi_namespace_node *node;
|
||||
- acpi_status status;
|
||||
|
||||
- ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
|
||||
+ ACPI_FUNCTION_TRACE(ev_initialize_region);
|
||||
|
||||
if (!region_obj) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
@@ -580,39 +588,17 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
handler_obj, region_obj,
|
||||
obj_desc));
|
||||
|
||||
- status =
|
||||
- acpi_ev_attach_region(handler_obj,
|
||||
- region_obj,
|
||||
- acpi_ns_locked);
|
||||
+ (void)acpi_ev_attach_region(handler_obj,
|
||||
+ region_obj, FALSE);
|
||||
|
||||
/*
|
||||
* Tell all users that this region is usable by
|
||||
* running the _REG method
|
||||
*/
|
||||
- if (acpi_ns_locked) {
|
||||
- status =
|
||||
- acpi_ut_release_mutex
|
||||
- (ACPI_MTX_NAMESPACE);
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- return_ACPI_STATUS(status);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
acpi_ex_exit_interpreter();
|
||||
- status =
|
||||
- acpi_ev_execute_reg_method(region_obj,
|
||||
- ACPI_REG_CONNECT);
|
||||
+ (void)acpi_ev_execute_reg_method(region_obj,
|
||||
+ ACPI_REG_CONNECT);
|
||||
acpi_ex_enter_interpreter();
|
||||
-
|
||||
- if (acpi_ns_locked) {
|
||||
- status =
|
||||
- acpi_ut_acquire_mutex
|
||||
- (ACPI_MTX_NAMESPACE);
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- return_ACPI_STATUS(status);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
}
|
||||
@@ -622,12 +608,15 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
- /* If we get here, there is no handler for this region */
|
||||
-
|
||||
+ /*
|
||||
+ * If we get here, there is no handler for this region. This is not
|
||||
+ * fatal because many regions get created before a handler is installed
|
||||
+ * for said region.
|
||||
+ */
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||
"No handler for RegionType %s(%X) (RegionObj %p)\n",
|
||||
acpi_ut_get_region_name(space_id), space_id,
|
||||
region_obj));
|
||||
|
||||
- return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
+ return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+192
-170
@@ -1,9 +1,13 @@
|
||||
From 3e3791c0b4ef3b2067f8454e58001af8e3da3840 Mon Sep 17 00:00:00 2001
|
||||
From 0432a5c7bfc4a11531c1e58f574c733a2552f149 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Valente <paolo.valente@linaro.org>
|
||||
Date: Tue, 17 May 2016 08:28:04 +0200
|
||||
Subject: [PATCH 4/4] Turn into BFQ-v8r6 for 4.9.0
|
||||
Subject: [PATCH 4/4] Turn into BFQ-v8r7 for 4.9.0
|
||||
|
||||
CHANGELOG from v8r4 to v8r6
|
||||
CHANGELOG from v8r4 to v8r7
|
||||
|
||||
BFQ v8r7
|
||||
|
||||
BUGFIX: make BFQ compile also without hierarchical support
|
||||
|
||||
BFQ v8r6
|
||||
|
||||
@@ -125,9 +129,9 @@ Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||
block/Kconfig.iosched | 18 +-
|
||||
block/bfq-cgroup.c | 501 +++---
|
||||
block/bfq-iosched.c | 3278 ++++++++++++++++++++++-------------
|
||||
block/bfq-sched.c | 1270 +++++++++++---
|
||||
block/bfq-sched.c | 1288 +++++++++++---
|
||||
block/bfq.h | 800 +++++----
|
||||
7 files changed, 4310 insertions(+), 2089 deletions(-)
|
||||
7 files changed, 4320 insertions(+), 2097 deletions(-)
|
||||
create mode 100644 Documentation/block/bfq-iosched.txt
|
||||
|
||||
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX
|
||||
@@ -1601,7 +1605,7 @@ index 0367996..bbaecd0 100644
|
||||
|
||||
static struct bfq_group *
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index cf3e9b1..0f9cd53 100644
|
||||
index cf3e9b1..2a2c130 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -1,5 +1,5 @@
|
||||
@@ -6201,7 +6205,7 @@ index cf3e9b1..0f9cd53 100644
|
||||
-
|
||||
- if (bfq_timeout_async == 0)
|
||||
- bfq_timeout_async = 1;
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r6";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r7";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
@@ -6265,10 +6269,10 @@ index cf3e9b1..0f9cd53 100644
|
||||
return 0;
|
||||
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index a5ed694..4af77f4 100644
|
||||
index a5ed694..797bce7 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -7,28 +7,46 @@
|
||||
@@ -7,28 +7,166 @@
|
||||
* Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
|
||||
* Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
@@ -6276,8 +6280,8 @@ index a5ed694..4af77f4 100644
|
||||
+ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
*/
|
||||
|
||||
+ */
|
||||
+
|
||||
+static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
+
|
||||
+/**
|
||||
@@ -6292,63 +6296,17 @@ index a5ed694..4af77f4 100644
|
||||
+ return (s64)(a - b) > 0;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
-#define for_each_entity(entity) \
|
||||
+/* both next loops stop at one of the child entities of the root group */
|
||||
+#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
|
||||
-static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
|
||||
- int extract,
|
||||
- struct bfq_data *bfqd);
|
||||
-
|
||||
-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
|
||||
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+/*
|
||||
+ * Returns true if this budget changes may let next_in_service->parent
|
||||
+ * become the next_in_service entity for its parent entity.
|
||||
+ */
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
struct bfq_entity *bfqg_entity;
|
||||
struct bfq_group *bfqg;
|
||||
struct bfq_sched_data *group_sd;
|
||||
+ bool ret = false;
|
||||
|
||||
BUG_ON(!next_in_service);
|
||||
|
||||
@@ -41,39 +59,134 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
* as it must never become an in-service entity.
|
||||
*/
|
||||
bfqg_entity = bfqg->my_entity;
|
||||
- if (bfqg_entity)
|
||||
+ if (bfqg_entity) {
|
||||
+ if (bfqg_entity->budget > next_in_service->budget)
|
||||
+ ret = true;
|
||||
bfqg_entity->budget = next_in_service->budget;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree)
|
||||
{
|
||||
- struct bfq_entity *next_in_service;
|
||||
+{
|
||||
+ struct rb_node *node = tree->rb_node;
|
||||
|
||||
- if (sd->in_service_entity)
|
||||
- /* will update/requeue at the end of service */
|
||||
- return 0;
|
||||
+
|
||||
+ return rb_entry(node, struct bfq_entity, rb_node);
|
||||
+}
|
||||
+
|
||||
+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
|
||||
+
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service);
|
||||
+
|
||||
+/**
|
||||
+ * bfq_update_next_in_service - update sd->next_in_service
|
||||
+ * @sd: sched_data for which to perform the update.
|
||||
@@ -6371,20 +6329,15 @@ index a5ed694..4af77f4 100644
|
||||
+ * Returns true if sd->next_in_service changes in such a way that
|
||||
+ * entity->parent may become the next_in_service for its parent
|
||||
+ * entity.
|
||||
+ */
|
||||
*/
|
||||
+static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
|
||||
+ struct bfq_entity *new_entity)
|
||||
+{
|
||||
+ struct bfq_entity *next_in_service = sd->next_in_service;
|
||||
+ struct bfq_queue *bfqq;
|
||||
+ bool parent_sched_may_change = false;
|
||||
|
||||
/*
|
||||
- * NOTE: this can be improved in many ways, such as returning
|
||||
- * 1 (and thus propagating upwards the update) only when the
|
||||
- * budget changes, or caching the bfqq that will be scheduled
|
||||
- * next from this subtree. By now we worry more about
|
||||
- * correctness than about performance...
|
||||
+
|
||||
+ /*
|
||||
+ * If this update is triggered by the activation, requeueing
|
||||
+ * or repositiong of an entity that does not coincide with
|
||||
+ * sd->next_in_service, then a full lookup in the active tree
|
||||
@@ -6395,8 +6348,7 @@ index a5ed694..4af77f4 100644
|
||||
+ * finish time than sd->next_in_service. If this compound
|
||||
+ * condition holds, then the new entity becomes the new
|
||||
+ * next_in_service. Otherwise no change is needed.
|
||||
*/
|
||||
- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
|
||||
+ */
|
||||
+ if (new_entity && new_entity != sd->next_in_service) {
|
||||
+ /*
|
||||
+ * Flag used to decide whether to replace
|
||||
@@ -6445,54 +6397,160 @@ index a5ed694..4af77f4 100644
|
||||
+ bfq_update_parent_budget(next_in_service);
|
||||
+ }
|
||||
+
|
||||
sd->next_in_service = next_in_service;
|
||||
|
||||
- if (next_in_service)
|
||||
- bfq_update_budget(next_in_service);
|
||||
+ sd->next_in_service = next_in_service;
|
||||
+
|
||||
+ if (!next_in_service)
|
||||
+ return parent_sched_may_change;
|
||||
|
||||
- return 1;
|
||||
-}
|
||||
+ bfqq = bfq_entity_to_bfqq(next_in_service);
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||
+ "update_next_in_service: chosen this queue");
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
-#define for_each_entity(entity) \
|
||||
+ else {
|
||||
+ struct bfq_group *bfqg =
|
||||
+ container_of(next_in_service,
|
||||
+ struct bfq_group, entity);
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
-{
|
||||
- BUG_ON(sd->next_in_service != entity);
|
||||
+
|
||||
+ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
|
||||
+ "update_next_in_service: chosen this entity");
|
||||
+ }
|
||||
+#endif
|
||||
+ return parent_sched_may_change;
|
||||
}
|
||||
+}
|
||||
+
|
||||
#else
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = NULL)
|
||||
@@ -86,12 +199,7 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
return 0;
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
+/* both next loops stop at one of the child entities of the root group */
|
||||
+#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
-
|
||||
-static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
|
||||
- int extract,
|
||||
- struct bfq_data *bfqd);
|
||||
-
|
||||
-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
-
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+/*
|
||||
+ * Returns true if this budget changes may let next_in_service->parent
|
||||
+ * become the next_in_service entity for its parent entity.
|
||||
+ */
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
struct bfq_entity *bfqg_entity;
|
||||
struct bfq_group *bfqg;
|
||||
struct bfq_sched_data *group_sd;
|
||||
+ bool ret = false;
|
||||
|
||||
BUG_ON(!next_in_service);
|
||||
|
||||
@@ -41,60 +179,68 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
* as it must never become an in-service entity.
|
||||
*/
|
||||
bfqg_entity = bfqg->my_entity;
|
||||
- if (bfqg_entity)
|
||||
+ if (bfqg_entity) {
|
||||
+ if (bfqg_entity->budget > next_in_service->budget)
|
||||
+ ret = true;
|
||||
bfqg_entity->budget = next_in_service->budget;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+/*
|
||||
+ * This function tells whether entity stops being a candidate for next
|
||||
+ * service, according to the following logic.
|
||||
+ *
|
||||
+ * This function is invoked for an entity that is about to be set in
|
||||
+ * service. If such an entity is a queue, then the entity is no longer
|
||||
+ * a candidate for next service (i.e, a candidate entity to serve
|
||||
+ * after the in-service entity is expired). The function then returns
|
||||
+ * true.
|
||||
+ *
|
||||
+ * In contrast, the entity could stil be a candidate for next service
|
||||
+ * if it is not a queue, and has more than one child. In fact, even if
|
||||
+ * one of its children is about to be set in service, other children
|
||||
+ * may still be the next to serve. As a consequence, a non-queue
|
||||
+ * entity is not a candidate for next-service only if it has only one
|
||||
+ * child. And only if this condition holds, then the function returns
|
||||
+ * true for a non-queue entity.
|
||||
+ */
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
{
|
||||
- struct bfq_entity *next_in_service;
|
||||
+ struct bfq_group *bfqg;
|
||||
|
||||
- if (sd->in_service_entity)
|
||||
- /* will update/requeue at the end of service */
|
||||
- return 0;
|
||||
+ if (bfq_entity_to_bfqq(entity))
|
||||
+ return true;
|
||||
|
||||
- /*
|
||||
- * NOTE: this can be improved in many ways, such as returning
|
||||
- * 1 (and thus propagating upwards the update) only when the
|
||||
- * budget changes, or caching the bfqq that will be scheduled
|
||||
- * next from this subtree. By now we worry more about
|
||||
- * correctness than about performance...
|
||||
- */
|
||||
- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
|
||||
- sd->next_in_service = next_in_service;
|
||||
+ bfqg = container_of(entity, struct bfq_group, entity);
|
||||
|
||||
- if (next_in_service)
|
||||
- bfq_update_budget(next_in_service);
|
||||
+ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
|
||||
+ BUG_ON(bfqg->active_entities == 0);
|
||||
+ if (bfqg->active_entities == 1)
|
||||
+ return true;
|
||||
|
||||
- return 1;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
-{
|
||||
- BUG_ON(sd->next_in_service != entity);
|
||||
-}
|
||||
-
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+static void bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
-#else
|
||||
+#else /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = NULL)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (parent = NULL; entity ; entity = parent)
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
#endif
|
||||
@@ -105,18 +213,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
{
|
||||
+ return true;
|
||||
}
|
||||
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
-{
|
||||
-}
|
||||
-#endif
|
||||
+#endif /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||
|
||||
/*
|
||||
* Shift for timestamp calculations. This actually limits the maximum
|
||||
@@ -105,18 +251,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
*/
|
||||
#define WFQ_SERVICE_SHIFT 22
|
||||
|
||||
@@ -6511,7 +6569,7 @@ index a5ed694..4af77f4 100644
|
||||
static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
|
||||
{
|
||||
struct bfq_queue *bfqq = NULL;
|
||||
@@ -151,20 +247,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight)
|
||||
@@ -151,20 +285,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);
|
||||
@@ -6550,7 +6608,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,10 +405,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
|
||||
@@ -293,10 +443,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);
|
||||
@@ -6577,7 +6635,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,8 +514,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
@@ -386,8 +552,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
BUG_ON(!bfqg);
|
||||
BUG_ON(!bfqd);
|
||||
bfqg->active_entities++;
|
||||
@@ -6586,7 +6644,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -399,7 +525,7 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
@@ -399,7 +563,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);
|
||||
@@ -6595,7 +6653,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,9 +548,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
|
||||
@@ -422,9 +586,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
|
||||
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
|
||||
|
||||
if (bfqq) {
|
||||
@@ -6607,7 +6665,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,10 +625,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
|
||||
@@ -499,10 +663,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
|
||||
BUG_ON(!bfqd);
|
||||
BUG_ON(!bfqg->active_entities);
|
||||
bfqg->active_entities--;
|
||||
@@ -6618,7 +6676,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -547,12 +669,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
@@ -547,12 +707,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
|
||||
BUG_ON(!entity->on_st);
|
||||
|
||||
@@ -6633,7 +6691,7 @@ index a5ed694..4af77f4 100644
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
}
|
||||
@@ -602,7 +724,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -602,7 +762,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);
|
||||
@@ -6642,7 +6700,7 @@ index a5ed694..4af77f4 100644
|
||||
struct bfq_data *bfqd = NULL;
|
||||
struct rb_root *root;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
@@ -630,7 +752,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -630,7 +790,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
entity->new_weight > BFQ_MAX_WEIGHT) {
|
||||
pr_crit("update_weight_prio: new_weight %d\n",
|
||||
entity->new_weight);
|
||||
@@ -6654,7 +6712,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
entity->orig_weight = entity->new_weight;
|
||||
if (bfqq)
|
||||
@@ -661,6 +786,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -661,6 +824,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
* associated with its new weight.
|
||||
*/
|
||||
if (prev_weight != new_weight) {
|
||||
@@ -6668,7 +6726,7 @@ index a5ed694..4af77f4 100644
|
||||
root = bfqq ? &bfqd->queue_weights_tree :
|
||||
&bfqd->group_weights_tree;
|
||||
bfq_weights_tree_remove(bfqd, entity, root);
|
||||
@@ -707,7 +839,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
@@ -707,7 +877,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
st = bfq_entity_service_tree(entity);
|
||||
|
||||
entity->service += served;
|
||||
@@ -6677,7 +6735,7 @@ index a5ed694..4af77f4 100644
|
||||
BUG_ON(st->wsum == 0);
|
||||
|
||||
st->vtime += bfq_delta(served, st->wsum);
|
||||
@@ -716,170 +848,419 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
@@ -716,170 +886,419 @@ 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
|
||||
@@ -6731,17 +6789,17 @@ index a5ed694..4af77f4 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;
|
||||
@@ -6948,19 +7006,20 @@ index a5ed694..4af77f4 100644
|
||||
- * @entity: the entity to activate.
|
||||
+ * __bfq_requeue_entity - handle requeueing or repositioning of an entity.
|
||||
+ * @entity: the entity being requeued or repositioned.
|
||||
*
|
||||
- * Activate @entity and all the entities on the path from it to the root.
|
||||
+ *
|
||||
+ * Requeueing is needed if this entity stops being served, which
|
||||
+ * happens if a leaf descendant entity has expired. On the other hand,
|
||||
+ * repositioning is needed if the next_inservice_entity for the child
|
||||
+ * entity has changed. See the comments inside the function for
|
||||
+ * details.
|
||||
+ *
|
||||
*
|
||||
- * Activate @entity and all the entities on the path from it to the root.
|
||||
+ * Basically, this function: 1) removes entity from its active tree if
|
||||
+ * present there, 2) updates the timestamps of entity and 3) inserts
|
||||
+ * entity back into its active tree (in the new, right position for
|
||||
+ * the new values of the timestamps).
|
||||
+ */
|
||||
*/
|
||||
-static void bfq_activate_entity(struct bfq_entity *entity)
|
||||
+static void __bfq_requeue_entity(struct bfq_entity *entity)
|
||||
+{
|
||||
+ struct bfq_sched_data *sd = entity->sched_data;
|
||||
@@ -7065,8 +7124,7 @@ index a5ed694..4af77f4 100644
|
||||
+ * @requeue: true if this is a requeue, which implies that bfqq is
|
||||
+ * being expired; thus ALL its ancestors stop being served and must
|
||||
+ * therefore be requeued
|
||||
*/
|
||||
-static void bfq_activate_entity(struct bfq_entity *entity)
|
||||
+ */
|
||||
+static void bfq_activate_requeue_entity(struct bfq_entity *entity,
|
||||
+ bool non_blocking_wait_rq,
|
||||
+ bool requeue)
|
||||
@@ -7186,7 +7244,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
struct bfq_sched_data *sd;
|
||||
struct bfq_entity *parent;
|
||||
@@ -887,63 +1268,153 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
|
||||
@@ -887,63 +1306,154 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
|
||||
for_each_entity_safe(entity, parent) {
|
||||
sd = entity->sched_data;
|
||||
|
||||
@@ -7309,7 +7367,8 @@ index a5ed694..4af77f4 100644
|
||||
+ if (!bfq_update_next_in_service(sd, entity) &&
|
||||
+ !expiration)
|
||||
+ /*
|
||||
+ * next_in_service unchanged, and no
|
||||
+ * next_in_service unchanged or not causing
|
||||
+ * any change in entity->parent->sd, and no
|
||||
+ * requeueing needed for expiration: stop
|
||||
+ * here.
|
||||
+ */
|
||||
@@ -7339,13 +7398,13 @@ index a5ed694..4af77f4 100644
|
||||
- struct bfq_entity *entry;
|
||||
- struct rb_node *node = st->active.rb_node;
|
||||
+ struct bfq_entity *root_entity = bfq_root_active_entity(&st->active);
|
||||
+
|
||||
+ if (bfq_gt(root_entity->min_start, st->vtime)) {
|
||||
+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
|
||||
|
||||
- entry = rb_entry(node, struct bfq_entity, rb_node);
|
||||
- if (bfq_gt(entry->min_start, st->vtime)) {
|
||||
- st->vtime = entry->min_start;
|
||||
+ if (bfq_gt(root_entity->min_start, st->vtime)) {
|
||||
+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
|
||||
+
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||
+ "calc_vtime_jump: new value %llu",
|
||||
@@ -7373,7 +7432,7 @@ index a5ed694..4af77f4 100644
|
||||
bfq_forget_idle(st);
|
||||
}
|
||||
}
|
||||
@@ -952,6 +1423,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
@@ -952,6 +1462,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
* bfq_first_active_entity - find the eligible entity with
|
||||
* the smallest finish time
|
||||
* @st: the service tree to select from.
|
||||
@@ -7381,7 +7440,7 @@ index a5ed694..4af77f4 100644
|
||||
*
|
||||
* This function searches the first schedulable entity, starting from the
|
||||
* root of the tree and going on the left every time on this side there is
|
||||
@@ -959,7 +1431,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
@@ -959,7 +1470,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
* the right is followed only if a) the left subtree contains no eligible
|
||||
* entities and b) no eligible entity has been found yet.
|
||||
*/
|
||||
@@ -7391,7 +7450,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
struct bfq_entity *entry, *first = NULL;
|
||||
struct rb_node *node = st->active.rb_node;
|
||||
@@ -967,15 +1440,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
@@ -967,15 +1479,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
while (node) {
|
||||
entry = rb_entry(node, struct bfq_entity, rb_node);
|
||||
left:
|
||||
@@ -7410,7 +7469,7 @@ index a5ed694..4af77f4 100644
|
||||
node = node->rb_left;
|
||||
goto left;
|
||||
}
|
||||
@@ -993,31 +1466,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
@@ -993,31 +1505,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
* __bfq_lookup_next_entity - return the first eligible entity in @st.
|
||||
* @st: the service tree.
|
||||
*
|
||||
@@ -7510,7 +7569,7 @@ index a5ed694..4af77f4 100644
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -1025,50 +1551,118 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
|
||||
@@ -1025,50 +1590,81 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
|
||||
/**
|
||||
* bfq_lookup_next_entity - return the first eligible entity in @sd.
|
||||
* @sd: the sched_data.
|
||||
@@ -7620,48 +7679,11 @@ index a5ed694..4af77f4 100644
|
||||
+
|
||||
+ return sd->next_in_service != sd->in_service_entity;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function tells whether entity stops being a candidate for next
|
||||
+ * service, according to the following logic.
|
||||
+ *
|
||||
+ * This function is invoked for an entity that is about to be set in
|
||||
+ * service. If such an entity is a queue, then the entity is no longer
|
||||
+ * a candidate for next service (i.e, a candidate entity to serve
|
||||
+ * after the in-service entity is expired). The function then returns
|
||||
+ * true.
|
||||
+ *
|
||||
+ * In contrast, the entity could stil be a candidate for next service
|
||||
+ * if it is not a queue, and has more than one child. In fact, even if
|
||||
+ * one of its children is about to be set in service, other children
|
||||
+ * may still be the next to serve. As a consequence, a non-queue
|
||||
+ * entity is not a candidate for next-service only if it has only one
|
||||
+ * child. And only if this condition holds, then the function returns
|
||||
+ * true for a non-queue entity.
|
||||
+ */
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
+{
|
||||
+ struct bfq_group *bfqg;
|
||||
+
|
||||
+ if (bfq_entity_to_bfqq(entity))
|
||||
+ return true;
|
||||
+
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
+ bfqg = container_of(entity, struct bfq_group, entity);
|
||||
+
|
||||
+ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
|
||||
+ BUG_ON(bfqg->active_entities == 0);
|
||||
+ if (bfqg->active_entities == 1)
|
||||
+ return true;
|
||||
+#endif
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Get next queue for service.
|
||||
*/
|
||||
@@ -1083,58 +1677,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
@@ -1083,58 +1679,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
if (bfqd->busy_queues == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -7883,7 +7905,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
BUG_ON(!bfq_bfqq_busy(bfqq));
|
||||
BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
@@ -1146,27 +1890,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
@@ -1146,27 +1892,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
BUG_ON(bfqd->busy_queues == 0);
|
||||
bfqd->busy_queues--;
|
||||
|
||||
@@ -7918,7 +7940,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1184,16 +1921,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
@@ -1184,16 +1923,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
bfq_mark_bfqq_busy(bfqq);
|
||||
bfqd->busy_queues++;
|
||||
|
||||
@@ -7938,13 +7960,13 @@ index a5ed694..4af77f4 100644
|
||||
bfqd->wr_busy_queues++;
|
||||
}
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index fcce855..57ab51d 100644
|
||||
index fcce855..bef8244 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 v8r6 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From 124298bd03acebd9c9da29a794718aca31bec1f7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Roschka <danielroschka@phoenitydawn.de>
|
||||
Date: Wed, 22 Feb 2017 15:17:29 -0700
|
||||
Subject: [PATCH] nvme: detect NVMe controller in recent MacBooks
|
||||
|
||||
Adds support for detection of the NVMe controller found in the
|
||||
following recent MacBooks:
|
||||
- Retina MacBook 2016 (MacBook9,1)
|
||||
- 13" MacBook Pro 2016 without Touch Bar (MacBook13,1)
|
||||
- 13" MacBook Pro 2016 with Touch Bar (MacBook13,2)
|
||||
|
||||
Signed-off-by: Daniel Roschka <danielroschka@phoenitydawn.de>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
|
||||
Signed-off-by: Jens Axboe <axboe@fb.com>
|
||||
---
|
||||
drivers/nvme/host/pci.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
|
||||
index d38dae9..319f5c5 100644
|
||||
--- a/drivers/nvme/host/pci.c
|
||||
+++ b/drivers/nvme/host/pci.c
|
||||
@@ -2120,6 +2120,7 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
|
||||
+ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, nvme_id_table);
|
||||
--
|
||||
2.10.2
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
block/bfq-iosched.c | 4 +++-
|
||||
block/bfq-sched.c | 15 ++++++++++++---
|
||||
block/bfq.h | 2 +-
|
||||
3 files changed, 16 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index 96b79a0dae9f..158628392d92 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -4572,6 +4572,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
|
||||
if (!bic)
|
||||
goto queue_fail;
|
||||
|
||||
+ bfq_check_ioprio_change(bic, bio);
|
||||
+
|
||||
bfq_bic_update_cgroup(bic, bio);
|
||||
|
||||
new_queue:
|
||||
@@ -5268,7 +5270,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
|
||||
static int __init bfq_init(void)
|
||||
{
|
||||
int ret;
|
||||
- char msg[60] = "BFQ I/O-scheduler: v8r10";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r11";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index 70aac56b02ef..8311bdbeceea 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -1280,14 +1280,23 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
bool ins_into_idle_tree)
|
||||
{
|
||||
struct bfq_sched_data *sd = entity->sched_data;
|
||||
- struct bfq_service_tree *st = bfq_entity_service_tree(entity);
|
||||
- bool is_in_service = entity == sd->in_service_entity;
|
||||
+ struct bfq_service_tree *st;
|
||||
+ bool is_in_service;
|
||||
|
||||
if (!entity->on_st) { /* entity never activated, or already inactive */
|
||||
- BUG_ON(entity == entity->sched_data->in_service_entity);
|
||||
+ BUG_ON(sd && entity == sd->in_service_entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If we get here, then entity is active, which implies that
|
||||
+ * bfq_group_set_parent has already been invoked for the group
|
||||
+ * represented by entity. Therefore, the field
|
||||
+ * entity->sched_data has been set, and we can safely use it.
|
||||
+ */
|
||||
+ st = bfq_entity_service_tree(entity);
|
||||
+ is_in_service = entity == sd->in_service_entity;
|
||||
+
|
||||
BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);
|
||||
|
||||
if (is_in_service)
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index e3855af1211b..a521ac40cac0 100644
|
||||
--- a/block/bfq.h
|
||||
+++ b/block/bfq.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r11 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
@@ -0,0 +1,729 @@
|
||||
block/bfq-cgroup.c | 12 +--
|
||||
block/bfq-iosched.c | 211 +++++++++++++++++++++++++++++++---------------------
|
||||
block/bfq-sched.c | 73 ++++++++++++------
|
||||
block/bfq.h | 4 +-
|
||||
4 files changed, 180 insertions(+), 120 deletions(-)
|
||||
|
||||
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
|
||||
index bbaecd0..a66a723 100644
|
||||
--- a/block/bfq-cgroup.c
|
||||
+++ b/block/bfq-cgroup.c
|
||||
@@ -771,7 +771,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
|
||||
|
||||
__bfq_deactivate_entity(entity, false);
|
||||
bfq_put_async_queues(bfqd, bfqg);
|
||||
- BUG_ON(entity->tree);
|
||||
|
||||
/*
|
||||
* @blkg is going offline and will be ignored by
|
||||
@@ -1140,6 +1139,9 @@ static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
|
||||
static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
|
||||
static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
|
||||
|
||||
+static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
+ struct bfq_group *bfqg) {}
|
||||
+
|
||||
static void bfq_init_entity(struct bfq_entity *entity,
|
||||
struct bfq_group *bfqg)
|
||||
{
|
||||
@@ -1154,13 +1156,7 @@ static void bfq_init_entity(struct bfq_entity *entity,
|
||||
entity->sched_data = &bfqg->sched_data;
|
||||
}
|
||||
|
||||
-static struct bfq_group *
|
||||
-bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
|
||||
-{
|
||||
- struct bfq_data *bfqd = bic_to_bfqd(bic);
|
||||
-
|
||||
- return bfqd->root_group;
|
||||
-}
|
||||
+static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) {}
|
||||
|
||||
static void bfq_end_wr_async(struct bfq_data *bfqd)
|
||||
{
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index 78baa07..96b79a0 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
|
||||
*
|
||||
* Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
|
||||
* file.
|
||||
@@ -107,7 +107,7 @@ static const int bfq_async_charge_factor = 10;
|
||||
/* Default timeout values, in jiffies, approximating CFQ defaults. */
|
||||
static const int bfq_timeout = (HZ / 8);
|
||||
|
||||
-struct kmem_cache *bfq_pool;
|
||||
+static struct kmem_cache *bfq_pool;
|
||||
|
||||
/* Below this threshold (in ns), we consider thinktime immediate. */
|
||||
#define BFQ_MIN_TT (2 * NSEC_PER_MSEC)
|
||||
@@ -483,6 +483,22 @@ static void bfq_weights_tree_add(struct bfq_data *bfqd,
|
||||
|
||||
entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
|
||||
GFP_ATOMIC);
|
||||
+
|
||||
+ /*
|
||||
+ * In the unlucky event of an allocation failure, we just
|
||||
+ * exit. This will cause the weight of entity to not be
|
||||
+ * considered in bfq_differentiated_weights, which, in its
|
||||
+ * turn, causes the scenario to be deemed wrongly symmetric in
|
||||
+ * case entity's weight would have been the only weight making
|
||||
+ * the scenario asymmetric. On the bright side, no unbalance
|
||||
+ * will however occur when entity becomes inactive again (the
|
||||
+ * invocation of this function is triggered by an activation
|
||||
+ * of entity). In fact, bfq_weights_tree_remove does nothing
|
||||
+ * if !entity->weight_counter.
|
||||
+ */
|
||||
+ if (unlikely(!entity->weight_counter))
|
||||
+ return;
|
||||
+
|
||||
entity->weight_counter->weight = entity->weight;
|
||||
rb_link_node(&entity->weight_counter->weights_node, parent, new);
|
||||
rb_insert_color(&entity->weight_counter->weights_node, root);
|
||||
@@ -519,13 +535,45 @@ static void bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
entity->weight_counter = NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Return expired entry, or NULL to just start from scratch in rbtree.
|
||||
+ */
|
||||
+static struct request *bfq_check_fifo(struct bfq_queue *bfqq,
|
||||
+ struct request *last)
|
||||
+{
|
||||
+ struct request *rq;
|
||||
+
|
||||
+ if (bfq_bfqq_fifo_expire(bfqq))
|
||||
+ return NULL;
|
||||
+
|
||||
+ bfq_mark_bfqq_fifo_expire(bfqq);
|
||||
+
|
||||
+ rq = rq_entry_fifo(bfqq->fifo.next);
|
||||
+
|
||||
+ if (rq == last || ktime_get_ns() < rq->fifo_time)
|
||||
+ return NULL;
|
||||
+
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "check_fifo: returned %p", rq);
|
||||
+ BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
|
||||
+ return rq;
|
||||
+}
|
||||
+
|
||||
static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq,
|
||||
struct request *last)
|
||||
{
|
||||
struct rb_node *rbnext = rb_next(&last->rb_node);
|
||||
struct rb_node *rbprev = rb_prev(&last->rb_node);
|
||||
- struct request *next = NULL, *prev = NULL;
|
||||
+ struct request *next, *prev = NULL;
|
||||
+
|
||||
+ BUG_ON(list_empty(&bfqq->fifo));
|
||||
+
|
||||
+ /* Follow expired path, else get first next available. */
|
||||
+ next = bfq_check_fifo(bfqq, last);
|
||||
+ if (next) {
|
||||
+ BUG_ON(next == last);
|
||||
+ return next;
|
||||
+ }
|
||||
|
||||
BUG_ON(RB_EMPTY_NODE(&last->rb_node));
|
||||
|
||||
@@ -1359,7 +1407,6 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
|
||||
|
||||
bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
|
||||
false, BFQ_BFQQ_PREEMPTED);
|
||||
- BUG_ON(in_serv->entity.budget < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1523,12 +1570,15 @@ static void bfq_remove_request(struct request *rq)
|
||||
elv_rb_del(&bfqq->sort_list, rq);
|
||||
|
||||
if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
|
||||
+ bfqq->next_rq = NULL;
|
||||
+
|
||||
BUG_ON(bfqq->entity.budget < 0);
|
||||
|
||||
if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) {
|
||||
+ BUG_ON(bfqq->ref < 2); /* referred by rq and on tree */
|
||||
bfq_del_bfqq_busy(bfqd, bfqq, false);
|
||||
-
|
||||
- /* bfqq emptied. In normal operation, when
|
||||
+ /*
|
||||
+ * bfqq emptied. In normal operation, when
|
||||
* bfqq is empty, bfqq->entity.service and
|
||||
* bfqq->entity.budget must contain,
|
||||
* respectively, the service received and the
|
||||
@@ -1537,7 +1587,8 @@ static void bfq_remove_request(struct request *rq)
|
||||
* this last removal occurred while bfqq is
|
||||
* not in service. To avoid inconsistencies,
|
||||
* reset both bfqq->entity.service and
|
||||
- * bfqq->entity.budget.
|
||||
+ * bfqq->entity.budget, if bfqq has still a
|
||||
+ * process that may issue I/O requests to it.
|
||||
*/
|
||||
bfqq->entity.budget = bfqq->entity.service = 0;
|
||||
}
|
||||
@@ -1868,7 +1919,7 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
|
||||
* positives. In case bfqq is weight-raised, such false positives
|
||||
* would evidently degrade latency guarantees for bfqq.
|
||||
*/
|
||||
-bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||
+static bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||
{
|
||||
return bfqq->wr_coeff > 1 &&
|
||||
time_is_before_jiffies(bfqq->last_wr_start_finish +
|
||||
@@ -2029,7 +2080,8 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
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;
|
||||
+ new_bfqq->wr_start_at_switch_to_srt =
|
||||
+ bfqq->wr_start_at_switch_to_srt;
|
||||
if (bfq_bfqq_busy(new_bfqq))
|
||||
bfqd->wr_busy_queues++;
|
||||
new_bfqq->entity.prio_changed = 1;
|
||||
@@ -2072,6 +2124,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
*/
|
||||
new_bfqq->bic = NULL;
|
||||
bfqq->bic = NULL;
|
||||
+ /* release process reference to bfqq */
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
|
||||
@@ -2298,7 +2351,7 @@ static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd)
|
||||
* 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)
|
||||
+static void update_thr_responsiveness_params(struct bfq_data *bfqd)
|
||||
{
|
||||
int dev_type = blk_queue_nonrot(bfqd->queue);
|
||||
|
||||
@@ -2333,7 +2386,7 @@ void update_thr_responsiveness_params(struct bfq_data *bfqd)
|
||||
BFQ_RATE_SHIFT);
|
||||
}
|
||||
|
||||
-void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
|
||||
+static 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() ;
|
||||
@@ -2350,7 +2403,7 @@ void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
|
||||
bfqd->tot_sectors_dispatched);
|
||||
}
|
||||
|
||||
-void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
+static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
{
|
||||
u32 rate, weight, divisor;
|
||||
|
||||
@@ -2400,7 +2453,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
* total, and rate is below the current estimated peak rate
|
||||
* - rate is unreasonably high (> 20M sectors/sec)
|
||||
*/
|
||||
- if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 &&
|
||||
+ if ((bfqd->sequential_samples < (3 * bfqd->peak_rate_samples)>>2 &&
|
||||
rate <= bfqd->peak_rate) ||
|
||||
rate > 20<<BFQ_RATE_SHIFT) {
|
||||
bfq_log(bfqd,
|
||||
@@ -2515,7 +2568,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
* of the observed dispatch rate. The function assumes to be invoked
|
||||
* on every request dispatch.
|
||||
*/
|
||||
-void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
|
||||
+static void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
|
||||
{
|
||||
u64 now_ns = ktime_get_ns();
|
||||
|
||||
@@ -2616,29 +2669,6 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
|
||||
elv_dispatch_sort(q, rq);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Return expired entry, or NULL to just start from scratch in rbtree.
|
||||
- */
|
||||
-static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
|
||||
-{
|
||||
- struct request *rq = NULL;
|
||||
-
|
||||
- if (bfq_bfqq_fifo_expire(bfqq))
|
||||
- return NULL;
|
||||
-
|
||||
- bfq_mark_bfqq_fifo_expire(bfqq);
|
||||
-
|
||||
- if (list_empty(&bfqq->fifo))
|
||||
- return NULL;
|
||||
-
|
||||
- rq = rq_entry_fifo(bfqq->fifo.next);
|
||||
-
|
||||
- if (ktime_get_ns() < rq->fifo_time)
|
||||
- return NULL;
|
||||
-
|
||||
- return rq;
|
||||
-}
|
||||
-
|
||||
static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
{
|
||||
BUG_ON(bfqq != bfqd->in_service_queue);
|
||||
@@ -2904,8 +2934,8 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
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) {
|
||||
+ /* don't use too short time intervals */
|
||||
+ if (delta_usecs < 1000) {
|
||||
if (blk_queue_nonrot(bfqd->queue))
|
||||
/*
|
||||
* give same worst-case guarantees as idling
|
||||
@@ -2915,7 +2945,7 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
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);
|
||||
+ bfq_log(bfqd, "bfq_bfqq_is_slow: too short %u", delta_usecs);
|
||||
|
||||
return slow;
|
||||
}
|
||||
@@ -3067,6 +3097,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
bool slow;
|
||||
unsigned long delta = 0;
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
+ int ref;
|
||||
|
||||
BUG_ON(bfqq != bfqd->in_service_queue);
|
||||
|
||||
@@ -3174,12 +3205,15 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
|
||||
BUG_ON(bfqq->next_rq == NULL &&
|
||||
bfqq->entity.budget < bfqq->entity.service);
|
||||
+ ref = bfqq->ref;
|
||||
__bfq_bfqq_expire(bfqd, bfqq);
|
||||
|
||||
- BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
|
||||
+ BUG_ON(ref > 1 &&
|
||||
+ !bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
|
||||
!bfq_class_idle(bfqq));
|
||||
|
||||
- if (!bfq_bfqq_busy(bfqq) &&
|
||||
+ /* mark bfqq as waiting a request only if a bic still points to it */
|
||||
+ if (ref > 1 && !bfq_bfqq_busy(bfqq) &&
|
||||
reason != BFQ_BFQQ_BUDGET_TIMEOUT &&
|
||||
reason != BFQ_BFQQ_BUDGET_EXHAUSTED)
|
||||
bfq_mark_bfqq_non_blocking_wait_rq(bfqq);
|
||||
@@ -3504,14 +3538,29 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
|
||||
!bfq_bfqq_must_idle(bfqq))
|
||||
goto expire;
|
||||
|
||||
+check_queue:
|
||||
+ /*
|
||||
+ * This loop is rarely executed more than once. Even when it
|
||||
+ * happens, it is much more convenient to re-execute this loop
|
||||
+ * than to return NULL and trigger a new dispatch to get a
|
||||
+ * request served.
|
||||
+ */
|
||||
next_rq = bfqq->next_rq;
|
||||
/*
|
||||
* If bfqq has requests queued and it has enough budget left to
|
||||
* serve them, keep the queue, otherwise expire it.
|
||||
*/
|
||||
if (next_rq) {
|
||||
+ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
+
|
||||
if (bfq_serv_to_charge(next_rq, bfqq) >
|
||||
bfq_bfqq_budget_left(bfqq)) {
|
||||
+ /*
|
||||
+ * Expire the queue for budget exhaustion,
|
||||
+ * which makes sure that the next budget is
|
||||
+ * enough to serve the next request, even if
|
||||
+ * it comes from the fifo expired path.
|
||||
+ */
|
||||
reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
|
||||
goto expire;
|
||||
} else {
|
||||
@@ -3559,9 +3608,16 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
|
||||
bfq_bfqq_expire(bfqd, bfqq, false, reason);
|
||||
new_queue:
|
||||
bfqq = bfq_set_in_service_queue(bfqd);
|
||||
- bfq_log(bfqd, "select_queue: new queue %d returned",
|
||||
- bfqq ? bfqq->pid : 0);
|
||||
+ if (bfqq) {
|
||||
+ bfq_log_bfqq(bfqd, bfqq, "select_queue: checking new queue");
|
||||
+ goto check_queue;
|
||||
+ }
|
||||
keep_queue:
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqd, bfqq, "select_queue: returned this queue");
|
||||
+ else
|
||||
+ bfq_log(bfqd, "select_queue: no queue returned");
|
||||
+
|
||||
return bfqq;
|
||||
}
|
||||
|
||||
@@ -3627,45 +3683,17 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq)
|
||||
{
|
||||
int dispatched = 0;
|
||||
- struct request *rq;
|
||||
+ struct request *rq = bfqq->next_rq;
|
||||
unsigned long service_to_charge;
|
||||
|
||||
BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
-
|
||||
- /* Follow expired path, else get first next available. */
|
||||
- rq = bfq_check_fifo(bfqq);
|
||||
- if (!rq)
|
||||
- rq = bfqq->next_rq;
|
||||
+ BUG_ON(!rq);
|
||||
service_to_charge = bfq_serv_to_charge(rq, bfqq);
|
||||
|
||||
- if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
|
||||
- /*
|
||||
- * This may happen if the next rq is chosen in fifo order
|
||||
- * instead of sector order. The budget is properly
|
||||
- * dimensioned to be always sufficient to serve the next
|
||||
- * request only if it is chosen in sector order. The reason
|
||||
- * is that it would be quite inefficient and little useful
|
||||
- * to always make sure that the budget is large enough to
|
||||
- * serve even the possible next rq in fifo order.
|
||||
- * In fact, requests are seldom served in fifo order.
|
||||
- *
|
||||
- * Expire the queue for budget exhaustion, and make sure
|
||||
- * that the next act_budget is enough to serve the next
|
||||
- * request, even if it comes from the fifo expired path.
|
||||
- */
|
||||
- bfqq->next_rq = rq;
|
||||
- /*
|
||||
- * Since this dispatch is failed, make sure that
|
||||
- * a new one will be performed
|
||||
- */
|
||||
- if (!bfqd->rq_in_driver)
|
||||
- bfq_schedule_dispatch(bfqd);
|
||||
- BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
- goto expire;
|
||||
- }
|
||||
+ BUG_ON(service_to_charge > bfq_bfqq_budget_left(bfqq));
|
||||
|
||||
BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
- /* Finally, insert request into driver dispatch list. */
|
||||
+
|
||||
bfq_bfqq_served(bfqq, service_to_charge);
|
||||
|
||||
BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
@@ -3805,7 +3833,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
|
||||
* Task holds one reference to the queue, dropped when task exits. Each rq
|
||||
* in-flight on this queue also holds a reference, dropped when rq is freed.
|
||||
*
|
||||
- * Queue lock must be held here.
|
||||
+ * Queue lock must be held here. Recall not to use bfqq after calling
|
||||
+ * this function on it.
|
||||
*/
|
||||
static void bfq_put_queue(struct bfq_queue *bfqq)
|
||||
{
|
||||
@@ -3874,7 +3903,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
|
||||
bfq_put_cooperator(bfqq);
|
||||
|
||||
- bfq_put_queue(bfqq);
|
||||
+ bfq_put_queue(bfqq); /* release process reference */
|
||||
}
|
||||
|
||||
static void bfq_init_icq(struct io_cq *icq)
|
||||
@@ -3973,6 +4002,7 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
|
||||
|
||||
bfqq = bic_to_bfqq(bic, false);
|
||||
if (bfqq) {
|
||||
+ /* release process reference on this queue */
|
||||
bfq_put_queue(bfqq);
|
||||
bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic);
|
||||
bic_set_bfqq(bic, bfqq, false);
|
||||
@@ -4093,14 +4123,20 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
|
||||
* prune it.
|
||||
*/
|
||||
if (async_bfqq) {
|
||||
- bfqq->ref++;
|
||||
+ bfqq->ref++; /*
|
||||
+ * Extra group reference, w.r.t. sync
|
||||
+ * queue. This extra reference is removed
|
||||
+ * only if bfqq->bfqg disappears, to
|
||||
+ * guarantee that this queue is not freed
|
||||
+ * until its group goes away.
|
||||
+ */
|
||||
bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
|
||||
bfqq, bfqq->ref);
|
||||
*async_bfqq = bfqq;
|
||||
}
|
||||
|
||||
out:
|
||||
- bfqq->ref++;
|
||||
+ bfqq->ref++; /* get a process reference to this queue */
|
||||
bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref);
|
||||
rcu_read_unlock();
|
||||
return bfqq;
|
||||
@@ -4274,10 +4310,14 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq)
|
||||
bfqq->allocated[rq_data_dir(rq)]--;
|
||||
new_bfqq->ref++;
|
||||
bfq_clear_bfqq_just_created(bfqq);
|
||||
- bfq_put_queue(bfqq);
|
||||
if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
|
||||
bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
|
||||
bfqq, new_bfqq);
|
||||
+ /*
|
||||
+ * rq is about to be enqueued into new_bfqq,
|
||||
+ * release rq reference on bfqq
|
||||
+ */
|
||||
+ bfq_put_queue(bfqq);
|
||||
rq->elv.priv[1] = new_bfqq;
|
||||
bfqq = new_bfqq;
|
||||
}
|
||||
@@ -4697,9 +4737,8 @@ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
|
||||
cancel_work_sync(&bfqd->unplug_work);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
|
||||
- struct bfq_queue **bfqq_ptr)
|
||||
+ struct bfq_queue **bfqq_ptr)
|
||||
{
|
||||
struct bfq_group *root_group = bfqd->root_group;
|
||||
struct bfq_queue *bfqq = *bfqq_ptr;
|
||||
@@ -4730,7 +4769,6 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
|
||||
|
||||
__bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void bfq_exit_queue(struct elevator_queue *e)
|
||||
{
|
||||
@@ -4755,6 +4793,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
blkcg_deactivate_policy(q, &blkcg_policy_bfq);
|
||||
#else
|
||||
+ bfq_put_async_queues(bfqd, bfqd->root_group);
|
||||
kfree(bfqd->root_group);
|
||||
#endif
|
||||
|
||||
@@ -5229,7 +5268,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
|
||||
static int __init bfq_init(void)
|
||||
{
|
||||
int ret;
|
||||
- char msg[60] = "BFQ I/O-scheduler: v8r7";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r10";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
@@ -5255,7 +5294,7 @@ static int __init bfq_init(void)
|
||||
* be run for a long time.
|
||||
*/
|
||||
T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */
|
||||
- T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */
|
||||
+ T_slow[1] = msecs_to_jiffies(6000); /* actually 6.5 sec */
|
||||
T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */
|
||||
T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */
|
||||
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index 797bce7..70aac56 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -154,7 +154,13 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
-#define for_each_entity_safe(entity, parent) \
|
||||
+/*
|
||||
+ * For each iteration, compute parent in advance, so as to be safe if
|
||||
+ * entity is deallocated during the iteration. Such a deallocation may
|
||||
+ * happen as a consequence of a bfq_put_queue that frees the bfq_queue
|
||||
+ * containing entity.
|
||||
+ */
|
||||
+#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
/*
|
||||
@@ -691,27 +697,31 @@ static void bfq_idle_insert(struct bfq_service_tree *st,
|
||||
}
|
||||
|
||||
/**
|
||||
- * bfq_forget_entity - remove an entity from the wfq trees.
|
||||
+ * bfq_forget_entity - do not consider entity any longer for scheduling
|
||||
* @st: the service tree.
|
||||
* @entity: the entity being removed.
|
||||
+ * @is_in_service: true if entity is currently the in-service entity.
|
||||
*
|
||||
- * Update the device status and forget everything about @entity, putting
|
||||
- * the device reference to it, if it is a queue. Entities belonging to
|
||||
- * groups are not refcounted.
|
||||
+ * Forget everything about @entity. In addition, if entity represents
|
||||
+ * a queue, and the latter is not in service, then release the service
|
||||
+ * reference to the queue (the one taken through bfq_get_entity). In
|
||||
+ * fact, in this case, there is really no more service reference to
|
||||
+ * the queue, as the latter is also outside any service tree. If,
|
||||
+ * instead, the queue is in service, then __bfq_bfqd_reset_in_service
|
||||
+ * will take care of putting the reference when the queue finally
|
||||
+ * stops being served.
|
||||
*/
|
||||
static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
- struct bfq_entity *entity)
|
||||
+ struct bfq_entity *entity,
|
||||
+ bool is_in_service)
|
||||
{
|
||||
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
|
||||
- struct bfq_sched_data *sd;
|
||||
-
|
||||
BUG_ON(!entity->on_st);
|
||||
|
||||
entity->on_st = false;
|
||||
st->wsum -= entity->weight;
|
||||
- if (bfqq) {
|
||||
- sd = entity->sched_data;
|
||||
- bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
|
||||
+ if (bfqq && !is_in_service) {
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity (before): %p %d",
|
||||
bfqq, bfqq->ref);
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
@@ -726,7 +736,8 @@ static void bfq_put_idle_entity(struct bfq_service_tree *st,
|
||||
struct bfq_entity *entity)
|
||||
{
|
||||
bfq_idle_extract(st, entity);
|
||||
- bfq_forget_entity(st, entity);
|
||||
+ bfq_forget_entity(st, entity,
|
||||
+ entity == entity->sched_data->in_service_entity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1082,6 +1093,12 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
|
||||
*/
|
||||
entity->start = min_vstart;
|
||||
st->wsum += entity->weight;
|
||||
+ /*
|
||||
+ * entity is about to be inserted into a service tree,
|
||||
+ * and then set in service: get a reference to make
|
||||
+ * sure entity does not disappear until it is no
|
||||
+ * longer in service or scheduled for service.
|
||||
+ */
|
||||
bfq_get_entity(entity);
|
||||
|
||||
BUG_ON(entity->on_st && bfqq);
|
||||
@@ -1264,27 +1281,27 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
{
|
||||
struct bfq_sched_data *sd = entity->sched_data;
|
||||
struct bfq_service_tree *st = bfq_entity_service_tree(entity);
|
||||
- bool was_in_service = entity == sd->in_service_entity;
|
||||
+ bool is_in_service = entity == sd->in_service_entity;
|
||||
|
||||
if (!entity->on_st) { /* entity never activated, or already inactive */
|
||||
BUG_ON(entity == entity->sched_data->in_service_entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
- BUG_ON(was_in_service && entity->tree && entity->tree != &st->active);
|
||||
+ BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);
|
||||
|
||||
- if (was_in_service)
|
||||
+ if (is_in_service)
|
||||
bfq_calc_finish(entity, entity->service);
|
||||
|
||||
if (entity->tree == &st->active)
|
||||
bfq_active_extract(st, entity);
|
||||
- else if (!was_in_service && entity->tree == &st->idle)
|
||||
+ else if (!is_in_service && entity->tree == &st->idle)
|
||||
bfq_idle_extract(st, entity);
|
||||
else if (entity->tree)
|
||||
BUG();
|
||||
|
||||
if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime))
|
||||
- bfq_forget_entity(st, entity);
|
||||
+ bfq_forget_entity(st, entity, is_in_service);
|
||||
else
|
||||
bfq_idle_insert(st, entity);
|
||||
|
||||
@@ -1301,7 +1318,7 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
bool expiration)
|
||||
{
|
||||
struct bfq_sched_data *sd;
|
||||
- struct bfq_entity *parent;
|
||||
+ struct bfq_entity *parent = NULL;
|
||||
|
||||
for_each_entity_safe(entity, parent) {
|
||||
sd = entity->sched_data;
|
||||
@@ -1320,8 +1337,8 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
|
||||
if (!__bfq_deactivate_entity(entity, ins_into_idle_tree)) {
|
||||
/*
|
||||
- * Entity is not any tree any more, so, this
|
||||
- * deactivation is a no-op, and there is
|
||||
+ * entity is not in any tree any more, so
|
||||
+ * this deactivation is a no-op, and there is
|
||||
* nothing to change for upper-level entities
|
||||
* (in case of expiration, this can never
|
||||
* happen).
|
||||
@@ -1821,14 +1838,16 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
|
||||
static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
{
|
||||
- struct bfq_entity *entity = &bfqd->in_service_queue->entity;
|
||||
+ struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
|
||||
+ struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
|
||||
+ struct bfq_entity *entity = in_serv_entity;
|
||||
|
||||
if (bfqd->in_service_bic) {
|
||||
put_io_context(bfqd->in_service_bic->icq.ioc);
|
||||
bfqd->in_service_bic = NULL;
|
||||
}
|
||||
|
||||
- bfq_clear_bfqq_wait_request(bfqd->in_service_queue);
|
||||
+ bfq_clear_bfqq_wait_request(in_serv_bfqq);
|
||||
hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
|
||||
bfqd->in_service_queue = NULL;
|
||||
|
||||
@@ -1840,6 +1859,14 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
*/
|
||||
for_each_entity(entity)
|
||||
entity->sched_data->in_service_entity = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * in_serv_entity is no longer in service, so, if it is in no
|
||||
+ * service tree either, then release the service reference to
|
||||
+ * the queue it represents (taken with bfq_get_entity).
|
||||
+ */
|
||||
+ if (!in_serv_entity->on_st)
|
||||
+ bfq_put_queue(in_serv_bfqq);
|
||||
}
|
||||
|
||||
static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
@@ -1904,8 +1931,6 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
BUG_ON(bfqq->entity.budget < 0);
|
||||
|
||||
bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
|
||||
-
|
||||
- BUG_ON(bfqq->entity.budget < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index a9da002..e3855af 100644
|
||||
--- a/block/bfq.h
|
||||
+++ b/block/bfq.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
|
||||
*/
|
||||
|
||||
#ifndef _BFQ_H
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Subject: [PATCH] jbd2: Fix dbench4 performance regression for 'nobarrier' mounts
|
||||
Date: Fri, 28 Apr 2017 11:59:34 +0200
|
||||
|
||||
Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as
|
||||
synchronous" removed REQ_SYNC flag from WRITE_FUA implementation. Since
|
||||
JBD2 strips REQ_FUA and REQ_FLUSH flags from submitted IO when the
|
||||
filesystem is mounted with nobarrier mount option, journal superblock
|
||||
writes ended up being async writes after this patch and that caused
|
||||
heavy performance regression for dbench4 benchmark with high number of
|
||||
processes. In my test setup with HP RAID array with non-volatile write
|
||||
cache and 32 GB ram, dbench4 runs with 8 processes regressed by ~25%.
|
||||
|
||||
Fix the problem by making sure journal superblock writes are always
|
||||
treated as synchronous since they generally block progress of the
|
||||
journalling machinery and thus the whole filesystem.
|
||||
|
||||
Fixes: b685d3d65ac791406e0dfd8779cc9b3707fea5a3
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
---
|
||||
fs/jbd2/journal.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
|
||||
index 5adc2fb62b0f..e768126f6a72 100644
|
||||
--- a/fs/jbd2/journal.c
|
||||
+++ b/fs/jbd2/journal.c
|
||||
@@ -1348,7 +1348,7 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
|
||||
jbd2_superblock_csum_set(journal, sb);
|
||||
get_bh(bh);
|
||||
bh->b_end_io = end_buffer_write_sync;
|
||||
- ret = submit_bh(REQ_OP_WRITE, write_flags, bh);
|
||||
+ ret = submit_bh(REQ_OP_WRITE, write_flags | REQ_SYNC, bh);
|
||||
wait_on_buffer(bh);
|
||||
if (buffer_write_io_error(bh)) {
|
||||
clear_buffer_write_io_error(bh);
|
||||
--
|
||||
2.12.0
|
||||
@@ -0,0 +1,28 @@
|
||||
From cf8c73afb3abf0f8905efbaddd4ce11a0deec9da Mon Sep 17 00:00:00 2001
|
||||
From: Evan Quan <evan.quan@amd.com>
|
||||
Date: Fri, 17 Mar 2017 10:22:51 +0800
|
||||
Subject: [PATCH] drm/amd/amdgpu: add POLARIS12 PCI ID
|
||||
|
||||
Signed-off-by: Evan Quan <evan.quan@amd.com>
|
||||
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index f7adbac..b76cd69 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
@@ -421,6 +421,7 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
--
|
||||
2.10.2
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From fc8e9c54699e42754094ff475da46440778d8f19 Mon Sep 17 00:00:00 2001
|
||||
From: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Date: Thu, 4 Aug 2016 12:54:22 +0800
|
||||
Subject: [PATCH] drm/amd/amdgpu: add Polaris12 PCI ID
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Reviewed-by: Christian König <christian.koenig@amd.com>
|
||||
Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index 8cb937b..2534ada 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
@@ -418,6 +418,13 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x67CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
{0x1002, 0x67CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
{0x1002, 0x67CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
+ /* Polaris12 */
|
||||
+ {0x1002, 0x6980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
--
|
||||
2.10.2
|
||||
|
||||
@@ -0,0 +1,469 @@
|
||||
From c4642a479fac9f5c224ff7425d86c427b94011af Mon Sep 17 00:00:00 2001
|
||||
From: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Date: Wed, 14 Dec 2016 15:32:28 -0500
|
||||
Subject: [PATCH] drm/amd/amdgpu: add Polaris12 support (v3)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
v2: agd: squash in various fixes
|
||||
v3: agd: squash in:
|
||||
drm/amdgpu: remove unnecessary smc sk firmware for polaris12
|
||||
|
||||
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Reviewed-by: Christian König <christian.koenig@amd.com>
|
||||
Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
[ rebased for 4.9 / tmb ]
|
||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 3 +++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 13 ++++++++++---
|
||||
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 31 +++++++++++++++++++++++++-----
|
||||
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 6 ++++++
|
||||
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 5 +++--
|
||||
drivers/gpu/drm/amd/amdgpu/vi.c | 10 ++++++++++
|
||||
drivers/gpu/drm/amd/include/amd_shared.h | 1 +
|
||||
11 files changed, 76 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
index 9ada56c..4c851fde 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
@@ -840,6 +840,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
||||
else if (type == CGS_UCODE_ID_SMU_SK)
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ strcpy(fw_name, "amdgpu/polaris12_smc.bin");
|
||||
+ break;
|
||||
default:
|
||||
DRM_ERROR("SMC firmware not supported\n");
|
||||
return -EINVAL;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
index 60bd4af..fe3bb94 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
@@ -73,6 +73,7 @@ static const char *amdgpu_asic_name[] = {
|
||||
"STONEY",
|
||||
"POLARIS10",
|
||||
"POLARIS11",
|
||||
+ "POLARIS12",
|
||||
"LAST",
|
||||
};
|
||||
|
||||
@@ -1277,6 +1278,7 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
|
||||
case CHIP_FIJI:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY)
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
index a81dfae..1d564be 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
@@ -65,6 +65,7 @@
|
||||
#define FIRMWARE_STONEY "amdgpu/stoney_uvd.bin"
|
||||
#define FIRMWARE_POLARIS10 "amdgpu/polaris10_uvd.bin"
|
||||
#define FIRMWARE_POLARIS11 "amdgpu/polaris11_uvd.bin"
|
||||
+#define FIRMWARE_POLARIS12 "amdgpu/polaris12_uvd.bin"
|
||||
|
||||
/**
|
||||
* amdgpu_uvd_cs_ctx - Command submission parser context
|
||||
@@ -98,6 +99,7 @@ MODULE_FIRMWARE(FIRMWARE_FIJI);
|
||||
MODULE_FIRMWARE(FIRMWARE_STONEY);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS10);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS11);
|
||||
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
|
||||
|
||||
static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
|
||||
|
||||
@@ -149,6 +151,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS11:
|
||||
fw_name = FIRMWARE_POLARIS11;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ fw_name = FIRMWARE_POLARIS12;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
index 69b66b9..8fec802 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#define FIRMWARE_STONEY "amdgpu/stoney_vce.bin"
|
||||
#define FIRMWARE_POLARIS10 "amdgpu/polaris10_vce.bin"
|
||||
#define FIRMWARE_POLARIS11 "amdgpu/polaris11_vce.bin"
|
||||
+#define FIRMWARE_POLARIS12 "amdgpu/polaris12_vce.bin"
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
MODULE_FIRMWARE(FIRMWARE_BONAIRE);
|
||||
@@ -66,6 +67,7 @@ MODULE_FIRMWARE(FIRMWARE_FIJI);
|
||||
MODULE_FIRMWARE(FIRMWARE_STONEY);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS10);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS11);
|
||||
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
|
||||
|
||||
static void amdgpu_vce_idle_work_handler(struct work_struct *work);
|
||||
|
||||
@@ -121,6 +123,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
||||
case CHIP_POLARIS11:
|
||||
fw_name = FIRMWARE_POLARIS11;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ fw_name = FIRMWARE_POLARIS12;
|
||||
+ break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
index b3d62b9..2006abb 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
@@ -167,6 +167,7 @@ static void dce_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris11_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(polaris11_golden_settings_a11));
|
||||
@@ -608,6 +609,7 @@ static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
|
||||
num_crtc = 6;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
num_crtc = 5;
|
||||
break;
|
||||
default:
|
||||
@@ -1589,6 +1591,7 @@ static int dce_v11_0_audio_init(struct amdgpu_device *adev)
|
||||
adev->mode_info.audio.num_pins = 8;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->mode_info.audio.num_pins = 6;
|
||||
break;
|
||||
default:
|
||||
@@ -2388,7 +2391,8 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc)
|
||||
int pll;
|
||||
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
struct amdgpu_encoder *amdgpu_encoder =
|
||||
to_amdgpu_encoder(amdgpu_crtc->encoder);
|
||||
struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
|
||||
@@ -2822,7 +2826,8 @@ static int dce_v11_0_crtc_mode_set(struct drm_crtc *crtc,
|
||||
return -EINVAL;
|
||||
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
struct amdgpu_encoder *amdgpu_encoder =
|
||||
to_amdgpu_encoder(amdgpu_crtc->encoder);
|
||||
int encoder_mode =
|
||||
@@ -2992,6 +2997,7 @@ static int dce_v11_0_early_init(void *handle)
|
||||
adev->mode_info.num_dig = 6;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->mode_info.num_hpd = 5;
|
||||
adev->mode_info.num_dig = 5;
|
||||
break;
|
||||
@@ -3101,7 +3107,8 @@ static int dce_v11_0_hw_init(void *handle)
|
||||
amdgpu_atombios_crtc_powergate_init(adev);
|
||||
amdgpu_atombios_encoder_init_dig(adev);
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
amdgpu_atombios_crtc_set_dce_clock(adev, adev->clock.default_dispclk,
|
||||
DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS);
|
||||
amdgpu_atombios_crtc_set_dce_clock(adev, 0,
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
index d0ec009..3733741 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
@@ -138,6 +138,13 @@ MODULE_FIRMWARE("amdgpu/polaris10_mec.bi
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin");
|
||||
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_ce.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_me.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mec.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin");
|
||||
+
|
||||
static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] =
|
||||
{
|
||||
{mmGDS_VMID0_BASE, mmGDS_VMID0_SIZE, mmGDS_GWS_VMID0, mmGDS_OA_VMID0},
|
||||
@@ -687,6 +694,7 @@ static void gfx_v8_0_init_golden_registe
|
||||
(const u32)ARRAY_SIZE(tonga_golden_common_all));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -901,6 +909,9 @@ static int gfx_v8_0_init_microcode(struc
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_STONEY:
|
||||
chip_name = "stoney";
|
||||
break;
|
||||
@@ -1777,6 +1788,7 @@ static int gfx_v8_0_gpu_early_init(struc
|
||||
gb_addr_config = TONGA_GB_ADDR_CONFIG_GOLDEN;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
ret = amdgpu_atombios_get_gfx_info(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2695,6 +2707,7 @@ static void gfx_v8_0_tiling_mode_table_i
|
||||
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
|
||||
PIPE_CONFIG(ADDR_SURF_P4_16x16) |
|
||||
TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
|
||||
@@ -3516,6 +3529,7 @@ gfx_v8_0_raster_config(struct amdgpu_dev
|
||||
*rconf1 |= 0x0;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
*rconf |= RB_MAP_PKR0(2) | RB_XSEL2(1) | SE_MAP(2) |
|
||||
SE_XSEL(1) | SE_YSEL(1);
|
||||
*rconf1 |= 0x0;
|
||||
@@ -4029,7 +4043,8 @@ static void gfx_v8_0_init_pg(struct amdg
|
||||
cz_enable_cp_power_gating(adev, true);
|
||||
else
|
||||
cz_enable_cp_power_gating(adev, false);
|
||||
- } else if (adev->asic_type == CHIP_POLARIS11) {
|
||||
+ } else if ((adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS11)) {
|
||||
gfx_v8_0_init_power_gating(adev);
|
||||
}
|
||||
}
|
||||
@@ -4100,7 +4115,8 @@ static int gfx_v8_0_rlc_resume(struct am
|
||||
RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
|
||||
if (adev->asic_type == CHIP_POLARIS11 ||
|
||||
- adev->asic_type == CHIP_POLARIS10) {
|
||||
+ adev->asic_type == CHIP_POLARIS10 ||
|
||||
+ adev->asic_type == CHIP_POLARIS12) {
|
||||
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
|
||||
tmp &= ~0x3;
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
|
||||
@@ -4288,6 +4304,7 @@ static int gfx_v8_0_cp_gfx_start(struct
|
||||
amdgpu_ring_write(ring, 0x0000002A);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_ring_write(ring, 0x16000012);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
@@ -4938,7 +4955,8 @@ static int gfx_v8_0_cp_compute_resume(st
|
||||
(adev->asic_type == CHIP_FIJI) ||
|
||||
(adev->asic_type == CHIP_STONEY) ||
|
||||
(adev->asic_type == CHIP_POLARIS11) ||
|
||||
- (adev->asic_type == CHIP_POLARIS10)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS10) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER,
|
||||
AMDGPU_DOORBELL_KIQ << 2);
|
||||
WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
|
||||
@@ -4974,7 +4992,8 @@ static int gfx_v8_0_cp_compute_resume(st
|
||||
mqd->cp_hqd_persistent_state = tmp;
|
||||
if (adev->asic_type == CHIP_STONEY ||
|
||||
adev->asic_type == CHIP_POLARIS11 ||
|
||||
- adev->asic_type == CHIP_POLARIS10) {
|
||||
+ adev->asic_type == CHIP_POLARIS10 ||
|
||||
+ adev->asic_type == CHIP_POLARIS12) {
|
||||
tmp = RREG32(mmCP_ME1_PIPE3_INT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE3_INT_CNTL, GENERIC2_INT_ENABLE, 1);
|
||||
WREG32(mmCP_ME1_PIPE3_INT_CNTL, tmp);
|
||||
@@ -5488,7 +5507,8 @@ static int gfx_v8_0_late_init(void *hand
|
||||
static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
- if (adev->asic_type == CHIP_POLARIS11)
|
||||
+ if ((adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12))
|
||||
/* Send msg to SMU via Powerplay */
|
||||
amdgpu_set_powergating_state(adev,
|
||||
AMD_IP_BLOCK_TYPE_SMC,
|
||||
@@ -5565,6 +5585,7 @@ static int gfx_v8_0_set_powergating_stat
|
||||
gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, false);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable)
|
||||
gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true);
|
||||
else
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
index 0daac3a..476bc9f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
@@ -46,6 +46,7 @@ static int gmc_v8_0_wait_for_idle(void *handle);
|
||||
MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_mc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_mc.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mc.bin");
|
||||
|
||||
static const u32 golden_settings_tonga_a11[] =
|
||||
{
|
||||
@@ -130,6 +131,7 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -225,6 +227,9 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_FIJI:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
index 1170a64..034ace7 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
@@ -60,6 +60,8 @@ MODULE_FIRMWARE("amdgpu/polaris10_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_sdma1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_sdma1.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_sdma.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_sdma1.bin");
|
||||
|
||||
|
||||
static const u32 sdma_offsets[SDMA_MAX_INSTANCE] =
|
||||
@@ -206,6 +208,7 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -278,6 +281,9 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_CARRIZO:
|
||||
chip_name = "carrizo";
|
||||
break;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
index 6b3293a..5fb0b7f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
@@ -320,11 +320,12 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
- /* Fiji, Stoney, Polaris10, Polaris11 are single pipe */
|
||||
+ /* Fiji, Stoney, Polaris10, Polaris11, Polaris12 are single pipe */
|
||||
if ((adev->asic_type == CHIP_FIJI) ||
|
||||
(adev->asic_type == CHIP_STONEY) ||
|
||||
(adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11))
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12))
|
||||
return AMDGPU_VCE_HARVEST_VCE1;
|
||||
|
||||
/* Tonga and CZ are dual or single pipe */
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
index bf088d6..c2ac54f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
@@ -88,6 +88,7 @@ MODULE_FIRMWARE("amdgpu/polaris10_smc.bi
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
@@ -312,6 +313,7 @@ static void vi_init_golden_registers(str
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -592,6 +594,7 @@ static int vi_read_register(struct amdgp
|
||||
case CHIP_TONGA:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
asic_register_table = cz_allowed_read_registers;
|
||||
@@ -1465,6 +1468,7 @@ int vi_set_ip_blocks(struct amdgpu_devic
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->ip_blocks = polaris11_ip_blocks_vd;
|
||||
adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks_vd);
|
||||
break;
|
||||
@@ -1608,6 +1612,11 @@ static int vi_common_early_init(void *ha
|
||||
adev->pg_flags = 0;
|
||||
adev->external_rev_id = adev->rev_id + 0x50;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG;
|
||||
+ adev->pg_flags = 0;
|
||||
+ adev->external_rev_id = adev->rev_id + 0x64;
|
||||
+ break;
|
||||
case CHIP_CARRIZO:
|
||||
adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGCG |
|
||||
@@ -1897,6 +1906,7 @@ static int vi_common_set_clockgating_sta
|
||||
case CHIP_TONGA:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
vi_common_set_clockgating_state_by_smu(adev, state);
|
||||
default:
|
||||
break;
|
||||
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
index c02469a..5f59117 100644
|
||||
--- a/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
@@ -46,6 +46,7 @@ enum amd_asic_type {
|
||||
CHIP_STONEY,
|
||||
CHIP_POLARIS10,
|
||||
CHIP_POLARIS11,
|
||||
+ CHIP_POLARIS12,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
--
|
||||
2.10.2
|
||||
@@ -0,0 +1,24 @@
|
||||
From 6e88491cf2a3b17199c78bd53348b39dc6a88275 Mon Sep 17 00:00:00 2001
|
||||
From: Junshan Fang <Junshan.Fang@amd.com>
|
||||
Date: Thu, 15 Jun 2017 14:02:20 +0800
|
||||
Subject: [PATCH] drm/amdgpu: add Polaris12 DID
|
||||
|
||||
Signed-off-by: Junshan Fang <Junshan.Fang@amd.com>
|
||||
Reviewed-by: Roger.He <Hongbo.He@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index f2d705e6a75a..ab6b0d0febab 100644
|
||||
@@ -418,6 +418,7 @@ static const struct pci_device_id pciidl
|
||||
{0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From c10c8f7c27103bd7ac02d041d9d6e97296d48fc1 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Deucher <alexander.deucher@amd.com>
|
||||
Date: Fri, 10 Feb 2017 18:09:32 -0500
|
||||
Subject: [PATCH] drm/amdgpu/pm: check for headless before calling
|
||||
compute_clocks
|
||||
|
||||
Don't update display bandwidth on headless asics.
|
||||
|
||||
bug:
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=99387
|
||||
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
index 95e026a..346e80a 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
@@ -1283,7 +1283,9 @@ void amdgpu_pm_compute_clocks(struct amd
|
||||
if (adev->pp_enabled) {
|
||||
int i = 0;
|
||||
|
||||
- amdgpu_display_bandwidth_update(adev);
|
||||
+ if (adev->mode_info.num_crtc)
|
||||
+ amdgpu_display_bandwidth_update(adev);
|
||||
+
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
if (ring && ring->ready)
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
From f4309526576db325264b6dc9ee150ee70b330a42 Mon Sep 17 00:00:00 2001
|
||||
From: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Date: Wed, 14 Dec 2016 15:40:48 -0500
|
||||
Subject: [PATCH] drm/amdgpu/powerplay: add Polaris12 support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Reviewed-by: Christian König <christian.koenig@amd.com>
|
||||
Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 1 +
|
||||
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 3 ++-
|
||||
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | 2 +-
|
||||
drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | 1 +
|
||||
4 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
|
||||
index fc592c2..95a568d 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
|
||||
@@ -98,6 +98,7 @@ static int amdgpu_pp_early_init(void *handle)
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TOPAZ:
|
||||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
|
||||
index dc6700a..b036064 100644
|
||||
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
|
||||
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
|
||||
@@ -95,6 +95,7 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
polaris_set_asic_special_caps(hwmgr);
|
||||
hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
|
||||
break;
|
||||
@@ -745,7 +746,7 @@ int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_TablelessHardwareInterface);
|
||||
|
||||
- if (hwmgr->chip_id == CHIP_POLARIS11)
|
||||
+ if ((hwmgr->chip_id == CHIP_POLARIS11) || (hwmgr->chip_id == CHIP_POLARIS12))
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_SPLLShutdownSupport);
|
||||
return 0;
|
||||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
|
||||
index 26477f0..6cd1287 100644
|
||||
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
|
||||
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
|
||||
@@ -521,7 +521,7 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr)
|
||||
PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result);
|
||||
result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris10);
|
||||
PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result);
|
||||
- } else if (hwmgr->chip_id == CHIP_POLARIS11) {
|
||||
+ } else if ((hwmgr->chip_id == CHIP_POLARIS11) || (hwmgr->chip_id == CHIP_POLARIS12)) {
|
||||
result = smu7_program_pt_config_registers(hwmgr, GCCACConfig_Polaris11);
|
||||
PP_ASSERT_WITH_CODE((result == 0), "DIDT Config failed.", return result);
|
||||
result = smu7_program_pt_config_registers(hwmgr, DIDTConfig_Polaris11);
|
||||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
|
||||
index e5812aa..6e618aa 100644
|
||||
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
|
||||
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
|
||||
@@ -65,6 +65,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
polaris10_smum_init(smumgr);
|
||||
break;
|
||||
default:
|
||||
--
|
||||
2.10.2
|
||||
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
From 8726f2faa371514fba2f594d799db95203dfeee0 Mon Sep 17 00:00:00 2001
|
||||
From: Francisco Jerez <currojerez@riseup.net>
|
||||
Date: Thu, 12 Jan 2017 12:44:54 +0200
|
||||
Subject: drm/i915: Remove WaDisableLSQCROPERFforOCL KBL workaround.
|
||||
|
||||
The WaDisableLSQCROPERFforOCL workaround has the side effect of
|
||||
disabling an L3SQ optimization that has huge performance implications
|
||||
and is unlikely to be necessary for the correct functioning of usual
|
||||
graphic workloads. Userspace is free to re-enable the workaround on
|
||||
demand, and is generally in a better position to determine whether the
|
||||
workaround is necessary than the DRM is (e.g. only during the
|
||||
execution of compute kernels that rely on both L3 fences and HDC R/W
|
||||
requests).
|
||||
|
||||
The same workaround seems to apply to BDW (at least to production
|
||||
stepping G1) and SKL as well (the internal workaround database claims
|
||||
that it does for all steppings, while the BSpec workaround table only
|
||||
mentions pre-production steppings), but the DRM doesn't do anything
|
||||
beyond whitelisting the L3SQCREG4 register so userspace can enable it
|
||||
when it sees fit. Do the same on KBL platforms.
|
||||
|
||||
Improves performance of the GFXBench4 gl_manhattan31 benchmark by 60%,
|
||||
and gl_4 (AKA car chase) by 14% on a KBL GT2 running Mesa master --
|
||||
This is followed by a regression of 35% and 10% respectively for the
|
||||
same benchmarks and platform caused by my recent patch series
|
||||
switching userspace to use the dataport constant cache instead of the
|
||||
sampler to implement uniform pull constant loads, which caused us to
|
||||
hit more heavily the L3 cache (and on platforms other than KBL had the
|
||||
opposite effect of improving performance of the same two benchmarks).
|
||||
The overall effect on KBL of this change combined with the recent
|
||||
userspace change is respectively 4.6% and 2.6%. SynMark2 OglShMapPcf
|
||||
was affected by the constant cache changes (though it improved as it
|
||||
did on other platforms rather than regressing), but is not
|
||||
significantly affected by this patch (with statistical significance of
|
||||
5% and sample size 20).
|
||||
|
||||
v2: Drop some more code to avoid unused variable warning.
|
||||
|
||||
Fixes: 738fa1b3123f ("drm/i915/kbl: Add WaDisableLSQCROPERFforOCL")
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99256
|
||||
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
|
||||
Cc: Matthew Auld <matthew.william.auld@gmail.com>
|
||||
Cc: Eero Tamminen <eero.t.tamminen@intel.com>
|
||||
Cc: Jani Nikula <jani.nikula@intel.com>
|
||||
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
|
||||
Cc: beignet@lists.freedesktop.org
|
||||
Cc: <stable@vger.kernel.org> # v4.7+
|
||||
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
|
||||
[Removed double Fixes tag]
|
||||
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/1484217894-20505-1-git-send-email-mika.kuoppala@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
index db714dc..8acab87 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lrc.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
@@ -970,18 +970,8 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
|
||||
uint32_t *batch,
|
||||
uint32_t index)
|
||||
{
|
||||
- struct drm_i915_private *dev_priv = engine->i915;
|
||||
uint32_t l3sqc4_flush = (0x40400000 | GEN8_LQSC_FLUSH_COHERENT_LINES);
|
||||
|
||||
- /*
|
||||
- * WaDisableLSQCROPERFforOCL:kbl
|
||||
- * This WA is implemented in skl_init_clock_gating() but since
|
||||
- * this batch updates GEN8_L3SQCREG4 with default value we need to
|
||||
- * set this bit here to retain the WA during flush.
|
||||
- */
|
||||
- if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
|
||||
- l3sqc4_flush |= GEN8_LQSC_RO_PERF_DIS;
|
||||
-
|
||||
wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 |
|
||||
MI_SRM_LRM_GLOBAL_GTT));
|
||||
wa_ctx_emit_reg(batch, index, GEN8_L3SQCREG4);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
index ab83fc2..49fa800 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
@@ -1095,14 +1095,6 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine)
|
||||
WA_SET_BIT_MASKED(HDC_CHICKEN0,
|
||||
HDC_FENCE_DEST_SLM_DISABLE);
|
||||
|
||||
- /* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
|
||||
- * involving this register should also be added to WA batch as required.
|
||||
- */
|
||||
- if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
|
||||
- /* WaDisableLSQCROPERFforOCL:kbl */
|
||||
- I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
|
||||
- GEN8_LQSC_RO_PERF_DIS);
|
||||
-
|
||||
/* WaToEnableHwFixForPushConstHWBug:kbl */
|
||||
if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
|
||||
WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From 853277481178fdf14d1a4e9e6ac7174d6046176f Mon Sep 17 00:00:00 2001
|
||||
From: Jani Nikula <jani.nikula@intel.com>
|
||||
Date: Wed, 1 Feb 2017 15:46:09 +0200
|
||||
Subject: [PATCH] drm/i915: don't warn about Skylake CPU - KabyPoint PCH combo
|
||||
|
||||
Apparently there are machines out there with Skylake CPU and KabyPoint
|
||||
PCH. Judging from our driver code, there doesn't seem to be any code
|
||||
paths that would do anything different between SunrisePoint and
|
||||
KabyPoint PCHs, so it would seem okay to accept the combo without
|
||||
warnings.
|
||||
|
||||
Fixes: 22dea0be50b2 ("drm/i915: Introduce Kabypoint PCH for Kabylake H/DT.")
|
||||
References: https://lists.freedesktop.org/archives/intel-gfx/2017-February/118611.html
|
||||
Reported-by: Rainer Koenig <Rainer.Koenig@ts.fujitsu.com>
|
||||
Cc: Rainer Koenig <Rainer.Koenig@ts.fujitsu.com>
|
||||
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
|
||||
Cc: <stable@vger.kernel.org> # v4.8+
|
||||
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/1485956769-26015-1-git-send-email-jani.nikula@intel.com
|
||||
(cherry picked from commit 3aac4acb89710fe782c9e78e7b1febf76e112c6c)
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
[ rebased for 4.9 / tmb ]
|
||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_drv.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
|
||||
index b2c4a0b..8d63098 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_drv.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
||||
@@ -207,7 +207,8 @@ static void intel_detect_pch(struct drm_
|
||||
} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
|
||||
dev_priv->pch_type = PCH_KBP;
|
||||
DRM_DEBUG_KMS("Found KabyPoint PCH\n");
|
||||
- WARN_ON(!IS_KABYLAKE(dev));
|
||||
+ WARN_ON(!IS_SKYLAKE(dev) &&
|
||||
+ !IS_KABYLAKE(dev));
|
||||
} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
|
||||
(id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
|
||||
((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
From a117f378f44150e6d13d2f19740fb757425b651f Mon Sep 17 00:00:00 2001
|
||||
From: Jani Nikula <jani.nikula@intel.com>
|
||||
Date: Fri, 16 Sep 2016 16:59:44 +0300
|
||||
Subject: drm/i915/skl: drop workarounds for A0 and B0 revisions
|
||||
|
||||
Pre-production hardware is not supported.
|
||||
|
||||
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/7929af62a68504c84038a8db1625bd96ebaa9e6f.1474034059.git.jani.nikula@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
|
||||
index 0568fb5..57da2b7 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_dp.c
|
||||
@@ -1299,10 +1299,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_device *dev = dig_port->base.base.dev;
|
||||
|
||||
- /* WaDisableHBR2:skl */
|
||||
- if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
|
||||
- return false;
|
||||
-
|
||||
if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
|
||||
(INTEL_INFO(dev)->gen >= 9))
|
||||
return true;
|
||||
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
|
||||
index c438b02..0048b52 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
|
||||
@@ -225,9 +225,6 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
|
||||
* Intel platforms that support HBR2 also support TPS3. TPS3 support is
|
||||
* also mandatory for downstream devices that support HBR2. However, not
|
||||
* all sinks follow the spec.
|
||||
- *
|
||||
- * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
|
||||
- * supported in source but still not enabled.
|
||||
*/
|
||||
source_tps3 = intel_dp_source_supports_hbr2(intel_dp);
|
||||
sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
|
||||
index 6fd39ef..acc1dbd 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
|
||||
@@ -375,9 +375,8 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
|
||||
/* Enable MIA caching. GuC clock gating is disabled. */
|
||||
I915_WRITE(GUC_SHIM_CONTROL, GUC_SHIM_CONTROL_VALUE);
|
||||
|
||||
- /* WaDisableMinuteIaClockGating:skl,bxt */
|
||||
- if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) ||
|
||||
- IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
|
||||
+ /* WaDisableMinuteIaClockGating:bxt */
|
||||
+ if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
|
||||
I915_WRITE(GUC_SHIM_CONTROL, (I915_READ(GUC_SHIM_CONTROL) &
|
||||
~GUC_ENABLE_MIA_CLOCK_GATING));
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
index 39417b7..47f7afa 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lrc.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
@@ -269,8 +269,7 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *engine)
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
|
||||
engine->disable_lite_restore_wa =
|
||||
- (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0) ||
|
||||
- IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) &&
|
||||
+ IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1) &&
|
||||
(engine->id == VCS || engine->id == VCS2);
|
||||
|
||||
engine->ctx_desc_template = GEN8_CTX_VALID;
|
||||
@@ -1068,9 +1067,8 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
|
||||
{
|
||||
uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
|
||||
|
||||
- /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */
|
||||
- if (IS_SKL_REVID(engine->i915, 0, SKL_REVID_B0) ||
|
||||
- IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) {
|
||||
+ /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
|
||||
+ if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) {
|
||||
wa_ctx_emit(batch, index, MI_LOAD_REGISTER_IMM(1));
|
||||
wa_ctx_emit_reg(batch, index, GEN9_SLICE_COMMON_ECO_CHICKEN0);
|
||||
wa_ctx_emit(batch, index,
|
||||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
index 7a74750..2faf64f 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
@@ -851,15 +851,13 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
|
||||
WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
|
||||
GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
|
||||
|
||||
- /* WaDisableDgMirrorFixInHalfSliceChicken5:skl,bxt */
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0) ||
|
||||
- IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
|
||||
+ /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
|
||||
+ if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
|
||||
WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
|
||||
GEN9_DG_MIRROR_FIX_ENABLE);
|
||||
|
||||
- /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0) ||
|
||||
- IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
|
||||
+ /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
|
||||
+ if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
|
||||
WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
|
||||
GEN9_RHWO_OPTIMIZATION_DISABLE);
|
||||
/*
|
||||
@@ -1023,15 +1021,8 @@ static int skl_init_workarounds(struct intel_engine_cs *engine)
|
||||
GEN8_LQSC_RO_PERF_DIS);
|
||||
|
||||
/* WaEnableGapsTsvCreditFix:skl */
|
||||
- if (IS_SKL_REVID(dev_priv, SKL_REVID_C0, REVID_FOREVER)) {
|
||||
- I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
|
||||
- GEN9_GAPS_TSV_CREDIT_DISABLE));
|
||||
- }
|
||||
-
|
||||
- /* WaDisablePowerCompilerClockGating:skl */
|
||||
- if (IS_SKL_REVID(dev_priv, SKL_REVID_B0, SKL_REVID_B0))
|
||||
- WA_SET_BIT_MASKED(HIZ_CHICKEN,
|
||||
- BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE);
|
||||
+ I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
|
||||
+ GEN9_GAPS_TSV_CREDIT_DISABLE));
|
||||
|
||||
/* WaBarrierPerformanceFixDisable:skl */
|
||||
if (IS_SKL_REVID(dev_priv, SKL_REVID_C0, SKL_REVID_D0))
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
From 9fc736e833d226853fd53843e35d6a1d542394ed Mon Sep 17 00:00:00 2001
|
||||
From: Jani Nikula <jani.nikula@intel.com>
|
||||
Date: Fri, 16 Sep 2016 16:59:46 +0300
|
||||
Subject: drm/i915/skl: drop workarounds for D0 revision
|
||||
|
||||
Pre-production hardware is not supported.
|
||||
|
||||
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/d28d21ceddeec226b5d1a20a7382bee9a72709a4.1474034059.git.jani.nikula@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
index 47f7afa..ca649cc 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lrc.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
@@ -994,9 +994,8 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine,
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
uint32_t index = wa_ctx_start(wa_ctx, *offset, CACHELINE_DWORDS);
|
||||
|
||||
- /* WaDisableCtxRestoreArbitration:skl,bxt */
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_D0) ||
|
||||
- IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
|
||||
+ /* WaDisableCtxRestoreArbitration:bxt */
|
||||
+ if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
|
||||
wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_DISABLE);
|
||||
|
||||
/* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt */
|
||||
@@ -1095,9 +1094,8 @@ static int gen9_init_perctx_bb(struct intel_engine_cs *engine,
|
||||
wa_ctx_emit(batch, index, MI_NOOP);
|
||||
}
|
||||
|
||||
- /* WaDisableCtxRestoreArbitration:skl,bxt */
|
||||
- if (IS_SKL_REVID(engine->i915, 0, SKL_REVID_D0) ||
|
||||
- IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1))
|
||||
+ /* WaDisableCtxRestoreArbitration:bxt */
|
||||
+ if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1))
|
||||
wa_ctx_emit(batch, index, MI_ARB_ON_OFF | MI_ARB_ENABLE);
|
||||
|
||||
wa_ctx_emit(batch, index, MI_BATCH_BUFFER_END);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
||||
index 2df06b7..a860c40 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_pm.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
||||
@@ -5335,8 +5335,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
|
||||
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
|
||||
DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
|
||||
/* WaRsUseTimeoutMode */
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_D0) ||
|
||||
- IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
|
||||
+ if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
|
||||
I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */
|
||||
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
|
||||
GEN7_RC_CTL_TO_MODE |
|
||||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
index 474ce84..6880082 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
@@ -1000,10 +1000,8 @@ static int skl_init_workarounds(struct intel_engine_cs *engine)
|
||||
* until D0 which is the default case so this is equivalent to
|
||||
* !WaDisablePerCtxtPreemptionGranularityControl:skl
|
||||
*/
|
||||
- if (IS_SKL_REVID(dev_priv, SKL_REVID_E0, REVID_FOREVER)) {
|
||||
- I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
|
||||
- _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
|
||||
- }
|
||||
+ I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
|
||||
+ _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
|
||||
|
||||
if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0)) {
|
||||
/* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */
|
||||
@@ -1023,12 +1021,6 @@ static int skl_init_workarounds(struct intel_engine_cs *engine)
|
||||
I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
|
||||
GEN9_GAPS_TSV_CREDIT_DISABLE));
|
||||
|
||||
- /* WaBarrierPerformanceFixDisable:skl */
|
||||
- if (IS_SKL_REVID(dev_priv, SKL_REVID_C0, SKL_REVID_D0))
|
||||
- WA_SET_BIT_MASKED(HDC_CHICKEN0,
|
||||
- HDC_FENCE_DEST_SLM_DISABLE |
|
||||
- HDC_BARRIER_PERFORMANCE_DISABLE);
|
||||
-
|
||||
/* WaDisableSbeCacheDispatchPortSharing:skl */
|
||||
if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0))
|
||||
WA_SET_BIT_MASKED(
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
From 3be192e92ddcad15f7bf6b4b9e3f195eb8c1fe76 Mon Sep 17 00:00:00 2001
|
||||
From: Jani Nikula <jani.nikula@intel.com>
|
||||
Date: Fri, 16 Sep 2016 16:59:47 +0300
|
||||
Subject: drm/i915/skl: drop workarounds for E0 revision
|
||||
|
||||
Pre-production hardware is not supported.
|
||||
|
||||
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/0633a02177195703502ef2396aab03efc0314334.1474034059.git.jani.nikula@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
index ca649cc..2d8eb2e 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lrc.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lrc.c
|
||||
@@ -845,13 +845,12 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
|
||||
uint32_t l3sqc4_flush = (0x40400000 | GEN8_LQSC_FLUSH_COHERENT_LINES);
|
||||
|
||||
/*
|
||||
- * WaDisableLSQCROPERFforOCL:skl,kbl
|
||||
+ * WaDisableLSQCROPERFforOCL:kbl
|
||||
* This WA is implemented in skl_init_clock_gating() but since
|
||||
* this batch updates GEN8_L3SQCREG4 with default value we need to
|
||||
* set this bit here to retain the WA during flush.
|
||||
*/
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0) ||
|
||||
- IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
|
||||
+ if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
|
||||
l3sqc4_flush |= GEN8_LQSC_RO_PERF_DIS;
|
||||
|
||||
wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 |
|
||||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
index 6880082..68dc27f 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
|
||||
@@ -1003,20 +1003,6 @@ static int skl_init_workarounds(struct intel_engine_cs *engine)
|
||||
I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
|
||||
_MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
|
||||
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0)) {
|
||||
- /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */
|
||||
- I915_WRITE(FF_SLICE_CS_CHICKEN2,
|
||||
- _MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE));
|
||||
- }
|
||||
-
|
||||
- /* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
|
||||
- * involving this register should also be added to WA batch as required.
|
||||
- */
|
||||
- if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0))
|
||||
- /* WaDisableLSQCROPERFforOCL:skl */
|
||||
- I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
|
||||
- GEN8_LQSC_RO_PERF_DIS);
|
||||
-
|
||||
/* WaEnableGapsTsvCreditFix:skl */
|
||||
I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
|
||||
GEN9_GAPS_TSV_CREDIT_DISABLE));
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
From: Arindam Nath <arindam.nath@amd.com>
|
||||
|
||||
Change History
|
||||
--------------
|
||||
|
||||
v3:
|
||||
- add Fixes and CC tags
|
||||
- add link to Bugzilla
|
||||
|
||||
v2: changes suggested by Joerg
|
||||
- add flush flag to improve efficiency of flush operation
|
||||
|
||||
v1:
|
||||
- The idea behind flush queues is to defer the IOTLB flushing
|
||||
for domains for which the mappings are no longer valid. We
|
||||
add such domains in queue_add(), and when the queue size
|
||||
reaches FLUSH_QUEUE_SIZE, we perform __queue_flush().
|
||||
|
||||
Since we have already taken lock before __queue_flush()
|
||||
is called, we need to make sure the IOTLB flushing is
|
||||
performed as quickly as possible.
|
||||
|
||||
In the current implementation, we perform IOTLB flushing
|
||||
for all domains irrespective of which ones were actually
|
||||
added in the flush queue initially. This can be quite
|
||||
expensive especially for domains for which unmapping is
|
||||
not required at this point of time.
|
||||
|
||||
This patch makes use of domain information in
|
||||
'struct flush_queue_entry' to make sure we only flush
|
||||
IOTLBs for domains who need it, skipping others.
|
||||
|
||||
Bugzilla: https://bugs.freedesktop.org/101029
|
||||
Fixes: b1516a14657a ("iommu/amd: Implement flush queue")
|
||||
Cc: stable@vger.kernel.org
|
||||
Suggested-by: Joerg Roedel <joro@8bytes.org>
|
||||
Signed-off-by: Arindam Nath <arindam.nath@amd.com>
|
||||
---
|
||||
drivers/iommu/amd_iommu.c | 27 ++++++++++++++++++++-------
|
||||
drivers/iommu/amd_iommu_types.h | 2 ++
|
||||
2 files changed, 22 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
|
||||
index 63cacf5..1edeebec 100644
|
||||
--- a/drivers/iommu/amd_iommu.c
|
||||
+++ b/drivers/iommu/amd_iommu.c
|
||||
@@ -2227,15 +2227,26 @@ static struct iommu_group *amd_iommu_device_group(struct device *dev)
|
||||
|
||||
static void __queue_flush(struct flush_queue *queue)
|
||||
{
|
||||
- struct protection_domain *domain;
|
||||
- unsigned long flags;
|
||||
int idx;
|
||||
|
||||
- /* First flush TLB of all known domains */
|
||||
- spin_lock_irqsave(&amd_iommu_pd_lock, flags);
|
||||
- list_for_each_entry(domain, &amd_iommu_pd_list, list)
|
||||
- domain_flush_tlb(domain);
|
||||
- spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
|
||||
+ /* First flush TLB of all domains which were added to flush queue */
|
||||
+ for (idx = 0; idx < queue->next; ++idx) {
|
||||
+ struct flush_queue_entry *entry;
|
||||
+
|
||||
+ entry = queue->entries + idx;
|
||||
+
|
||||
+ /*
|
||||
+ * There might be cases where multiple IOVA entries for the
|
||||
+ * same domain are queued in the flush queue. To avoid
|
||||
+ * flushing the same domain again, we check whether the
|
||||
+ * flag is set or not. This improves the efficiency of
|
||||
+ * flush operation.
|
||||
+ */
|
||||
+ if (!entry->dma_dom->domain.already_flushed) {
|
||||
+ entry->dma_dom->domain.already_flushed = true;
|
||||
+ domain_flush_tlb(&entry->dma_dom->domain);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* Wait until flushes have completed */
|
||||
domain_flush_complete(NULL);
|
||||
@@ -2289,6 +2300,8 @@ static void queue_add(struct dma_ops_domain *dma_dom,
|
||||
pages = __roundup_pow_of_two(pages);
|
||||
address >>= PAGE_SHIFT;
|
||||
|
||||
+ dma_dom->domain.already_flushed = false;
|
||||
+
|
||||
queue = get_cpu_ptr(&flush_queue);
|
||||
spin_lock_irqsave(&queue->lock, flags);
|
||||
|
||||
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
|
||||
index 4de8f41..4f5519d 100644
|
||||
--- a/drivers/iommu/amd_iommu_types.h
|
||||
+++ b/drivers/iommu/amd_iommu_types.h
|
||||
@@ -454,6 +454,8 @@ struct protection_domain {
|
||||
bool updated; /* complete domain flush required */
|
||||
unsigned dev_cnt; /* devices assigned to this domain */
|
||||
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
|
||||
+ bool already_flushed; /* flag to avoid flushing the same domain again
|
||||
+ in a single invocation of __queue_flush() */
|
||||
};
|
||||
|
||||
/*
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
From 2638fd0f92d4397884fd991d8f4925cb3f081901 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Mon, 3 Apr 2017 10:55:11 -0700
|
||||
Subject: [PATCH] netfilter: xt_TCPMSS: add more sanity tests on tcph->doff
|
||||
|
||||
Denys provided an awesome KASAN report pointing to an use
|
||||
after free in xt_TCPMSS
|
||||
|
||||
I have provided three patches to fix this issue, either in xt_TCPMSS or
|
||||
in xt_tcpudp.c. It seems xt_TCPMSS patch has the smallest possible
|
||||
impact.
|
||||
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Reported-by: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
net/netfilter/xt_TCPMSS.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
|
||||
index 27241a767f17..c64aca611ac5 100644
|
||||
--- a/net/netfilter/xt_TCPMSS.c
|
||||
+++ b/net/netfilter/xt_TCPMSS.c
|
||||
@@ -104,7 +104,7 @@ tcpmss_mangle_packet(struct sk_buff *skb,
|
||||
tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
|
||||
tcp_hdrlen = tcph->doff * 4;
|
||||
|
||||
- if (len < tcp_hdrlen)
|
||||
+ if (len < tcp_hdrlen || tcp_hdrlen < sizeof(struct tcphdr))
|
||||
return -1;
|
||||
|
||||
if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
|
||||
@@ -152,6 +152,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
|
||||
if (len > tcp_hdrlen)
|
||||
return 0;
|
||||
|
||||
+ /* tcph->doff has 4 bits, do not wrap it to 0 */
|
||||
+ if (tcp_hdrlen >= 15 * 4)
|
||||
+ return 0;
|
||||
+
|
||||
/*
|
||||
* MSS Option not found ?! add it..
|
||||
*/
|
||||
--
|
||||
2.13.2
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
|
||||
From: Gavin Li <git@thegavinli.com>
|
||||
|
||||
brcmf_sdio_fromevntchan() was being called on the the data frame
|
||||
rather than the software header, causing some frames to be
|
||||
mischaracterized as on the event channel rather than the data channel.
|
||||
|
||||
This fixes a major performance regression (due to dropped packets).
|
||||
|
||||
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
|
||||
Signed-off-by: Gavin Li <git@thegavinli.com>
|
||||
Cc: <stable@vger.kernel.org> [4.7+]
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
index dfb0658713d9..d2219885071f 100644
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
pfirst->len, pfirst->next,
|
||||
pfirst->prev);
|
||||
skb_unlink(pfirst, &bus->glom);
|
||||
- if (brcmf_sdio_fromevntchan(pfirst->data))
|
||||
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
|
||||
brcmf_rx_event(bus->sdiodev->dev, pfirst);
|
||||
else
|
||||
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
|
||||
@@ -0,0 +1,371 @@
|
||||
|
||||
From upstream 4.11-rc2+ git
|
||||
|
||||
Fixes mga #20508
|
||||
|
||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||
|
||||
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 29 ++--
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c | 2
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 4
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c | 2
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_872tb.c | 2
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 121 +++++++++++------
|
||||
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 2
|
||||
7 files changed, 105 insertions(+), 57 deletions(-)
|
||||
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c 2017-03-07 22:29:07.840867965 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* RTL8XXXU mac80211 USB driver - 8188c/8188r/8192c specific subdriver
|
||||
*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* Portions, notably calibration code:
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c 2017-03-07 22:29:07.841868054 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* RTL8XXXU mac80211 USB driver - 8192e specific subdriver
|
||||
*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* Portions, notably calibration code:
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
@@ -1556,7 +1556,7 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void rtl8192eu_power_off(struct rtl8xxxu_priv *priv)
|
||||
+static void rtl8192eu_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c 2017-03-07 22:29:07.841868054 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* RTL8XXXU mac80211 USB driver - 8723a specific subdriver
|
||||
*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* Portions, notably calibration code:
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c 2017-03-07 22:29:07.841868054 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* RTL8XXXU mac80211 USB driver - 8723b specific subdriver
|
||||
*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* Portions, notably calibration code:
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 2017-03-18 13:35:47.148080457 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 2017-03-07 22:29:07.841868054 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* RTL8XXXU mac80211 USB driver
|
||||
*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* Portions, notably calibration code:
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
@@ -48,7 +48,7 @@ static bool rtl8xxxu_dma_aggregation;
|
||||
static int rtl8xxxu_dma_agg_timeout = -1;
|
||||
static int rtl8xxxu_dma_agg_pages = -1;
|
||||
|
||||
-MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
|
||||
+MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
|
||||
MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
|
||||
@@ -4767,13 +4767,28 @@ static void rtl8xxxu_dump_action(struct
|
||||
* This format is used on 8188cu/8192cu/8723au
|
||||
*/
|
||||
void
|
||||
-rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
|
||||
- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
|
||||
- u16 rate_flag, bool sgi, bool short_preamble,
|
||||
- bool ampdu_enable)
|
||||
+rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
|
||||
+ bool short_preamble, bool ampdu_enable, u32 rts_rate)
|
||||
{
|
||||
+ struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
|
||||
+ struct rtl8xxxu_priv *priv = hw->priv;
|
||||
+ struct device *dev = &priv->udev->dev;
|
||||
+ u32 rate;
|
||||
+ u16 rate_flags = tx_info->control.rates[0].flags;
|
||||
u16 seq_number;
|
||||
|
||||
+ if (rate_flags & IEEE80211_TX_RC_MCS &&
|
||||
+ !ieee80211_is_mgmt(hdr->frame_control))
|
||||
+ rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
|
||||
+ else
|
||||
+ rate = tx_rate->hw_value;
|
||||
+
|
||||
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
|
||||
+ dev_info(dev, "%s: TX rate: %d, pkt size %d\n",
|
||||
+ __func__, rate, cpu_to_le16(tx_desc->pkt_size));
|
||||
+
|
||||
seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
tx_desc->txdw5 = cpu_to_le32(rate);
|
||||
@@ -4804,15 +4819,16 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211
|
||||
if (sgi)
|
||||
tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI);
|
||||
|
||||
- if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
- /*
|
||||
- * Use RTS rate 24M - does the mac80211 tell
|
||||
- * us which to use?
|
||||
- */
|
||||
- tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
|
||||
- TXDESC32_RTS_RATE_SHIFT);
|
||||
+ /*
|
||||
+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
|
||||
+ */
|
||||
+ tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT);
|
||||
+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE);
|
||||
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
|
||||
+ } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE);
|
||||
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4821,16 +4837,31 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211
|
||||
* This format is used on 8192eu/8723bu
|
||||
*/
|
||||
void
|
||||
-rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
|
||||
- struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
|
||||
- u16 rate_flag, bool sgi, bool short_preamble,
|
||||
- bool ampdu_enable)
|
||||
+rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
|
||||
+ bool short_preamble, bool ampdu_enable, u32 rts_rate)
|
||||
{
|
||||
+ struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
|
||||
+ struct rtl8xxxu_priv *priv = hw->priv;
|
||||
+ struct device *dev = &priv->udev->dev;
|
||||
struct rtl8xxxu_txdesc40 *tx_desc40;
|
||||
+ u32 rate;
|
||||
+ u16 rate_flags = tx_info->control.rates[0].flags;
|
||||
u16 seq_number;
|
||||
|
||||
tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32;
|
||||
|
||||
+ if (rate_flags & IEEE80211_TX_RC_MCS &&
|
||||
+ !ieee80211_is_mgmt(hdr->frame_control))
|
||||
+ rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
|
||||
+ else
|
||||
+ rate = tx_rate->hw_value;
|
||||
+
|
||||
+ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
|
||||
+ dev_info(dev, "%s: TX rate: %d, pkt size %d\n",
|
||||
+ __func__, rate, cpu_to_le16(tx_desc40->pkt_size));
|
||||
+
|
||||
seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
tx_desc40->txdw4 = cpu_to_le32(rate);
|
||||
@@ -4857,15 +4888,19 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211
|
||||
if (short_preamble)
|
||||
tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE);
|
||||
|
||||
- if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
- /*
|
||||
- * Use RTS rate 24M - does the mac80211 tell
|
||||
- * us which to use?
|
||||
- */
|
||||
- tx_desc40->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
|
||||
- TXDESC40_RTS_RATE_SHIFT);
|
||||
+ tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT);
|
||||
+ /*
|
||||
+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
|
||||
+ */
|
||||
+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE);
|
||||
tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE);
|
||||
+ } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
+ /*
|
||||
+ * For some reason the vendor driver doesn't set
|
||||
+ * TXDESC40_HW_RTS_ENABLE for CTS to SELF
|
||||
+ */
|
||||
+ tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_CTS_SELF_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4875,14 +4910,13 @@ static void rtl8xxxu_tx(struct ieee80211
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
- struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
|
||||
struct rtl8xxxu_priv *priv = hw->priv;
|
||||
struct rtl8xxxu_txdesc32 *tx_desc;
|
||||
struct rtl8xxxu_tx_urb *tx_urb;
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
struct ieee80211_vif *vif = tx_info->control.vif;
|
||||
struct device *dev = &priv->udev->dev;
|
||||
- u32 queue, rate;
|
||||
+ u32 queue, rts_rate;
|
||||
u16 pktlen = skb->len;
|
||||
u16 seq_number;
|
||||
u16 rate_flag = tx_info->control.rates[0].flags;
|
||||
@@ -4909,10 +4943,6 @@ static void rtl8xxxu_tx(struct ieee80211
|
||||
goto error;
|
||||
}
|
||||
|
||||
- if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
|
||||
- dev_info(dev, "%s: TX rate: %d (%d), pkt size %d\n",
|
||||
- __func__, tx_rate->bitrate, tx_rate->hw_value, pktlen);
|
||||
-
|
||||
if (ieee80211_is_action(hdr->frame_control))
|
||||
rtl8xxxu_dump_action(dev, hdr);
|
||||
|
||||
@@ -4966,12 +4996,6 @@ static void rtl8xxxu_tx(struct ieee80211
|
||||
}
|
||||
}
|
||||
|
||||
- if (rate_flag & IEEE80211_TX_RC_MCS &&
|
||||
- !ieee80211_is_mgmt(hdr->frame_control))
|
||||
- rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
|
||||
- else
|
||||
- rate = tx_rate->hw_value;
|
||||
-
|
||||
if (rate_flag & IEEE80211_TX_RC_SHORT_GI ||
|
||||
(ieee80211_is_data_qos(hdr->frame_control) &&
|
||||
sta && sta->ht_cap.cap &
|
||||
@@ -4982,10 +5006,17 @@ static void rtl8xxxu_tx(struct ieee80211
|
||||
(sta && vif && vif->bss_conf.use_short_preamble))
|
||||
short_preamble = true;
|
||||
|
||||
+ if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS)
|
||||
+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
|
||||
+ else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT)
|
||||
+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
|
||||
+ else
|
||||
+ rts_rate = 0;
|
||||
+
|
||||
seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
- priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag,
|
||||
- sgi, short_preamble, ampdu_enable);
|
||||
+ priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble,
|
||||
+ ampdu_enable, rts_rate);
|
||||
|
||||
rtl8xxxu_calc_tx_desc_csum(tx_desc);
|
||||
|
||||
@@ -5969,6 +6000,7 @@ static int rtl8xxxu_probe(struct usb_int
|
||||
case 0x8176:
|
||||
case 0x8178:
|
||||
case 0x817f:
|
||||
+ case 0x818b:
|
||||
untested = 0;
|
||||
break;
|
||||
}
|
||||
@@ -6165,6 +6197,12 @@ static struct usb_device_id dev_table[]
|
||||
.driver_info = (unsigned long)&rtl8723au_fops},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
+/* TP-Link TL-WN822N v4 */
|
||||
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
+/* D-Link DWA-131 rev E1, tested by David Patiño */
|
||||
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
/* Tested by Myckel Habets */
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff),
|
||||
.driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
@@ -6316,6 +6354,13 @@ static struct usb_device_id dev_table[]
|
||||
.driver_info = (unsigned long)&rtl8192cu_fops},
|
||||
{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff),
|
||||
.driver_info = (unsigned long)&rtl8192cu_fops},
|
||||
+/* found in rtl8192eu vendor driver */
|
||||
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff),
|
||||
+ .driver_info = (unsigned long)&rtl8192eu_fops},
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h 2017-03-07 22:29:07.840867965 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@@ -1337,10 +1337,11 @@ struct rtl8xxxu_fileops {
|
||||
u32 ramask, int sgi);
|
||||
void (*report_connect) (struct rtl8xxxu_priv *priv,
|
||||
u8 macid, bool connect);
|
||||
- void (*fill_txdesc) (struct ieee80211_hdr *hdr,
|
||||
- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
|
||||
- u16 rate_flag, bool sgi, bool short_preamble,
|
||||
- bool ampdu_enable);
|
||||
+ void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
|
||||
+ bool short_preamble, bool ampdu_enable,
|
||||
+ u32 rts_rate);
|
||||
int writeN_block_size;
|
||||
int rx_agg_buf_size;
|
||||
char tx_desc_size;
|
||||
@@ -1434,14 +1435,16 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x
|
||||
int rtl8xxxu_gen2_channel_to_group(int channel);
|
||||
bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
|
||||
int result[][8], int c1, int c2);
|
||||
-void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
|
||||
- struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
|
||||
- u16 rate_flag, bool sgi, bool short_preamble,
|
||||
- bool ampdu_enable);
|
||||
-void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
|
||||
- struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
|
||||
- u16 rate_flag, bool sgi, bool short_preamble,
|
||||
- bool ampdu_enable);
|
||||
+void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
|
||||
+ bool short_preamble, bool ampdu_enable,
|
||||
+ u32 rts_rate);
|
||||
+void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
|
||||
+ bool short_preamble, bool ampdu_enable,
|
||||
+ u32 rts_rate);
|
||||
|
||||
extern struct rtl8xxxu_fileops rtl8192cu_fops;
|
||||
extern struct rtl8xxxu_fileops rtl8192eu_fops;
|
||||
diff -Nurp linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
|
||||
--- linux-4.9.16/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h 2016-12-11 21:17:54.000000000 +0200
|
||||
+++ linux-4.11-rc/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h 2017-03-07 22:29:07.842868144 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@@ -0,0 +1,43 @@
|
||||
From: Joerg Roedel <jroedel@suse.de>
|
||||
|
||||
ATS is broken on these devices. Under invalidation load, the
|
||||
GPU does not reply to invalidations anymore, causing
|
||||
Completion-wait loop timeouts on the AMD IOMMU driver side.
|
||||
Fix it by not enabling ATS on these devices.
|
||||
|
||||
Note that below mentioned commit is not broken, it just
|
||||
triggers the issue because it might cause invalidation
|
||||
storms on devices.
|
||||
|
||||
Fixes: b1516a14657a ('iommu/amd: Implement flush queue')
|
||||
Reported-by: Daniel Drake <drake@endlessm.com>
|
||||
Cc: Daniel Drake <drake@endlessm.com>
|
||||
Cc: Alexander Deucher <Alexander.Deucher@amd.com>
|
||||
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||
---
|
||||
drivers/pci/ats.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
|
||||
index eeb9fb2..711bdb2 100644
|
||||
--- a/drivers/pci/ats.c
|
||||
+++ b/drivers/pci/ats.c
|
||||
@@ -17,10 +17,18 @@
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
+static const struct pci_device_id broken_ats_tbl[] = {
|
||||
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x98e4) }, /* AMD Stoney GPU part */
|
||||
+ { 0 }
|
||||
+};
|
||||
+
|
||||
void pci_ats_init(struct pci_dev *dev)
|
||||
{
|
||||
int pos;
|
||||
|
||||
+ if (pci_match_id(broken_ats_tbl, dev))
|
||||
+ return;
|
||||
+
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
|
||||
if (!pos)
|
||||
return;
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
From ba714a9c1dea85e0bf2899d02dfeb9c70040427c Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Gleixner <tglx@linutronix.de>
|
||||
Date: Tue, 23 May 2017 23:23:32 +0200
|
||||
Subject: [PATCH] pinctrl/amd: Use regular interrupt instead of chained
|
||||
|
||||
The AMD pinctrl driver uses a chained interrupt to demultiplex the GPIO
|
||||
interrupts. Kevin Vandeventer reported, that his new AMD Ryzen locks up
|
||||
hard on boot when the AMD pinctrl driver is initialized. The reason is an
|
||||
interrupt storm. It's not clear whether that's caused by hardware or
|
||||
firmware or both.
|
||||
|
||||
Using chained interrupts on X86 is a dangerous endavour. If a system is
|
||||
misconfigured or the hardware buggy there is no safety net to catch an
|
||||
interrupt storm.
|
||||
|
||||
Convert the driver to use a regular interrupt for the demultiplex
|
||||
handler. This allows the interrupt storm detector to catch the malfunction
|
||||
and lets the system boot up.
|
||||
|
||||
This should be backported to stable because it's likely that more users run
|
||||
into this problem as the AMD Ryzen machines are spreading.
|
||||
|
||||
Reported-by: Kevin Vandeventer
|
||||
Link: https://bugzilla.suse.com/show_bug.cgi?id=1034261
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Backported to 4.9 by: Borislav Petkov <bp@alien8.de>
|
||||
|
||||
---
|
||||
drivers/pinctrl/pinctrl-amd.c | 91 +++++++++++++++++++------------------------
|
||||
1 file changed, 41 insertions(+), 50 deletions(-)
|
||||
|
||||
|
||||
Date: Thu, 22 Jun 2017 11:16:31 +0200
|
||||
From:
|
||||
To: Thomas Backlund <tmb@mageia.org>
|
||||
Cc: stable <stable@vger.kernel.org>, Thomas Gleixner <tglx@linutronix.de>,
|
||||
Linus Walleij <linus.walleij@linaro.org>,
|
||||
"Shah, Nehal-bakulchandra" <Nehal-bakulchandra.Shah@amd.com>,
|
||||
"Xue, Ken" <Ken.Xue@amd.com>,
|
||||
"S-k, Shyam-sundar" <Shyam-sundar.S-k@amd.com>,
|
||||
Sherry Hurwitz <sherry.hurwitz@amd.com>
|
||||
Subject: Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
|
||||
|
||||
On Thu, Jun 22, 2017 at 12:03:50PM +0300, Thomas Backlund wrote:
|
||||
> If it's intended for 4.9 -longterm, a proper backport is needed.
|
||||
|
||||
Something like this, I guess. But I need to find a box to test it.
|
||||
|
||||
Regards/Gruss,
|
||||
Boris.
|
||||
|
||||
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
|
||||
index c9a146948192..531e2224f38f 100644
|
||||
--- a/drivers/pinctrl/pinctrl-amd.c
|
||||
+++ b/drivers/pinctrl/pinctrl-amd.c
|
||||
@@ -476,64 +476,54 @@ static struct irq_chip amd_gpio_irqchip = {
|
||||
.irq_set_type = amd_gpio_irq_set_type,
|
||||
};
|
||||
|
||||
-static void amd_gpio_irq_handler(struct irq_desc *desc)
|
||||
+#define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
|
||||
+
|
||||
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
- u32 i;
|
||||
- u32 off;
|
||||
- u32 reg;
|
||||
- u32 pin_reg;
|
||||
- u64 reg64;
|
||||
- int handled = 0;
|
||||
- unsigned int irq;
|
||||
+ struct amd_gpio *gpio_dev = dev_id;
|
||||
+ struct gpio_chip *gc = &gpio_dev->gc;
|
||||
+ irqreturn_t ret = IRQ_NONE;
|
||||
+ unsigned int i, irqnr;
|
||||
unsigned long flags;
|
||||
- struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
- struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
- struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
|
||||
+ u32 *regs, regval;
|
||||
+ u64 status, mask;
|
||||
|
||||
- chained_irq_enter(chip, desc);
|
||||
- /*enable GPIO interrupt again*/
|
||||
+ /* Read the wake status */
|
||||
spin_lock_irqsave(&gpio_dev->lock, flags);
|
||||
- reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
|
||||
- reg64 = reg;
|
||||
- reg64 = reg64 << 32;
|
||||
-
|
||||
- reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
|
||||
- reg64 |= reg;
|
||||
+ status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
|
||||
+ status <<= 32;
|
||||
+ status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
|
||||
spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||
|
||||
- /*
|
||||
- * first 46 bits indicates interrupt status.
|
||||
- * one bit represents four interrupt sources.
|
||||
- */
|
||||
- for (off = 0; off < 46 ; off++) {
|
||||
- if (reg64 & BIT(off)) {
|
||||
- for (i = 0; i < 4; i++) {
|
||||
- pin_reg = readl(gpio_dev->base +
|
||||
- (off * 4 + i) * 4);
|
||||
- if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
|
||||
- (pin_reg & BIT(WAKE_STS_OFF))) {
|
||||
- irq = irq_find_mapping(gc->irqdomain,
|
||||
- off * 4 + i);
|
||||
- generic_handle_irq(irq);
|
||||
- writel(pin_reg,
|
||||
- gpio_dev->base
|
||||
- + (off * 4 + i) * 4);
|
||||
- handled++;
|
||||
- }
|
||||
- }
|
||||
+ /* Bit 0-45 contain the relevant status bits */
|
||||
+ status &= (1ULL << 46) - 1;
|
||||
+ regs = gpio_dev->base;
|
||||
+ for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
|
||||
+ if (!(status & mask))
|
||||
+ continue;
|
||||
+ status &= ~mask;
|
||||
+
|
||||
+ /* Each status bit covers four pins */
|
||||
+ for (i = 0; i < 4; i++) {
|
||||
+ regval = readl(regs + i);
|
||||
+ if (!(regval & PIN_IRQ_PENDING))
|
||||
+ continue;
|
||||
+ irq = irq_find_mapping(gc->irqdomain, irqnr + i);
|
||||
+ generic_handle_irq(irq);
|
||||
+ /* Clear interrupt */
|
||||
+ writel(regval, regs + i);
|
||||
+ ret = IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
- if (handled == 0)
|
||||
- handle_bad_irq(desc);
|
||||
-
|
||||
+ /* Signal EOI to the GPIO unit */
|
||||
spin_lock_irqsave(&gpio_dev->lock, flags);
|
||||
- reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
|
||||
- reg |= EOI_MASK;
|
||||
- writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
|
||||
+ regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
|
||||
+ regval |= EOI_MASK;
|
||||
+ writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
|
||||
spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||
|
||||
- chained_irq_exit(chip, desc);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
@@ -801,10 +791,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
|
||||
goto out2;
|
||||
}
|
||||
|
||||
- gpiochip_set_chained_irqchip(&gpio_dev->gc,
|
||||
- &amd_gpio_irqchip,
|
||||
- irq_base,
|
||||
- amd_gpio_irq_handler);
|
||||
+ ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
|
||||
+ KBUILD_MODNAME, gpio_dev);
|
||||
+ if (ret)
|
||||
+ goto out2;
|
||||
+
|
||||
|
||||
platform_set_drvdata(pdev, gpio_dev);
|
||||
|
||||
|
||||
--
|
||||
Regards/Gruss,
|
||||
Boris.
|
||||
|
||||
Good mailing practices for 400: avoid top-posting and trim the reply.
|
||||
@@ -14,14 +14,31 @@
|
||||
###
|
||||
### Stable Queue
|
||||
###
|
||||
|
||||
# CVE-2016-8405
|
||||
stable-fbdev-color-map-copying-bounds-checking.patch
|
||||
|
||||
stable-tile-ptrace-preserve-previous-registers-for-short-regset-write.patch
|
||||
stable-drm-schedule-the-output_poll_work-with-1s-delay-if-we-have-delayed-event.patch
|
||||
stable-drm-fix-broken-vt-switch-with-video-1366x768-option.patch
|
||||
stable-drm-i915-ignore-bogus-plane-coordinates-on-skl-when-the-plane-is-not-visible.patch
|
||||
stable-ipv6-release-dst-on-error-in-ip6_dst_lookup_tail.patch
|
||||
stable-net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch
|
||||
stable-decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch
|
||||
stable-net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch
|
||||
stable-net-vrf-make-add_fib_rules-per-network-namespace-flag.patch
|
||||
stable-af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch
|
||||
stable-fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch
|
||||
stable-sctp-disable-bh-in-sctp_for_each_endpoint.patch
|
||||
stable-net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch
|
||||
stable-net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch
|
||||
stable-net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch
|
||||
stable-net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch
|
||||
stable-proc-snmp6-use-correct-type-in-memset.patch
|
||||
stable-igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch
|
||||
stable-igmp-add-a-missing-spin_lock_init.patch
|
||||
stable-ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch
|
||||
stable-sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch
|
||||
stable-net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch
|
||||
stable-net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch
|
||||
stable-net-mlx5e-fix-timestamping-capabilities-reporting.patch
|
||||
stable-decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch
|
||||
stable-net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch
|
||||
stable-sfc-provide-dummy-definitions-of-vswitch-functions.patch
|
||||
stable-ipv6-do-not-leak-throw-route-references.patch
|
||||
stable-rtnetlink-add-ifla_group-to-ifla_policy.patch
|
||||
|
||||
###
|
||||
### Arch x86
|
||||
@@ -46,14 +63,14 @@ x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch
|
||||
# slows down boot
|
||||
Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch
|
||||
|
||||
# breaks nvidia304
|
||||
Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch
|
||||
|
||||
###
|
||||
### Core
|
||||
###
|
||||
base-cacheinfo-silence-DT-warnings.patch
|
||||
|
||||
# fixes crash on boot on some Amd systems
|
||||
iommu-amd-flush-IOTLB-for-specific-domains-only-v3.patch
|
||||
|
||||
###
|
||||
### i2c
|
||||
###
|
||||
@@ -68,6 +85,9 @@ base-cacheinfo-silence-DT-warnings.patch
|
||||
pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch
|
||||
pci-quirks-drop-devinit-exit.patch
|
||||
|
||||
# Stoney iommu hang
|
||||
pci-Blacklist-AMD-Stoney-GPU-devices-for-ATS.patch
|
||||
|
||||
###
|
||||
### PNP core
|
||||
###
|
||||
@@ -88,6 +108,9 @@ ACPI-video-Add-a-quirk-to-force-acpi-video-backlight.patch
|
||||
# drop obsolete warn
|
||||
acpi-do-not-warn-if-_BQC-does-not-exist.patch
|
||||
|
||||
# silence useless acpi warnings
|
||||
acpi-ACPICA-Events-Fix-acpi_ev_initialize_region-return-v.patch
|
||||
|
||||
###
|
||||
### Block
|
||||
###
|
||||
@@ -135,7 +158,12 @@ block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch
|
||||
block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.5.0.patch
|
||||
block-introduce-the-BFQ-v7r11-I-O-sched-for-4.5.0.patch
|
||||
block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch
|
||||
block-Turn-into-BFQ-v8r6-for-4.9.0.patch
|
||||
block-Turn-into-BFQ-v8r7-for-4.9.0.patch
|
||||
block-update-bfq-from-v8r7-to-v8r10.patch
|
||||
block-update-bfq-from-v8r10-to-v8r11.patch
|
||||
|
||||
# new macbooks
|
||||
block-nvme-detect-NVMe-controller-in-recent-MacBooks.patch
|
||||
|
||||
###
|
||||
### Char
|
||||
@@ -161,6 +189,9 @@ fs-aufs-4.9-modular.patch
|
||||
# needed for mdadm: imsm: enable bad block support for imsm metadata
|
||||
fs-seq_file-reset-iterator-to-first-record-for-zero-off.patch
|
||||
|
||||
# performance regression fix
|
||||
fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch
|
||||
|
||||
###
|
||||
### FireWire
|
||||
###
|
||||
@@ -194,11 +225,18 @@ gpu-drm-mach64-linux-3.14-buildfix.patch
|
||||
gpu-drm-mach64-3.17-buildfix.patch
|
||||
gpu-drm-mach64-3.18-buildfix.patch
|
||||
|
||||
# i915 skl/kbl speedup
|
||||
gpu-drm-i915-skl-drop-workarounds-for-A0-and-B0-revisions.patch
|
||||
gpu-drm-i915-skl-drop-workarounds-for-D0-revision.patch
|
||||
gpu-drm-i915-skl-drop-workarounds-for-E0-revision.patch
|
||||
gpu-drm-i915-Remove-WaDisableLSQCROPERFforOCL-KBL-workaround.patch
|
||||
#
|
||||
gpu-drm-i915-don-t-warn-about-Skylake-CPU-KabyPoint-PCH-.patch
|
||||
|
||||
# Amd polaris12 support
|
||||
gpu-drm-amd-amdgpu-add-Polaris12-PCI-ID.patch
|
||||
gpu-drm-amd-amdgpu-add-Polaris12-support-v3.patch
|
||||
gpu-drm-amdgpu-powerplay-add-Polaris12-support.patch
|
||||
gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch
|
||||
gpu-drm-amdgpu-add-Polaris12-DID.patch
|
||||
|
||||
# fix crash
|
||||
gpu-drm-amdgpu-pm-check-for-headless-before-calling-comp.patch
|
||||
|
||||
###
|
||||
### Hardware Monitoring
|
||||
@@ -256,8 +294,18 @@ net-netfilter-psd-fix-redefines.patch
|
||||
net-wireless-rtlwifi-Use-dev_kfree_skb_irq-instead-of-kfree_skb.patch
|
||||
net-wireless-rtlwifi-Fix-kernel-oops-introduced-with-commit-e4965.patch
|
||||
|
||||
# fix speed regression
|
||||
net-wireless-brcmfmac-fix-incorrect-event-channel-deduction.patch
|
||||
# update rtl8xxxu for mga#20508
|
||||
net-wireless-realtek-rtl8xxxu-linux-4.11-rc.patch
|
||||
|
||||
# fixes issue triggable by remote peers
|
||||
net-netfilter-xt_TCPMSS-add-more-sanity-tests-on-tcph-do.patch
|
||||
|
||||
###
|
||||
### pinctrl
|
||||
###
|
||||
|
||||
# fix non-booting Ryzen+ due to interrupt storm
|
||||
pinctrl_amd-Use-regular-interrupt-instead-of-chained.patch
|
||||
|
||||
###
|
||||
### Platform drivers
|
||||
@@ -284,6 +332,24 @@ include-kbuild-export-pci_ids.patch
|
||||
### Sound
|
||||
###
|
||||
|
||||
# new codecs
|
||||
sound-ALSA-hda-realtek-Add-new-codec-ID-ALC299.patch
|
||||
sound-ALSA-hda-realtek-New-codec-support-of-ALC1220.patch
|
||||
|
||||
# add support for Gigabyte GA-AX370 Gaming 5 with dual codecs (TTL: 4.12)
|
||||
sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch
|
||||
sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch
|
||||
sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch
|
||||
sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch
|
||||
# another dual codec system
|
||||
sound-ALSA-hda-Apply-dual-codec-quirk-for-MSI-Z270-Gaming-.patch
|
||||
sound-ALSA-hda-Fix-applying-MSI-dual-codec-mobo-quirk.patch
|
||||
|
||||
# intel
|
||||
sound-ALSA-hda-Add-Geminilake-id-to-SKL_PLUS.patch
|
||||
sound-ALSA-hda-Add-Coffelake-PCI-ID.patch
|
||||
sound-ALSA-hda-Apply-quirks-to-Broxton-T-too.patch
|
||||
|
||||
###
|
||||
### Staging
|
||||
###
|
||||
@@ -306,6 +372,9 @@ hid-usbhid-IBM-BladeCenterHS20-quirk.patch
|
||||
usb-storage-unusual_devs-add-id.patch
|
||||
usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch
|
||||
|
||||
# amd xhci fix
|
||||
usb-xhci-Limit-USB2-port-wake-support-for-AMD-Promontory-hosts.patch
|
||||
|
||||
###
|
||||
### V4L
|
||||
###
|
||||
@@ -364,6 +433,9 @@ video-mageia-logo.patch
|
||||
# add rtl8723bs support (mga#15874)
|
||||
3rd-rtl8723bs.patch
|
||||
|
||||
# add rtl8812 support (mga#21043)
|
||||
3rd-rtl8812au.patch
|
||||
|
||||
###
|
||||
### Security
|
||||
###
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
From 9f3dadb156692e15933a4a97ef659f65151be4a1 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 10 Apr 2017 17:12:33 +0200
|
||||
Subject: [PATCH 1/4] ALSA: hda - A new flag to enforce prefix to each pin
|
||||
|
||||
This is a preliminary patch for a smooth multi-codec support, and it
|
||||
introduces a new flag, force_pin_prefix, to struct hda_codec.
|
||||
This flag is used to force to add the pin location prefix to each
|
||||
input pin. For example, when there is only one microphone pin,
|
||||
usually the auto-parser assigns the string "Mic". With this flag on,
|
||||
it'll be like "Front Mic". Also, the creation of "Master" or "PCM"
|
||||
playback volume for a single pin is suppressed, too.
|
||||
|
||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195305
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_auto_parser.c | 1 +
|
||||
sound/pci/hda/hda_codec.h | 1 +
|
||||
sound/pci/hda/hda_generic.c | 2 ++
|
||||
3 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
|
||||
index a03cf68..d3ea731 100644
|
||||
--- a/sound/pci/hda/hda_auto_parser.c
|
||||
+++ b/sound/pci/hda/hda_auto_parser.c
|
||||
@@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
|
||||
has_multiple_pins = 1;
|
||||
if (has_multiple_pins && type == AUTO_PIN_MIC)
|
||||
has_multiple_pins &= check_mic_location_need(codec, cfg, input);
|
||||
+ has_multiple_pins |= codec->force_pin_prefix;
|
||||
return hda_get_input_pin_label(codec, &cfg->inputs[input],
|
||||
cfg->inputs[input].pin,
|
||||
has_multiple_pins);
|
||||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
|
||||
index f17f252..d6fb2d5 100644
|
||||
--- a/sound/pci/hda/hda_codec.h
|
||||
+++ b/sound/pci/hda/hda_codec.h
|
||||
@@ -256,6 +256,7 @@ struct hda_codec {
|
||||
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
|
||||
unsigned int power_save_node:1; /* advanced PM for each widget */
|
||||
unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
|
||||
+ unsigned int force_pin_prefix:1; /* Add location prefix */
|
||||
#ifdef CONFIG_PM
|
||||
unsigned long power_on_acct;
|
||||
unsigned long power_off_acct;
|
||||
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
|
||||
index e7c8f4f..4438328 100644
|
||||
--- a/sound/pci/hda/hda_generic.c
|
||||
+++ b/sound/pci/hda/hda_generic.c
|
||||
@@ -1125,6 +1125,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
|
||||
|
||||
*index = 0;
|
||||
if (cfg->line_outs == 1 && !spec->multi_ios &&
|
||||
+ !codec->force_pin_prefix &&
|
||||
!cfg->hp_outs && !cfg->speaker_outs)
|
||||
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
||||
|
||||
@@ -1132,6 +1133,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
|
||||
* use it master (or "PCM" if a vmaster hook is present)
|
||||
*/
|
||||
if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
|
||||
+ !codec->force_pin_prefix &&
|
||||
!spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
|
||||
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
||||
|
||||
--
|
||||
2.10.2
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From e79b0006c45c9b0b22f3ea54ff6e256b34c1f208 Mon Sep 17 00:00:00 2001
|
||||
From: Megha Dey <megha.dey@intel.com>
|
||||
Date: Wed, 14 Jun 2017 09:51:56 +0530
|
||||
Subject: [PATCH] ALSA: hda - Add Coffelake PCI ID
|
||||
|
||||
Coffelake is another Intel part, so need to add PCI ID for it.
|
||||
|
||||
Signed-off-by: Megha Dey <megha.dey@intel.com>
|
||||
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
|
||||
Acked-by: Vinod Koul <vinod.koul@intel.com>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_intel.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
||||
index 1770f085c2a6..e3c696c46a21 100644
|
||||
--- a/sound/pci/hda/hda_intel.c
|
||||
+++ b/sound/pci/hda/hda_intel.c
|
||||
@@ -371,9 +371,10 @@ enum {
|
||||
#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
|
||||
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
||||
#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
|
||||
+#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
|
||||
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
|
||||
IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \
|
||||
- IS_GLK(pci)
|
||||
+ IS_GLK(pci) || IS_CFL(pci)
|
||||
|
||||
static char *driver_short_names[] = {
|
||||
[AZX_DRIVER_ICH] = "HDA Intel",
|
||||
@@ -2378,6 +2379,9 @@ static const struct pci_device_id azx_ids[] = {
|
||||
/* Kabylake-H */
|
||||
{ PCI_DEVICE(0x8086, 0xa2f0),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
|
||||
+ /* Coffelake */
|
||||
+ { PCI_DEVICE(0x8086, 0xa348),
|
||||
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
/* Broxton-P(Apollolake) */
|
||||
{ PCI_DEVICE(0x8086, 0x5a98),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
|
||||
--
|
||||
2.13.1
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 12ee4022f67f8854061b46e5c0a7ad6258ab66c2 Mon Sep 17 00:00:00 2001
|
||||
From: "Subhransu S. Prusty" <subhransu.s.prusty@intel.com>
|
||||
Date: Wed, 12 Apr 2017 09:54:00 +0530
|
||||
Subject: [PATCH] ALSA: hda: Add Geminilake id to SKL_PLUS
|
||||
|
||||
Geminilake is Skylake family platform. So add it's id to skl_plus check.
|
||||
|
||||
Fixes: 126cfa2f5e15 ("ALSA: hda: Add Geminilake HDMI codec ID")
|
||||
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
|
||||
Cc: Senthilnathan Veppur <senthilnathanx.veppur@intel.com>
|
||||
Cc: Vinod Koul <vinod.koul@intel.com>
|
||||
Cc: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_intel.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
||||
index 59ab34fa0bc8..b786fbab029f 100644
|
||||
--- a/sound/pci/hda/hda_intel.c
|
||||
+++ b/sound/pci/hda/hda_intel.c
|
||||
@@ -370,8 +370,10 @@ enum {
|
||||
#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
|
||||
#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
|
||||
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
||||
+#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
|
||||
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
|
||||
- IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)
|
||||
+ IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \
|
||||
+ IS_GLK(pci)
|
||||
|
||||
static char *driver_short_names[] = {
|
||||
[AZX_DRIVER_ICH] = "HDA Intel",
|
||||
--
|
||||
2.13.1
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From 7480316c265c9fcdbf73b1b8dec061b893b7e987 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 10 Apr 2017 17:37:34 +0200
|
||||
Subject: [PATCH 2/4] ALSA: hda - Allow to enable/disable vmaster build
|
||||
explicitly
|
||||
|
||||
Another preliminary patch for the dual-codec support: since the
|
||||
support of vmaster over multiple codecs is difficult, simply disable
|
||||
it by a new flag to hda_codec struct. A new user hint is added as
|
||||
well for consistency.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
Documentation/sound/hd-audio/notes.rst | 2 ++
|
||||
sound/pci/hda/hda_generic.c | 7 +++++--
|
||||
sound/pci/hda/hda_generic.h | 1 +
|
||||
3 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
#diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst
|
||||
#index 9eeb9b4..f59c3cd 100644
|
||||
#--- a/Documentation/sound/hd-audio/notes.rst
|
||||
#+++ b/Documentation/sound/hd-audio/notes.rst
|
||||
#@@ -494,6 +494,8 @@ add_hp_mic (bool)
|
||||
# hp_mic_detect (bool)
|
||||
# enable/disable the hp/mic shared input for a single built-in mic
|
||||
# case; default true
|
||||
#+vmaster (bool)
|
||||
#+ enable/disable the virtual Master control; default true
|
||||
# mixer_nid (int)
|
||||
# specifies the widget NID of the analog-loopback mixer
|
||||
#
|
||||
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
|
||||
index 4438328..2842c82 100644
|
||||
--- a/sound/pci/hda/hda_generic.c
|
||||
+++ b/sound/pci/hda/hda_generic.c
|
||||
@@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
|
||||
val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
|
||||
if (val >= 0)
|
||||
spec->suppress_hp_mic_detect = !val;
|
||||
+ val = snd_hda_get_bool_hint(codec, "vmaster");
|
||||
+ if (val >= 0)
|
||||
+ spec->suppress_vmaster = !val;
|
||||
|
||||
if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
|
||||
spec->mixer_nid = val;
|
||||
@@ -5033,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
/* if we have no master control, let's create it */
|
||||
- if (!spec->no_analog &&
|
||||
+ if (!spec->no_analog && !spec->suppress_vmaster &&
|
||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
|
||||
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
|
||||
spec->vmaster_tlv, slave_pfxs,
|
||||
@@ -5041,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
- if (!spec->no_analog &&
|
||||
+ if (!spec->no_analog && !spec->suppress_vmaster &&
|
||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
|
||||
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
||||
NULL, slave_pfxs,
|
||||
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
|
||||
index f66fc7e..6177231 100644
|
||||
--- a/sound/pci/hda/hda_generic.h
|
||||
+++ b/sound/pci/hda/hda_generic.h
|
||||
@@ -229,6 +229,7 @@ struct hda_gen_spec {
|
||||
unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
|
||||
unsigned int power_down_unused:1; /* power down unused widgets */
|
||||
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
||||
+ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
||||
|
||||
/* other internal flags */
|
||||
unsigned int no_analog:1; /* digital I/O only */
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
From 63691587f7b0028326ddd1226c378aaaeca4d4e4 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 22 May 2017 16:32:46 +0200
|
||||
Subject: [PATCH] ALSA: hda - Apply dual-codec quirk for MSI Z270-Gaming mobo
|
||||
|
||||
MSI Z270-Gamin mobo has also two ALC1220 codecs like Gigabyte AZ370-
|
||||
Gaming mobo. Apply the same quirk to this one.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 9c22ad694534..3fdd5af190a4 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -2328,6 +2328,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||
+ SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||
--
|
||||
2.13.1
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From c7ecb9068e6772c43941ce609f08bc53f36e1dce Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 14 Jun 2017 07:37:14 +0200
|
||||
Subject: [PATCH] ALSA: hda - Apply quirks to Broxton-T, too
|
||||
|
||||
Broxton-T was a forgotten child and we didn't apply the quirks for
|
||||
Skylake+ properly. Meanwhile, a quirk for reducing the DMA latency
|
||||
seems specific to the early Broxton model, so we leave as is.
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_intel.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
||||
index e3c696c46a21..01eb1dc7b5b3 100644
|
||||
--- a/sound/pci/hda/hda_intel.c
|
||||
+++ b/sound/pci/hda/hda_intel.c
|
||||
@@ -370,11 +370,12 @@ enum {
|
||||
#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
|
||||
#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
|
||||
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
||||
+#define IS_BXT_T(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x1a98)
|
||||
#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
|
||||
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
|
||||
-#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
|
||||
- IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \
|
||||
- IS_GLK(pci) || IS_CFL(pci)
|
||||
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci) || \
|
||||
+ IS_BXT_T(pci) || IS_KBL(pci) || IS_KBL_LP(pci) || \
|
||||
+ IS_KBL_H(pci) || IS_GLK(pci) || IS_CFL(pci))
|
||||
|
||||
static char *driver_short_names[] = {
|
||||
[AZX_DRIVER_ICH] = "HDA Intel",
|
||||
--
|
||||
2.13.1
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From d2c3b14e1f0dcebdb695617c0c1342a36b914a47 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 1 Jun 2017 09:35:30 +0200
|
||||
Subject: [PATCH] ALSA: hda - Fix applying MSI dual-codec mobo quirk
|
||||
|
||||
The previous commit [63691587f7b0: ALSA: hda - Apply dual-codec quirk
|
||||
for MSI Z270-Gaming mobo] attempted to apply the existing dual-codec
|
||||
quirk for a MSI mobo. But it turned out that this isn't applied
|
||||
properly due to the MSI-vendor quirk before this entry. I overlooked
|
||||
such two MSI entries just because they were put in the wrong position,
|
||||
although we have a list ordered by PCI SSID numbers.
|
||||
|
||||
This patch fixes it by rearranging the unordered entries.
|
||||
|
||||
Fixes: 63691587f7b0 ("ALSA: hda - Apply dual-codec quirk for MSI Z270-Gaming mobo")
|
||||
Reported-by: Rudolf Schmidt <info@rudolfschmidt.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 918e45268915..a57988d617e9 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -2324,11 +2324,11 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
|
||||
|
||||
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
|
||||
- SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
||||
- SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||
+ SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
||||
SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||
+ SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||
--
|
||||
2.13.1
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
From 7beb3a6e9335d13872f24566b451f8371edd238f Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 10 Apr 2017 18:05:52 +0200
|
||||
Subject: [PATCH 3/4] ALSA: hda - Support Gigabyte Gaming board with dual
|
||||
Realtek codecs
|
||||
|
||||
This patch adds some workarounds to make Gigabyte GA-AX370 Gaming 5
|
||||
board working without the conflicts of kctls, etc. In general, the
|
||||
dual codec configs result in the conflicts of the following stuff:
|
||||
- Master controls
|
||||
- Capture controls
|
||||
- Analog loopback controls
|
||||
In addition, the auto-mute and the auto-mic can't work well among
|
||||
multiple codecs.
|
||||
|
||||
The current "solution" is to disable all these features, and use UCM
|
||||
for a better PulseAudio management. For a dedicated UCM profile, the
|
||||
patch overrides the card longname so that the system an get a unique
|
||||
profile path.
|
||||
|
||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195305
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 61 +++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 61 insertions(+)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 9371f1a..e81cf83 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -1800,6 +1800,7 @@ enum {
|
||||
ALC882_FIXUP_NO_PRIMARY_HP,
|
||||
ALC887_FIXUP_ASUS_BASS,
|
||||
ALC887_FIXUP_BASS_CHMAP,
|
||||
+ ALC1220_FIXUP_GB_DUAL_CODECS,
|
||||
};
|
||||
|
||||
static void alc889_fixup_coef(struct hda_codec *codec,
|
||||
@@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
|
||||
static void alc_fixup_bass_chmap(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action);
|
||||
|
||||
+/* For dual-codec configuration, we need to disable some features to avoid
|
||||
+ * conflicts of kctls and PCM streams
|
||||
+ */
|
||||
+static void alc_fixup_dual_codecs(struct hda_codec *codec,
|
||||
+ const struct hda_fixup *fix, int action)
|
||||
+{
|
||||
+ struct alc_spec *spec = codec->spec;
|
||||
+
|
||||
+ if (action != HDA_FIXUP_ACT_PRE_PROBE)
|
||||
+ return;
|
||||
+ /* disable vmaster */
|
||||
+ spec->gen.suppress_vmaster = 1;
|
||||
+ /* auto-mute and auto-mic switch don't work with multiple codecs */
|
||||
+ spec->gen.suppress_auto_mute = 1;
|
||||
+ spec->gen.suppress_auto_mic = 1;
|
||||
+ /* disable aamix as well */
|
||||
+ spec->gen.mixer_nid = 0;
|
||||
+ /* add location prefix to avoid conflicts */
|
||||
+ codec->force_pin_prefix = 1;
|
||||
+}
|
||||
+
|
||||
+static void rename_ctl(struct hda_codec *codec, const char *oldname,
|
||||
+ const char *newname)
|
||||
+{
|
||||
+ struct snd_kcontrol *kctl;
|
||||
+
|
||||
+ kctl = snd_hda_find_mixer_ctl(codec, oldname);
|
||||
+ if (kctl)
|
||||
+ strcpy(kctl->id.name, newname);
|
||||
+}
|
||||
+
|
||||
+static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
|
||||
+ const struct hda_fixup *fix,
|
||||
+ int action)
|
||||
+{
|
||||
+ alc_fixup_dual_codecs(codec, fix, action);
|
||||
+ switch (action) {
|
||||
+ case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
+ /* override card longname to provide a unique UCM profile */
|
||||
+ strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
|
||||
+ break;
|
||||
+ case HDA_FIXUP_ACT_BUILD:
|
||||
+ /* rename Capture controls depending on the codec */
|
||||
+ rename_ctl(codec, "Capture Volume",
|
||||
+ codec->addr == 0 ?
|
||||
+ "Rear-Panel Capture Volume" :
|
||||
+ "Front-Panel Capture Volume");
|
||||
+ rename_ctl(codec, "Capture Switch",
|
||||
+ codec->addr == 0 ?
|
||||
+ "Rear-Panel Capture Switch" :
|
||||
+ "Front-Panel Capture Switch");
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static const struct hda_fixup alc882_fixups[] = {
|
||||
[ALC882_FIXUP_ABIT_AW9D_MAX] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_bass_chmap,
|
||||
},
|
||||
+ [ALC1220_FIXUP_GB_DUAL_CODECS] = {
|
||||
+ .type = HDA_FIXUP_FUNC,
|
||||
+ .v.func = alc1220_fixup_gb_dual_codecs,
|
||||
+ },
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
@@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
||||
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
||||
+ SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From 56798e6b3a2264b58d50b93cfd66586ede77d661 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 11 Apr 2017 08:10:52 +0200
|
||||
Subject: [PATCH 4/4] ALSA: hda - Use a helper function for renaming kctl names
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 11 ++++-------
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index e81cf83..57eeefd 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -4724,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
|
||||
{ 0x1b, 0x21114000 }, /* dock speaker pin */
|
||||
{}
|
||||
};
|
||||
- struct snd_kcontrol *kctl;
|
||||
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
@@ -4739,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
|
||||
/* this is a bit tricky; give more sane names for the main
|
||||
* (tablet) speaker and the dock speaker, respectively
|
||||
*/
|
||||
- kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
|
||||
- if (kctl)
|
||||
- strcpy(kctl->id.name, "Dock Speaker Playback Switch");
|
||||
- kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
|
||||
- if (kctl)
|
||||
- strcpy(kctl->id.name, "Speaker Playback Switch");
|
||||
+ rename_ctl(codec, "Speaker Playback Switch",
|
||||
+ "Dock Speaker Playback Switch");
|
||||
+ rename_ctl(codec, "Bass Speaker Playback Switch",
|
||||
+ "Speaker Playback Switch");
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
From 28f1f9b26cee161ddd3985b3eb78e3ffada08dda Mon Sep 17 00:00:00 2001
|
||||
From: Kailang Yang <kailang@realtek.com>
|
||||
Date: Wed, 4 Jan 2017 14:49:07 +0800
|
||||
Subject: [PATCH] ALSA: hda/realtek - Add new codec ID ALC299
|
||||
|
||||
ALC299 was similar as ALC225.
|
||||
Add headset support for ALC299.
|
||||
ALC3271 was for Dell rename.
|
||||
|
||||
Signed-off-by: Kailang Yang <kailang@realtek.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 1ae29fd..3c69647 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -337,6 +337,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
||||
case 0x10ec0288:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0298:
|
||||
+ case 0x10ec0299:
|
||||
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
|
||||
break;
|
||||
case 0x10ec0285:
|
||||
@@ -912,6 +913,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
|
||||
{ 0x10ec0256, 0x1028, 0, "ALC3246" },
|
||||
{ 0x10ec0225, 0x1028, 0, "ALC3253" },
|
||||
{ 0x10ec0295, 0x1028, 0, "ALC3254" },
|
||||
+ { 0x10ec0299, 0x1028, 0, "ALC3271" },
|
||||
{ 0x10ec0670, 0x1025, 0, "ALC669X" },
|
||||
{ 0x10ec0676, 0x1025, 0, "ALC679X" },
|
||||
{ 0x10ec0282, 0x1043, 0, "ALC3229" },
|
||||
@@ -3716,6 +3718,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0867:
|
||||
@@ -3823,6 +3826,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
|
||||
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
@@ -3881,6 +3885,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0255:
|
||||
@@ -3996,6 +4001,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0867:
|
||||
@@ -4089,6 +4095,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
}
|
||||
@@ -4173,6 +4180,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
msleep(800);
|
||||
val = alc_read_coef_idx(codec, 0x46);
|
||||
@@ -6219,6 +6227,7 @@ static int patch_alc269(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
+ case 0x10ec0299:
|
||||
spec->codec_variant = ALC269_TYPE_ALC225;
|
||||
break;
|
||||
case 0x10ec0234:
|
||||
@@ -7256,6 +7265,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
||||
HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
|
||||
+ HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
|
||||
HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
|
||||
HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
|
||||
HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
From a535ad57d0e6b959cd79914a1127caade36a9459 Mon Sep 17 00:00:00 2001
|
||||
From: Kailang Yang <kailang@realtek.com>
|
||||
Date: Mon, 16 Jan 2017 16:59:26 +0800
|
||||
Subject: [PATCH] ALSA: hda/realtek - New codec support of ALC1220
|
||||
|
||||
Add support for new codec of ALC1220.
|
||||
It's compatible with ALC882 & co.
|
||||
|
||||
Signed-off-by: Kailang Yang <kailang@realtek.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
|
||||
index 3c69647..1c88da8 100644
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -380,6 +380,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0899:
|
||||
case 0x10ec0900:
|
||||
+ case 0x10ec1220:
|
||||
alc_update_coef_idx(codec, 0x7, 1<<1, 0);
|
||||
break;
|
||||
}
|
||||
@@ -2310,6 +2311,7 @@ static int patch_alc882(struct hda_codec *codec)
|
||||
case 0x10ec0882:
|
||||
case 0x10ec0885:
|
||||
case 0x10ec0900:
|
||||
+ case 0x10ec1220:
|
||||
break;
|
||||
default:
|
||||
/* ALC883 and variants */
|
||||
@@ -7297,6 +7299,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
||||
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
|
||||
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
|
||||
+ HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
Date: Thu, 8 Jun 2017 11:13:36 +0200
|
||||
Subject: af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers
|
||||
|
||||
From: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
|
||||
|
||||
[ Upstream commit defbcf2decc903a28d8398aa477b6881e711e3ea ]
|
||||
|
||||
Verify that the caller-provided sockaddr structure is large enough to
|
||||
contain the sa_family field, before accessing it in bind() and connect()
|
||||
handlers of the AF_UNIX socket. Since neither syscall enforces a minimum
|
||||
size of the corresponding memory region, very short sockaddrs (zero or
|
||||
one byte long) result in operating on uninitialized memory while
|
||||
referencing .sa_family.
|
||||
|
||||
Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/unix/af_unix.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -998,7 +998,8 @@ static int unix_bind(struct socket *sock
|
||||
struct path path = { NULL, NULL };
|
||||
|
||||
err = -EINVAL;
|
||||
- if (sunaddr->sun_family != AF_UNIX)
|
||||
+ if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
|
||||
+ sunaddr->sun_family != AF_UNIX)
|
||||
goto out;
|
||||
|
||||
if (addr_len == sizeof(short)) {
|
||||
@@ -1109,6 +1110,10 @@ static int unix_dgram_connect(struct soc
|
||||
unsigned int hash;
|
||||
int err;
|
||||
|
||||
+ err = -EINVAL;
|
||||
+ if (alen < offsetofend(struct sockaddr, sa_family))
|
||||
+ goto out;
|
||||
+
|
||||
if (addr->sa_family != AF_UNSPEC) {
|
||||
err = unix_mkname(sunaddr, alen, &hash);
|
||||
if (err < 0)
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Wei Wang <weiwan@google.com>
|
||||
Date: Fri, 16 Jun 2017 10:46:37 -0700
|
||||
Subject: decnet: always not take dst->__refcnt when inserting dst into hash table
|
||||
|
||||
From: Wei Wang <weiwan@google.com>
|
||||
|
||||
|
||||
[ Upstream commit 76371d2e3ad1f84426a30ebcd8c3b9b98f4c724f ]
|
||||
|
||||
In the existing dn_route.c code, dn_route_output_slow() takes
|
||||
dst->__refcnt before calling dn_insert_route() while dn_route_input_slow()
|
||||
does not take dst->__refcnt before calling dn_insert_route().
|
||||
This makes the whole routing code very buggy.
|
||||
In dn_dst_check_expire(), dnrt_free() is called when rt expires. This
|
||||
makes the routes inserted by dn_route_output_slow() not able to be
|
||||
freed as the refcnt is not released.
|
||||
In dn_dst_gc(), dnrt_drop() is called to release rt which could
|
||||
potentially cause the dst->__refcnt to be dropped to -1.
|
||||
In dn_run_flush(), dst_free() is called to release all the dst. Again,
|
||||
it makes the dst inserted by dn_route_output_slow() not able to be
|
||||
released and also, it does not wait on the rcu and could potentially
|
||||
cause crash in the path where other users still refer to this dst.
|
||||
|
||||
This patch makes sure both input and output path do not take
|
||||
dst->__refcnt before calling dn_insert_route() and also makes sure
|
||||
dnrt_free()/dst_free() is called when removing dst from the hash table.
|
||||
The only difference between those 2 calls is that dnrt_free() waits on
|
||||
the rcu while dst_free() does not.
|
||||
|
||||
Signed-off-by: Wei Wang <weiwan@google.com>
|
||||
Acked-by: Martin KaFai Lau <kafai@fb.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/decnet/dn_route.c | 14 ++++----------
|
||||
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/net/decnet/dn_route.c
|
||||
+++ b/net/decnet/dn_route.c
|
||||
@@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_r
|
||||
call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
|
||||
}
|
||||
|
||||
-static inline void dnrt_drop(struct dn_route *rt)
|
||||
-{
|
||||
- dst_release(&rt->dst);
|
||||
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
|
||||
-}
|
||||
-
|
||||
static void dn_dst_check_expire(unsigned long dummy)
|
||||
{
|
||||
int i;
|
||||
@@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops
|
||||
}
|
||||
*rtp = rt->dst.dn_next;
|
||||
rt->dst.dn_next = NULL;
|
||||
- dnrt_drop(rt);
|
||||
+ dnrt_free(rt);
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&dn_rt_hash_table[i].lock);
|
||||
@@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_rou
|
||||
dst_use(&rth->dst, now);
|
||||
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
|
||||
|
||||
- dnrt_drop(rt);
|
||||
+ dst_free(&rt->dst);
|
||||
*rp = rth;
|
||||
return 0;
|
||||
}
|
||||
@@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long d
|
||||
for(; rt; rt = next) {
|
||||
next = rcu_dereference_raw(rt->dst.dn_next);
|
||||
RCU_INIT_POINTER(rt->dst.dn_next, NULL);
|
||||
- dst_free((struct dst_entry *)rt);
|
||||
+ dnrt_free(rt);
|
||||
}
|
||||
|
||||
nothing_to_declare:
|
||||
@@ -1187,7 +1181,7 @@ make_route:
|
||||
if (dev_out->flags & IFF_LOOPBACK)
|
||||
flags |= RTCF_LOCAL;
|
||||
|
||||
- rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
|
||||
+ rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
|
||||
if (rt == NULL)
|
||||
goto e_nobufs;
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
Date: Wed, 7 Jun 2017 16:14:29 +0200
|
||||
Subject: decnet: dn_rtmsg: Improve input length sanitization in dnrmg_receive_user_skb
|
||||
|
||||
From: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
|
||||
|
||||
[ Upstream commit dd0da17b209ed91f39872766634ca967c170ada1 ]
|
||||
|
||||
Verify that the length of the socket buffer is sufficient to cover the
|
||||
nlmsghdr structure before accessing the nlh->nlmsg_len field for further
|
||||
input sanitization. If the client only supplies 1-3 bytes of data in
|
||||
sk_buff, then nlh->nlmsg_len remains partially uninitialized and
|
||||
contains leftover memory from the corresponding kernel allocation.
|
||||
Operating on such data may result in indeterminate evaluation of the
|
||||
nlmsg_len < sizeof(*nlh) expression.
|
||||
|
||||
The bug was discovered by a runtime instrumentation designed to detect
|
||||
use of uninitialized memory in the kernel. The patch prevents this and
|
||||
other similar tools (e.g. KMSAN) from flagging this behavior in the future.
|
||||
|
||||
Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/decnet/netfilter/dn_rtmsg.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/decnet/netfilter/dn_rtmsg.c
|
||||
+++ b/net/decnet/netfilter/dn_rtmsg.c
|
||||
@@ -102,7 +102,9 @@ static inline void dnrmg_receive_user_sk
|
||||
{
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(skb);
|
||||
|
||||
- if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
|
||||
+ if (skb->len < sizeof(*nlh) ||
|
||||
+ nlh->nlmsg_len < sizeof(*nlh) ||
|
||||
+ skb->len < nlh->nlmsg_len)
|
||||
return;
|
||||
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
From fdf35a6b22247746a7053fc764d04218a9306f82 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 9 Jan 2017 15:56:14 +0100
|
||||
Subject: drm: Fix broken VT switch with video=1366x768 option
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
commit fdf35a6b22247746a7053fc764d04218a9306f82 upstream.
|
||||
|
||||
I noticed that the VT switch doesn't work any longer with a Dell
|
||||
laptop with 1366x768 eDP when the machine is connected with a DP
|
||||
monitor. It behaves as if VT were switched, but the graphics remain
|
||||
frozen. Actually the keyboard works, so I could switch back to VT7
|
||||
again.
|
||||
|
||||
I tried to track down the problem, and encountered a long story until
|
||||
we reach to this error:
|
||||
|
||||
- The machine is booted with video=1366x768 option (the distro
|
||||
installer seems to add it as default).
|
||||
- Recently, drm_helper_probe_single_connector_modes() deals with
|
||||
cmdline modes, and it tries to create a new mode when no
|
||||
matching mode is found.
|
||||
- The drm_mode_create_from_cmdline_mode() creates a mode based on
|
||||
either CVT of GFT according to the given cmdline mode; in our case,
|
||||
it's 1366x768.
|
||||
- Since both CVT and GFT can't express the width 1366 due to
|
||||
alignment, the resultant mode becomes 1368x768, slightly larger than
|
||||
the given size.
|
||||
- Later on, the atomic commit is performed, and in
|
||||
drm_atomic_check_only(), the size of each plane is checked.
|
||||
- The size check of 1366x768 fails due to the above, and eventually
|
||||
the whole VT switch fails.
|
||||
|
||||
Back in the history, we've had a manual fix-up of 1368x768 in various
|
||||
places via c09dedb7a50e ("drm/edid: Add a workaround for 1366x768 HD
|
||||
panel"), but they have been all in drm_edid.c at probing the modes
|
||||
from EDID. For addressing the problem above, we need a similar hack
|
||||
to the mode newly created from cmdline, manually adjusting the width
|
||||
when the expected size is 1366 while we get 1368 instead.
|
||||
|
||||
Fixes: eaf99c749d43 ("drm: Perform cmdline mode parsing during...")
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/20170109145614.29454-1-tiwai@suse.de
|
||||
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
drivers/gpu/drm/drm_modes.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/gpu/drm/drm_modes.c
|
||||
+++ b/drivers/gpu/drm/drm_modes.c
|
||||
@@ -1462,6 +1462,13 @@ drm_mode_create_from_cmdline_mode(struct
|
||||
return NULL;
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_USERDEF;
|
||||
+ /* fix up 1368x768: GFT/CVT can't express 1366 width due to alignment */
|
||||
+ if (cmd->xres == 1366 && mode->hdisplay == 1368) {
|
||||
+ mode->hdisplay = 1366;
|
||||
+ mode->hsync_start--;
|
||||
+ mode->hsync_end--;
|
||||
+ drm_mode_set_name(mode);
|
||||
+ }
|
||||
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
|
||||
return mode;
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
From 3bfdfdcbce2796ce75bf2d85fd8471858d702e5d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
|
||||
Date: Mon, 7 Nov 2016 22:20:54 +0200
|
||||
Subject: drm/i915: Ignore bogus plane coordinates on SKL when the plane is not visible
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||
|
||||
commit 3bfdfdcbce2796ce75bf2d85fd8471858d702e5d upstream.
|
||||
|
||||
When the plane is invisible we may have all sorts of bogus stuff
|
||||
in the coordinates, which we must ignore or else we might fail the
|
||||
plane update. This started to happen on SKL when I moved the plane
|
||||
offset computation to happen in the check phase. Previously we
|
||||
happily ignored it all since we never called the update_plane hook
|
||||
with an invisible plane.
|
||||
|
||||
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
|
||||
Cc: drm-intel-fixes@lists.freedesktop.org
|
||||
Fixes: b63a16f6cd89 ("drm/i915: Compute display surface offset in the plane check hook for SKL+")
|
||||
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98258
|
||||
Testcase: igt/pm_rpm/legacy-planes
|
||||
Testcase: igt/pm_rpm/universal-planes
|
||||
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
|
||||
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/1478550057-24864-3-git-send-email-ville.syrjala@linux.intel.com
|
||||
(cherry picked from commit a5e4c7d0aa6784d8abe95c3ceef0da9656d17468)
|
||||
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
drivers/gpu/drm/i915/intel_display.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/gpu/drm/i915/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_display.c
|
||||
@@ -2975,6 +2975,9 @@ int skl_check_plane_surface(struct intel
|
||||
unsigned int rotation = plane_state->base.rotation;
|
||||
int ret;
|
||||
|
||||
+ if (!plane_state->base.visible)
|
||||
+ return 0;
|
||||
+
|
||||
/* Rotate src coordinates to match rotated GTT view */
|
||||
if (intel_rotation_90_or_270(rotation))
|
||||
drm_rect_rotate(&plane_state->base.src,
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
From 68f458eec7069d618a6c884ca007426e0cea411b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
Date: Mon, 9 Jan 2017 16:31:58 +0200
|
||||
Subject: drm: Schedule the output_poll_work with 1s delay if we have delayed event
|
||||
|
||||
From: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
|
||||
commit 68f458eec7069d618a6c884ca007426e0cea411b upstream.
|
||||
|
||||
Instead of scheduling the work to handle the initial delayed event, use 1s
|
||||
delay.
|
||||
|
||||
This delay should not be needed, but Optimus/nouveau will fail in a
|
||||
mysterious way if the delayed event is handled as soon as possible like it
|
||||
is done in drm_helper_probe_single_connector_modes() in case the poll
|
||||
was enabled before.
|
||||
|
||||
Reverting 339fd36238dd would give back the 10 sec (!) delay to handle the
|
||||
delayed event. Adding 1sec delay to the poll_work is enough to work around
|
||||
the issue in Optimus setups and gives shorter response on handling the
|
||||
initial delayed event.
|
||||
|
||||
Fixes: 339fd36238dd ("drm: drm_probe_helper: Fix output_poll_work scheduling")
|
||||
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
[danvet: Add FIXME to the comment to make it stick out more.]
|
||||
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
Link: http://patchwork.freedesktop.org/patch/msgid/20170109143158.21917-1-peter.ujfalusi@ti.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
drivers/gpu/drm/drm_probe_helper.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/drm_probe_helper.c
|
||||
+++ b/drivers/gpu/drm/drm_probe_helper.c
|
||||
@@ -143,8 +143,18 @@ void drm_kms_helper_poll_enable_locked(s
|
||||
}
|
||||
|
||||
if (dev->mode_config.delayed_event) {
|
||||
+ /*
|
||||
+ * FIXME:
|
||||
+ *
|
||||
+ * Use short (1s) delay to handle the initial delayed event.
|
||||
+ * This delay should not be needed, but Optimus/nouveau will
|
||||
+ * fail in a mysterious way if the delayed event is handled as
|
||||
+ * soon as possible like it is done in
|
||||
+ * drm_helper_probe_single_connector_modes() in case the poll
|
||||
+ * was enabled before.
|
||||
+ */
|
||||
poll = true;
|
||||
- delay = 0;
|
||||
+ delay = HZ;
|
||||
}
|
||||
|
||||
if (poll)
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
From 2dc705a9930b4806250fbf5a76e55266e59389f2 Mon Sep 17 00:00:00 2001
|
||||
From: Kees Cook <keescook@chromium.org>
|
||||
Date: Tue, 24 Jan 2017 15:18:24 -0800
|
||||
Subject: fbdev: color map copying bounds checking
|
||||
|
||||
From: Kees Cook <keescook@chromium.org>
|
||||
|
||||
commit 2dc705a9930b4806250fbf5a76e55266e59389f2 upstream.
|
||||
|
||||
Copying color maps to userspace doesn't check the value of to->start,
|
||||
which will cause kernel heap buffer OOB read due to signedness wraps.
|
||||
|
||||
CVE-2016-8405
|
||||
|
||||
Link: http://lkml.kernel.org/r/20170105224249.GA50925@beast
|
||||
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
|
||||
Signed-off-by: Kees Cook <keescook@chromium.org>
|
||||
Reported-by: Peter Pi (@heisecode) of Trend Micro
|
||||
Cc: Min Chong <mchong@google.com>
|
||||
Cc: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
drivers/video/fbdev/core/fbcmap.c | 26 ++++++++++++++------------
|
||||
1 file changed, 14 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/video/fbdev/core/fbcmap.c
|
||||
+++ b/drivers/video/fbdev/core/fbcmap.c
|
||||
@@ -163,17 +163,18 @@ void fb_dealloc_cmap(struct fb_cmap *cma
|
||||
|
||||
int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
|
||||
{
|
||||
- int tooff = 0, fromoff = 0;
|
||||
- int size;
|
||||
+ unsigned int tooff = 0, fromoff = 0;
|
||||
+ size_t size;
|
||||
|
||||
if (to->start > from->start)
|
||||
fromoff = to->start - from->start;
|
||||
else
|
||||
tooff = from->start - to->start;
|
||||
- size = to->len - tooff;
|
||||
- if (size > (int) (from->len - fromoff))
|
||||
- size = from->len - fromoff;
|
||||
- if (size <= 0)
|
||||
+ if (fromoff >= from->len || tooff >= to->len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ size = min_t(size_t, to->len - tooff, from->len - fromoff);
|
||||
+ if (size == 0)
|
||||
return -EINVAL;
|
||||
size *= sizeof(u16);
|
||||
|
||||
@@ -187,17 +188,18 @@ int fb_copy_cmap(const struct fb_cmap *f
|
||||
|
||||
int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
|
||||
{
|
||||
- int tooff = 0, fromoff = 0;
|
||||
- int size;
|
||||
+ unsigned int tooff = 0, fromoff = 0;
|
||||
+ size_t size;
|
||||
|
||||
if (to->start > from->start)
|
||||
fromoff = to->start - from->start;
|
||||
else
|
||||
tooff = from->start - to->start;
|
||||
- size = to->len - tooff;
|
||||
- if (size > (int) (from->len - fromoff))
|
||||
- size = from->len - fromoff;
|
||||
- if (size <= 0)
|
||||
+ if (fromoff >= from->len || tooff >= to->len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ size = min_t(size_t, to->len - tooff, from->len - fromoff);
|
||||
+ if (size == 0)
|
||||
return -EINVAL;
|
||||
size *= sizeof(u16);
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Krister Johansen <kjlx@templeofstupid.com>
|
||||
Date: Thu, 8 Jun 2017 13:12:38 -0700
|
||||
Subject: Fix an intermittent pr_emerg warning about lo becoming free.
|
||||
|
||||
From: Krister Johansen <kjlx@templeofstupid.com>
|
||||
|
||||
|
||||
[ Upstream commit f186ce61bb8235d80068c390dc2aad7ca427a4c2 ]
|
||||
|
||||
It looks like this:
|
||||
|
||||
Message from syslogd@flamingo at Apr 26 00:45:00 ...
|
||||
kernel:unregister_netdevice: waiting for lo to become free. Usage count = 4
|
||||
|
||||
They seem to coincide with net namespace teardown.
|
||||
|
||||
The message is emitted by netdev_wait_allrefs().
|
||||
|
||||
Forced a kdump in netdev_run_todo, but found that the refcount on the lo
|
||||
device was already 0 at the time we got to the panic.
|
||||
|
||||
Used bcc to check the blocking in netdev_run_todo. The only places
|
||||
where we're off cpu there are in the rcu_barrier() and msleep() calls.
|
||||
That behavior is expected. The msleep time coincides with the amount of
|
||||
time we spend waiting for the refcount to reach zero; the rcu_barrier()
|
||||
wait times are not excessive.
|
||||
|
||||
After looking through the list of callbacks that the netdevice notifiers
|
||||
invoke in this path, it appears that the dst_dev_event is the most
|
||||
interesting. The dst_ifdown path places a hold on the loopback_dev as
|
||||
part of releasing the dev associated with the original dst cache entry.
|
||||
Most of our notifier callbacks are straight-forward, but this one a)
|
||||
looks complex, and b) places a hold on the network interface in
|
||||
question.
|
||||
|
||||
I constructed a new bcc script that watches various events in the
|
||||
liftime of a dst cache entry. Note that dst_ifdown will take a hold on
|
||||
the loopback device until the invalidated dst entry gets freed.
|
||||
|
||||
[ __dst_free] on DST: ffff883ccabb7900 IF tap1008300eth0 invoked at 1282115677036183
|
||||
__dst_free
|
||||
rcu_nocb_kthread
|
||||
kthread
|
||||
ret_from_fork
|
||||
Acked-by: Eric Dumazet <edumazet@google.com>
|
||||
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/dst.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/net/core/dst.c
|
||||
+++ b/net/core/dst.c
|
||||
@@ -470,6 +470,20 @@ static int dst_dev_event(struct notifier
|
||||
spin_lock_bh(&dst_garbage.lock);
|
||||
dst = dst_garbage.list;
|
||||
dst_garbage.list = NULL;
|
||||
+ /* The code in dst_ifdown places a hold on the loopback device.
|
||||
+ * If the gc entry processing is set to expire after a lengthy
|
||||
+ * interval, this hold can cause netdev_wait_allrefs() to hang
|
||||
+ * out and wait for a long time -- until the the loopback
|
||||
+ * interface is released. If we're really unlucky, it'll emit
|
||||
+ * pr_emerg messages to console too. Reset the interval here,
|
||||
+ * so dst cleanups occur in a more timely fashion.
|
||||
+ */
|
||||
+ if (dst_garbage.timer_inc > DST_GC_INC) {
|
||||
+ dst_garbage.timer_inc = DST_GC_INC;
|
||||
+ dst_garbage.timer_expires = DST_GC_MIN;
|
||||
+ mod_delayed_work(system_wq, &dst_gc_work,
|
||||
+ dst_garbage.timer_expires);
|
||||
+ }
|
||||
spin_unlock_bh(&dst_garbage.lock);
|
||||
|
||||
if (last)
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
Date: Mon, 12 Jun 2017 09:52:26 -0700
|
||||
Subject: igmp: acquire pmc lock for ip_mc_clear_src()
|
||||
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit c38b7d327aafd1e3ad7ff53eefac990673b65667 ]
|
||||
|
||||
Andrey reported a use-after-free in add_grec():
|
||||
|
||||
for (psf = *psf_list; psf; psf = psf_next) {
|
||||
...
|
||||
psf_next = psf->sf_next;
|
||||
|
||||
where the struct ip_sf_list's were already freed by:
|
||||
|
||||
kfree+0xe8/0x2b0 mm/slub.c:3882
|
||||
ip_mc_clear_src+0x69/0x1c0 net/ipv4/igmp.c:2078
|
||||
ip_mc_dec_group+0x19a/0x470 net/ipv4/igmp.c:1618
|
||||
ip_mc_drop_socket+0x145/0x230 net/ipv4/igmp.c:2609
|
||||
inet_release+0x4e/0x1c0 net/ipv4/af_inet.c:411
|
||||
sock_release+0x8d/0x1e0 net/socket.c:597
|
||||
sock_close+0x16/0x20 net/socket.c:1072
|
||||
|
||||
This happens because we don't hold pmc->lock in ip_mc_clear_src()
|
||||
and a parallel mr_ifc_timer timer could jump in and access them.
|
||||
|
||||
The RCU lock is there but it is merely for pmc itself, this
|
||||
spinlock could actually ensure we don't access them in parallel.
|
||||
|
||||
Thanks to Eric and Long for discussion on this bug.
|
||||
|
||||
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||
Cc: Eric Dumazet <edumazet@google.com>
|
||||
Cc: Xin Long <lucien.xin@gmail.com>
|
||||
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Reviewed-by: Xin Long <lucien.xin@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv4/igmp.c | 21 +++++++++++++--------
|
||||
1 file changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/net/ipv4/igmp.c
|
||||
+++ b/net/ipv4/igmp.c
|
||||
@@ -2071,21 +2071,26 @@ static int ip_mc_add_src(struct in_devic
|
||||
|
||||
static void ip_mc_clear_src(struct ip_mc_list *pmc)
|
||||
{
|
||||
- struct ip_sf_list *psf, *nextpsf;
|
||||
+ struct ip_sf_list *psf, *nextpsf, *tomb, *sources;
|
||||
|
||||
- for (psf = pmc->tomb; psf; psf = nextpsf) {
|
||||
+ spin_lock_bh(&pmc->lock);
|
||||
+ tomb = pmc->tomb;
|
||||
+ pmc->tomb = NULL;
|
||||
+ sources = pmc->sources;
|
||||
+ pmc->sources = NULL;
|
||||
+ pmc->sfmode = MCAST_EXCLUDE;
|
||||
+ pmc->sfcount[MCAST_INCLUDE] = 0;
|
||||
+ pmc->sfcount[MCAST_EXCLUDE] = 1;
|
||||
+ spin_unlock_bh(&pmc->lock);
|
||||
+
|
||||
+ for (psf = tomb; psf; psf = nextpsf) {
|
||||
nextpsf = psf->sf_next;
|
||||
kfree(psf);
|
||||
}
|
||||
- pmc->tomb = NULL;
|
||||
- for (psf = pmc->sources; psf; psf = nextpsf) {
|
||||
+ for (psf = sources; psf; psf = nextpsf) {
|
||||
nextpsf = psf->sf_next;
|
||||
kfree(psf);
|
||||
}
|
||||
- pmc->sources = NULL;
|
||||
- pmc->sfmode = MCAST_EXCLUDE;
|
||||
- pmc->sfcount[MCAST_INCLUDE] = 0;
|
||||
- pmc->sfcount[MCAST_EXCLUDE] = 1;
|
||||
}
|
||||
|
||||
/* Join a multicast group
|
||||
@@ -0,0 +1,57 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
Date: Tue, 20 Jun 2017 10:46:27 -0700
|
||||
Subject: igmp: add a missing spin_lock_init()
|
||||
|
||||
From: WANG Cong <xiyou.wangcong@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit b4846fc3c8559649277e3e4e6b5cec5348a8d208 ]
|
||||
|
||||
Andrey reported a lockdep warning on non-initialized
|
||||
spinlock:
|
||||
|
||||
INFO: trying to register non-static key.
|
||||
the code is fine but needs lockdep annotation.
|
||||
turning off the locking correctness validator.
|
||||
CPU: 1 PID: 4099 Comm: a.out Not tainted 4.12.0-rc6+ #9
|
||||
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||
Call Trace:
|
||||
__dump_stack lib/dump_stack.c:16
|
||||
dump_stack+0x292/0x395 lib/dump_stack.c:52
|
||||
register_lock_class+0x717/0x1aa0 kernel/locking/lockdep.c:755
|
||||
? 0xffffffffa0000000
|
||||
__lock_acquire+0x269/0x3690 kernel/locking/lockdep.c:3255
|
||||
lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855
|
||||
__raw_spin_lock_bh ./include/linux/spinlock_api_smp.h:135
|
||||
_raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:175
|
||||
spin_lock_bh ./include/linux/spinlock.h:304
|
||||
ip_mc_clear_src+0x27/0x1e0 net/ipv4/igmp.c:2076
|
||||
igmpv3_clear_delrec+0xee/0x4f0 net/ipv4/igmp.c:1194
|
||||
ip_mc_destroy_dev+0x4e/0x190 net/ipv4/igmp.c:1736
|
||||
|
||||
We miss a spin_lock_init() in igmpv3_add_delrec(), probably
|
||||
because previously we never use it on this code path. Since
|
||||
we already unlink it from the global mc_tomb list, it is
|
||||
probably safe not to acquire this spinlock here. It does not
|
||||
harm to have it although, to avoid conditional locking.
|
||||
|
||||
Fixes: c38b7d327aaf ("igmp: acquire pmc lock for ip_mc_clear_src()")
|
||||
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv4/igmp.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/net/ipv4/igmp.c
|
||||
+++ b/net/ipv4/igmp.c
|
||||
@@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_
|
||||
pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
|
||||
if (!pmc)
|
||||
return;
|
||||
+ spin_lock_init(&pmc->lock);
|
||||
spin_lock_bh(&im->lock);
|
||||
pmc->interface = im->interface;
|
||||
in_dev_hold(in_dev);
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
Date: Tue, 20 Jun 2017 13:29:25 +0300
|
||||
Subject: ipv6: Do not leak throw route references
|
||||
|
||||
From: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit 07f615574f8ac499875b21c1142f26308234a92c ]
|
||||
|
||||
While commit 73ba57bfae4a ("ipv6: fix backtracking for throw routes")
|
||||
does good job on error propagation to the fib_rules_lookup()
|
||||
in fib rules core framework that also corrects throw routes
|
||||
handling, it does not solve route reference leakage problem
|
||||
happened when we return -EAGAIN to the fib_rules_lookup()
|
||||
and leave routing table entry referenced in arg->result.
|
||||
|
||||
If rule with matched throw route isn't last matched in the
|
||||
list we overwrite arg->result losing reference on throw
|
||||
route stored previously forever.
|
||||
|
||||
We also partially revert commit ab997ad40839 ("ipv6: fix the
|
||||
incorrect return value of throw route") since we never return
|
||||
routing table entry with dst.error == -EAGAIN when
|
||||
CONFIG_IPV6_MULTIPLE_TABLES is on. Also there is no point
|
||||
to check for RTF_REJECT flag since it is always set throw
|
||||
route.
|
||||
|
||||
Fixes: 73ba57bfae4a ("ipv6: fix backtracking for throw routes")
|
||||
Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/fib6_rules.c | 22 ++++++----------------
|
||||
net/ipv6/ip6_fib.c | 3 +--
|
||||
2 files changed, 7 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/net/ipv6/fib6_rules.c
|
||||
+++ b/net/ipv6/fib6_rules.c
|
||||
@@ -32,7 +32,6 @@ struct fib6_rule {
|
||||
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
||||
int flags, pol_lookup_t lookup)
|
||||
{
|
||||
- struct rt6_info *rt;
|
||||
struct fib_lookup_arg arg = {
|
||||
.lookup_ptr = lookup,
|
||||
.flags = FIB_LOOKUP_NOREF,
|
||||
@@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struc
|
||||
fib_rules_lookup(net->ipv6.fib6_rules_ops,
|
||||
flowi6_to_flowi(fl6), flags, &arg);
|
||||
|
||||
- rt = arg.result;
|
||||
+ if (arg.result)
|
||||
+ return arg.result;
|
||||
|
||||
- if (!rt) {
|
||||
- dst_hold(&net->ipv6.ip6_null_entry->dst);
|
||||
- return &net->ipv6.ip6_null_entry->dst;
|
||||
- }
|
||||
-
|
||||
- if (rt->rt6i_flags & RTF_REJECT &&
|
||||
- rt->dst.error == -EAGAIN) {
|
||||
- ip6_rt_put(rt);
|
||||
- rt = net->ipv6.ip6_null_entry;
|
||||
- dst_hold(&rt->dst);
|
||||
- }
|
||||
-
|
||||
- return &rt->dst;
|
||||
+ dst_hold(&net->ipv6.ip6_null_entry->dst);
|
||||
+ return &net->ipv6.ip6_null_entry->dst;
|
||||
}
|
||||
|
||||
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
||||
@@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_r
|
||||
flp6->saddr = saddr;
|
||||
}
|
||||
err = rt->dst.error;
|
||||
- goto out;
|
||||
+ if (err != -EAGAIN)
|
||||
+ goto out;
|
||||
}
|
||||
again:
|
||||
ip6_rt_put(rt);
|
||||
--- a/net/ipv6/ip6_fib.c
|
||||
+++ b/net/ipv6/ip6_fib.c
|
||||
@@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struc
|
||||
struct rt6_info *rt;
|
||||
|
||||
rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
|
||||
- if (rt->rt6i_flags & RTF_REJECT &&
|
||||
- rt->dst.error == -EAGAIN) {
|
||||
+ if (rt->dst.error == -EAGAIN) {
|
||||
ip6_rt_put(rt);
|
||||
rt = net->ipv6.ip6_null_entry;
|
||||
dst_hold(&rt->dst);
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
Date: Thu, 15 Jun 2017 16:33:58 +0800
|
||||
Subject: ipv6: fix calling in6_ifa_hold incorrectly for dad work
|
||||
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit f8a894b218138888542a5058d0e902378fd0d4ec ]
|
||||
|
||||
Now when starting the dad work in addrconf_mod_dad_work, if the dad work
|
||||
is idle and queued, it needs to hold ifa.
|
||||
|
||||
The problem is there's one gap in [1], during which if the pending dad work
|
||||
is removed elsewhere. It will miss to hold ifa, but the dad word is still
|
||||
idea and queue.
|
||||
|
||||
if (!delayed_work_pending(&ifp->dad_work))
|
||||
in6_ifa_hold(ifp);
|
||||
<--------------[1]
|
||||
mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
|
||||
|
||||
An use-after-free issue can be caused by this.
|
||||
|
||||
Chen Wei found this issue when WARN_ON(!hlist_unhashed(&ifp->addr_lst)) in
|
||||
net6_ifa_finish_destroy was hit because of it.
|
||||
|
||||
As Hannes' suggestion, this patch is to fix it by holding ifa first in
|
||||
addrconf_mod_dad_work, then calling mod_delayed_work and putting ifa if
|
||||
the dad_work is already in queue.
|
||||
|
||||
Note that this patch did not choose to fix it with:
|
||||
|
||||
if (!mod_delayed_work(delay))
|
||||
in6_ifa_hold(ifp);
|
||||
|
||||
As with it, when delay == 0, dad_work would be scheduled immediately, all
|
||||
addrconf_mod_dad_work(0) callings had to be moved under ifp->lock.
|
||||
|
||||
Reported-by: Wei Chen <weichen@redhat.com>
|
||||
Suggested-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/addrconf.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/net/ipv6/addrconf.c
|
||||
+++ b/net/ipv6/addrconf.c
|
||||
@@ -315,9 +315,9 @@ static void addrconf_mod_rs_timer(struct
|
||||
static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
|
||||
unsigned long delay)
|
||||
{
|
||||
- if (!delayed_work_pending(&ifp->dad_work))
|
||||
- in6_ifa_hold(ifp);
|
||||
- mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
|
||||
+ in6_ifa_hold(ifp);
|
||||
+ if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
|
||||
+ in6_ifa_put(ifp);
|
||||
}
|
||||
|
||||
static int snmp6_alloc_dev(struct inet6_dev *idev)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 00ea1ceebe0d9f2dc1cc2b7bd575a00100c27869 Mon Sep 17 00:00:00 2001
|
||||
From: Willem de Bruijn <willemb@google.com>
|
||||
Date: Sat, 18 Feb 2017 19:00:45 -0500
|
||||
Subject: ipv6: release dst on error in ip6_dst_lookup_tail
|
||||
|
||||
From: Willem de Bruijn <willemb@google.com>
|
||||
|
||||
commit 00ea1ceebe0d9f2dc1cc2b7bd575a00100c27869 upstream.
|
||||
|
||||
If ip6_dst_lookup_tail has acquired a dst and fails the IPv4-mapped
|
||||
check, release the dst before returning an error.
|
||||
|
||||
Fixes: ec5e3b0a1d41 ("ipv6: Inhibit IPv4-mapped src address on the wire.")
|
||||
Signed-off-by: Willem de Bruijn <willemb@google.com>
|
||||
Acked-by: Eric Dumazet <edumazet@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
net/ipv6/ip6_output.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/ipv6/ip6_output.c
|
||||
+++ b/net/ipv6/ip6_output.c
|
||||
@@ -1020,8 +1020,10 @@ static int ip6_dst_lookup_tail(struct ne
|
||||
}
|
||||
#endif
|
||||
if (ipv6_addr_v4mapped(&fl6->saddr) &&
|
||||
- !(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr)))
|
||||
- return -EAFNOSUPPORT;
|
||||
+ !(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr))) {
|
||||
+ err = -EAFNOSUPPORT;
|
||||
+ goto out_err_release;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Gao Feng <gfree.wind@vip.163.com>
|
||||
Date: Fri, 16 Jun 2017 15:00:02 +0800
|
||||
Subject: net: 8021q: Fix one possible panic caused by BUG_ON in free_netdev
|
||||
|
||||
From: Gao Feng <gfree.wind@vip.163.com>
|
||||
|
||||
|
||||
[ Upstream commit 9745e362add89432d2c951272a99b0a5fe4348a9 ]
|
||||
|
||||
The register_vlan_device would invoke free_netdev directly, when
|
||||
register_vlan_dev failed. It would trigger the BUG_ON in free_netdev
|
||||
if the dev was already registered. In this case, the netdev would be
|
||||
freed in netdev_run_todo later.
|
||||
|
||||
So add one condition check now. Only when dev is not registered, then
|
||||
free it directly.
|
||||
|
||||
The following is the part coredump when netdev_upper_dev_link failed
|
||||
in register_vlan_dev. I removed the lines which are too long.
|
||||
|
||||
[ 411.237457] ------------[ cut here ]------------
|
||||
[ 411.237458] kernel BUG at net/core/dev.c:7998!
|
||||
[ 411.237484] invalid opcode: 0000 [#1] SMP
|
||||
[ 411.237705] [last unloaded: 8021q]
|
||||
[ 411.237718] CPU: 1 PID: 12845 Comm: vconfig Tainted: G E 4.12.0-rc5+ #6
|
||||
[ 411.237737] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
|
||||
[ 411.237764] task: ffff9cbeb6685580 task.stack: ffffa7d2807d8000
|
||||
[ 411.237782] RIP: 0010:free_netdev+0x116/0x120
|
||||
[ 411.237794] RSP: 0018:ffffa7d2807dbdb0 EFLAGS: 00010297
|
||||
[ 411.237808] RAX: 0000000000000002 RBX: ffff9cbeb6ba8fd8 RCX: 0000000000001878
|
||||
[ 411.237826] RDX: 0000000000000001 RSI: 0000000000000282 RDI: 0000000000000000
|
||||
[ 411.237844] RBP: ffffa7d2807dbdc8 R08: 0002986100029841 R09: 0002982100029801
|
||||
[ 411.237861] R10: 0004000100029980 R11: 0004000100029980 R12: ffff9cbeb6ba9000
|
||||
[ 411.238761] R13: ffff9cbeb6ba9060 R14: ffff9cbe60f1a000 R15: ffff9cbeb6ba9000
|
||||
[ 411.239518] FS: 00007fb690d81700(0000) GS:ffff9cbebb640000(0000) knlGS:0000000000000000
|
||||
[ 411.239949] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
[ 411.240454] CR2: 00007f7115624000 CR3: 0000000077cdf000 CR4: 00000000003406e0
|
||||
[ 411.240936] Call Trace:
|
||||
[ 411.241462] vlan_ioctl_handler+0x3f1/0x400 [8021q]
|
||||
[ 411.241910] sock_ioctl+0x18b/0x2c0
|
||||
[ 411.242394] do_vfs_ioctl+0xa1/0x5d0
|
||||
[ 411.242853] ? sock_alloc_file+0xa6/0x130
|
||||
[ 411.243465] SyS_ioctl+0x79/0x90
|
||||
[ 411.243900] entry_SYSCALL_64_fastpath+0x1e/0xa9
|
||||
[ 411.244425] RIP: 0033:0x7fb69089a357
|
||||
[ 411.244863] RSP: 002b:00007ffcd04e0fc8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
|
||||
[ 411.245445] RAX: ffffffffffffffda RBX: 00007ffcd04e2884 RCX: 00007fb69089a357
|
||||
[ 411.245903] RDX: 00007ffcd04e0fd0 RSI: 0000000000008983 RDI: 0000000000000003
|
||||
[ 411.246527] RBP: 00007ffcd04e0fd0 R08: 0000000000000000 R09: 1999999999999999
|
||||
[ 411.246976] R10: 000000000000053f R11: 0000000000000202 R12: 0000000000000004
|
||||
[ 411.247414] R13: 00007ffcd04e1128 R14: 00007ffcd04e2888 R15: 0000000000000001
|
||||
[ 411.249129] RIP: free_netdev+0x116/0x120 RSP: ffffa7d2807dbdb0
|
||||
|
||||
Signed-off-by: Gao Feng <gfree.wind@vip.163.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/8021q/vlan.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/8021q/vlan.c
|
||||
+++ b/net/8021q/vlan.c
|
||||
@@ -277,7 +277,8 @@ static int register_vlan_device(struct n
|
||||
return 0;
|
||||
|
||||
out_free_newdev:
|
||||
- free_netdev(new_dev);
|
||||
+ if (new_dev->reg_state == NETREG_UNINITIALIZED)
|
||||
+ free_netdev(new_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
Date: Sat, 10 Jun 2017 16:49:39 +0800
|
||||
Subject: net: caif: Fix a sleep-in-atomic bug in cfpkt_create_pfx
|
||||
|
||||
From: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
|
||||
|
||||
[ Upstream commit f146e872eb12ebbe92d8e583b2637e0741440db3 ]
|
||||
|
||||
The kernel may sleep under a rcu read lock in cfpkt_create_pfx, and the
|
||||
function call path is:
|
||||
cfcnfg_linkup_rsp (acquire the lock by rcu_read_lock)
|
||||
cfctrl_linkdown_req
|
||||
cfpkt_create
|
||||
cfpkt_create_pfx
|
||||
alloc_skb(GFP_KERNEL) --> may sleep
|
||||
cfserl_receive (acquire the lock by rcu_read_lock)
|
||||
cfpkt_split
|
||||
cfpkt_create_pfx
|
||||
alloc_skb(GFP_KERNEL) --> may sleep
|
||||
|
||||
There is "in_interrupt" in cfpkt_create_pfx to decide use "GFP_KERNEL" or
|
||||
"GFP_ATOMIC". In this situation, "GFP_KERNEL" is used because the function
|
||||
is called under a rcu read lock, instead in interrupt.
|
||||
|
||||
To fix it, only "GFP_ATOMIC" is used in cfpkt_create_pfx.
|
||||
|
||||
Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/caif/cfpkt_skbuff.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
--- a/net/caif/cfpkt_skbuff.c
|
||||
+++ b/net/caif/cfpkt_skbuff.c
|
||||
@@ -81,11 +81,7 @@ static struct cfpkt *cfpkt_create_pfx(u1
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
- if (likely(in_interrupt()))
|
||||
- skb = alloc_skb(len + pfx, GFP_ATOMIC);
|
||||
- else
|
||||
- skb = alloc_skb(len + pfx, GFP_KERNEL);
|
||||
-
|
||||
+ skb = alloc_skb(len + pfx, GFP_ATOMIC);
|
||||
if (unlikely(skb == NULL))
|
||||
return NULL;
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Alexander Potapenko <glider@google.com>
|
||||
Date: Tue, 6 Jun 2017 15:56:54 +0200
|
||||
Subject: net: don't call strlen on non-terminated string in dev_set_alias()
|
||||
|
||||
From: Alexander Potapenko <glider@google.com>
|
||||
|
||||
|
||||
[ Upstream commit c28294b941232931fbd714099798eb7aa7e865d7 ]
|
||||
|
||||
KMSAN reported a use of uninitialized memory in dev_set_alias(),
|
||||
which was caused by calling strlcpy() (which in turn called strlen())
|
||||
on the user-supplied non-terminated string.
|
||||
|
||||
Signed-off-by: Alexander Potapenko <glider@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/dev.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -1250,8 +1250,9 @@ int dev_set_alias(struct net_device *dev
|
||||
if (!new_ifalias)
|
||||
return -ENOMEM;
|
||||
dev->ifalias = new_ifalias;
|
||||
+ memcpy(dev->ifalias, alias, len);
|
||||
+ dev->ifalias[len] = 0;
|
||||
|
||||
- strlcpy(dev->ifalias, alias, len+1);
|
||||
return len;
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Eli Cohen <eli@mellanox.com>
|
||||
Date: Thu, 8 Jun 2017 11:33:16 -0500
|
||||
Subject: net/mlx5: Wait for FW readiness before initializing command interface
|
||||
|
||||
From: Eli Cohen <eli@mellanox.com>
|
||||
|
||||
|
||||
[ Upstream commit 6c780a0267b8a1075f40b39851132eeaefefcff5 ]
|
||||
|
||||
Before attempting to initialize the command interface we must wait till
|
||||
the fw_initializing bit is clear.
|
||||
|
||||
If we fail to meet this condition the hardware will drop our
|
||||
configuration, specifically the descriptors page address. This scenario
|
||||
can happen when the firmware is still executing an FLR flow and did not
|
||||
finish yet so the driver needs to wait for that to finish.
|
||||
|
||||
Fixes: e3297246c2c8 ('net/mlx5_core: Wait for FW readiness on startup')
|
||||
Signed-off-by: Eli Cohen <eli@mellanox.com>
|
||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/main.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
|
||||
@@ -155,8 +155,9 @@ static struct mlx5_profile profile[] = {
|
||||
},
|
||||
};
|
||||
|
||||
-#define FW_INIT_TIMEOUT_MILI 2000
|
||||
-#define FW_INIT_WAIT_MS 2
|
||||
+#define FW_INIT_TIMEOUT_MILI 2000
|
||||
+#define FW_INIT_WAIT_MS 2
|
||||
+#define FW_PRE_INIT_TIMEOUT_MILI 10000
|
||||
|
||||
static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
|
||||
{
|
||||
@@ -956,6 +957,15 @@ static int mlx5_load_one(struct mlx5_cor
|
||||
*/
|
||||
dev->state = MLX5_DEVICE_STATE_UP;
|
||||
|
||||
+ /* wait for firmware to accept initialization segments configurations
|
||||
+ */
|
||||
+ err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI);
|
||||
+ if (err) {
|
||||
+ dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
|
||||
+ FW_PRE_INIT_TIMEOUT_MILI);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
err = mlx5_cmd_init(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Tal Gilboa <talgi@mellanox.com>
|
||||
Date: Mon, 15 May 2017 14:13:16 +0300
|
||||
Subject: net/mlx5e: Added BW check for DIM decision mechanism
|
||||
|
||||
From: Tal Gilboa <talgi@mellanox.com>
|
||||
|
||||
|
||||
[ Upstream commit c3164d2fc48fd4fa0477ab658b644559c3fe9073 ]
|
||||
|
||||
DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for
|
||||
changing the channel interrupt moderation values in order to reduce CPU
|
||||
overhead for all traffic types.
|
||||
Until now only interrupt and packet rate were sampled.
|
||||
We found a scenario on which we get a false indication since a change in
|
||||
DIM caused more aggregation and reduced packet rate while increasing BW.
|
||||
|
||||
We now regard a change as succesfull iff:
|
||||
current_BW > (prev_BW + threshold) or
|
||||
current_BW ~= prev_BW and current_PR > (prev_PR + threshold) or
|
||||
current_BW ~= prev_BW and current_PR ~= prev_PR and
|
||||
current_IR < (prev_IR - threshold)
|
||||
Where BW = Bandwidth, PR = Packet rate and IR = Interrupt rate
|
||||
|
||||
Improvements (ConnectX-4Lx 25GbE, single RX queue, LRO off)
|
||||
--------------------------------------------------
|
||||
packet size | before[Mb/s] | after[Mb/s] | gain |
|
||||
2B | 343.4 | 359.4 | 4.5% |
|
||||
16B | 2739.7 | 2814.8 | 2.7% |
|
||||
64B | 9739 | 10185.3 | 4.5% |
|
||||
|
||||
Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
|
||||
Signed-off-by: Tal Gilboa <talgi@mellanox.com>
|
||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c | 41 +++++++++++----------
|
||||
2 files changed, 24 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
||||
@@ -283,12 +283,14 @@ struct mlx5e_dma_info {
|
||||
|
||||
struct mlx5e_rx_am_stats {
|
||||
int ppms; /* packets per msec */
|
||||
+ int bpms; /* bytes per msec */
|
||||
int epms; /* events per msec */
|
||||
};
|
||||
|
||||
struct mlx5e_rx_am_sample {
|
||||
ktime_t time;
|
||||
unsigned int pkt_ctr;
|
||||
+ unsigned int byte_ctr;
|
||||
u16 event_ctr;
|
||||
};
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
||||
@@ -183,28 +183,27 @@ static void mlx5e_am_exit_parking(struct
|
||||
mlx5e_am_step(am);
|
||||
}
|
||||
|
||||
+#define IS_SIGNIFICANT_DIFF(val, ref) \
|
||||
+ (((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
|
||||
+
|
||||
static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,
|
||||
struct mlx5e_rx_am_stats *prev)
|
||||
{
|
||||
- int diff;
|
||||
-
|
||||
- if (!prev->ppms)
|
||||
- return curr->ppms ? MLX5E_AM_STATS_BETTER :
|
||||
- MLX5E_AM_STATS_SAME;
|
||||
-
|
||||
- diff = curr->ppms - prev->ppms;
|
||||
- if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */
|
||||
- return (diff > 0) ? MLX5E_AM_STATS_BETTER :
|
||||
- MLX5E_AM_STATS_WORSE;
|
||||
-
|
||||
- if (!prev->epms)
|
||||
- return curr->epms ? MLX5E_AM_STATS_WORSE :
|
||||
+ if (!prev->bpms)
|
||||
+ return curr->bpms ? MLX5E_AM_STATS_BETTER :
|
||||
MLX5E_AM_STATS_SAME;
|
||||
|
||||
- diff = curr->epms - prev->epms;
|
||||
- if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */
|
||||
- return (diff < 0) ? MLX5E_AM_STATS_BETTER :
|
||||
- MLX5E_AM_STATS_WORSE;
|
||||
+ if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms))
|
||||
+ return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER :
|
||||
+ MLX5E_AM_STATS_WORSE;
|
||||
+
|
||||
+ if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms))
|
||||
+ return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER :
|
||||
+ MLX5E_AM_STATS_WORSE;
|
||||
+
|
||||
+ if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms))
|
||||
+ return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
|
||||
+ MLX5E_AM_STATS_WORSE;
|
||||
|
||||
return MLX5E_AM_STATS_SAME;
|
||||
}
|
||||
@@ -266,6 +265,7 @@ static void mlx5e_am_sample(struct mlx5e
|
||||
{
|
||||
s->time = ktime_get();
|
||||
s->pkt_ctr = rq->stats.packets;
|
||||
+ s->byte_ctr = rq->stats.bytes;
|
||||
s->event_ctr = rq->cq.event_ctr;
|
||||
}
|
||||
|
||||
@@ -278,12 +278,15 @@ static void mlx5e_am_calc_stats(struct m
|
||||
/* u32 holds up to 71 minutes, should be enough */
|
||||
u32 delta_us = ktime_us_delta(end->time, start->time);
|
||||
unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
|
||||
+ unsigned int nbytes = end->byte_ctr - start->byte_ctr;
|
||||
|
||||
if (!delta_us)
|
||||
return;
|
||||
|
||||
- curr_stats->ppms = (npkts * USEC_PER_MSEC) / delta_us;
|
||||
- curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
|
||||
+ curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
|
||||
+ curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
|
||||
+ curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC,
|
||||
+ delta_us);
|
||||
}
|
||||
|
||||
void mlx5e_rx_am_work(struct work_struct *work)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
Date: Thu, 15 Jun 2017 20:08:32 +0300
|
||||
Subject: net/mlx5e: Avoid doing a cleanup call if the profile doesn't have it
|
||||
|
||||
From: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
|
||||
|
||||
[ Upstream commit 31ac93386d135a6c96de9c8bab406f5ccabf5a4d ]
|
||||
|
||||
The error flow of mlx5e_create_netdev calls the cleanup call
|
||||
of the given profile without checking if it exists, fix that.
|
||||
|
||||
Currently the VF reps don't register that callback and we crash
|
||||
if getting into error -- can be reproduced by the user doing ctrl^C
|
||||
while attempting to change the sriov mode from legacy to switchdev.
|
||||
|
||||
Fixes: 26e59d8077a3 '(net/mlx5e: Implement mlx5e interface attach/detach callbacks')
|
||||
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
|
||||
Reported-by: Sabrina Dubroca <sdubroca@redhat.com>
|
||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
|
||||
@@ -3846,7 +3846,8 @@ struct net_device *mlx5e_create_netdev(s
|
||||
return netdev;
|
||||
|
||||
err_cleanup_nic:
|
||||
- profile->cleanup(priv);
|
||||
+ if (profile->cleanup)
|
||||
+ profile->cleanup(priv);
|
||||
free_netdev(netdev);
|
||||
|
||||
return NULL;
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Maor Dickman <maord@mellanox.com>
|
||||
Date: Thu, 18 May 2017 15:15:08 +0300
|
||||
Subject: net/mlx5e: Fix timestamping capabilities reporting
|
||||
|
||||
From: Maor Dickman <maord@mellanox.com>
|
||||
|
||||
|
||||
[ Upstream commit f0b381178b01b831f9907d72f467d6443afdea67 ]
|
||||
|
||||
Misuse of (BIT) macro caused to report wrong flags for
|
||||
"Hardware Transmit Timestamp Modes" and "Hardware Receive
|
||||
Filter Modes"
|
||||
|
||||
Fixes: ef9814deafd0 ('net/mlx5e: Add HW timestamping (TS) support')
|
||||
Signed-off-by: Maor Dickman <maord@mellanox.com>
|
||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
|
||||
@@ -1183,11 +1183,11 @@ static int mlx5e_get_ts_info(struct net_
|
||||
SOF_TIMESTAMPING_RX_HARDWARE |
|
||||
SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||
|
||||
- info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
|
||||
- (BIT(1) << HWTSTAMP_TX_ON);
|
||||
+ info->tx_types = BIT(HWTSTAMP_TX_OFF) |
|
||||
+ BIT(HWTSTAMP_TX_ON);
|
||||
|
||||
- info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
|
||||
- (BIT(1) << HWTSTAMP_FILTER_ALL);
|
||||
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
|
||||
+ BIT(HWTSTAMP_FILTER_ALL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Tal Gilboa <talgi@mellanox.com>
|
||||
Date: Mon, 29 May 2017 17:02:55 +0300
|
||||
Subject: net/mlx5e: Fix wrong indications in DIM due to counter wraparound
|
||||
|
||||
From: Tal Gilboa <talgi@mellanox.com>
|
||||
|
||||
|
||||
[ Upstream commit 53acd76ce571e3b71f9205f2d49ab285a9f1aad8 ]
|
||||
|
||||
DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for
|
||||
changing the channel interrupt moderation values in order to reduce CPU
|
||||
overhead for all traffic types.
|
||||
Each iteration of the algorithm, DIM calculates the difference in
|
||||
throughput, packet rate and interrupt rate from last iteration in order
|
||||
to make a decision. DIM relies on counters for each metric. When these
|
||||
counters get to their type's max value they wraparound. In this case
|
||||
the delta between 'end' and 'start' samples is negative and when
|
||||
translated to unsigned integers - very high. This results in a false
|
||||
indication to the algorithm and might result in a wrong decision.
|
||||
|
||||
The fix calculates the 'distance' between 'end' and 'start' samples in a
|
||||
cyclic way around the relevant type's max value. It can also be viewed as
|
||||
an absolute value around the type's max value instead of around 0.
|
||||
|
||||
Testing show higher stability in DIM profile selection and no wraparound
|
||||
issues.
|
||||
|
||||
Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
|
||||
Signed-off-by: Tal Gilboa <talgi@mellanox.com>
|
||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en.h | 8 ++++----
|
||||
drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c | 10 +++++++---
|
||||
2 files changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
||||
@@ -288,10 +288,10 @@ struct mlx5e_rx_am_stats {
|
||||
};
|
||||
|
||||
struct mlx5e_rx_am_sample {
|
||||
- ktime_t time;
|
||||
- unsigned int pkt_ctr;
|
||||
- unsigned int byte_ctr;
|
||||
- u16 event_ctr;
|
||||
+ ktime_t time;
|
||||
+ u32 pkt_ctr;
|
||||
+ u32 byte_ctr;
|
||||
+ u16 event_ctr;
|
||||
};
|
||||
|
||||
struct mlx5e_rx_am { /* Adaptive Moderation */
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
|
||||
@@ -270,6 +270,8 @@ static void mlx5e_am_sample(struct mlx5e
|
||||
}
|
||||
|
||||
#define MLX5E_AM_NEVENTS 64
|
||||
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
|
||||
+#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
|
||||
|
||||
static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
|
||||
struct mlx5e_rx_am_sample *end,
|
||||
@@ -277,8 +279,9 @@ static void mlx5e_am_calc_stats(struct m
|
||||
{
|
||||
/* u32 holds up to 71 minutes, should be enough */
|
||||
u32 delta_us = ktime_us_delta(end->time, start->time);
|
||||
- unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
|
||||
- unsigned int nbytes = end->byte_ctr - start->byte_ctr;
|
||||
+ u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
|
||||
+ u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
|
||||
+ start->byte_ctr);
|
||||
|
||||
if (!delta_us)
|
||||
return;
|
||||
@@ -311,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)
|
||||
|
||||
switch (am->state) {
|
||||
case MLX5E_AM_MEASURE_IN_PROGRESS:
|
||||
- nevents = rq->cq.event_ctr - am->start_sample.event_ctr;
|
||||
+ nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr,
|
||||
+ am->start_sample.event_ctr);
|
||||
if (nevents < MLX5E_AM_NEVENTS)
|
||||
break;
|
||||
mlx5e_am_sample(rq, &end_sample);
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
Date: Sat, 10 Jun 2017 17:03:35 +0800
|
||||
Subject: net: tipc: Fix a sleep-in-atomic bug in tipc_msg_reverse
|
||||
|
||||
From: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
|
||||
|
||||
[ Upstream commit 343eba69c6968190d8654b857aea952fed9a6749 ]
|
||||
|
||||
The kernel may sleep under a rcu read lock in tipc_msg_reverse, and the
|
||||
function call path is:
|
||||
tipc_l2_rcv_msg (acquire the lock by rcu_read_lock)
|
||||
tipc_rcv
|
||||
tipc_sk_rcv
|
||||
tipc_msg_reverse
|
||||
pskb_expand_head(GFP_KERNEL) --> may sleep
|
||||
tipc_node_broadcast
|
||||
tipc_node_xmit_skb
|
||||
tipc_node_xmit
|
||||
tipc_sk_rcv
|
||||
tipc_msg_reverse
|
||||
pskb_expand_head(GFP_KERNEL) --> may sleep
|
||||
|
||||
To fix it, "GFP_KERNEL" is replaced with "GFP_ATOMIC".
|
||||
|
||||
Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/tipc/msg.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/tipc/msg.c
|
||||
+++ b/net/tipc/msg.c
|
||||
@@ -508,7 +508,7 @@ bool tipc_msg_reverse(u32 own_node, str
|
||||
}
|
||||
|
||||
if (skb_cloned(_skb) &&
|
||||
- pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL))
|
||||
+ pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
|
||||
goto exit;
|
||||
|
||||
/* Now reverse the concerned fields */
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: David Ahern <dsahern@gmail.com>
|
||||
Date: Thu, 8 Jun 2017 11:31:11 -0600
|
||||
Subject: net: vrf: Make add_fib_rules per network namespace flag
|
||||
|
||||
From: David Ahern <dsahern@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit 097d3c9508dc58286344e4a22b300098cf0c1566 ]
|
||||
|
||||
Commit 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
|
||||
adds the l3mdev FIB rule the first time a VRF device is created. However,
|
||||
it only creates the rule once and only in the namespace the first device
|
||||
is created - which may not be init_net. Fix by using the net_generic
|
||||
capability to make the add_fib_rules flag per network namespace.
|
||||
|
||||
Fixes: 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
|
||||
Reported-by: Petr Machata <petrm@mellanox.com>
|
||||
Signed-off-by: David Ahern <dsahern@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/vrf.c | 36 ++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/vrf.c
|
||||
+++ b/drivers/net/vrf.c
|
||||
@@ -36,12 +36,14 @@
|
||||
#include <net/addrconf.h>
|
||||
#include <net/l3mdev.h>
|
||||
#include <net/fib_rules.h>
|
||||
+#include <net/netns/generic.h>
|
||||
|
||||
#define DRV_NAME "vrf"
|
||||
#define DRV_VERSION "1.0"
|
||||
|
||||
#define FIB_RULE_PREF 1000 /* default preference for FIB rules */
|
||||
-static bool add_fib_rules = true;
|
||||
+
|
||||
+static unsigned int vrf_net_id;
|
||||
|
||||
struct net_vrf {
|
||||
struct rtable __rcu *rth;
|
||||
@@ -1237,6 +1239,8 @@ static int vrf_newlink(struct net *src_n
|
||||
struct nlattr *tb[], struct nlattr *data[])
|
||||
{
|
||||
struct net_vrf *vrf = netdev_priv(dev);
|
||||
+ bool *add_fib_rules;
|
||||
+ struct net *net;
|
||||
int err;
|
||||
|
||||
if (!data || !data[IFLA_VRF_TABLE])
|
||||
@@ -1252,13 +1256,15 @@ static int vrf_newlink(struct net *src_n
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
- if (add_fib_rules) {
|
||||
+ net = dev_net(dev);
|
||||
+ add_fib_rules = net_generic(net, vrf_net_id);
|
||||
+ if (*add_fib_rules) {
|
||||
err = vrf_add_fib_rules(dev);
|
||||
if (err) {
|
||||
unregister_netdevice(dev);
|
||||
goto out;
|
||||
}
|
||||
- add_fib_rules = false;
|
||||
+ *add_fib_rules = false;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -1341,16 +1347,38 @@ static struct notifier_block vrf_notifie
|
||||
.notifier_call = vrf_device_event,
|
||||
};
|
||||
|
||||
+/* Initialize per network namespace state */
|
||||
+static int __net_init vrf_netns_init(struct net *net)
|
||||
+{
|
||||
+ bool *add_fib_rules = net_generic(net, vrf_net_id);
|
||||
+
|
||||
+ *add_fib_rules = true;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct pernet_operations vrf_net_ops __net_initdata = {
|
||||
+ .init = vrf_netns_init,
|
||||
+ .id = &vrf_net_id,
|
||||
+ .size = sizeof(bool),
|
||||
+};
|
||||
+
|
||||
static int __init vrf_init_module(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
register_netdevice_notifier(&vrf_notifier_block);
|
||||
|
||||
- rc = rtnl_link_register(&vrf_link_ops);
|
||||
+ rc = register_pernet_subsys(&vrf_net_ops);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
+ rc = rtnl_link_register(&vrf_link_ops);
|
||||
+ if (rc < 0) {
|
||||
+ unregister_pernet_subsys(&vrf_net_ops);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
error:
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
|
||||
Date: Wed, 7 Jun 2017 21:00:33 +0300
|
||||
Subject: net: Zero ifla_vf_info in rtnl_fill_vfinfo()
|
||||
|
||||
From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
|
||||
|
||||
|
||||
[ Upstream commit 0eed9cf58446b28b233388b7f224cbca268b6986 ]
|
||||
|
||||
Some of the structure's fields are not initialized by the
|
||||
rtnetlink. If driver doesn't set those in ndo_get_vf_config(),
|
||||
they'd leak memory to user.
|
||||
|
||||
Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
|
||||
CC: Michal Schmidt <mschmidt@redhat.com>
|
||||
Reviewed-by: Greg Rose <gvrose8192@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/rtnetlink.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -1130,6 +1130,8 @@ static noinline_for_stack int rtnl_fill_
|
||||
struct ifla_vf_mac vf_mac;
|
||||
struct ifla_vf_info ivi;
|
||||
|
||||
+ memset(&ivi, 0, sizeof(ivi));
|
||||
+
|
||||
/* Not all SR-IOV capable drivers support the
|
||||
* spoofcheck and "RSS query enable" query. Preset to
|
||||
* -1 so the user space tool can detect that the driver
|
||||
@@ -1138,7 +1140,6 @@ static noinline_for_stack int rtnl_fill_
|
||||
ivi.spoofchk = -1;
|
||||
ivi.rss_query_en = -1;
|
||||
ivi.trusted = -1;
|
||||
- memset(ivi.mac, 0, sizeof(ivi.mac));
|
||||
/* The default value for VF link state is "auto"
|
||||
* IFLA_VF_LINK_STATE_AUTO which equals zero
|
||||
*/
|
||||
@@ -0,0 +1,32 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Christian Perle <christian.perle@secunet.com>
|
||||
Date: Mon, 12 Jun 2017 10:06:57 +0200
|
||||
Subject: proc: snmp6: Use correct type in memset
|
||||
|
||||
From: Christian Perle <christian.perle@secunet.com>
|
||||
|
||||
|
||||
[ Upstream commit 3500cd73dff48f28f4ba80c171c4c80034d40f76 ]
|
||||
|
||||
Reading /proc/net/snmp6 yields bogus values on 32 bit kernels.
|
||||
Use "u64" instead of "unsigned long" in sizeof().
|
||||
|
||||
Fixes: 4a4857b1c81e ("proc: Reduce cache miss in snmp6_seq_show")
|
||||
Signed-off-by: Christian Perle <christian.perle@secunet.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/ipv6/proc.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/net/ipv6/proc.c
|
||||
+++ b/net/ipv6/proc.c
|
||||
@@ -219,7 +219,7 @@ static void snmp6_seq_show_item64(struct
|
||||
u64 buff64[SNMP_MIB_MAX];
|
||||
int i;
|
||||
|
||||
- memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
|
||||
+ memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
|
||||
|
||||
snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
|
||||
for (i = 0; itemlist[i].name; i++)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
Date: Tue, 20 Jun 2017 14:35:23 +0300
|
||||
Subject: rtnetlink: add IFLA_GROUP to ifla_policy
|
||||
|
||||
From: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit db833d40ad3263b2ee3b59a1ba168bb3cfed8137 ]
|
||||
|
||||
Network interface groups support added while ago, however
|
||||
there is no IFLA_GROUP attribute description in policy
|
||||
and netlink message size calculations until now.
|
||||
|
||||
Add IFLA_GROUP attribute to the policy.
|
||||
|
||||
Fixes: cbda10fa97d7 ("net_device: add support for network device groups")
|
||||
Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/rtnetlink.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -937,6 +937,7 @@ static noinline size_t if_nlmsg_size(con
|
||||
+ nla_total_size(1) /* IFLA_LINKMODE */
|
||||
+ nla_total_size(4) /* IFLA_CARRIER_CHANGES */
|
||||
+ nla_total_size(4) /* IFLA_LINK_NETNSID */
|
||||
+ + nla_total_size(4) /* IFLA_GROUP */
|
||||
+ nla_total_size(ext_filter_mask
|
||||
& RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
|
||||
+ rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
|
||||
@@ -1465,6 +1466,7 @@ static const struct nla_policy ifla_poli
|
||||
[IFLA_LINK_NETNSID] = { .type = NLA_S32 },
|
||||
[IFLA_PROTO_DOWN] = { .type = NLA_U8 },
|
||||
[IFLA_XDP] = { .type = NLA_NESTED },
|
||||
+ [IFLA_GROUP] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
Date: Sat, 10 Jun 2017 14:48:14 +0800
|
||||
Subject: sctp: disable BH in sctp_for_each_endpoint
|
||||
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit 581409dacc9176b0de1f6c4ca8d66e13aa8e1b29 ]
|
||||
|
||||
Now sctp holds read_lock when foreach sctp_ep_hashtable without disabling
|
||||
BH. If CPU schedules to another thread A at this moment, the thread A may
|
||||
be trying to hold the write_lock with disabling BH.
|
||||
|
||||
As BH is disabled and CPU cannot schedule back to the thread holding the
|
||||
read_lock, while the thread A keeps waiting for the read_lock. A dead
|
||||
lock would be triggered by this.
|
||||
|
||||
This patch is to fix this dead lock by calling read_lock_bh instead to
|
||||
disable BH when holding the read_lock in sctp_for_each_endpoint.
|
||||
|
||||
Fixes: 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
|
||||
Reported-by: Xiumei Mu <xmu@redhat.com>
|
||||
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
||||
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/sctp/socket.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/sctp/socket.c
|
||||
+++ b/net/sctp/socket.c
|
||||
@@ -4460,13 +4460,13 @@ int sctp_for_each_endpoint(int (*cb)(str
|
||||
|
||||
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
|
||||
hash++, head++) {
|
||||
- read_lock(&head->lock);
|
||||
+ read_lock_bh(&head->lock);
|
||||
sctp_for_each_hentry(epb, &head->chain) {
|
||||
err = cb(sctp_ep(epb), p);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
- read_unlock(&head->lock);
|
||||
+ read_unlock_bh(&head->lock);
|
||||
}
|
||||
|
||||
return err;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
Date: Thu, 15 Jun 2017 17:49:08 +0800
|
||||
Subject: sctp: return next obj by passing pos + 1 into sctp_transport_get_idx
|
||||
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
|
||||
|
||||
[ Upstream commit 988c7322116970696211e902b468aefec95b6ec4 ]
|
||||
|
||||
In sctp_for_each_transport, pos is used to save how many objs it has
|
||||
dumped. Now it gets the last obj by sctp_transport_get_idx, then gets
|
||||
the next obj by sctp_transport_get_next.
|
||||
|
||||
The issue is that in the meanwhile if some objs in transport hashtable
|
||||
are removed and the objs nums are less than pos, sctp_transport_get_idx
|
||||
would return NULL and hti.walker.tbl is NULL as well. At this moment
|
||||
it should stop hti, instead of continue getting the next obj. Or it
|
||||
would cause a NULL pointer dereference in sctp_transport_get_next.
|
||||
|
||||
This patch is to pass pos + 1 into sctp_transport_get_idx to get the
|
||||
next obj directly, even if pos > objs nums, it would return NULL and
|
||||
stop hti.
|
||||
|
||||
Fixes: 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
|
||||
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/sctp/socket.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/net/sctp/socket.c
|
||||
+++ b/net/sctp/socket.c
|
||||
@@ -4506,9 +4506,8 @@ int sctp_for_each_transport(int (*cb)(st
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- sctp_transport_get_idx(net, &hti, pos);
|
||||
- obj = sctp_transport_get_next(net, &hti);
|
||||
- for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
|
||||
+ obj = sctp_transport_get_idx(net, &hti, pos + 1);
|
||||
+ for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) {
|
||||
struct sctp_transport *transport = obj;
|
||||
|
||||
if (!sctp_transport_hold(transport))
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
From foo@baz Thu Jun 29 18:57:46 CEST 2017
|
||||
From: Bert Kenward <bkenward@solarflare.com>
|
||||
Date: Fri, 16 Jun 2017 09:45:08 +0100
|
||||
Subject: sfc: provide dummy definitions of vswitch functions
|
||||
|
||||
From: Bert Kenward <bkenward@solarflare.com>
|
||||
|
||||
|
||||
efx_probe_all() calls efx->type->vswitching_probe during probe. For
|
||||
SFC4000 (Falcon) NICs this function is not defined, leading to a BUG
|
||||
with the top of the call stack similar to:
|
||||
? efx_pci_probe_main+0x29a/0x830
|
||||
efx_pci_probe+0x7d3/0xe70
|
||||
|
||||
vswitching_restore and vswitching_remove also need to be defined.
|
||||
|
||||
Fixed in mainline by:
|
||||
commit 5a6681e22c14 ("sfc: separate out SFC4000 ("Falcon") support into new sfc-falcon driver")
|
||||
|
||||
Fixes: 6d8aaaf6f798 ("sfc: create VEB vswitch and vport above default firmware setup")
|
||||
Signed-off-by: Bert Kenward <bkenward@solarflare.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/net/ethernet/sfc/falcon.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/sfc/falcon.c
|
||||
+++ b/drivers/net/ethernet/sfc/falcon.c
|
||||
@@ -2801,6 +2801,11 @@ const struct efx_nic_type falcon_a1_nic_
|
||||
.timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
|
||||
.offload_features = NETIF_F_IP_CSUM,
|
||||
.mcdi_max_ver = -1,
|
||||
+#ifdef CONFIG_SFC_SRIOV
|
||||
+ .vswitching_probe = efx_port_dummy_op_int,
|
||||
+ .vswitching_restore = efx_port_dummy_op_int,
|
||||
+ .vswitching_remove = efx_port_dummy_op_void,
|
||||
+#endif
|
||||
};
|
||||
|
||||
const struct efx_nic_type falcon_b0_nic_type = {
|
||||
@@ -2902,4 +2907,9 @@ const struct efx_nic_type falcon_b0_nic_
|
||||
.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
|
||||
.mcdi_max_ver = -1,
|
||||
.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
|
||||
+#ifdef CONFIG_SFC_SRIOV
|
||||
+ .vswitching_probe = efx_port_dummy_op_int,
|
||||
+ .vswitching_restore = efx_port_dummy_op_int,
|
||||
+ .vswitching_remove = efx_port_dummy_op_void,
|
||||
+#endif
|
||||
};
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
From fd7c99142d77dc4a851879a66715abf12a3193fb Mon Sep 17 00:00:00 2001
|
||||
From: Dave Martin <Dave.Martin@arm.com>
|
||||
Date: Fri, 6 Jan 2017 17:54:51 +0000
|
||||
Subject: tile/ptrace: Preserve previous registers for short regset write
|
||||
|
||||
From: Dave Martin <Dave.Martin@arm.com>
|
||||
|
||||
commit fd7c99142d77dc4a851879a66715abf12a3193fb upstream.
|
||||
|
||||
Ensure that if userspace supplies insufficient data to
|
||||
PTRACE_SETREGSET to fill all the registers, the thread's old
|
||||
registers are preserved.
|
||||
|
||||
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
|
||||
Signed-off-by: Chris Metcalf <cmetcalf@mellanox.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
---
|
||||
arch/tile/kernel/ptrace.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/tile/kernel/ptrace.c
|
||||
+++ b/arch/tile/kernel/ptrace.c
|
||||
@@ -111,7 +111,7 @@ static int tile_gpr_set(struct task_stru
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
- struct pt_regs regs;
|
||||
+ struct pt_regs regs = *task_pt_regs(target);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s, 0,
|
||||
sizeof(regs));
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
From dec08194ffeccfa1cf085906b53d301930eae18f Mon Sep 17 00:00:00 2001
|
||||
From: Jiahau Chang <jiahau@gmail.com>
|
||||
Date: Mon, 19 Jun 2017 13:08:30 +0300
|
||||
Subject: xhci: Limit USB2 port wake support for AMD Promontory hosts
|
||||
|
||||
For AMD Promontory xHCI host, although you can disable USB 2.0 ports in
|
||||
BIOS settings, those ports will be enabled anyway after you remove a
|
||||
device on that port and re-plug it in again. It's a known limitation of
|
||||
the chip. As a workaround we can clear the PORT_WAKE_BITS.
|
||||
|
||||
This will disable wake on connect, disconnect and overcurrent on
|
||||
AMD Promontory USB2 ports
|
||||
|
||||
[checkpatch cleanup and commit message reword -Mathias]
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Cc: Tsai Nicholas <nicholas.tsai@amd.com>
|
||||
Signed-off-by: Jiahau Chang <Lars_Chang@asmedia.com.tw>
|
||||
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/xhci-hub.c | 3 +++
|
||||
drivers/usb/host/xhci-pci.c | 12 ++++++++++++
|
||||
drivers/usb/host/xhci.h | 1 +
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
|
||||
index 0dde49c..1adae9e 100644
|
||||
--- a/drivers/usb/host/xhci-hub.c
|
||||
+++ b/drivers/usb/host/xhci-hub.c
|
||||
@@ -1461,6 +1461,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
|
||||
t2 |= PORT_WKOC_E | PORT_WKCONN_E;
|
||||
t2 &= ~PORT_WKDISC_E;
|
||||
}
|
||||
+ if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
|
||||
+ (hcd->speed < HCD_USB3))
|
||||
+ t2 &= ~PORT_WAKE_BITS;
|
||||
} else
|
||||
t2 &= ~PORT_WAKE_BITS;
|
||||
|
||||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
|
||||
index 1bcf971..0965bae 100644
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -54,6 +54,11 @@
|
||||
#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
|
||||
#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0
|
||||
|
||||
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
|
||||
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
|
||||
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
|
||||
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
|
||||
+
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
|
||||
static struct hc_driver __read_mostly xhci_pci_hc_driver;
|
||||
@@ -135,6 +140,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_AMD)
|
||||
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
|
||||
+ if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
|
||||
+ ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
|
||||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
|
||||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
|
||||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
|
||||
+ xhci->quirks |= XHCI_U2_DISABLE_WAKE;
|
||||
+
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
xhci->quirks |= XHCI_LPM_SUPPORT;
|
||||
xhci->quirks |= XHCI_INTEL_HOST;
|
||||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
|
||||
index 73a28a9..dcd9649 100644
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1819,6 +1819,7 @@ struct xhci_hcd {
|
||||
/* For controller with a broken Port Disable implementation */
|
||||
#define XHCI_BROKEN_PORT_PED (1 << 25)
|
||||
#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
|
||||
+#define XHCI_U2_DISABLE_WAKE (1 << 27)
|
||||
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+73
-17
@@ -28,25 +28,48 @@
|
||||
</BuildDependencies>
|
||||
<Patches>
|
||||
<!-- Linux patches -->
|
||||
<Patch level="1" compressionType="xz">patches/linux/patch-4.9.6.xz</Patch>
|
||||
<!-- Mageia Linux patches // compatible with http://svnweb.mageia.org/packages/cauldron/kernel/releases/4.9.6/1.mga6/PATCHES/patches/series-->
|
||||
<Patch level="1" compressionType="xz">patches/linux/patch-4.9.35.xz</Patch>
|
||||
<!-- Mageia Linux patches // compatible with http://svnweb.mageia.org/packages/cauldron/kernel/releases/4.9.35/1.mga6/PATCHES/patches/series-->
|
||||
<!--stable patches-->
|
||||
<Patch level="1">patches/mageia/stable-ipv6-release-dst-on-error-in-ip6_dst_lookup_tail.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-vrf-make-add_fib_rules-per-network-namespace-flag.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-sctp-disable-bh-in-sctp_for_each_endpoint.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-proc-snmp6-use-correct-type-in-memset.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-igmp-add-a-missing-spin_lock_init.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-mlx5e-fix-timestamping-capabilities-reporting.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-sfc-provide-dummy-definitions-of-vswitch-functions.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-ipv6-do-not-leak-throw-route-references.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-rtnetlink-add-ifla_group-to-ifla_policy.patch</Patch>
|
||||
|
||||
<!--CVE-2016-8405-->
|
||||
<Patch level="1">patches/mageia/stable-fbdev-color-map-copying-bounds-checking.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-tile-ptrace-preserve-previous-registers-for-short-regset-write.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-drm-schedule-the-output_poll_work-with-1s-delay-if-we-have-delayed-event.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-drm-fix-broken-vt-switch-with-video-1366x768-option.patch</Patch>
|
||||
<Patch level="1">patches/mageia/stable-drm-i915-ignore-bogus-plane-coordinates-on-skl-when-the-plane-is-not-visible.patch</Patch>
|
||||
<!--other patches-->
|
||||
<Patch level="1">patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch</Patch>
|
||||
<Patch level="1">patches/mageia/Revert-x86-mm-mtrr-Remove-kernel-internal-MTRR-inter.patch</Patch>
|
||||
<Patch level="1">patches/mageia/base-cacheinfo-silence-DT-warnings.patch</Patch>
|
||||
<Patch level="1">patches/mageia/iommu-amd-flush-IOTLB-for-specific-domains-only-v3.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pci-quirks-drop-devinit-exit.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pci-Blacklist-AMD-Stoney-GPU-devices-for-ATS.patch</Patch>
|
||||
<Patch level="1">patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch</Patch>
|
||||
<Patch level="1">patches/mageia/acpi-processor-M720SR-limit-to-C2.patch</Patch>
|
||||
<Patch level="1">patches/mageia/ACPI-video-Add-a-quirk-to-force-acpi-video-backlight.patch</Patch>
|
||||
<Patch level="1">patches/mageia/acpi-do-not-warn-if-_BQC-does-not-exist.patch</Patch>
|
||||
<Patch level="1">patches/mageia/acpi-ACPICA-Events-Fix-acpi_ev_initialize_region-return-v.patch</Patch>
|
||||
<!--Patch level="1">patches/mageia/scsi-ppscsi-2.6.2.patch</Patch>
|
||||
<Patch level="1">patches/mageia/scsi-ppscsi_fixes.patch</Patch>
|
||||
<Patch level="1">patches/mageia/scsi-ppscsi-sg-helper-update.patch</Patch>
|
||||
@@ -60,17 +83,23 @@
|
||||
<Patch level="1">patches/mageia/block-floppy-disable-pnp-modalias.patch</Patch>
|
||||
<Patch level="1">patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch</Patch>
|
||||
<!--Patch level="1">patches/mageia/block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.5.0.patch</Patch>
|
||||
<!--2-->
|
||||
<Patch level="1">patches/mageia/block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.5.0.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-introduce-the-BFQ-v7r11-I-O-sched-for-4.5.0.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-Turn-into-BFQ-v8r6-for-4.9.0.patch</Patch>--><!--2-->
|
||||
<Patch level="1">patches/mageia/block-Turn-into-BFQ-v8r7-for-4.9.0.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-update-bfq-from-v8r7-to-v8r10.patch</Patch>
|
||||
<Patch level="1">patches/mageia/block-update-bfq-from-v8r10-to-v8r11.patch</Patch><!--2-->
|
||||
<Patch level="1">patches/mageia/block-nvme-detect-NVMe-controller-in-recent-MacBooks.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-tpm-tpm_crb-implement-tpm-crb-idle-state.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-tmp-tpm_crb-fix-Intel-PTT-hw-bug-during-idle-state.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-tpm-tpm_crb-open-code-the-crb_init-into-acpi_add.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-tmp-tpm_crb-implement-runtime-pm-for-tpm_crb.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-aufs-4.9.patch</Patch>
|
||||
<Patch level="1">patches/fs-aufs-4.9-posix_acl.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-aufs-4.9-modular.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-seq_file-reset-iterator-to-first-record-for-zero-off.patch</Patch>
|
||||
<Patch level="1">patches/mageia/fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch</Patch>
|
||||
<Patch level="1">patches/mageia/firewire-ieee1394-module-aliases.patch</Patch>
|
||||
<Patch level="1">patches/mageia/char-agp-intel-new-Q57-id.patch</Patch>
|
||||
<!--remove external mach64 support for buildfix-->
|
||||
@@ -91,10 +120,13 @@
|
||||
<Patch level="1">patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-mach64-3.17-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-mach64-3.18-buildfix.patch</Patch--><!--1-->
|
||||
<Patch level="1">patches/mageia/gpu-drm-i915-skl-drop-workarounds-for-A0-and-B0-revisions.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-i915-skl-drop-workarounds-for-D0-revision.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-i915-skl-drop-workarounds-for-E0-revision.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-i915-Remove-WaDisableLSQCROPERFforOCL-KBL-workaround.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-i915-don-t-warn-about-Skylake-CPU-KabyPoint-PCH-.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amd-amdgpu-add-Polaris12-PCI-ID.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amdgpu-add-Polaris12-DID.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amd-amdgpu-add-Polaris12-support-v3.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amdgpu-powerplay-add-Polaris12-support.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch</Patch>
|
||||
<Patch level="1">patches/mageia/gpu-drm-amdgpu-pm-check-for-headless-before-calling-comp.patch</Patch>
|
||||
<Patch level="1">patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-sis190-fix-list-usage.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-IFWLOG.patch</Patch>
|
||||
@@ -110,14 +142,28 @@
|
||||
<Patch level="1">patches/mageia/net-netfilter-psd-fix-redefines.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-wireless-rtlwifi-Use-dev_kfree_skb_irq-instead-of-kfree_skb.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-wireless-rtlwifi-Fix-kernel-oops-introduced-with-commit-e4965.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-wireless-brcmfmac-fix-incorrect-event-channel-deduction.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-wireless-realtek-rtl8xxxu-linux-4.11-rc.patch</Patch>
|
||||
<Patch level="1">patches/mageia/net-netfilter-xt_TCPMSS-add-more-sanity-tests-on-tcph-do.patch</Patch>
|
||||
<Patch level="1">patches/mageia/pinctrl_amd-Use-regular-interrupt-instead-of-chained.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-add-shuttle-wmi-driver.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch</Patch>
|
||||
<Patch level="1">patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/include-kbuild-export-pci_ids.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-realtek-Add-new-codec-ID-ALC299.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-realtek-New-codec-support-of-ALC1220.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Apply-dual-codec-quirk-for-MSI-Z270-Gaming-.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Fix-applying-MSI-dual-codec-mobo-quirk.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Add-Geminilake-id-to-SKL_PLUS.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Add-Coffelake-PCI-ID.patch</Patch>
|
||||
<Patch level="1">patches/mageia/sound-ALSA-hda-Apply-quirks-to-Broxton-T-too.patch</Patch>
|
||||
<Patch level="1">patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-storage-unusual_devs-add-id.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/usb-xhci-Limit-USB2-port-wake-support-for-AMD-Promontory-hosts.patch</Patch>
|
||||
<Patch level="1">patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-3rdparty-1.0-tree.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-3rdparty-merge.patch</Patch>
|
||||
@@ -145,6 +191,7 @@
|
||||
<Patch level="1">patches/mageia/3rd-viahss-2.6.35-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-viahss-3.0-buildfix.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-rtl8723bs.patch</Patch>
|
||||
<Patch level="1">patches/mageia/3rd-rtl8812au.patch</Patch>
|
||||
<Patch level="1">patches/mageia/tools-testing-selftest-Makefile-remove-powerpc-reference.patch</Patch>
|
||||
<Patch level="1">patches/mageia/tools-build-Make-fixdep-parsing-wait-for-last-target.patch</Patch>
|
||||
<Patch level="1">patches/mageia/tools-perf-tools-Force-fixdep-compilation-at-the-start-of-.patch</Patch>
|
||||
@@ -158,13 +205,11 @@
|
||||
<Dependency>pisi</Dependency>
|
||||
<Dependency>linux-firmware</Dependency>
|
||||
<Dependency>grub2</Dependency>
|
||||
<!--Dependency>mkinitcpio</Dependency-->
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
<Path fileType="executable" permanent="true">/boot</Path>
|
||||
<Path fileType="library" permanent="true">/lib/modules</Path>
|
||||
<Path fileType="data">/etc/kernel</Path>
|
||||
<Path fileType="config">/etc/mkinitcpio.d</Path>
|
||||
</Files>
|
||||
<Provides>
|
||||
<COMAR script="package.py">System.Package</COMAR>
|
||||
@@ -204,6 +249,17 @@
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="10">
|
||||
<Date>2017-07-02</Date>
|
||||
<Version>4.9.35</Version>
|
||||
<Comment>Version Bump.</Comment>
|
||||
<Type package="kernel">security</Type>
|
||||
<Requires>
|
||||
<Action package="kernel">systemRestart</Action>
|
||||
</Requires>
|
||||
<Name>Ertuğrul Erata</Name>
|
||||
<Email>ertugrulerata@gmail.com</Email>
|
||||
</Update>
|
||||
<Update release="9">
|
||||
<Date>2017-01-27</Date>
|
||||
<Version>4.9.6</Version>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
diff -Nuar linux-4.9.orig/fs/aufs/posix_acl.c linux-4.9/fs/aufs/posix_acl.c
|
||||
--- linux-4.9.orig/fs/aufs/posix_acl.c 2017-04-09 09:33:00.155052337 +0300
|
||||
+++ linux-4.9/fs/aufs/posix_acl.c 2017-04-09 09:34:03.760053849 +0300
|
||||
@@ -1,5 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Junjiro R. Okajima
|
||||
+ *
|
||||
+ * This program, aufs is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -36,6 +49,8 @@
|
||||
|
||||
/* always topmost only */
|
||||
acl = get_acl(h_inode, type);
|
||||
+ if (!IS_ERR_OR_NULL(acl))
|
||||
+ set_cached_acl(inode, type, acl);
|
||||
|
||||
out:
|
||||
ii_read_unlock(inode);
|
||||
@@ -77,8 +92,10 @@
|
||||
ssz = au_sxattr(dentry, inode, &arg);
|
||||
dput(dentry);
|
||||
err = ssz;
|
||||
- if (ssz >= 0)
|
||||
+ if (ssz >= 0) {
|
||||
err = 0;
|
||||
+ set_cached_acl(inode, type, acl);
|
||||
+ }
|
||||
|
||||
out:
|
||||
return err;
|
||||
diff -Nuar linux-4.9.orig/fs/aufs/xattr.c linux-4.9/fs/aufs/xattr.c
|
||||
--- linux-4.9.orig/fs/aufs/xattr.c 2017-04-09 09:33:00.160052337 +0300
|
||||
+++ linux-4.9/fs/aufs/xattr.c 2017-04-09 09:34:08.757053967 +0300
|
||||
@@ -1,11 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Junjiro R. Okajima
|
||||
+ *
|
||||
+ * This program, aufs is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* handling xattr functions
|
||||
*/
|
||||
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/posix_acl_xattr.h>
|
||||
#include <linux/xattr.h>
|
||||
#include "aufs.h"
|
||||
|
||||
@@ -309,7 +324,11 @@
|
||||
};
|
||||
|
||||
static const struct xattr_handler *au_xattr_handlers[] = {
|
||||
- &au_xattr_handler,
|
||||
+#ifdef CONFIG_FS_POSIX_ACL
|
||||
+ &posix_acl_access_xattr_handler,
|
||||
+ &posix_acl_default_xattr_handler,
|
||||
+#endif
|
||||
+ &au_xattr_handler, /* must be last */
|
||||
NULL
|
||||
};
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
-70
@@ -1,70 +0,0 @@
|
||||
From ca45663819accf038291dbe2d67ed66dc48d714c Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Backlund <tmb@mageia.org>
|
||||
Date: Sun, 29 Nov 2015 14:44:22 +0200
|
||||
Subject: [PATCH] Revert "x86/mm/mtrr: Remove kernel internal MTRR interfaces:
|
||||
unexport mtrr_add() and mtrr_del()"
|
||||
|
||||
This reverts commit 2baa891e42d84159b693eadd44f6fe1486285bdc.
|
||||
|
||||
It currently breaks nvidia304 driver.
|
||||
|
||||
Signed-of-by: Thomas Backlund <tmb@mageia.org>
|
||||
---
|
||||
Documentation/x86/mtrr.txt | 20 ++++----------------
|
||||
arch/x86/kernel/cpu/mtrr/main.c | 2 ++
|
||||
2 files changed, 6 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/Documentation/x86/mtrr.txt b/Documentation/x86/mtrr.txt
|
||||
index dc3e703..860bc3a 100644
|
||||
--- a/Documentation/x86/mtrr.txt
|
||||
+++ b/Documentation/x86/mtrr.txt
|
||||
@@ -6,22 +6,10 @@ Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
|
||||
===============================================================================
|
||||
Phasing out MTRR use
|
||||
|
||||
-MTRR use is replaced on modern x86 hardware with PAT. Direct MTRR use by
|
||||
-drivers on Linux is now completely phased out, device drivers should use
|
||||
-arch_phys_wc_add() in combination with ioremap_wc() to make MTRR effective on
|
||||
-non-PAT systems while a no-op but equally effective on PAT enabled systems.
|
||||
-
|
||||
-Even if Linux does not use MTRRs directly, some x86 platform firmware may still
|
||||
-set up MTRRs early before booting the OS. They do this as some platform
|
||||
-firmware may still have implemented access to MTRRs which would be controlled
|
||||
-and handled by the platform firmware directly. An example of platform use of
|
||||
-MTRRs is through the use of SMI handlers, one case could be for fan control,
|
||||
-the platform code would need uncachable access to some of its fan control
|
||||
-registers. Such platform access does not need any Operating System MTRR code in
|
||||
-place other than mtrr_type_lookup() to ensure any OS specific mapping requests
|
||||
-are aligned with platform MTRR setup. If MTRRs are only set up by the platform
|
||||
-firmware code though and the OS does not make any specific MTRR mapping
|
||||
-requests mtrr_type_lookup() should always return MTRR_TYPE_INVALID.
|
||||
+MTRR use is replaced on modern x86 hardware with PAT. Over time the only type
|
||||
+of effective MTRR that is expected to be supported will be for write-combining.
|
||||
+As MTRR use is phased out device drivers should use arch_phys_wc_add() to make
|
||||
+MTRR effective on non-PAT systems while a no-op on PAT enabled systems.
|
||||
|
||||
For details refer to Documentation/x86/pat.txt.
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
|
||||
index f891b47..e7ed0d8 100644
|
||||
--- a/arch/x86/kernel/cpu/mtrr/main.c
|
||||
+++ b/arch/x86/kernel/cpu/mtrr/main.c
|
||||
@@ -448,6 +448,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
|
||||
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
|
||||
increment);
|
||||
}
|
||||
+EXPORT_SYMBOL(mtrr_add);
|
||||
|
||||
/**
|
||||
* mtrr_del_page - delete a memory type region
|
||||
@@ -536,6 +537,7 @@ int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
return -EINVAL;
|
||||
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
|
||||
}
|
||||
+EXPORT_SYMBOL(mtrr_del);
|
||||
|
||||
/**
|
||||
* arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable
|
||||
--
|
||||
2.3.10
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
From 760235cd6ca8ae0d7509055d75a0f1d8b3c60668 Mon Sep 17 00:00:00 2001
|
||||
From: Lv Zheng <lv.zheng@intel.com>
|
||||
Date: Wed, 30 Nov 2016 15:21:12 +0800
|
||||
Subject: [PATCH] ACPICA: Events: Fix acpi_ev_initialize_region() return value
|
||||
|
||||
ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8
|
||||
|
||||
This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST
|
||||
from it so that, not only in acpi_ds_load2_end_op(), but all places invoking
|
||||
this function won't emit exceptions. The exception can be seen in
|
||||
acpi_ds_initialize_objects() when certain table loading mode is chosen.
|
||||
|
||||
This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region()
|
||||
as this function will always be invoked with interpreter lock held now, and
|
||||
the lock granularity has been tuned to lock around _REG execution, thus it
|
||||
is now handled by acpi_ex_exit_interpreter(). Lv Zheng.
|
||||
|
||||
Link: https://github.com/acpica/acpica/commit/543342ab
|
||||
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
|
||||
Signed-off-by: Bob Moore <robert.moore@intel.com>
|
||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
---
|
||||
drivers/acpi/acpica/acevents.h | 4 +--
|
||||
drivers/acpi/acpica/dsopcode.c | 2 +-
|
||||
drivers/acpi/acpica/dswload2.c | 13 +---------
|
||||
drivers/acpi/acpica/evrgnini.c | 59 +++++++++++++++++-------------------------
|
||||
4 files changed, 27 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
|
||||
index 92fa47c..8a0049d 100644
|
||||
--- a/drivers/acpi/acpica/acevents.h
|
||||
+++ b/drivers/acpi/acpica/acevents.h
|
||||
@@ -243,9 +243,7 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
u32 function,
|
||||
void *handler_context, void **region_context);
|
||||
|
||||
-acpi_status
|
||||
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
- u8 acpi_ns_locked);
|
||||
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
|
||||
|
||||
/*
|
||||
* evsci - SCI (System Control Interrupt) handling/dispatch
|
||||
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
|
||||
index 4cc9d98..77fd7c8 100644
|
||||
--- a/drivers/acpi/acpica/dsopcode.c
|
||||
+++ b/drivers/acpi/acpica/dsopcode.c
|
||||
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
|
||||
|
||||
/* Namespace is NOT locked */
|
||||
|
||||
- status = acpi_ev_initialize_region(obj_desc, FALSE);
|
||||
+ status = acpi_ev_initialize_region(obj_desc);
|
||||
return (status);
|
||||
}
|
||||
|
||||
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
|
||||
index e362182..651f35a 100644
|
||||
--- a/drivers/acpi/acpica/dswload2.c
|
||||
+++ b/drivers/acpi/acpica/dswload2.c
|
||||
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
|
||||
status =
|
||||
acpi_ev_initialize_region
|
||||
- (acpi_ns_get_attached_object(node), FALSE);
|
||||
-
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- /*
|
||||
- * If AE_NOT_EXIST is returned, it is not fatal
|
||||
- * because many regions get created before a handler
|
||||
- * is installed for said region.
|
||||
- */
|
||||
- if (AE_NOT_EXIST == status) {
|
||||
- status = AE_OK;
|
||||
- }
|
||||
- }
|
||||
+ (acpi_ns_get_attached_object(node));
|
||||
break;
|
||||
|
||||
case AML_NAME_OP:
|
||||
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
|
||||
index 75ddd16..a909225 100644
|
||||
--- a/drivers/acpi/acpica/evrgnini.c
|
||||
+++ b/drivers/acpi/acpica/evrgnini.c
|
||||
@@ -479,7 +479,6 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
* FUNCTION: acpi_ev_initialize_region
|
||||
*
|
||||
* PARAMETERS: region_obj - Region we are initializing
|
||||
- * acpi_ns_locked - Is namespace locked?
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
@@ -497,19 +496,28 @@ acpi_ev_default_region_setup(acpi_handle handle,
|
||||
* MUTEX: Interpreter should be unlocked, because we may run the _REG
|
||||
* method for this region.
|
||||
*
|
||||
+ * NOTE: Possible incompliance:
|
||||
+ * There is a behavior conflict in automatic _REG execution:
|
||||
+ * 1. When the interpreter is evaluating a method, we can only
|
||||
+ * automatically run _REG for the following case:
|
||||
+ * operation_region (OPR1, 0x80, 0x1000010, 0x4)
|
||||
+ * 2. When the interpreter is loading a table, we can also
|
||||
+ * automatically run _REG for the following case:
|
||||
+ * operation_region (OPR1, 0x80, 0x1000010, 0x4)
|
||||
+ * Though this may not be compliant to the de-facto standard, the
|
||||
+ * logic is kept in order not to trigger regressions. And keeping
|
||||
+ * this logic should be taken care by the caller of this function.
|
||||
+ *
|
||||
******************************************************************************/
|
||||
|
||||
-acpi_status
|
||||
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
- u8 acpi_ns_locked)
|
||||
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
|
||||
{
|
||||
union acpi_operand_object *handler_obj;
|
||||
union acpi_operand_object *obj_desc;
|
||||
acpi_adr_space_type space_id;
|
||||
struct acpi_namespace_node *node;
|
||||
- acpi_status status;
|
||||
|
||||
- ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
|
||||
+ ACPI_FUNCTION_TRACE(ev_initialize_region);
|
||||
|
||||
if (!region_obj) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
@@ -580,39 +588,17 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
handler_obj, region_obj,
|
||||
obj_desc));
|
||||
|
||||
- status =
|
||||
- acpi_ev_attach_region(handler_obj,
|
||||
- region_obj,
|
||||
- acpi_ns_locked);
|
||||
+ (void)acpi_ev_attach_region(handler_obj,
|
||||
+ region_obj, FALSE);
|
||||
|
||||
/*
|
||||
* Tell all users that this region is usable by
|
||||
* running the _REG method
|
||||
*/
|
||||
- if (acpi_ns_locked) {
|
||||
- status =
|
||||
- acpi_ut_release_mutex
|
||||
- (ACPI_MTX_NAMESPACE);
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- return_ACPI_STATUS(status);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
acpi_ex_exit_interpreter();
|
||||
- status =
|
||||
- acpi_ev_execute_reg_method(region_obj,
|
||||
- ACPI_REG_CONNECT);
|
||||
+ (void)acpi_ev_execute_reg_method(region_obj,
|
||||
+ ACPI_REG_CONNECT);
|
||||
acpi_ex_enter_interpreter();
|
||||
-
|
||||
- if (acpi_ns_locked) {
|
||||
- status =
|
||||
- acpi_ut_acquire_mutex
|
||||
- (ACPI_MTX_NAMESPACE);
|
||||
- if (ACPI_FAILURE(status)) {
|
||||
- return_ACPI_STATUS(status);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
}
|
||||
@@ -622,12 +608,15 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
- /* If we get here, there is no handler for this region */
|
||||
-
|
||||
+ /*
|
||||
+ * If we get here, there is no handler for this region. This is not
|
||||
+ * fatal because many regions get created before a handler is installed
|
||||
+ * for said region.
|
||||
+ */
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
|
||||
"No handler for RegionType %s(%X) (RegionObj %p)\n",
|
||||
acpi_ut_get_region_name(space_id), space_id,
|
||||
region_obj));
|
||||
|
||||
- return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
+ return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+192
-170
@@ -1,9 +1,13 @@
|
||||
From 3e3791c0b4ef3b2067f8454e58001af8e3da3840 Mon Sep 17 00:00:00 2001
|
||||
From 0432a5c7bfc4a11531c1e58f574c733a2552f149 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Valente <paolo.valente@linaro.org>
|
||||
Date: Tue, 17 May 2016 08:28:04 +0200
|
||||
Subject: [PATCH 4/4] Turn into BFQ-v8r6 for 4.9.0
|
||||
Subject: [PATCH 4/4] Turn into BFQ-v8r7 for 4.9.0
|
||||
|
||||
CHANGELOG from v8r4 to v8r6
|
||||
CHANGELOG from v8r4 to v8r7
|
||||
|
||||
BFQ v8r7
|
||||
|
||||
BUGFIX: make BFQ compile also without hierarchical support
|
||||
|
||||
BFQ v8r6
|
||||
|
||||
@@ -125,9 +129,9 @@ Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||
block/Kconfig.iosched | 18 +-
|
||||
block/bfq-cgroup.c | 501 +++---
|
||||
block/bfq-iosched.c | 3278 ++++++++++++++++++++++-------------
|
||||
block/bfq-sched.c | 1270 +++++++++++---
|
||||
block/bfq-sched.c | 1288 +++++++++++---
|
||||
block/bfq.h | 800 +++++----
|
||||
7 files changed, 4310 insertions(+), 2089 deletions(-)
|
||||
7 files changed, 4320 insertions(+), 2097 deletions(-)
|
||||
create mode 100644 Documentation/block/bfq-iosched.txt
|
||||
|
||||
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX
|
||||
@@ -1601,7 +1605,7 @@ index 0367996..bbaecd0 100644
|
||||
|
||||
static struct bfq_group *
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index cf3e9b1..0f9cd53 100644
|
||||
index cf3e9b1..2a2c130 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -1,5 +1,5 @@
|
||||
@@ -6201,7 +6205,7 @@ index cf3e9b1..0f9cd53 100644
|
||||
-
|
||||
- if (bfq_timeout_async == 0)
|
||||
- bfq_timeout_async = 1;
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r6";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r7";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
@@ -6265,10 +6269,10 @@ index cf3e9b1..0f9cd53 100644
|
||||
return 0;
|
||||
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index a5ed694..4af77f4 100644
|
||||
index a5ed694..797bce7 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -7,28 +7,46 @@
|
||||
@@ -7,28 +7,166 @@
|
||||
* Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
|
||||
* Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
@@ -6276,8 +6280,8 @@ index a5ed694..4af77f4 100644
|
||||
+ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
*/
|
||||
|
||||
+ */
|
||||
+
|
||||
+static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
+
|
||||
+/**
|
||||
@@ -6292,63 +6296,17 @@ index a5ed694..4af77f4 100644
|
||||
+ return (s64)(a - b) > 0;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
-#define for_each_entity(entity) \
|
||||
+/* both next loops stop at one of the child entities of the root group */
|
||||
+#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
|
||||
-static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
|
||||
- int extract,
|
||||
- struct bfq_data *bfqd);
|
||||
-
|
||||
-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
|
||||
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+/*
|
||||
+ * Returns true if this budget changes may let next_in_service->parent
|
||||
+ * become the next_in_service entity for its parent entity.
|
||||
+ */
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
struct bfq_entity *bfqg_entity;
|
||||
struct bfq_group *bfqg;
|
||||
struct bfq_sched_data *group_sd;
|
||||
+ bool ret = false;
|
||||
|
||||
BUG_ON(!next_in_service);
|
||||
|
||||
@@ -41,39 +59,134 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
* as it must never become an in-service entity.
|
||||
*/
|
||||
bfqg_entity = bfqg->my_entity;
|
||||
- if (bfqg_entity)
|
||||
+ if (bfqg_entity) {
|
||||
+ if (bfqg_entity->budget > next_in_service->budget)
|
||||
+ ret = true;
|
||||
bfqg_entity->budget = next_in_service->budget;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree)
|
||||
{
|
||||
- struct bfq_entity *next_in_service;
|
||||
+{
|
||||
+ struct rb_node *node = tree->rb_node;
|
||||
|
||||
- if (sd->in_service_entity)
|
||||
- /* will update/requeue at the end of service */
|
||||
- return 0;
|
||||
+
|
||||
+ return rb_entry(node, struct bfq_entity, rb_node);
|
||||
+}
|
||||
+
|
||||
+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
|
||||
+
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service);
|
||||
+
|
||||
+/**
|
||||
+ * bfq_update_next_in_service - update sd->next_in_service
|
||||
+ * @sd: sched_data for which to perform the update.
|
||||
@@ -6371,20 +6329,15 @@ index a5ed694..4af77f4 100644
|
||||
+ * Returns true if sd->next_in_service changes in such a way that
|
||||
+ * entity->parent may become the next_in_service for its parent
|
||||
+ * entity.
|
||||
+ */
|
||||
*/
|
||||
+static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
|
||||
+ struct bfq_entity *new_entity)
|
||||
+{
|
||||
+ struct bfq_entity *next_in_service = sd->next_in_service;
|
||||
+ struct bfq_queue *bfqq;
|
||||
+ bool parent_sched_may_change = false;
|
||||
|
||||
/*
|
||||
- * NOTE: this can be improved in many ways, such as returning
|
||||
- * 1 (and thus propagating upwards the update) only when the
|
||||
- * budget changes, or caching the bfqq that will be scheduled
|
||||
- * next from this subtree. By now we worry more about
|
||||
- * correctness than about performance...
|
||||
+
|
||||
+ /*
|
||||
+ * If this update is triggered by the activation, requeueing
|
||||
+ * or repositiong of an entity that does not coincide with
|
||||
+ * sd->next_in_service, then a full lookup in the active tree
|
||||
@@ -6395,8 +6348,7 @@ index a5ed694..4af77f4 100644
|
||||
+ * finish time than sd->next_in_service. If this compound
|
||||
+ * condition holds, then the new entity becomes the new
|
||||
+ * next_in_service. Otherwise no change is needed.
|
||||
*/
|
||||
- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
|
||||
+ */
|
||||
+ if (new_entity && new_entity != sd->next_in_service) {
|
||||
+ /*
|
||||
+ * Flag used to decide whether to replace
|
||||
@@ -6445,54 +6397,160 @@ index a5ed694..4af77f4 100644
|
||||
+ bfq_update_parent_budget(next_in_service);
|
||||
+ }
|
||||
+
|
||||
sd->next_in_service = next_in_service;
|
||||
|
||||
- if (next_in_service)
|
||||
- bfq_update_budget(next_in_service);
|
||||
+ sd->next_in_service = next_in_service;
|
||||
+
|
||||
+ if (!next_in_service)
|
||||
+ return parent_sched_may_change;
|
||||
|
||||
- return 1;
|
||||
-}
|
||||
+ bfqq = bfq_entity_to_bfqq(next_in_service);
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||
+ "update_next_in_service: chosen this queue");
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
-#define for_each_entity(entity) \
|
||||
+ else {
|
||||
+ struct bfq_group *bfqg =
|
||||
+ container_of(next_in_service,
|
||||
+ struct bfq_group, entity);
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
-{
|
||||
- BUG_ON(sd->next_in_service != entity);
|
||||
+
|
||||
+ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
|
||||
+ "update_next_in_service: chosen this entity");
|
||||
+ }
|
||||
+#endif
|
||||
+ return parent_sched_may_change;
|
||||
}
|
||||
+}
|
||||
+
|
||||
#else
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = NULL)
|
||||
@@ -86,12 +199,7 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
return 0;
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
+/* both next loops stop at one of the child entities of the root group */
|
||||
+#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
-
|
||||
-static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
|
||||
- int extract,
|
||||
- struct bfq_data *bfqd);
|
||||
-
|
||||
-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
|
||||
-
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+/*
|
||||
+ * Returns true if this budget changes may let next_in_service->parent
|
||||
+ * become the next_in_service entity for its parent entity.
|
||||
+ */
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
struct bfq_entity *bfqg_entity;
|
||||
struct bfq_group *bfqg;
|
||||
struct bfq_sched_data *group_sd;
|
||||
+ bool ret = false;
|
||||
|
||||
BUG_ON(!next_in_service);
|
||||
|
||||
@@ -41,60 +179,68 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
* as it must never become an in-service entity.
|
||||
*/
|
||||
bfqg_entity = bfqg->my_entity;
|
||||
- if (bfqg_entity)
|
||||
+ if (bfqg_entity) {
|
||||
+ if (bfqg_entity->budget > next_in_service->budget)
|
||||
+ ret = true;
|
||||
bfqg_entity->budget = next_in_service->budget;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+/*
|
||||
+ * This function tells whether entity stops being a candidate for next
|
||||
+ * service, according to the following logic.
|
||||
+ *
|
||||
+ * This function is invoked for an entity that is about to be set in
|
||||
+ * service. If such an entity is a queue, then the entity is no longer
|
||||
+ * a candidate for next service (i.e, a candidate entity to serve
|
||||
+ * after the in-service entity is expired). The function then returns
|
||||
+ * true.
|
||||
+ *
|
||||
+ * In contrast, the entity could stil be a candidate for next service
|
||||
+ * if it is not a queue, and has more than one child. In fact, even if
|
||||
+ * one of its children is about to be set in service, other children
|
||||
+ * may still be the next to serve. As a consequence, a non-queue
|
||||
+ * entity is not a candidate for next-service only if it has only one
|
||||
+ * child. And only if this condition holds, then the function returns
|
||||
+ * true for a non-queue entity.
|
||||
+ */
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
{
|
||||
- struct bfq_entity *next_in_service;
|
||||
+ struct bfq_group *bfqg;
|
||||
|
||||
- if (sd->in_service_entity)
|
||||
- /* will update/requeue at the end of service */
|
||||
- return 0;
|
||||
+ if (bfq_entity_to_bfqq(entity))
|
||||
+ return true;
|
||||
|
||||
- /*
|
||||
- * NOTE: this can be improved in many ways, such as returning
|
||||
- * 1 (and thus propagating upwards the update) only when the
|
||||
- * budget changes, or caching the bfqq that will be scheduled
|
||||
- * next from this subtree. By now we worry more about
|
||||
- * correctness than about performance...
|
||||
- */
|
||||
- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
|
||||
- sd->next_in_service = next_in_service;
|
||||
+ bfqg = container_of(entity, struct bfq_group, entity);
|
||||
|
||||
- if (next_in_service)
|
||||
- bfq_update_budget(next_in_service);
|
||||
+ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
|
||||
+ BUG_ON(bfqg->active_entities == 0);
|
||||
+ if (bfqg->active_entities == 1)
|
||||
+ return true;
|
||||
|
||||
- return 1;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
-{
|
||||
- BUG_ON(sd->next_in_service != entity);
|
||||
-}
|
||||
-
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
+static void bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
-#else
|
||||
+#else /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = NULL)
|
||||
|
||||
#define for_each_entity_safe(entity, parent) \
|
||||
for (parent = NULL; entity ; entity = parent)
|
||||
|
||||
-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
|
||||
+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
|
||||
{
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
#endif
|
||||
@@ -105,18 +213,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
|
||||
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
|
||||
- struct bfq_entity *entity)
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
{
|
||||
+ return true;
|
||||
}
|
||||
|
||||
-static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
-{
|
||||
-}
|
||||
-#endif
|
||||
+#endif /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||
|
||||
/*
|
||||
* Shift for timestamp calculations. This actually limits the maximum
|
||||
@@ -105,18 +251,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
|
||||
*/
|
||||
#define WFQ_SERVICE_SHIFT 22
|
||||
|
||||
@@ -6511,7 +6569,7 @@ index a5ed694..4af77f4 100644
|
||||
static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
|
||||
{
|
||||
struct bfq_queue *bfqq = NULL;
|
||||
@@ -151,20 +247,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight)
|
||||
@@ -151,20 +285,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);
|
||||
@@ -6550,7 +6608,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,10 +405,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
|
||||
@@ -293,10 +443,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);
|
||||
@@ -6577,7 +6635,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,8 +514,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
@@ -386,8 +552,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
BUG_ON(!bfqg);
|
||||
BUG_ON(!bfqd);
|
||||
bfqg->active_entities++;
|
||||
@@ -6586,7 +6644,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -399,7 +525,7 @@ static void bfq_active_insert(struct bfq_service_tree *st,
|
||||
@@ -399,7 +563,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);
|
||||
@@ -6595,7 +6653,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,9 +548,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
|
||||
@@ -422,9 +586,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
|
||||
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
|
||||
|
||||
if (bfqq) {
|
||||
@@ -6607,7 +6665,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,10 +625,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
|
||||
@@ -499,10 +663,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
|
||||
BUG_ON(!bfqd);
|
||||
BUG_ON(!bfqg->active_entities);
|
||||
bfqg->active_entities--;
|
||||
@@ -6618,7 +6676,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -547,12 +669,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
@@ -547,12 +707,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
|
||||
BUG_ON(!entity->on_st);
|
||||
|
||||
@@ -6633,7 +6691,7 @@ index a5ed694..4af77f4 100644
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
}
|
||||
@@ -602,7 +724,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -602,7 +762,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);
|
||||
@@ -6642,7 +6700,7 @@ index a5ed694..4af77f4 100644
|
||||
struct bfq_data *bfqd = NULL;
|
||||
struct rb_root *root;
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
@@ -630,7 +752,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -630,7 +790,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
entity->new_weight > BFQ_MAX_WEIGHT) {
|
||||
pr_crit("update_weight_prio: new_weight %d\n",
|
||||
entity->new_weight);
|
||||
@@ -6654,7 +6712,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
entity->orig_weight = entity->new_weight;
|
||||
if (bfqq)
|
||||
@@ -661,6 +786,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
@@ -661,6 +824,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
|
||||
* associated with its new weight.
|
||||
*/
|
||||
if (prev_weight != new_weight) {
|
||||
@@ -6668,7 +6726,7 @@ index a5ed694..4af77f4 100644
|
||||
root = bfqq ? &bfqd->queue_weights_tree :
|
||||
&bfqd->group_weights_tree;
|
||||
bfq_weights_tree_remove(bfqd, entity, root);
|
||||
@@ -707,7 +839,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
@@ -707,7 +877,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
st = bfq_entity_service_tree(entity);
|
||||
|
||||
entity->service += served;
|
||||
@@ -6677,7 +6735,7 @@ index a5ed694..4af77f4 100644
|
||||
BUG_ON(st->wsum == 0);
|
||||
|
||||
st->vtime += bfq_delta(served, st->wsum);
|
||||
@@ -716,170 +848,419 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||
@@ -716,170 +886,419 @@ 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
|
||||
@@ -6731,17 +6789,17 @@ index a5ed694..4af77f4 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;
|
||||
@@ -6948,19 +7006,20 @@ index a5ed694..4af77f4 100644
|
||||
- * @entity: the entity to activate.
|
||||
+ * __bfq_requeue_entity - handle requeueing or repositioning of an entity.
|
||||
+ * @entity: the entity being requeued or repositioned.
|
||||
*
|
||||
- * Activate @entity and all the entities on the path from it to the root.
|
||||
+ *
|
||||
+ * Requeueing is needed if this entity stops being served, which
|
||||
+ * happens if a leaf descendant entity has expired. On the other hand,
|
||||
+ * repositioning is needed if the next_inservice_entity for the child
|
||||
+ * entity has changed. See the comments inside the function for
|
||||
+ * details.
|
||||
+ *
|
||||
*
|
||||
- * Activate @entity and all the entities on the path from it to the root.
|
||||
+ * Basically, this function: 1) removes entity from its active tree if
|
||||
+ * present there, 2) updates the timestamps of entity and 3) inserts
|
||||
+ * entity back into its active tree (in the new, right position for
|
||||
+ * the new values of the timestamps).
|
||||
+ */
|
||||
*/
|
||||
-static void bfq_activate_entity(struct bfq_entity *entity)
|
||||
+static void __bfq_requeue_entity(struct bfq_entity *entity)
|
||||
+{
|
||||
+ struct bfq_sched_data *sd = entity->sched_data;
|
||||
@@ -7065,8 +7124,7 @@ index a5ed694..4af77f4 100644
|
||||
+ * @requeue: true if this is a requeue, which implies that bfqq is
|
||||
+ * being expired; thus ALL its ancestors stop being served and must
|
||||
+ * therefore be requeued
|
||||
*/
|
||||
-static void bfq_activate_entity(struct bfq_entity *entity)
|
||||
+ */
|
||||
+static void bfq_activate_requeue_entity(struct bfq_entity *entity,
|
||||
+ bool non_blocking_wait_rq,
|
||||
+ bool requeue)
|
||||
@@ -7186,7 +7244,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
struct bfq_sched_data *sd;
|
||||
struct bfq_entity *parent;
|
||||
@@ -887,63 +1268,153 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
|
||||
@@ -887,63 +1306,154 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
|
||||
for_each_entity_safe(entity, parent) {
|
||||
sd = entity->sched_data;
|
||||
|
||||
@@ -7309,7 +7367,8 @@ index a5ed694..4af77f4 100644
|
||||
+ if (!bfq_update_next_in_service(sd, entity) &&
|
||||
+ !expiration)
|
||||
+ /*
|
||||
+ * next_in_service unchanged, and no
|
||||
+ * next_in_service unchanged or not causing
|
||||
+ * any change in entity->parent->sd, and no
|
||||
+ * requeueing needed for expiration: stop
|
||||
+ * here.
|
||||
+ */
|
||||
@@ -7339,13 +7398,13 @@ index a5ed694..4af77f4 100644
|
||||
- struct bfq_entity *entry;
|
||||
- struct rb_node *node = st->active.rb_node;
|
||||
+ struct bfq_entity *root_entity = bfq_root_active_entity(&st->active);
|
||||
+
|
||||
+ if (bfq_gt(root_entity->min_start, st->vtime)) {
|
||||
+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
|
||||
|
||||
- entry = rb_entry(node, struct bfq_entity, rb_node);
|
||||
- if (bfq_gt(entry->min_start, st->vtime)) {
|
||||
- st->vtime = entry->min_start;
|
||||
+ if (bfq_gt(root_entity->min_start, st->vtime)) {
|
||||
+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
|
||||
+
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||
+ "calc_vtime_jump: new value %llu",
|
||||
@@ -7373,7 +7432,7 @@ index a5ed694..4af77f4 100644
|
||||
bfq_forget_idle(st);
|
||||
}
|
||||
}
|
||||
@@ -952,6 +1423,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
@@ -952,6 +1462,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
* bfq_first_active_entity - find the eligible entity with
|
||||
* the smallest finish time
|
||||
* @st: the service tree to select from.
|
||||
@@ -7381,7 +7440,7 @@ index a5ed694..4af77f4 100644
|
||||
*
|
||||
* This function searches the first schedulable entity, starting from the
|
||||
* root of the tree and going on the left every time on this side there is
|
||||
@@ -959,7 +1431,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
@@ -959,7 +1470,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
|
||||
* the right is followed only if a) the left subtree contains no eligible
|
||||
* entities and b) no eligible entity has been found yet.
|
||||
*/
|
||||
@@ -7391,7 +7450,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
struct bfq_entity *entry, *first = NULL;
|
||||
struct rb_node *node = st->active.rb_node;
|
||||
@@ -967,15 +1440,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
@@ -967,15 +1479,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
while (node) {
|
||||
entry = rb_entry(node, struct bfq_entity, rb_node);
|
||||
left:
|
||||
@@ -7410,7 +7469,7 @@ index a5ed694..4af77f4 100644
|
||||
node = node->rb_left;
|
||||
goto left;
|
||||
}
|
||||
@@ -993,31 +1466,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
@@ -993,31 +1505,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
|
||||
* __bfq_lookup_next_entity - return the first eligible entity in @st.
|
||||
* @st: the service tree.
|
||||
*
|
||||
@@ -7510,7 +7569,7 @@ index a5ed694..4af77f4 100644
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -1025,50 +1551,118 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
|
||||
@@ -1025,50 +1590,81 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
|
||||
/**
|
||||
* bfq_lookup_next_entity - return the first eligible entity in @sd.
|
||||
* @sd: the sched_data.
|
||||
@@ -7620,48 +7679,11 @@ index a5ed694..4af77f4 100644
|
||||
+
|
||||
+ return sd->next_in_service != sd->in_service_entity;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function tells whether entity stops being a candidate for next
|
||||
+ * service, according to the following logic.
|
||||
+ *
|
||||
+ * This function is invoked for an entity that is about to be set in
|
||||
+ * service. If such an entity is a queue, then the entity is no longer
|
||||
+ * a candidate for next service (i.e, a candidate entity to serve
|
||||
+ * after the in-service entity is expired). The function then returns
|
||||
+ * true.
|
||||
+ *
|
||||
+ * In contrast, the entity could stil be a candidate for next service
|
||||
+ * if it is not a queue, and has more than one child. In fact, even if
|
||||
+ * one of its children is about to be set in service, other children
|
||||
+ * may still be the next to serve. As a consequence, a non-queue
|
||||
+ * entity is not a candidate for next-service only if it has only one
|
||||
+ * child. And only if this condition holds, then the function returns
|
||||
+ * true for a non-queue entity.
|
||||
+ */
|
||||
+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
|
||||
+{
|
||||
+ struct bfq_group *bfqg;
|
||||
+
|
||||
+ if (bfq_entity_to_bfqq(entity))
|
||||
+ return true;
|
||||
+
|
||||
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
+ bfqg = container_of(entity, struct bfq_group, entity);
|
||||
+
|
||||
+ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
|
||||
+ BUG_ON(bfqg->active_entities == 0);
|
||||
+ if (bfqg->active_entities == 1)
|
||||
+ return true;
|
||||
+#endif
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Get next queue for service.
|
||||
*/
|
||||
@@ -1083,58 +1677,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
@@ -1083,58 +1679,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
if (bfqd->busy_queues == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -7883,7 +7905,7 @@ index a5ed694..4af77f4 100644
|
||||
{
|
||||
BUG_ON(!bfq_bfqq_busy(bfqq));
|
||||
BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
@@ -1146,27 +1890,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
@@ -1146,27 +1892,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
BUG_ON(bfqd->busy_queues == 0);
|
||||
bfqd->busy_queues--;
|
||||
|
||||
@@ -7918,7 +7940,7 @@ index a5ed694..4af77f4 100644
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1184,16 +1921,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
@@ -1184,16 +1923,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
bfq_mark_bfqq_busy(bfqq);
|
||||
bfqd->busy_queues++;
|
||||
|
||||
@@ -7938,13 +7960,13 @@ index a5ed694..4af77f4 100644
|
||||
bfqd->wr_busy_queues++;
|
||||
}
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index fcce855..57ab51d 100644
|
||||
index fcce855..bef8244 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 v8r6 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From 124298bd03acebd9c9da29a794718aca31bec1f7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Roschka <danielroschka@phoenitydawn.de>
|
||||
Date: Wed, 22 Feb 2017 15:17:29 -0700
|
||||
Subject: [PATCH] nvme: detect NVMe controller in recent MacBooks
|
||||
|
||||
Adds support for detection of the NVMe controller found in the
|
||||
following recent MacBooks:
|
||||
- Retina MacBook 2016 (MacBook9,1)
|
||||
- 13" MacBook Pro 2016 without Touch Bar (MacBook13,1)
|
||||
- 13" MacBook Pro 2016 with Touch Bar (MacBook13,2)
|
||||
|
||||
Signed-off-by: Daniel Roschka <danielroschka@phoenitydawn.de>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
|
||||
Signed-off-by: Jens Axboe <axboe@fb.com>
|
||||
---
|
||||
drivers/nvme/host/pci.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
|
||||
index d38dae9..319f5c5 100644
|
||||
--- a/drivers/nvme/host/pci.c
|
||||
+++ b/drivers/nvme/host/pci.c
|
||||
@@ -2120,6 +2120,7 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
|
||||
+ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, nvme_id_table);
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
block/bfq-iosched.c | 4 +++-
|
||||
block/bfq-sched.c | 15 ++++++++++++---
|
||||
block/bfq.h | 2 +-
|
||||
3 files changed, 16 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index 96b79a0dae9f..158628392d92 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -4572,6 +4572,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
|
||||
if (!bic)
|
||||
goto queue_fail;
|
||||
|
||||
+ bfq_check_ioprio_change(bic, bio);
|
||||
+
|
||||
bfq_bic_update_cgroup(bic, bio);
|
||||
|
||||
new_queue:
|
||||
@@ -5268,7 +5270,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
|
||||
static int __init bfq_init(void)
|
||||
{
|
||||
int ret;
|
||||
- char msg[60] = "BFQ I/O-scheduler: v8r10";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r11";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index 70aac56b02ef..8311bdbeceea 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -1280,14 +1280,23 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
bool ins_into_idle_tree)
|
||||
{
|
||||
struct bfq_sched_data *sd = entity->sched_data;
|
||||
- struct bfq_service_tree *st = bfq_entity_service_tree(entity);
|
||||
- bool is_in_service = entity == sd->in_service_entity;
|
||||
+ struct bfq_service_tree *st;
|
||||
+ bool is_in_service;
|
||||
|
||||
if (!entity->on_st) { /* entity never activated, or already inactive */
|
||||
- BUG_ON(entity == entity->sched_data->in_service_entity);
|
||||
+ BUG_ON(sd && entity == sd->in_service_entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If we get here, then entity is active, which implies that
|
||||
+ * bfq_group_set_parent has already been invoked for the group
|
||||
+ * represented by entity. Therefore, the field
|
||||
+ * entity->sched_data has been set, and we can safely use it.
|
||||
+ */
|
||||
+ st = bfq_entity_service_tree(entity);
|
||||
+ is_in_service = entity == sd->in_service_entity;
|
||||
+
|
||||
BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);
|
||||
|
||||
if (is_in_service)
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index e3855af1211b..a521ac40cac0 100644
|
||||
--- a/block/bfq.h
|
||||
+++ b/block/bfq.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r11 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
+729
@@ -0,0 +1,729 @@
|
||||
block/bfq-cgroup.c | 12 +--
|
||||
block/bfq-iosched.c | 211 +++++++++++++++++++++++++++++++---------------------
|
||||
block/bfq-sched.c | 73 ++++++++++++------
|
||||
block/bfq.h | 4 +-
|
||||
4 files changed, 180 insertions(+), 120 deletions(-)
|
||||
|
||||
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
|
||||
index bbaecd0..a66a723 100644
|
||||
--- a/block/bfq-cgroup.c
|
||||
+++ b/block/bfq-cgroup.c
|
||||
@@ -771,7 +771,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
|
||||
|
||||
__bfq_deactivate_entity(entity, false);
|
||||
bfq_put_async_queues(bfqd, bfqg);
|
||||
- BUG_ON(entity->tree);
|
||||
|
||||
/*
|
||||
* @blkg is going offline and will be ignored by
|
||||
@@ -1140,6 +1139,9 @@ static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
|
||||
static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
|
||||
static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
|
||||
|
||||
+static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
+ struct bfq_group *bfqg) {}
|
||||
+
|
||||
static void bfq_init_entity(struct bfq_entity *entity,
|
||||
struct bfq_group *bfqg)
|
||||
{
|
||||
@@ -1154,13 +1156,7 @@ static void bfq_init_entity(struct bfq_entity *entity,
|
||||
entity->sched_data = &bfqg->sched_data;
|
||||
}
|
||||
|
||||
-static struct bfq_group *
|
||||
-bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
|
||||
-{
|
||||
- struct bfq_data *bfqd = bic_to_bfqd(bic);
|
||||
-
|
||||
- return bfqd->root_group;
|
||||
-}
|
||||
+static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) {}
|
||||
|
||||
static void bfq_end_wr_async(struct bfq_data *bfqd)
|
||||
{
|
||||
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||
index 78baa07..96b79a0 100644
|
||||
--- a/block/bfq-iosched.c
|
||||
+++ b/block/bfq-iosched.c
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
|
||||
*
|
||||
* Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
|
||||
* file.
|
||||
@@ -107,7 +107,7 @@ static const int bfq_async_charge_factor = 10;
|
||||
/* Default timeout values, in jiffies, approximating CFQ defaults. */
|
||||
static const int bfq_timeout = (HZ / 8);
|
||||
|
||||
-struct kmem_cache *bfq_pool;
|
||||
+static struct kmem_cache *bfq_pool;
|
||||
|
||||
/* Below this threshold (in ns), we consider thinktime immediate. */
|
||||
#define BFQ_MIN_TT (2 * NSEC_PER_MSEC)
|
||||
@@ -483,6 +483,22 @@ static void bfq_weights_tree_add(struct bfq_data *bfqd,
|
||||
|
||||
entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
|
||||
GFP_ATOMIC);
|
||||
+
|
||||
+ /*
|
||||
+ * In the unlucky event of an allocation failure, we just
|
||||
+ * exit. This will cause the weight of entity to not be
|
||||
+ * considered in bfq_differentiated_weights, which, in its
|
||||
+ * turn, causes the scenario to be deemed wrongly symmetric in
|
||||
+ * case entity's weight would have been the only weight making
|
||||
+ * the scenario asymmetric. On the bright side, no unbalance
|
||||
+ * will however occur when entity becomes inactive again (the
|
||||
+ * invocation of this function is triggered by an activation
|
||||
+ * of entity). In fact, bfq_weights_tree_remove does nothing
|
||||
+ * if !entity->weight_counter.
|
||||
+ */
|
||||
+ if (unlikely(!entity->weight_counter))
|
||||
+ return;
|
||||
+
|
||||
entity->weight_counter->weight = entity->weight;
|
||||
rb_link_node(&entity->weight_counter->weights_node, parent, new);
|
||||
rb_insert_color(&entity->weight_counter->weights_node, root);
|
||||
@@ -519,13 +535,45 @@ static void bfq_weights_tree_remove(struct bfq_data *bfqd,
|
||||
entity->weight_counter = NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Return expired entry, or NULL to just start from scratch in rbtree.
|
||||
+ */
|
||||
+static struct request *bfq_check_fifo(struct bfq_queue *bfqq,
|
||||
+ struct request *last)
|
||||
+{
|
||||
+ struct request *rq;
|
||||
+
|
||||
+ if (bfq_bfqq_fifo_expire(bfqq))
|
||||
+ return NULL;
|
||||
+
|
||||
+ bfq_mark_bfqq_fifo_expire(bfqq);
|
||||
+
|
||||
+ rq = rq_entry_fifo(bfqq->fifo.next);
|
||||
+
|
||||
+ if (rq == last || ktime_get_ns() < rq->fifo_time)
|
||||
+ return NULL;
|
||||
+
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "check_fifo: returned %p", rq);
|
||||
+ BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
|
||||
+ return rq;
|
||||
+}
|
||||
+
|
||||
static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq,
|
||||
struct request *last)
|
||||
{
|
||||
struct rb_node *rbnext = rb_next(&last->rb_node);
|
||||
struct rb_node *rbprev = rb_prev(&last->rb_node);
|
||||
- struct request *next = NULL, *prev = NULL;
|
||||
+ struct request *next, *prev = NULL;
|
||||
+
|
||||
+ BUG_ON(list_empty(&bfqq->fifo));
|
||||
+
|
||||
+ /* Follow expired path, else get first next available. */
|
||||
+ next = bfq_check_fifo(bfqq, last);
|
||||
+ if (next) {
|
||||
+ BUG_ON(next == last);
|
||||
+ return next;
|
||||
+ }
|
||||
|
||||
BUG_ON(RB_EMPTY_NODE(&last->rb_node));
|
||||
|
||||
@@ -1359,7 +1407,6 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
|
||||
|
||||
bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
|
||||
false, BFQ_BFQQ_PREEMPTED);
|
||||
- BUG_ON(in_serv->entity.budget < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1523,12 +1570,15 @@ static void bfq_remove_request(struct request *rq)
|
||||
elv_rb_del(&bfqq->sort_list, rq);
|
||||
|
||||
if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
|
||||
+ bfqq->next_rq = NULL;
|
||||
+
|
||||
BUG_ON(bfqq->entity.budget < 0);
|
||||
|
||||
if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) {
|
||||
+ BUG_ON(bfqq->ref < 2); /* referred by rq and on tree */
|
||||
bfq_del_bfqq_busy(bfqd, bfqq, false);
|
||||
-
|
||||
- /* bfqq emptied. In normal operation, when
|
||||
+ /*
|
||||
+ * bfqq emptied. In normal operation, when
|
||||
* bfqq is empty, bfqq->entity.service and
|
||||
* bfqq->entity.budget must contain,
|
||||
* respectively, the service received and the
|
||||
@@ -1537,7 +1587,8 @@ static void bfq_remove_request(struct request *rq)
|
||||
* this last removal occurred while bfqq is
|
||||
* not in service. To avoid inconsistencies,
|
||||
* reset both bfqq->entity.service and
|
||||
- * bfqq->entity.budget.
|
||||
+ * bfqq->entity.budget, if bfqq has still a
|
||||
+ * process that may issue I/O requests to it.
|
||||
*/
|
||||
bfqq->entity.budget = bfqq->entity.service = 0;
|
||||
}
|
||||
@@ -1868,7 +1919,7 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
|
||||
* positives. In case bfqq is weight-raised, such false positives
|
||||
* would evidently degrade latency guarantees for bfqq.
|
||||
*/
|
||||
-bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||
+static bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||
{
|
||||
return bfqq->wr_coeff > 1 &&
|
||||
time_is_before_jiffies(bfqq->last_wr_start_finish +
|
||||
@@ -2029,7 +2080,8 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
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;
|
||||
+ new_bfqq->wr_start_at_switch_to_srt =
|
||||
+ bfqq->wr_start_at_switch_to_srt;
|
||||
if (bfq_bfqq_busy(new_bfqq))
|
||||
bfqd->wr_busy_queues++;
|
||||
new_bfqq->entity.prio_changed = 1;
|
||||
@@ -2072,6 +2124,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
|
||||
*/
|
||||
new_bfqq->bic = NULL;
|
||||
bfqq->bic = NULL;
|
||||
+ /* release process reference to bfqq */
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
|
||||
@@ -2298,7 +2351,7 @@ static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd)
|
||||
* 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)
|
||||
+static void update_thr_responsiveness_params(struct bfq_data *bfqd)
|
||||
{
|
||||
int dev_type = blk_queue_nonrot(bfqd->queue);
|
||||
|
||||
@@ -2333,7 +2386,7 @@ void update_thr_responsiveness_params(struct bfq_data *bfqd)
|
||||
BFQ_RATE_SHIFT);
|
||||
}
|
||||
|
||||
-void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
|
||||
+static 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() ;
|
||||
@@ -2350,7 +2403,7 @@ void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
|
||||
bfqd->tot_sectors_dispatched);
|
||||
}
|
||||
|
||||
-void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
+static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
{
|
||||
u32 rate, weight, divisor;
|
||||
|
||||
@@ -2400,7 +2453,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
* total, and rate is below the current estimated peak rate
|
||||
* - rate is unreasonably high (> 20M sectors/sec)
|
||||
*/
|
||||
- if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 &&
|
||||
+ if ((bfqd->sequential_samples < (3 * bfqd->peak_rate_samples)>>2 &&
|
||||
rate <= bfqd->peak_rate) ||
|
||||
rate > 20<<BFQ_RATE_SHIFT) {
|
||||
bfq_log(bfqd,
|
||||
@@ -2515,7 +2568,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
|
||||
* of the observed dispatch rate. The function assumes to be invoked
|
||||
* on every request dispatch.
|
||||
*/
|
||||
-void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
|
||||
+static void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
|
||||
{
|
||||
u64 now_ns = ktime_get_ns();
|
||||
|
||||
@@ -2616,29 +2669,6 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
|
||||
elv_dispatch_sort(q, rq);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Return expired entry, or NULL to just start from scratch in rbtree.
|
||||
- */
|
||||
-static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
|
||||
-{
|
||||
- struct request *rq = NULL;
|
||||
-
|
||||
- if (bfq_bfqq_fifo_expire(bfqq))
|
||||
- return NULL;
|
||||
-
|
||||
- bfq_mark_bfqq_fifo_expire(bfqq);
|
||||
-
|
||||
- if (list_empty(&bfqq->fifo))
|
||||
- return NULL;
|
||||
-
|
||||
- rq = rq_entry_fifo(bfqq->fifo.next);
|
||||
-
|
||||
- if (ktime_get_ns() < rq->fifo_time)
|
||||
- return NULL;
|
||||
-
|
||||
- return rq;
|
||||
-}
|
||||
-
|
||||
static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
{
|
||||
BUG_ON(bfqq != bfqd->in_service_queue);
|
||||
@@ -2904,8 +2934,8 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
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) {
|
||||
+ /* don't use too short time intervals */
|
||||
+ if (delta_usecs < 1000) {
|
||||
if (blk_queue_nonrot(bfqd->queue))
|
||||
/*
|
||||
* give same worst-case guarantees as idling
|
||||
@@ -2915,7 +2945,7 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
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);
|
||||
+ bfq_log(bfqd, "bfq_bfqq_is_slow: too short %u", delta_usecs);
|
||||
|
||||
return slow;
|
||||
}
|
||||
@@ -3067,6 +3097,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
bool slow;
|
||||
unsigned long delta = 0;
|
||||
struct bfq_entity *entity = &bfqq->entity;
|
||||
+ int ref;
|
||||
|
||||
BUG_ON(bfqq != bfqd->in_service_queue);
|
||||
|
||||
@@ -3174,12 +3205,15 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||
__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
|
||||
BUG_ON(bfqq->next_rq == NULL &&
|
||||
bfqq->entity.budget < bfqq->entity.service);
|
||||
+ ref = bfqq->ref;
|
||||
__bfq_bfqq_expire(bfqd, bfqq);
|
||||
|
||||
- BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
|
||||
+ BUG_ON(ref > 1 &&
|
||||
+ !bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
|
||||
!bfq_class_idle(bfqq));
|
||||
|
||||
- if (!bfq_bfqq_busy(bfqq) &&
|
||||
+ /* mark bfqq as waiting a request only if a bic still points to it */
|
||||
+ if (ref > 1 && !bfq_bfqq_busy(bfqq) &&
|
||||
reason != BFQ_BFQQ_BUDGET_TIMEOUT &&
|
||||
reason != BFQ_BFQQ_BUDGET_EXHAUSTED)
|
||||
bfq_mark_bfqq_non_blocking_wait_rq(bfqq);
|
||||
@@ -3504,14 +3538,29 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
|
||||
!bfq_bfqq_must_idle(bfqq))
|
||||
goto expire;
|
||||
|
||||
+check_queue:
|
||||
+ /*
|
||||
+ * This loop is rarely executed more than once. Even when it
|
||||
+ * happens, it is much more convenient to re-execute this loop
|
||||
+ * than to return NULL and trigger a new dispatch to get a
|
||||
+ * request served.
|
||||
+ */
|
||||
next_rq = bfqq->next_rq;
|
||||
/*
|
||||
* If bfqq has requests queued and it has enough budget left to
|
||||
* serve them, keep the queue, otherwise expire it.
|
||||
*/
|
||||
if (next_rq) {
|
||||
+ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
+
|
||||
if (bfq_serv_to_charge(next_rq, bfqq) >
|
||||
bfq_bfqq_budget_left(bfqq)) {
|
||||
+ /*
|
||||
+ * Expire the queue for budget exhaustion,
|
||||
+ * which makes sure that the next budget is
|
||||
+ * enough to serve the next request, even if
|
||||
+ * it comes from the fifo expired path.
|
||||
+ */
|
||||
reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
|
||||
goto expire;
|
||||
} else {
|
||||
@@ -3559,9 +3608,16 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
|
||||
bfq_bfqq_expire(bfqd, bfqq, false, reason);
|
||||
new_queue:
|
||||
bfqq = bfq_set_in_service_queue(bfqd);
|
||||
- bfq_log(bfqd, "select_queue: new queue %d returned",
|
||||
- bfqq ? bfqq->pid : 0);
|
||||
+ if (bfqq) {
|
||||
+ bfq_log_bfqq(bfqd, bfqq, "select_queue: checking new queue");
|
||||
+ goto check_queue;
|
||||
+ }
|
||||
keep_queue:
|
||||
+ if (bfqq)
|
||||
+ bfq_log_bfqq(bfqd, bfqq, "select_queue: returned this queue");
|
||||
+ else
|
||||
+ bfq_log(bfqd, "select_queue: no queue returned");
|
||||
+
|
||||
return bfqq;
|
||||
}
|
||||
|
||||
@@ -3627,45 +3683,17 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
|
||||
struct bfq_queue *bfqq)
|
||||
{
|
||||
int dispatched = 0;
|
||||
- struct request *rq;
|
||||
+ struct request *rq = bfqq->next_rq;
|
||||
unsigned long service_to_charge;
|
||||
|
||||
BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
|
||||
-
|
||||
- /* Follow expired path, else get first next available. */
|
||||
- rq = bfq_check_fifo(bfqq);
|
||||
- if (!rq)
|
||||
- rq = bfqq->next_rq;
|
||||
+ BUG_ON(!rq);
|
||||
service_to_charge = bfq_serv_to_charge(rq, bfqq);
|
||||
|
||||
- if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
|
||||
- /*
|
||||
- * This may happen if the next rq is chosen in fifo order
|
||||
- * instead of sector order. The budget is properly
|
||||
- * dimensioned to be always sufficient to serve the next
|
||||
- * request only if it is chosen in sector order. The reason
|
||||
- * is that it would be quite inefficient and little useful
|
||||
- * to always make sure that the budget is large enough to
|
||||
- * serve even the possible next rq in fifo order.
|
||||
- * In fact, requests are seldom served in fifo order.
|
||||
- *
|
||||
- * Expire the queue for budget exhaustion, and make sure
|
||||
- * that the next act_budget is enough to serve the next
|
||||
- * request, even if it comes from the fifo expired path.
|
||||
- */
|
||||
- bfqq->next_rq = rq;
|
||||
- /*
|
||||
- * Since this dispatch is failed, make sure that
|
||||
- * a new one will be performed
|
||||
- */
|
||||
- if (!bfqd->rq_in_driver)
|
||||
- bfq_schedule_dispatch(bfqd);
|
||||
- BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
- goto expire;
|
||||
- }
|
||||
+ BUG_ON(service_to_charge > bfq_bfqq_budget_left(bfqq));
|
||||
|
||||
BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
- /* Finally, insert request into driver dispatch list. */
|
||||
+
|
||||
bfq_bfqq_served(bfqq, service_to_charge);
|
||||
|
||||
BUG_ON(bfqq->entity.budget < bfqq->entity.service);
|
||||
@@ -3805,7 +3833,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
|
||||
* Task holds one reference to the queue, dropped when task exits. Each rq
|
||||
* in-flight on this queue also holds a reference, dropped when rq is freed.
|
||||
*
|
||||
- * Queue lock must be held here.
|
||||
+ * Queue lock must be held here. Recall not to use bfqq after calling
|
||||
+ * this function on it.
|
||||
*/
|
||||
static void bfq_put_queue(struct bfq_queue *bfqq)
|
||||
{
|
||||
@@ -3874,7 +3903,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||
|
||||
bfq_put_cooperator(bfqq);
|
||||
|
||||
- bfq_put_queue(bfqq);
|
||||
+ bfq_put_queue(bfqq); /* release process reference */
|
||||
}
|
||||
|
||||
static void bfq_init_icq(struct io_cq *icq)
|
||||
@@ -3973,6 +4002,7 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
|
||||
|
||||
bfqq = bic_to_bfqq(bic, false);
|
||||
if (bfqq) {
|
||||
+ /* release process reference on this queue */
|
||||
bfq_put_queue(bfqq);
|
||||
bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic);
|
||||
bic_set_bfqq(bic, bfqq, false);
|
||||
@@ -4093,14 +4123,20 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
|
||||
* prune it.
|
||||
*/
|
||||
if (async_bfqq) {
|
||||
- bfqq->ref++;
|
||||
+ bfqq->ref++; /*
|
||||
+ * Extra group reference, w.r.t. sync
|
||||
+ * queue. This extra reference is removed
|
||||
+ * only if bfqq->bfqg disappears, to
|
||||
+ * guarantee that this queue is not freed
|
||||
+ * until its group goes away.
|
||||
+ */
|
||||
bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
|
||||
bfqq, bfqq->ref);
|
||||
*async_bfqq = bfqq;
|
||||
}
|
||||
|
||||
out:
|
||||
- bfqq->ref++;
|
||||
+ bfqq->ref++; /* get a process reference to this queue */
|
||||
bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref);
|
||||
rcu_read_unlock();
|
||||
return bfqq;
|
||||
@@ -4274,10 +4310,14 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq)
|
||||
bfqq->allocated[rq_data_dir(rq)]--;
|
||||
new_bfqq->ref++;
|
||||
bfq_clear_bfqq_just_created(bfqq);
|
||||
- bfq_put_queue(bfqq);
|
||||
if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
|
||||
bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
|
||||
bfqq, new_bfqq);
|
||||
+ /*
|
||||
+ * rq is about to be enqueued into new_bfqq,
|
||||
+ * release rq reference on bfqq
|
||||
+ */
|
||||
+ bfq_put_queue(bfqq);
|
||||
rq->elv.priv[1] = new_bfqq;
|
||||
bfqq = new_bfqq;
|
||||
}
|
||||
@@ -4697,9 +4737,8 @@ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
|
||||
cancel_work_sync(&bfqd->unplug_work);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
|
||||
- struct bfq_queue **bfqq_ptr)
|
||||
+ struct bfq_queue **bfqq_ptr)
|
||||
{
|
||||
struct bfq_group *root_group = bfqd->root_group;
|
||||
struct bfq_queue *bfqq = *bfqq_ptr;
|
||||
@@ -4730,7 +4769,6 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
|
||||
|
||||
__bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void bfq_exit_queue(struct elevator_queue *e)
|
||||
{
|
||||
@@ -4755,6 +4793,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
blkcg_deactivate_policy(q, &blkcg_policy_bfq);
|
||||
#else
|
||||
+ bfq_put_async_queues(bfqd, bfqd->root_group);
|
||||
kfree(bfqd->root_group);
|
||||
#endif
|
||||
|
||||
@@ -5229,7 +5268,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
|
||||
static int __init bfq_init(void)
|
||||
{
|
||||
int ret;
|
||||
- char msg[60] = "BFQ I/O-scheduler: v8r7";
|
||||
+ char msg[60] = "BFQ I/O-scheduler: v8r10";
|
||||
|
||||
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||
ret = blkcg_policy_register(&blkcg_policy_bfq);
|
||||
@@ -5255,7 +5294,7 @@ static int __init bfq_init(void)
|
||||
* be run for a long time.
|
||||
*/
|
||||
T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */
|
||||
- T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */
|
||||
+ T_slow[1] = msecs_to_jiffies(6000); /* actually 6.5 sec */
|
||||
T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */
|
||||
T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */
|
||||
|
||||
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
|
||||
index 797bce7..70aac56 100644
|
||||
--- a/block/bfq-sched.c
|
||||
+++ b/block/bfq-sched.c
|
||||
@@ -154,7 +154,13 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
|
||||
#define for_each_entity(entity) \
|
||||
for (; entity ; entity = entity->parent)
|
||||
|
||||
-#define for_each_entity_safe(entity, parent) \
|
||||
+/*
|
||||
+ * For each iteration, compute parent in advance, so as to be safe if
|
||||
+ * entity is deallocated during the iteration. Such a deallocation may
|
||||
+ * happen as a consequence of a bfq_put_queue that frees the bfq_queue
|
||||
+ * containing entity.
|
||||
+ */
|
||||
+#define for_each_entity_safe(entity, parent) \
|
||||
for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
|
||||
|
||||
/*
|
||||
@@ -691,27 +697,31 @@ static void bfq_idle_insert(struct bfq_service_tree *st,
|
||||
}
|
||||
|
||||
/**
|
||||
- * bfq_forget_entity - remove an entity from the wfq trees.
|
||||
+ * bfq_forget_entity - do not consider entity any longer for scheduling
|
||||
* @st: the service tree.
|
||||
* @entity: the entity being removed.
|
||||
+ * @is_in_service: true if entity is currently the in-service entity.
|
||||
*
|
||||
- * Update the device status and forget everything about @entity, putting
|
||||
- * the device reference to it, if it is a queue. Entities belonging to
|
||||
- * groups are not refcounted.
|
||||
+ * Forget everything about @entity. In addition, if entity represents
|
||||
+ * a queue, and the latter is not in service, then release the service
|
||||
+ * reference to the queue (the one taken through bfq_get_entity). In
|
||||
+ * fact, in this case, there is really no more service reference to
|
||||
+ * the queue, as the latter is also outside any service tree. If,
|
||||
+ * instead, the queue is in service, then __bfq_bfqd_reset_in_service
|
||||
+ * will take care of putting the reference when the queue finally
|
||||
+ * stops being served.
|
||||
*/
|
||||
static void bfq_forget_entity(struct bfq_service_tree *st,
|
||||
- struct bfq_entity *entity)
|
||||
+ struct bfq_entity *entity,
|
||||
+ bool is_in_service)
|
||||
{
|
||||
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
|
||||
- struct bfq_sched_data *sd;
|
||||
-
|
||||
BUG_ON(!entity->on_st);
|
||||
|
||||
entity->on_st = false;
|
||||
st->wsum -= entity->weight;
|
||||
- if (bfqq) {
|
||||
- sd = entity->sched_data;
|
||||
- bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
|
||||
+ if (bfqq && !is_in_service) {
|
||||
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity (before): %p %d",
|
||||
bfqq, bfqq->ref);
|
||||
bfq_put_queue(bfqq);
|
||||
}
|
||||
@@ -726,7 +736,8 @@ static void bfq_put_idle_entity(struct bfq_service_tree *st,
|
||||
struct bfq_entity *entity)
|
||||
{
|
||||
bfq_idle_extract(st, entity);
|
||||
- bfq_forget_entity(st, entity);
|
||||
+ bfq_forget_entity(st, entity,
|
||||
+ entity == entity->sched_data->in_service_entity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1082,6 +1093,12 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
|
||||
*/
|
||||
entity->start = min_vstart;
|
||||
st->wsum += entity->weight;
|
||||
+ /*
|
||||
+ * entity is about to be inserted into a service tree,
|
||||
+ * and then set in service: get a reference to make
|
||||
+ * sure entity does not disappear until it is no
|
||||
+ * longer in service or scheduled for service.
|
||||
+ */
|
||||
bfq_get_entity(entity);
|
||||
|
||||
BUG_ON(entity->on_st && bfqq);
|
||||
@@ -1264,27 +1281,27 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
{
|
||||
struct bfq_sched_data *sd = entity->sched_data;
|
||||
struct bfq_service_tree *st = bfq_entity_service_tree(entity);
|
||||
- bool was_in_service = entity == sd->in_service_entity;
|
||||
+ bool is_in_service = entity == sd->in_service_entity;
|
||||
|
||||
if (!entity->on_st) { /* entity never activated, or already inactive */
|
||||
BUG_ON(entity == entity->sched_data->in_service_entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
- BUG_ON(was_in_service && entity->tree && entity->tree != &st->active);
|
||||
+ BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);
|
||||
|
||||
- if (was_in_service)
|
||||
+ if (is_in_service)
|
||||
bfq_calc_finish(entity, entity->service);
|
||||
|
||||
if (entity->tree == &st->active)
|
||||
bfq_active_extract(st, entity);
|
||||
- else if (!was_in_service && entity->tree == &st->idle)
|
||||
+ else if (!is_in_service && entity->tree == &st->idle)
|
||||
bfq_idle_extract(st, entity);
|
||||
else if (entity->tree)
|
||||
BUG();
|
||||
|
||||
if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime))
|
||||
- bfq_forget_entity(st, entity);
|
||||
+ bfq_forget_entity(st, entity, is_in_service);
|
||||
else
|
||||
bfq_idle_insert(st, entity);
|
||||
|
||||
@@ -1301,7 +1318,7 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
bool expiration)
|
||||
{
|
||||
struct bfq_sched_data *sd;
|
||||
- struct bfq_entity *parent;
|
||||
+ struct bfq_entity *parent = NULL;
|
||||
|
||||
for_each_entity_safe(entity, parent) {
|
||||
sd = entity->sched_data;
|
||||
@@ -1320,8 +1337,8 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
|
||||
|
||||
if (!__bfq_deactivate_entity(entity, ins_into_idle_tree)) {
|
||||
/*
|
||||
- * Entity is not any tree any more, so, this
|
||||
- * deactivation is a no-op, and there is
|
||||
+ * entity is not in any tree any more, so
|
||||
+ * this deactivation is a no-op, and there is
|
||||
* nothing to change for upper-level entities
|
||||
* (in case of expiration, this can never
|
||||
* happen).
|
||||
@@ -1821,14 +1838,16 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
|
||||
|
||||
static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
{
|
||||
- struct bfq_entity *entity = &bfqd->in_service_queue->entity;
|
||||
+ struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
|
||||
+ struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
|
||||
+ struct bfq_entity *entity = in_serv_entity;
|
||||
|
||||
if (bfqd->in_service_bic) {
|
||||
put_io_context(bfqd->in_service_bic->icq.ioc);
|
||||
bfqd->in_service_bic = NULL;
|
||||
}
|
||||
|
||||
- bfq_clear_bfqq_wait_request(bfqd->in_service_queue);
|
||||
+ bfq_clear_bfqq_wait_request(in_serv_bfqq);
|
||||
hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
|
||||
bfqd->in_service_queue = NULL;
|
||||
|
||||
@@ -1840,6 +1859,14 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
|
||||
*/
|
||||
for_each_entity(entity)
|
||||
entity->sched_data->in_service_entity = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * in_serv_entity is no longer in service, so, if it is in no
|
||||
+ * service tree either, then release the service reference to
|
||||
+ * the queue it represents (taken with bfq_get_entity).
|
||||
+ */
|
||||
+ if (!in_serv_entity->on_st)
|
||||
+ bfq_put_queue(in_serv_bfqq);
|
||||
}
|
||||
|
||||
static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
@@ -1904,8 +1931,6 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||
BUG_ON(bfqq->entity.budget < 0);
|
||||
|
||||
bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
|
||||
-
|
||||
- BUG_ON(bfqq->entity.budget < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/block/bfq.h b/block/bfq.h
|
||||
index a9da002..e3855af 100644
|
||||
--- a/block/bfq.h
|
||||
+++ b/block/bfq.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
|
||||
+ * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
|
||||
*
|
||||
* Based on ideas and code from CFQ:
|
||||
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
|
||||
*
|
||||
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
|
||||
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
|
||||
*/
|
||||
|
||||
#ifndef _BFQ_H
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Subject: [PATCH] jbd2: Fix dbench4 performance regression for 'nobarrier' mounts
|
||||
Date: Fri, 28 Apr 2017 11:59:34 +0200
|
||||
|
||||
Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as
|
||||
synchronous" removed REQ_SYNC flag from WRITE_FUA implementation. Since
|
||||
JBD2 strips REQ_FUA and REQ_FLUSH flags from submitted IO when the
|
||||
filesystem is mounted with nobarrier mount option, journal superblock
|
||||
writes ended up being async writes after this patch and that caused
|
||||
heavy performance regression for dbench4 benchmark with high number of
|
||||
processes. In my test setup with HP RAID array with non-volatile write
|
||||
cache and 32 GB ram, dbench4 runs with 8 processes regressed by ~25%.
|
||||
|
||||
Fix the problem by making sure journal superblock writes are always
|
||||
treated as synchronous since they generally block progress of the
|
||||
journalling machinery and thus the whole filesystem.
|
||||
|
||||
Fixes: b685d3d65ac791406e0dfd8779cc9b3707fea5a3
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
---
|
||||
fs/jbd2/journal.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
|
||||
index 5adc2fb62b0f..e768126f6a72 100644
|
||||
--- a/fs/jbd2/journal.c
|
||||
+++ b/fs/jbd2/journal.c
|
||||
@@ -1348,7 +1348,7 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
|
||||
jbd2_superblock_csum_set(journal, sb);
|
||||
get_bh(bh);
|
||||
bh->b_end_io = end_buffer_write_sync;
|
||||
- ret = submit_bh(REQ_OP_WRITE, write_flags, bh);
|
||||
+ ret = submit_bh(REQ_OP_WRITE, write_flags | REQ_SYNC, bh);
|
||||
wait_on_buffer(bh);
|
||||
if (buffer_write_io_error(bh)) {
|
||||
clear_buffer_write_io_error(bh);
|
||||
--
|
||||
2.12.0
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
From cf8c73afb3abf0f8905efbaddd4ce11a0deec9da Mon Sep 17 00:00:00 2001
|
||||
From: Evan Quan <evan.quan@amd.com>
|
||||
Date: Fri, 17 Mar 2017 10:22:51 +0800
|
||||
Subject: [PATCH] drm/amd/amdgpu: add POLARIS12 PCI ID
|
||||
|
||||
Signed-off-by: Evan Quan <evan.quan@amd.com>
|
||||
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index f7adbac..b76cd69 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
@@ -421,6 +421,7 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From fc8e9c54699e42754094ff475da46440778d8f19 Mon Sep 17 00:00:00 2001
|
||||
From: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Date: Thu, 4 Aug 2016 12:54:22 +0800
|
||||
Subject: [PATCH] drm/amd/amdgpu: add Polaris12 PCI ID
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Reviewed-by: Christian König <christian.koenig@amd.com>
|
||||
Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index 8cb937b..2534ada 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
@@ -418,6 +418,13 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x67CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
{0x1002, 0x67CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
{0x1002, 0x67CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10},
|
||||
+ /* Polaris12 */
|
||||
+ {0x1002, 0x6980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
--
|
||||
2.10.2
|
||||
|
||||
+469
@@ -0,0 +1,469 @@
|
||||
From c4642a479fac9f5c224ff7425d86c427b94011af Mon Sep 17 00:00:00 2001
|
||||
From: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Date: Wed, 14 Dec 2016 15:32:28 -0500
|
||||
Subject: [PATCH] drm/amd/amdgpu: add Polaris12 support (v3)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
v2: agd: squash in various fixes
|
||||
v3: agd: squash in:
|
||||
drm/amdgpu: remove unnecessary smc sk firmware for polaris12
|
||||
|
||||
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Reviewed-by: Christian König <christian.koenig@amd.com>
|
||||
Reviewed-by: Ken Wang <Qingqing.Wang@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
[ rebased for 4.9 / tmb ]
|
||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 3 +++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 13 ++++++++++---
|
||||
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 31 +++++++++++++++++++++++++-----
|
||||
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 5 +++++
|
||||
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 6 ++++++
|
||||
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 5 +++--
|
||||
drivers/gpu/drm/amd/amdgpu/vi.c | 10 ++++++++++
|
||||
drivers/gpu/drm/amd/include/amd_shared.h | 1 +
|
||||
11 files changed, 76 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
index 9ada56c..4c851fde 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
|
||||
@@ -840,6 +840,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
||||
else if (type == CGS_UCODE_ID_SMU_SK)
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ strcpy(fw_name, "amdgpu/polaris12_smc.bin");
|
||||
+ break;
|
||||
default:
|
||||
DRM_ERROR("SMC firmware not supported\n");
|
||||
return -EINVAL;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
index 60bd4af..fe3bb94 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
@@ -73,6 +73,7 @@ static const char *amdgpu_asic_name[] = {
|
||||
"STONEY",
|
||||
"POLARIS10",
|
||||
"POLARIS11",
|
||||
+ "POLARIS12",
|
||||
"LAST",
|
||||
};
|
||||
|
||||
@@ -1277,6 +1278,7 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
|
||||
case CHIP_FIJI:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY)
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
index a81dfae..1d564be 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
|
||||
@@ -65,6 +65,7 @@
|
||||
#define FIRMWARE_STONEY "amdgpu/stoney_uvd.bin"
|
||||
#define FIRMWARE_POLARIS10 "amdgpu/polaris10_uvd.bin"
|
||||
#define FIRMWARE_POLARIS11 "amdgpu/polaris11_uvd.bin"
|
||||
+#define FIRMWARE_POLARIS12 "amdgpu/polaris12_uvd.bin"
|
||||
|
||||
/**
|
||||
* amdgpu_uvd_cs_ctx - Command submission parser context
|
||||
@@ -98,6 +99,7 @@ MODULE_FIRMWARE(FIRMWARE_FIJI);
|
||||
MODULE_FIRMWARE(FIRMWARE_STONEY);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS10);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS11);
|
||||
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
|
||||
|
||||
static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
|
||||
|
||||
@@ -149,6 +151,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS11:
|
||||
fw_name = FIRMWARE_POLARIS11;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ fw_name = FIRMWARE_POLARIS12;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
index 69b66b9..8fec802 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#define FIRMWARE_STONEY "amdgpu/stoney_vce.bin"
|
||||
#define FIRMWARE_POLARIS10 "amdgpu/polaris10_vce.bin"
|
||||
#define FIRMWARE_POLARIS11 "amdgpu/polaris11_vce.bin"
|
||||
+#define FIRMWARE_POLARIS12 "amdgpu/polaris12_vce.bin"
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
MODULE_FIRMWARE(FIRMWARE_BONAIRE);
|
||||
@@ -66,6 +67,7 @@ MODULE_FIRMWARE(FIRMWARE_FIJI);
|
||||
MODULE_FIRMWARE(FIRMWARE_STONEY);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS10);
|
||||
MODULE_FIRMWARE(FIRMWARE_POLARIS11);
|
||||
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
|
||||
|
||||
static void amdgpu_vce_idle_work_handler(struct work_struct *work);
|
||||
|
||||
@@ -121,6 +123,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
||||
case CHIP_POLARIS11:
|
||||
fw_name = FIRMWARE_POLARIS11;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ fw_name = FIRMWARE_POLARIS12;
|
||||
+ break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
index b3d62b9..2006abb 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
|
||||
@@ -167,6 +167,7 @@ static void dce_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris11_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(polaris11_golden_settings_a11));
|
||||
@@ -608,6 +609,7 @@ static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
|
||||
num_crtc = 6;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
num_crtc = 5;
|
||||
break;
|
||||
default:
|
||||
@@ -1589,6 +1591,7 @@ static int dce_v11_0_audio_init(struct amdgpu_device *adev)
|
||||
adev->mode_info.audio.num_pins = 8;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->mode_info.audio.num_pins = 6;
|
||||
break;
|
||||
default:
|
||||
@@ -2388,7 +2391,8 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc)
|
||||
int pll;
|
||||
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
struct amdgpu_encoder *amdgpu_encoder =
|
||||
to_amdgpu_encoder(amdgpu_crtc->encoder);
|
||||
struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
|
||||
@@ -2822,7 +2826,8 @@ static int dce_v11_0_crtc_mode_set(struct drm_crtc *crtc,
|
||||
return -EINVAL;
|
||||
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
struct amdgpu_encoder *amdgpu_encoder =
|
||||
to_amdgpu_encoder(amdgpu_crtc->encoder);
|
||||
int encoder_mode =
|
||||
@@ -2992,6 +2997,7 @@ static int dce_v11_0_early_init(void *handle)
|
||||
adev->mode_info.num_dig = 6;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->mode_info.num_hpd = 5;
|
||||
adev->mode_info.num_dig = 5;
|
||||
break;
|
||||
@@ -3101,7 +3107,8 @@ static int dce_v11_0_hw_init(void *handle)
|
||||
amdgpu_atombios_crtc_powergate_init(adev);
|
||||
amdgpu_atombios_encoder_init_dig(adev);
|
||||
if ((adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
amdgpu_atombios_crtc_set_dce_clock(adev, adev->clock.default_dispclk,
|
||||
DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS);
|
||||
amdgpu_atombios_crtc_set_dce_clock(adev, 0,
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
index d0ec009..3733741 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
|
||||
@@ -138,6 +138,13 @@ MODULE_FIRMWARE("amdgpu/polaris10_mec.bi
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin");
|
||||
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_ce.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_me.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mec.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin");
|
||||
+
|
||||
static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] =
|
||||
{
|
||||
{mmGDS_VMID0_BASE, mmGDS_VMID0_SIZE, mmGDS_GWS_VMID0, mmGDS_OA_VMID0},
|
||||
@@ -687,6 +694,7 @@ static void gfx_v8_0_init_golden_registe
|
||||
(const u32)ARRAY_SIZE(tonga_golden_common_all));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -901,6 +909,9 @@ static int gfx_v8_0_init_microcode(struc
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_STONEY:
|
||||
chip_name = "stoney";
|
||||
break;
|
||||
@@ -1777,6 +1788,7 @@ static int gfx_v8_0_gpu_early_init(struc
|
||||
gb_addr_config = TONGA_GB_ADDR_CONFIG_GOLDEN;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
ret = amdgpu_atombios_get_gfx_info(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2695,6 +2707,7 @@ static void gfx_v8_0_tiling_mode_table_i
|
||||
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
|
||||
PIPE_CONFIG(ADDR_SURF_P4_16x16) |
|
||||
TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
|
||||
@@ -3516,6 +3529,7 @@ gfx_v8_0_raster_config(struct amdgpu_dev
|
||||
*rconf1 |= 0x0;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
*rconf |= RB_MAP_PKR0(2) | RB_XSEL2(1) | SE_MAP(2) |
|
||||
SE_XSEL(1) | SE_YSEL(1);
|
||||
*rconf1 |= 0x0;
|
||||
@@ -4029,7 +4043,8 @@ static void gfx_v8_0_init_pg(struct amdg
|
||||
cz_enable_cp_power_gating(adev, true);
|
||||
else
|
||||
cz_enable_cp_power_gating(adev, false);
|
||||
- } else if (adev->asic_type == CHIP_POLARIS11) {
|
||||
+ } else if ((adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS11)) {
|
||||
gfx_v8_0_init_power_gating(adev);
|
||||
}
|
||||
}
|
||||
@@ -4100,7 +4115,8 @@ static int gfx_v8_0_rlc_resume(struct am
|
||||
RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
|
||||
if (adev->asic_type == CHIP_POLARIS11 ||
|
||||
- adev->asic_type == CHIP_POLARIS10) {
|
||||
+ adev->asic_type == CHIP_POLARIS10 ||
|
||||
+ adev->asic_type == CHIP_POLARIS12) {
|
||||
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
|
||||
tmp &= ~0x3;
|
||||
WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
|
||||
@@ -4288,6 +4304,7 @@ static int gfx_v8_0_cp_gfx_start(struct
|
||||
amdgpu_ring_write(ring, 0x0000002A);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_ring_write(ring, 0x16000012);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
@@ -4938,7 +4955,8 @@ static int gfx_v8_0_cp_compute_resume(st
|
||||
(adev->asic_type == CHIP_FIJI) ||
|
||||
(adev->asic_type == CHIP_STONEY) ||
|
||||
(adev->asic_type == CHIP_POLARIS11) ||
|
||||
- (adev->asic_type == CHIP_POLARIS10)) {
|
||||
+ (adev->asic_type == CHIP_POLARIS10) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12)) {
|
||||
WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER,
|
||||
AMDGPU_DOORBELL_KIQ << 2);
|
||||
WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
|
||||
@@ -4974,7 +4992,8 @@ static int gfx_v8_0_cp_compute_resume(st
|
||||
mqd->cp_hqd_persistent_state = tmp;
|
||||
if (adev->asic_type == CHIP_STONEY ||
|
||||
adev->asic_type == CHIP_POLARIS11 ||
|
||||
- adev->asic_type == CHIP_POLARIS10) {
|
||||
+ adev->asic_type == CHIP_POLARIS10 ||
|
||||
+ adev->asic_type == CHIP_POLARIS12) {
|
||||
tmp = RREG32(mmCP_ME1_PIPE3_INT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE3_INT_CNTL, GENERIC2_INT_ENABLE, 1);
|
||||
WREG32(mmCP_ME1_PIPE3_INT_CNTL, tmp);
|
||||
@@ -5488,7 +5507,8 @@ static int gfx_v8_0_late_init(void *hand
|
||||
static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
- if (adev->asic_type == CHIP_POLARIS11)
|
||||
+ if ((adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12))
|
||||
/* Send msg to SMU via Powerplay */
|
||||
amdgpu_set_powergating_state(adev,
|
||||
AMD_IP_BLOCK_TYPE_SMC,
|
||||
@@ -5565,6 +5585,7 @@ static int gfx_v8_0_set_powergating_stat
|
||||
gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, false);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable)
|
||||
gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true);
|
||||
else
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
index 0daac3a..476bc9f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
|
||||
@@ -46,6 +46,7 @@ static int gmc_v8_0_wait_for_idle(void *handle);
|
||||
MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_mc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_mc.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_mc.bin");
|
||||
|
||||
static const u32 golden_settings_tonga_a11[] =
|
||||
{
|
||||
@@ -130,6 +131,7 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -225,6 +227,9 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_FIJI:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
index 1170a64..034ace7 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
|
||||
@@ -60,6 +60,8 @@ MODULE_FIRMWARE("amdgpu/polaris10_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_sdma1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_sdma1.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_sdma.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_sdma1.bin");
|
||||
|
||||
|
||||
static const u32 sdma_offsets[SDMA_MAX_INSTANCE] =
|
||||
@@ -206,6 +208,7 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
@@ -278,6 +281,9 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS10:
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ chip_name = "polaris12";
|
||||
+ break;
|
||||
case CHIP_CARRIZO:
|
||||
chip_name = "carrizo";
|
||||
break;
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
index 6b3293a..5fb0b7f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
|
||||
@@ -320,11 +320,12 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
- /* Fiji, Stoney, Polaris10, Polaris11 are single pipe */
|
||||
+ /* Fiji, Stoney, Polaris10, Polaris11, Polaris12 are single pipe */
|
||||
if ((adev->asic_type == CHIP_FIJI) ||
|
||||
(adev->asic_type == CHIP_STONEY) ||
|
||||
(adev->asic_type == CHIP_POLARIS10) ||
|
||||
- (adev->asic_type == CHIP_POLARIS11))
|
||||
+ (adev->asic_type == CHIP_POLARIS11) ||
|
||||
+ (adev->asic_type == CHIP_POLARIS12))
|
||||
return AMDGPU_VCE_HARVEST_VCE1;
|
||||
|
||||
/* Tonga and CZ are dual or single pipe */
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
index bf088d6..c2ac54f 100644
|
||||
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
|
||||
@@ -88,6 +88,7 @@ MODULE_FIRMWARE("amdgpu/polaris10_smc.bi
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
|
||||
+MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
@@ -312,6 +313,7 @@ static void vi_init_golden_registers(str
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -592,6 +594,7 @@ static int vi_read_register(struct amdgp
|
||||
case CHIP_TONGA:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
asic_register_table = cz_allowed_read_registers;
|
||||
@@ -1465,6 +1468,7 @@ int vi_set_ip_blocks(struct amdgpu_devic
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
+ case CHIP_POLARIS12:
|
||||
adev->ip_blocks = polaris11_ip_blocks_vd;
|
||||
adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks_vd);
|
||||
break;
|
||||
@@ -1608,6 +1612,11 @@ static int vi_common_early_init(void *ha
|
||||
adev->pg_flags = 0;
|
||||
adev->external_rev_id = adev->rev_id + 0x50;
|
||||
break;
|
||||
+ case CHIP_POLARIS12:
|
||||
+ adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG;
|
||||
+ adev->pg_flags = 0;
|
||||
+ adev->external_rev_id = adev->rev_id + 0x64;
|
||||
+ break;
|
||||
case CHIP_CARRIZO:
|
||||
adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGCG |
|
||||
@@ -1897,6 +1906,7 @@ static int vi_common_set_clockgating_sta
|
||||
case CHIP_TONGA:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
+ case CHIP_POLARIS12:
|
||||
vi_common_set_clockgating_state_by_smu(adev, state);
|
||||
default:
|
||||
break;
|
||||
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
index c02469a..5f59117 100644
|
||||
--- a/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
|
||||
@@ -46,6 +46,7 @@ enum amd_asic_type {
|
||||
CHIP_STONEY,
|
||||
CHIP_POLARIS10,
|
||||
CHIP_POLARIS11,
|
||||
+ CHIP_POLARIS12,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
--
|
||||
2.10.2
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
From 6e88491cf2a3b17199c78bd53348b39dc6a88275 Mon Sep 17 00:00:00 2001
|
||||
From: Junshan Fang <Junshan.Fang@amd.com>
|
||||
Date: Thu, 15 Jun 2017 14:02:20 +0800
|
||||
Subject: [PATCH] drm/amdgpu: add Polaris12 DID
|
||||
|
||||
Signed-off-by: Junshan Fang <Junshan.Fang@amd.com>
|
||||
Reviewed-by: Roger.He <Hongbo.He@amd.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
|
||||
index f2d705e6a75a..ab6b0d0febab 100644
|
||||
@@ -418,6 +418,7 @@ static const struct pci_device_id pciidl
|
||||
{0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
+ {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
{0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
|
||||
|
||||
{0, 0, 0}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user