work for 4.14.18
scsi module build fail?
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -83,10 +83,10 @@ diff -Nurp linux-4.2.2/Makefile linux-4.2.2-3rd/Makefile
|
|||||||
net-y := net/
|
net-y := net/
|
||||||
libs-y := lib/
|
libs-y := lib/
|
||||||
core-y := usr/
|
core-y := usr/
|
||||||
diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Makefile
|
diff -Nurp linux-4.14/scripts/kconfig/Makefile linux-4.14-3rd/scripts/kconfig/Makefile
|
||||||
--- linux-4.9/scripts/kconfig/Makefile
|
--- linux-4.14/scripts/kconfig/Makefile
|
||||||
+++ linux-4.9-3rd/scripts/kconfig/Makefile
|
+++ linux-4.14-3rd/scripts/kconfig/Makefile
|
||||||
@@ -18,28 +18,28 @@ endif
|
@@ -19,28 +19,28 @@ endif
|
||||||
# We need this, in case the user has it in its environment
|
# We need this, in case the user has it in its environment
|
||||||
unexport CONFIG_
|
unexport CONFIG_
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Make
|
|||||||
$(Q)mkdir -p include/config include/generated
|
$(Q)mkdir -p include/config include/generated
|
||||||
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
|
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
|
||||||
$(Q)if [ -f .config ]; then \
|
$(Q)if [ -f .config ]; then \
|
||||||
@@ -82,7 +82,7 @@ simple-targets := oldconfig allnoconfig
|
@@ -83,7 +83,7 @@ simple-targets := oldconfig allnoconfig
|
||||||
alldefconfig randconfig listnewconfig olddefconfig
|
alldefconfig randconfig listnewconfig olddefconfig
|
||||||
PHONY += $(simple-targets)
|
PHONY += $(simple-targets)
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Make
|
|||||||
$< $(silent) --$@ $(Kconfig)
|
$< $(silent) --$@ $(Kconfig)
|
||||||
|
|
||||||
PHONY += oldnoconfig savedefconfig defconfig
|
PHONY += oldnoconfig savedefconfig defconfig
|
||||||
@@ -90,12 +90,12 @@ PHONY += oldnoconfig savedefconfig defco
|
@@ -91,12 +91,12 @@ PHONY += oldnoconfig savedefconfig defco
|
||||||
# oldnoconfig is an alias of olddefconfig, because people already are dependent
|
# oldnoconfig is an alias of olddefconfig, because people already are dependent
|
||||||
# on its behavior (sets new symbols to their default value but not 'n') with the
|
# on its behavior (sets new symbols to their default value but not 'n') with the
|
||||||
# counter-intuitive name.
|
# counter-intuitive name.
|
||||||
@@ -147,7 +147,7 @@ diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Make
|
|||||||
ifeq ($(KBUILD_DEFCONFIG),)
|
ifeq ($(KBUILD_DEFCONFIG),)
|
||||||
$< $(silent) --defconfig $(Kconfig)
|
$< $(silent) --defconfig $(Kconfig)
|
||||||
else
|
else
|
||||||
@@ -108,26 +108,26 @@ else
|
@@ -109,26 +109,26 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Make
|
|||||||
$(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
|
$(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
|
||||||
|
|
||||||
# Help text used by make help
|
# Help text used by make help
|
||||||
@@ -190,6 +190,9 @@ gconf-objs := gconf.o zconf.tab.o
|
@@ -191,6 +191,9 @@ gconf-objs := gconf.o zconf.tab.o
|
||||||
|
|
||||||
hostprogs-y := conf nconf mconf kxgettext qconf gconf
|
hostprogs-y := conf nconf mconf kxgettext qconf gconf
|
||||||
|
|
||||||
@@ -187,5 +187,5 @@ diff -Nurp linux-4.9/scripts/kconfig/Makefile linux-4.9-3rd/scripts/kconfig/Make
|
|||||||
+ pushd $(srctree)/3rdparty ; $(PERL) ./mkbuild.pl ; popd
|
+ pushd $(srctree)/3rdparty ; $(PERL) ./mkbuild.pl ; popd
|
||||||
+
|
+
|
||||||
clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
|
clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
|
||||||
clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h
|
clean-files += zconf.tab.c zconf.lex.c gconf.glade.h
|
||||||
clean-files += config.pot linux.pot
|
clean-files += config.pot linux.pot
|
||||||
|
|||||||
+126
-118
@@ -1,6 +1,6 @@
|
|||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/crt.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/crt.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/crt.c linux-4.12.4-3rd/3rdparty/ndiswrapper/crt.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/crt.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/crt.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/crt.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/crt.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,589 @@
|
@@ -0,0 +1,589 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -591,9 +591,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/crt.c linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+ printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf);
|
+ printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf);
|
||||||
+ kfree(buf);
|
+ kfree(buf);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/divdi3.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/divdi3.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/divdi3.c linux-4.12.4-3rd/3rdparty/ndiswrapper/divdi3.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/divdi3.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/divdi3.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/divdi3.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/divdi3.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,329 @@
|
@@ -0,0 +1,329 @@
|
||||||
+/* 64-bit multiplication and division
|
+/* 64-bit multiplication and division
|
||||||
+ Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003
|
+ Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003
|
||||||
@@ -924,9 +924,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/divdi3.c linux-4.6-rc6-ndis/3rdpar
|
|||||||
+ __udivmoddi4 (u, v, &w);
|
+ __udivmoddi4 (u, v, &w);
|
||||||
+ return w;
|
+ return w;
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/hal.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/hal.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/hal.c linux-4.12.4-3rd/3rdparty/ndiswrapper/hal.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/hal.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/hal.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/hal.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/hal.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,157 @@
|
@@ -0,0 +1,157 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -1085,9 +1085,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/hal.c linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+#endif
|
+#endif
|
||||||
+ nt_spin_unlock(lock);
|
+ nt_spin_unlock(lock);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/iw_ndis.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/iw_ndis.c linux-4.12.4-3rd/3rdparty/ndiswrapper/iw_ndis.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/iw_ndis.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/iw_ndis.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/iw_ndis.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,2001 @@
|
@@ -0,0 +1,2001 @@
|
||||||
+ /*
|
+ /*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -3090,9 +3090,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.c linux-4.6-rc6-ndis/3rdpa
|
|||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/iw_ndis.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/iw_ndis.h linux-4.12.4-3rd/3rdparty/ndiswrapper/iw_ndis.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/iw_ndis.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/iw_ndis.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/iw_ndis.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,194 @@
|
@@ -0,0 +1,194 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -3288,9 +3288,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/iw_ndis.h linux-4.6-rc6-ndis/3rdpa
|
|||||||
+ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
|
+ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
|
||||||
+
|
+
|
||||||
+#endif // IW_NDIS_H
|
+#endif // IW_NDIS_H
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/lin2win.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/lin2win.h linux-4.12.4-3rd/3rdparty/ndiswrapper/lin2win.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/lin2win.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/lin2win.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/lin2win.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,111 @@
|
@@ -0,0 +1,111 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2006 Giridhar Pemmasani
|
+ * Copyright (C) 2006 Giridhar Pemmasani
|
||||||
@@ -3403,9 +3403,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.h linux-4.6-rc6-ndis/3rdpa
|
|||||||
+})
|
+})
|
||||||
+
|
+
|
||||||
+#endif // CONFIG_X86_64
|
+#endif // CONFIG_X86_64
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.S linux-4.6-rc6-ndis/3rdparty/ndiswrapper/lin2win.S
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/lin2win.S linux-4.12.4-3rd/3rdparty/ndiswrapper/lin2win.S
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.S 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/lin2win.S 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/lin2win.S 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/lin2win.S 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,138 @@
|
@@ -0,0 +1,138 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2011 Pavel Roskin
|
+ * Copyright (C) 2011 Pavel Roskin
|
||||||
@@ -3545,9 +3545,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/lin2win.S linux-4.6-rc6-ndis/3rdpa
|
|||||||
+lin2win lin2win4, 4
|
+lin2win lin2win4, 4
|
||||||
+lin2win lin2win5, 5
|
+lin2win lin2win5, 5
|
||||||
+lin2win lin2win6, 6
|
+lin2win lin2win6, 6
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/loader.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/loader.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/loader.c linux-4.12.4-3rd/3rdparty/ndiswrapper/loader.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/loader.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/loader.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/loader.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/loader.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,967 @@
|
@@ -0,0 +1,967 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -4516,10 +4516,10 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/loader.c linux-4.6-rc6-ndis/3rdpar
|
|||||||
+ mutex_unlock(&loader_mutex);
|
+ mutex_unlock(&loader_mutex);
|
||||||
+ EXIT1(return);
|
+ EXIT1(return);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/loader.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/loader.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/loader.h linux-4.12.4-3rd/3rdparty/ndiswrapper/loader.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/loader.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/loader.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/loader.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/loader.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,112 @@
|
@@ -0,0 +1,108 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
+ *
|
+ *
|
||||||
@@ -4538,10 +4538,6 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/loader.h linux-4.6-rc6-ndis/3rdpar
|
|||||||
+#ifndef _LOADER_H_
|
+#ifndef _LOADER_H_
|
||||||
+#define _LOADER_H_
|
+#define _LOADER_H_
|
||||||
+
|
+
|
||||||
+#if LINUX_VERSION_CODE > KERNEL_VERSION(4,0,0)
|
|
||||||
+#include <linux/vmalloc.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#include "ndiswrapper.h"
|
+#include "ndiswrapper.h"
|
||||||
+
|
+
|
||||||
+#ifndef __KERNEL__
|
+#ifndef __KERNEL__
|
||||||
@@ -4632,9 +4628,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/loader.h linux-4.6-rc6-ndis/3rdpar
|
|||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+#endif /* LOADER_H */
|
+#endif /* LOADER_H */
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/longlong.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/longlong.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/longlong.h linux-4.12.4-3rd/3rdparty/ndiswrapper/longlong.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/longlong.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/longlong.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/longlong.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/longlong.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1333 @@
|
@@ -0,0 +1,1333 @@
|
||||||
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
||||||
+ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
+ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
||||||
@@ -5969,9 +5965,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/longlong.h linux-4.6-rc6-ndis/3rdp
|
|||||||
+#ifndef UDIV_NEEDS_NORMALIZATION
|
+#ifndef UDIV_NEEDS_NORMALIZATION
|
||||||
+#define UDIV_NEEDS_NORMALIZATION 0
|
+#define UDIV_NEEDS_NORMALIZATION 0
|
||||||
+#endif
|
+#endif
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/Makefile linux-4.6-rc6-ndis/3rdparty/ndiswrapper/Makefile
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/Makefile linux-4.12.4-3rd/3rdparty/ndiswrapper/Makefile
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/Makefile 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/Makefile 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/Makefile 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/Makefile 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,213 @@
|
@@ -0,0 +1,213 @@
|
||||||
+# Name of the module
|
+# Name of the module
|
||||||
+MODNAME = ndiswrapper
|
+MODNAME = ndiswrapper
|
||||||
@@ -6186,9 +6182,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/Makefile linux-4.6-rc6-ndis/3rdpar
|
|||||||
+ done
|
+ done
|
||||||
+
|
+
|
||||||
+.PHONY: all modules clean install config_check dist
|
+.PHONY: all modules clean install config_check dist
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/mkexport.sh linux-4.6-rc6-ndis/3rdparty/ndiswrapper/mkexport.sh
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/mkexport.sh linux-4.12.4-3rd/3rdparty/ndiswrapper/mkexport.sh
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/mkexport.sh 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/mkexport.sh 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/mkexport.sh 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/mkexport.sh 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,42 @@
|
@@ -0,0 +1,42 @@
|
||||||
+#! /bin/sh
|
+#! /bin/sh
|
||||||
+
|
+
|
||||||
@@ -6232,9 +6228,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/mkexport.sh linux-4.6-rc6-ndis/3rd
|
|||||||
+
|
+
|
||||||
+echo " {NULL, NULL}"
|
+echo " {NULL, NULL}"
|
||||||
+echo "};"
|
+echo "};"
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/mkstubs.sh linux-4.6-rc6-ndis/3rdparty/ndiswrapper/mkstubs.sh
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/mkstubs.sh linux-4.12.4-3rd/3rdparty/ndiswrapper/mkstubs.sh
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/mkstubs.sh 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/mkstubs.sh 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/mkstubs.sh 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/mkstubs.sh 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,12 @@
|
@@ -0,0 +1,12 @@
|
||||||
+#! /bin/sh
|
+#! /bin/sh
|
||||||
+
|
+
|
||||||
@@ -6248,9 +6244,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/mkstubs.sh linux-4.6-rc6-ndis/3rdp
|
|||||||
+ win2lin(\1, \2)/p' \
|
+ win2lin(\1, \2)/p' \
|
||||||
+ $file | sed -e 's/[ \t ]\+//' | sort -u; \
|
+ $file | sed -e 's/[ \t ]\+//' | sort -u; \
|
||||||
+done
|
+done
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndis.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndis.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ndis.c linux-4.12.4-3rd/3rdparty/ndiswrapper/ndis.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ndis.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ndis.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndis.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ndis.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,3025 @@
|
@@ -0,0 +1,3025 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -9277,9 +9273,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndis.c linux-4.6-rc6-ndis/3rdparty
|
|||||||
+ destroy_workqueue(ndis_wq);
|
+ destroy_workqueue(ndis_wq);
|
||||||
+ EXIT1(return);
|
+ EXIT1(return);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndis.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndis.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ndis.h linux-4.12.4-3rd/3rdparty/ndiswrapper/ndis.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ndis.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ndis.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndis.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ndis.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1309 @@
|
@@ -0,0 +1,1309 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -10590,9 +10586,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndis.h linux-4.6-rc6-ndis/3rdparty
|
|||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#endif /* NDIS_H */
|
+#endif /* NDIS_H */
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndiswrapper.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndiswrapper.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ndiswrapper.h linux-4.12.4-3rd/3rdparty/ndiswrapper/ndiswrapper.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ndiswrapper.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ndiswrapper.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ndiswrapper.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ndiswrapper.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,219 @@
|
@@ -0,0 +1,219 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -10612,7 +10608,7 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndiswrapper.h linux-4.6-rc6-ndis/3
|
|||||||
+#ifndef _NDISWRAPPER_H_
|
+#ifndef _NDISWRAPPER_H_
|
||||||
+#define _NDISWRAPPER_H_
|
+#define _NDISWRAPPER_H_
|
||||||
+
|
+
|
||||||
+#define DRIVER_VERSION "1.60"
|
+#define DRIVER_VERSION "1.61"
|
||||||
+#define UTILS_VERSION "1.9"
|
+#define UTILS_VERSION "1.9"
|
||||||
+
|
+
|
||||||
+#define DRIVER_NAME "ndiswrapper"
|
+#define DRIVER_NAME "ndiswrapper"
|
||||||
@@ -10813,9 +10809,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ndiswrapper.h linux-4.6-rc6-ndis/3
|
|||||||
+#endif // __KERNEL__
|
+#endif // __KERNEL__
|
||||||
+
|
+
|
||||||
+#endif // NDISWRAPPER_H
|
+#endif // NDISWRAPPER_H
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ntoskernel.c linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ntoskernel.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,2677 @@
|
@@ -0,0 +1,2677 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -13494,10 +13490,10 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.c linux-4.6-rc6-ndis/3r
|
|||||||
+
|
+
|
||||||
+ EXIT2(return);
|
+ EXIT2(return);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ntoskernel.h linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ntoskernel.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1090 @@
|
@@ -0,0 +1,1102 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
+ *
|
+ *
|
||||||
@@ -13546,6 +13542,8 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.h linux-4.6-rc6-ndis/3r
|
|||||||
+#include <linux/percpu.h>
|
+#include <linux/percpu.h>
|
||||||
+#include <linux/kthread.h>
|
+#include <linux/kthread.h>
|
||||||
+#include <linux/workqueue.h>
|
+#include <linux/workqueue.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
+
|
||||||
+
|
+
|
||||||
+#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64)
|
+#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64)
|
||||||
+#error "this module is for x86 or x86_64 architectures only"
|
+#error "this module is for x86 or x86_64 architectures only"
|
||||||
@@ -13858,8 +13856,18 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.h linux-4.6-rc6-ndis/3r
|
|||||||
+#define prandom_seed(seed) net_srandom(seed)
|
+#define prandom_seed(seed) net_srandom(seed)
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
|
||||||
+#define strncasecmp strnicmp
|
+static int strncasecmp(const char *s1, const char *s2, size_t n)
|
||||||
|
+{
|
||||||
|
+ strnicmp(s1, s2, n);
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
|
||||||
|
+static inline void netif_trans_update(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ dev->trans_start = jiffies;
|
||||||
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+/* TICK is 100ns */
|
+/* TICK is 100ns */
|
||||||
@@ -14588,9 +14596,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel.h linux-4.6-rc6-ndis/3r
|
|||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+#endif // _NTOSKERNEL_H_
|
+#endif // _NTOSKERNEL_H_
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel_io.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel_io.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/ntoskernel_io.c linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel_io.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel_io.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/ntoskernel_io.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/ntoskernel_io.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/ntoskernel_io.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1161 @@
|
@@ -0,0 +1,1161 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -15753,9 +15761,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/ntoskernel_io.c linux-4.6-rc6-ndis
|
|||||||
+ IOTRACE("LowLimit: 0x%lx, HighLimit: 0x%lx", *LowLimit, *HighLimit);
|
+ IOTRACE("LowLimit: 0x%lx, HighLimit: 0x%lx", *LowLimit, *HighLimit);
|
||||||
+ IOEXIT(return);
|
+ IOEXIT(return);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pe_linker.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/pe_linker.c linux-4.12.4-3rd/3rdparty/ndiswrapper/pe_linker.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/pe_linker.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pe_linker.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/pe_linker.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,600 @@
|
@@ -0,0 +1,600 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -16357,9 +16365,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.c linux-4.6-rc6-ndis/3rd
|
|||||||
+ }
|
+ }
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pe_linker.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/pe_linker.h linux-4.12.4-3rd/3rdparty/ndiswrapper/pe_linker.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/pe_linker.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pe_linker.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/pe_linker.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,992 @@
|
@@ -0,0 +1,992 @@
|
||||||
+/*
|
+/*
|
||||||
+ * This file is an excerpt of winnt.h from WINE, which bears the
|
+ * This file is an excerpt of winnt.h from WINE, which bears the
|
||||||
@@ -17353,9 +17361,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pe_linker.h linux-4.6-rc6-ndis/3rd
|
|||||||
+ WORD Length;
|
+ WORD Length;
|
||||||
+ CHAR NameString[ 1 ];
|
+ CHAR NameString[ 1 ];
|
||||||
+} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
|
+} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pnp.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pnp.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/pnp.c linux-4.12.4-3rd/3rdparty/ndiswrapper/pnp.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/pnp.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/pnp.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pnp.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/pnp.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,697 @@
|
@@ -0,0 +1,697 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2005 Giridhar Pemmasani
|
+ * Copyright (C) 2005 Giridhar Pemmasani
|
||||||
@@ -18054,9 +18062,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pnp.c linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#endif // USB
|
+#endif // USB
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pnp.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pnp.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/pnp.h linux-4.12.4-3rd/3rdparty/ndiswrapper/pnp.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/pnp.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/pnp.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/pnp.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/pnp.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,36 @@
|
@@ -0,0 +1,36 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2005 Giridhar Pemmasani
|
+ * Copyright (C) 2005 Giridhar Pemmasani
|
||||||
@@ -18094,9 +18102,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/pnp.h linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+int wrap_pnp_resume_usb_device(struct usb_interface *intf);
|
+int wrap_pnp_resume_usb_device(struct usb_interface *intf);
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/proc.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/proc.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/proc.c linux-4.12.4-3rd/3rdparty/ndiswrapper/proc.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/proc.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/proc.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/proc.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/proc.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,588 @@
|
@@ -0,0 +1,588 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -18686,9 +18694,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/proc.c linux-4.6-rc6-ndis/3rdparty
|
|||||||
+ remove_proc_entry("debug", wrap_procfs_entry);
|
+ remove_proc_entry("debug", wrap_procfs_entry);
|
||||||
+ proc_remove(wrap_procfs_entry);
|
+ proc_remove(wrap_procfs_entry);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/rtl.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/rtl.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/rtl.c linux-4.12.4-3rd/3rdparty/ndiswrapper/rtl.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/rtl.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/rtl.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/rtl.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/rtl.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,715 @@
|
@@ -0,0 +1,715 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -19405,9 +19413,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/rtl.c linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+ TRACE1("version: %d", version);
|
+ TRACE1("version: %d", version);
|
||||||
+ return TRUE;
|
+ return TRUE;
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/usb.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/usb.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/usb.c linux-4.12.4-3rd/3rdparty/ndiswrapper/usb.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/usb.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/usb.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/usb.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/usb.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1496 @@
|
@@ -0,0 +1,1496 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2004 Jan Kiszka
|
+ * Copyright (C) 2004 Jan Kiszka
|
||||||
@@ -20905,9 +20913,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/usb.c linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+ kill_all_urbs(wd, 0);
|
+ kill_all_urbs(wd, 0);
|
||||||
+ USBEXIT(return);
|
+ USBEXIT(return);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/usb.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/usb.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/usb.h linux-4.12.4-3rd/3rdparty/ndiswrapper/usb.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/usb.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/usb.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/usb.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/usb.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,360 @@
|
@@ -0,0 +1,360 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2004 Jan Kiszka
|
+ * Copyright (C) 2004 Jan Kiszka
|
||||||
@@ -21269,9 +21277,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/usb.h linux-4.6-rc6-ndis/3rdparty/
|
|||||||
+ struct io_stack_location *irp_sl);
|
+ struct io_stack_location *irp_sl);
|
||||||
+
|
+
|
||||||
+#endif /* USB_H */
|
+#endif /* USB_H */
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/win2lin_stubs.S linux-4.6-rc6-ndis/3rdparty/ndiswrapper/win2lin_stubs.S
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/win2lin_stubs.S linux-4.12.4-3rd/3rdparty/ndiswrapper/win2lin_stubs.S
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/win2lin_stubs.S 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/win2lin_stubs.S 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/win2lin_stubs.S 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/win2lin_stubs.S 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,253 @@
|
@@ -0,0 +1,253 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani
|
+ * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani
|
||||||
@@ -21526,9 +21534,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/win2lin_stubs.S linux-4.6-rc6-ndis
|
|||||||
+#include "win2lin_stubs.h"
|
+#include "win2lin_stubs.h"
|
||||||
+
|
+
|
||||||
+#endif /* CONFIG_X86_64 */
|
+#endif /* CONFIG_X86_64 */
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/winnt_types.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/winnt_types.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/winnt_types.h linux-4.12.4-3rd/3rdparty/ndiswrapper/winnt_types.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/winnt_types.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/winnt_types.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/winnt_types.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/winnt_types.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,1701 @@
|
@@ -0,0 +1,1701 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -23231,9 +23239,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/winnt_types.h linux-4.6-rc6-ndis/3
|
|||||||
+
|
+
|
||||||
+
|
+
|
||||||
+#endif /* WINNT_TYPES_H */
|
+#endif /* WINNT_TYPES_H */
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/workqueue.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/workqueue.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/workqueue.c linux-4.12.4-3rd/3rdparty/ndiswrapper/workqueue.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/workqueue.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/workqueue.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/workqueue.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/workqueue.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,279 @@
|
@@ -0,0 +1,279 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2006 Giridhar Pemmasani
|
+ * Copyright (C) 2006 Giridhar Pemmasani
|
||||||
@@ -23514,9 +23522,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/workqueue.c linux-4.6-rc6-ndis/3rd
|
|||||||
+ wrap_destroy_wq_on(workq, i);
|
+ wrap_destroy_wq_on(workq, i);
|
||||||
+ kfree(workq);
|
+ kfree(workq);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapmem.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapmem.c linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapmem.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapmem.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapmem.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapmem.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,366 @@
|
@@ -0,0 +1,366 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2006 Giridhar Pemmasani
|
+ * Copyright (C) 2006 Giridhar Pemmasani
|
||||||
@@ -23884,9 +23892,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.c linux-4.6-rc6-ndis/3rdpa
|
|||||||
+#endif
|
+#endif
|
||||||
+ return;
|
+ return;
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapmem.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapmem.h linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapmem.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapmem.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapmem.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapmem.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,97 @@
|
@@ -0,0 +1,97 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2006 Giridhar Pemmasani
|
+ * Copyright (C) 2006 Giridhar Pemmasani
|
||||||
@@ -23985,9 +23993,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapmem.h linux-4.6-rc6-ndis/3rdpa
|
|||||||
+#endif // ALLOC_DEBUG
|
+#endif // ALLOC_DEBUG
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapndis.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapndis.c linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapndis.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapndis.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapndis.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapndis.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,2186 @@
|
@@ -0,0 +1,2186 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -24695,7 +24703,7 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.c linux-4.6-rc6-ndis/3rdp
|
|||||||
+ n = wnd->max_tx_packets;
|
+ n = wnd->max_tx_packets;
|
||||||
+ n = mp_tx_packets(wnd, wnd->tx_ring_start, n);
|
+ n = mp_tx_packets(wnd, wnd->tx_ring_start, n);
|
||||||
+ if (n) {
|
+ if (n) {
|
||||||
+ wnd->net_dev->trans_start = jiffies;
|
+ netif_trans_update(wnd->net_dev);
|
||||||
+ wnd->tx_ring_start =
|
+ wnd->tx_ring_start =
|
||||||
+ (wnd->tx_ring_start + n) % TX_RING_SIZE;
|
+ (wnd->tx_ring_start + n) % TX_RING_SIZE;
|
||||||
+ wnd->is_tx_ring_full = 0;
|
+ wnd->is_tx_ring_full = 0;
|
||||||
@@ -26175,9 +26183,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.c linux-4.6-rc6-ndis/3rdp
|
|||||||
+ if (wrapndis_wq)
|
+ if (wrapndis_wq)
|
||||||
+ destroy_workqueue(wrapndis_wq);
|
+ destroy_workqueue(wrapndis_wq);
|
||||||
+}
|
+}
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapndis.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapndis.h linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapndis.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapndis.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapndis.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapndis.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,86 @@
|
@@ -0,0 +1,86 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -26265,9 +26273,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapndis.h linux-4.6-rc6-ndis/3rdp
|
|||||||
+struct iw_statistics *get_iw_stats(struct net_device *dev);
|
+struct iw_statistics *get_iw_stats(struct net_device *dev);
|
||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapper.c linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapper.c
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapper.c linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapper.c
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapper.c 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapper.c 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapper.c 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapper.c 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,111 @@
|
@@ -0,0 +1,111 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -26380,9 +26388,9 @@ diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapper.c linux-4.6-rc6-ndis/3rdpa
|
|||||||
+
|
+
|
||||||
+module_init(wrapper_init);
|
+module_init(wrapper_init);
|
||||||
+module_exit(wrapper_exit);
|
+module_exit(wrapper_exit);
|
||||||
diff -Nurp linux-4.6-rc6/3rdparty/ndiswrapper/wrapper.h linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapper.h
|
diff -Nurp linux-4.12.4/3rdparty/ndiswrapper/wrapper.h linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapper.h
|
||||||
--- linux-4.6-rc6/3rdparty/ndiswrapper/wrapper.h 1970-01-01 02:00:00.000000000 +0200
|
--- linux-4.12.4/3rdparty/ndiswrapper/wrapper.h 1970-01-01 02:00:00.000000000 +0200
|
||||||
+++ linux-4.6-rc6-ndis/3rdparty/ndiswrapper/wrapper.h 2016-05-01 18:25:43.000000000 +0300
|
+++ linux-4.12.4-3rd/3rdparty/ndiswrapper/wrapper.h 2016-10-09 18:45:08.027226096 +0300
|
||||||
@@ -0,0 +1,24 @@
|
@@ -0,0 +1,24 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
+ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
last_rx is gone, most drivers does not really need/use it anyway.
|
||||||
|
|
||||||
|
Also, include signal.h to fix implicit deklaration of function ”signal_pending”
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- linux/3rdparty/ndiswrapper/ndis.c.orig 2016-10-09 18:45:08.027226096 +0300
|
||||||
|
+++ linux/3rdparty/ndiswrapper/ndis.c 2017-08-04 00:09:49.264110609 +0300
|
||||||
|
@@ -2258,7 +2258,6 @@ wstdcall void NdisMIndicateReceivePacket
|
||||||
|
WARNING("empty packet ignored");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- wnd->net_dev->last_rx = jiffies;
|
||||||
|
/* get total number of bytes in packet */
|
||||||
|
NdisGetFirstBufferFromPacketSafe(packet, &buffer, &virt,
|
||||||
|
&length, &total_length,
|
||||||
|
@@ -2346,7 +2345,6 @@ wstdcall void EthRxIndicateHandler(struc
|
||||||
|
ERROR("nmb is NULL");
|
||||||
|
EXIT3(return);
|
||||||
|
}
|
||||||
|
- wnd->net_dev->last_rx = jiffies;
|
||||||
|
|
||||||
|
if (look_ahead_size < packet_size) {
|
||||||
|
struct ndis_packet *packet;
|
||||||
|
@@ -2461,7 +2459,6 @@ wstdcall void NdisMTransferDataComplete(
|
||||||
|
WARNING("illegal packet");
|
||||||
|
EXIT3(return);
|
||||||
|
}
|
||||||
|
- wnd->net_dev->last_rx = jiffies;
|
||||||
|
oob_data = NDIS_PACKET_OOB_DATA(packet);
|
||||||
|
skb_size = sizeof(oob_data->header) + oob_data->look_ahead_size +
|
||||||
|
bytes_txed;
|
||||||
|
--- linux/3rdparty/ndiswrapper/ntoskernel.h.orig 2017-08-03 23:52:29.015367906 +0300
|
||||||
|
+++ linux/3rdparty/ndiswrapper/ntoskernel.h 2017-08-04 00:17:41.334914691 +0300
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
+#include <linux/sched/signal.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <asm/mman.h>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
__GFP_REPEAT is now __GFP_RETRY_MAYFAIL
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- linux/3rdparty/ndiswrapper/ntoskernel.h.orig 2017-10-15 01:11:56.041892449 +0300
|
||||||
|
+++ linux/3rdparty/ndiswrapper/ntoskernel.h 2017-10-15 01:11:06.159204294 +0300
|
||||||
|
@@ -122,7 +122,7 @@ static cpumask_t cpumasks[NR_CPUS];
|
||||||
|
|
||||||
|
#define PCI_DMA_ALLOC_COHERENT(pci_dev,size,dma_handle) \
|
||||||
|
dma_alloc_coherent(&pci_dev->dev,size,dma_handle, \
|
||||||
|
- GFP_KERNEL | __GFP_REPEAT)
|
||||||
|
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL)
|
||||||
|
#define PCI_DMA_FREE_COHERENT(pci_dev,size,cpu_addr,dma_handle) \
|
||||||
|
dma_free_coherent(&pci_dev->dev,size,cpu_addr,dma_handle)
|
||||||
|
#define PCI_DMA_MAP_SINGLE(pci_dev,addr,size,direction) \
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
Add supprto for 4.7 series kernels.
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
|
||||||
|
|
||||||
diff -urp linux/3rdparty/ndiswrapper.orig/wrapndis.c linux/3rdparty/ndiswrapper/wrapndis.c
|
|
||||||
--- linux/3rdparty/ndiswrapper.orig/wrapndis.c 2016-07-04 20:00:13.000000000 +0300
|
|
||||||
+++ linux/3rdparty/ndiswrapper/wrapndis.c 2016-07-04 20:23:29.454819702 +0300
|
|
||||||
@@ -704,7 +704,11 @@ static void tx_worker(struct work_struct
|
|
||||||
n = wnd->max_tx_packets;
|
|
||||||
n = mp_tx_packets(wnd, wnd->tx_ring_start, n);
|
|
||||||
if (n) {
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
|
|
||||||
wnd->net_dev->trans_start = jiffies;
|
|
||||||
+#else
|
|
||||||
+ netif_trans_update(wnd->net_dev);
|
|
||||||
+#endif
|
|
||||||
wnd->tx_ring_start =
|
|
||||||
(wnd->tx_ring_start + n) % TX_RING_SIZE;
|
|
||||||
wnd->is_tx_ring_full = 0;
|
|
||||||
File diff suppressed because it is too large
Load Diff
+78379
-279706
File diff suppressed because it is too large
Load Diff
-197
@@ -1,197 +0,0 @@
|
|||||||
From 43034bc4606f1f21186ca6fe27bc0448159d5e00 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Thomas Backlund <tmb@mageia.org>
|
|
||||||
Date: Thu, 10 Mar 2016 15:44:13 +0200
|
|
||||||
Subject: [PATCH] Revert "ipmi: Start the timer and thread on internal msgs"
|
|
||||||
|
|
||||||
This reverts commit 0cfec916e86d881e209de4b4ae9959a6271e6660.
|
|
||||||
|
|
||||||
It's reported on ipmi list that Dell R720xd servers will always panic
|
|
||||||
on dell ipmi services load
|
|
||||||
|
|
||||||
Reverting this fixes the issue.
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/char/ipmi/ipmi_si_intf.c | 73 ++++++++++++++++------------------------
|
|
||||||
1 file changed, 29 insertions(+), 44 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
|
|
||||||
index 4cc72fa..f667be8 100644
|
|
||||||
--- a/drivers/char/ipmi/ipmi_si_intf.c
|
|
||||||
+++ b/drivers/char/ipmi/ipmi_si_intf.c
|
|
||||||
@@ -412,42 +412,18 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
|
|
||||||
-{
|
|
||||||
- smi_info->last_timeout_jiffies = jiffies;
|
|
||||||
- mod_timer(&smi_info->si_timer, new_val);
|
|
||||||
- smi_info->timer_running = true;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Start a new message and (re)start the timer and thread.
|
|
||||||
- */
|
|
||||||
-static void start_new_msg(struct smi_info *smi_info, unsigned char *msg,
|
|
||||||
- unsigned int size)
|
|
||||||
-{
|
|
||||||
- smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
|
|
||||||
-
|
|
||||||
- if (smi_info->thread)
|
|
||||||
- wake_up_process(smi_info->thread);
|
|
||||||
-
|
|
||||||
- smi_info->handlers->start_transaction(smi_info->si_sm, msg, size);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void start_check_enables(struct smi_info *smi_info, bool start_timer)
|
|
||||||
+static void start_check_enables(struct smi_info *smi_info)
|
|
||||||
{
|
|
||||||
unsigned char msg[2];
|
|
||||||
|
|
||||||
msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
|
|
||||||
msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
|
|
||||||
|
|
||||||
- if (start_timer)
|
|
||||||
- start_new_msg(smi_info, msg, 2);
|
|
||||||
- else
|
|
||||||
- smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
|
|
||||||
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
|
|
||||||
smi_info->si_state = SI_CHECKING_ENABLES;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void start_clear_flags(struct smi_info *smi_info, bool start_timer)
|
|
||||||
+static void start_clear_flags(struct smi_info *smi_info)
|
|
||||||
{
|
|
||||||
unsigned char msg[3];
|
|
||||||
|
|
||||||
@@ -456,10 +432,7 @@ static void start_clear_flags(struct smi_info *smi_info, bool start_timer)
|
|
||||||
msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
|
|
||||||
msg[2] = WDT_PRE_TIMEOUT_INT;
|
|
||||||
|
|
||||||
- if (start_timer)
|
|
||||||
- start_new_msg(smi_info, msg, 3);
|
|
||||||
- else
|
|
||||||
- smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
|
|
||||||
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
|
|
||||||
smi_info->si_state = SI_CLEARING_FLAGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -469,8 +442,10 @@ static void start_getting_msg_queue(struct smi_info *smi_info)
|
|
||||||
smi_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
|
|
||||||
smi_info->curr_msg->data_size = 2;
|
|
||||||
|
|
||||||
- start_new_msg(smi_info, smi_info->curr_msg->data,
|
|
||||||
- smi_info->curr_msg->data_size);
|
|
||||||
+ smi_info->handlers->start_transaction(
|
|
||||||
+ smi_info->si_sm,
|
|
||||||
+ smi_info->curr_msg->data,
|
|
||||||
+ smi_info->curr_msg->data_size);
|
|
||||||
smi_info->si_state = SI_GETTING_MESSAGES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -480,11 +455,20 @@ static void start_getting_events(struct smi_info *smi_info)
|
|
||||||
smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
|
|
||||||
smi_info->curr_msg->data_size = 2;
|
|
||||||
|
|
||||||
- start_new_msg(smi_info, smi_info->curr_msg->data,
|
|
||||||
- smi_info->curr_msg->data_size);
|
|
||||||
+ smi_info->handlers->start_transaction(
|
|
||||||
+ smi_info->si_sm,
|
|
||||||
+ smi_info->curr_msg->data,
|
|
||||||
+ smi_info->curr_msg->data_size);
|
|
||||||
smi_info->si_state = SI_GETTING_EVENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
|
|
||||||
+{
|
|
||||||
+ smi_info->last_timeout_jiffies = jiffies;
|
|
||||||
+ mod_timer(&smi_info->si_timer, new_val);
|
|
||||||
+ smi_info->timer_running = true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* When we have a situtaion where we run out of memory and cannot
|
|
||||||
* allocate messages, we just leave them in the BMC and run the system
|
|
||||||
@@ -494,11 +478,11 @@ static void start_getting_events(struct smi_info *smi_info)
|
|
||||||
* Note that we cannot just use disable_irq(), since the interrupt may
|
|
||||||
* be shared.
|
|
||||||
*/
|
|
||||||
-static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer)
|
|
||||||
+static inline bool disable_si_irq(struct smi_info *smi_info)
|
|
||||||
{
|
|
||||||
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
|
|
||||||
smi_info->interrupt_disabled = true;
|
|
||||||
- start_check_enables(smi_info, start_timer);
|
|
||||||
+ start_check_enables(smi_info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
@@ -508,7 +492,7 @@ static inline bool enable_si_irq(struct smi_info *smi_info)
|
|
||||||
{
|
|
||||||
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
|
|
||||||
smi_info->interrupt_disabled = false;
|
|
||||||
- start_check_enables(smi_info, true);
|
|
||||||
+ start_check_enables(smi_info);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
@@ -526,7 +510,7 @@ static struct ipmi_smi_msg *alloc_msg_handle_irq(struct smi_info *smi_info)
|
|
||||||
|
|
||||||
msg = ipmi_alloc_smi_msg();
|
|
||||||
if (!msg) {
|
|
||||||
- if (!disable_si_irq(smi_info, true))
|
|
||||||
+ if (!disable_si_irq(smi_info))
|
|
||||||
smi_info->si_state = SI_NORMAL;
|
|
||||||
} else if (enable_si_irq(smi_info)) {
|
|
||||||
ipmi_free_smi_msg(msg);
|
|
||||||
@@ -542,7 +526,7 @@ static void handle_flags(struct smi_info *smi_info)
|
|
||||||
/* Watchdog pre-timeout */
|
|
||||||
smi_inc_stat(smi_info, watchdog_pretimeouts);
|
|
||||||
|
|
||||||
- start_clear_flags(smi_info, true);
|
|
||||||
+ start_clear_flags(smi_info);
|
|
||||||
smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
|
|
||||||
if (smi_info->intf)
|
|
||||||
ipmi_smi_watchdog_pretimeout(smi_info->intf);
|
|
||||||
@@ -895,7 +879,8 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|
||||||
msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
|
|
||||||
msg[1] = IPMI_GET_MSG_FLAGS_CMD;
|
|
||||||
|
|
||||||
- start_new_msg(smi_info, msg, 2);
|
|
||||||
+ smi_info->handlers->start_transaction(
|
|
||||||
+ smi_info->si_sm, msg, 2);
|
|
||||||
smi_info->si_state = SI_GETTING_FLAGS;
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
@@ -925,7 +910,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|
||||||
* disable and messages disabled.
|
|
||||||
*/
|
|
||||||
if (smi_info->supports_event_msg_buff || smi_info->irq) {
|
|
||||||
- start_check_enables(smi_info, true);
|
|
||||||
+ start_check_enables(smi_info);
|
|
||||||
} else {
|
|
||||||
smi_info->curr_msg = alloc_msg_handle_irq(smi_info);
|
|
||||||
if (!smi_info->curr_msg)
|
|
||||||
@@ -3635,7 +3620,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|
||||||
* Start clearing the flags before we enable interrupts or the
|
|
||||||
* timer to avoid racing with the timer.
|
|
||||||
*/
|
|
||||||
- start_clear_flags(new_smi, false);
|
|
||||||
+ start_clear_flags(new_smi);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IRQ is defined to be set when non-zero. req_events will
|
|
||||||
@@ -3930,7 +3915,7 @@ static void cleanup_one_si(struct smi_info *to_clean)
|
|
||||||
poll(to_clean);
|
|
||||||
schedule_timeout_uninterruptible(1);
|
|
||||||
}
|
|
||||||
- disable_si_irq(to_clean, false);
|
|
||||||
+ disable_si_irq(to_clean);
|
|
||||||
while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
|
|
||||||
poll(to_clean);
|
|
||||||
schedule_timeout_uninterruptible(1);
|
|
||||||
--
|
|
||||||
2.7.2
|
|
||||||
|
|
||||||
-192
@@ -1,192 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
From 7020bcb82838006e23d058ff07b063b393ed3f10 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Date: Tue, 29 Nov 2016 23:19:46 +0100
|
|
||||||
Subject: [PATCH] ACPI: do not warn if _BQC does not exist
|
|
||||||
|
|
||||||
Starting from ACPI spec 3.0, it's only clarified that _BCM control
|
|
||||||
method is required if _BCL is implemented. There is no word
|
|
||||||
saying _BQC is required.
|
|
||||||
|
|
||||||
And in ACPI spec 6.1 B.5.4, for _BQC, it is explicitly stated that
|
|
||||||
"This optional method returns the current brightness level of a
|
|
||||||
built-in display output device. If present, it must be set by
|
|
||||||
the platform for initial brightness."
|
|
||||||
|
|
||||||
Thus remove the obsolete warning message.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
|
||||||
---
|
|
||||||
drivers/acpi/scan.c | 3 ---
|
|
||||||
1 file changed, 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
|
|
||||||
index 3d1856f..07aa2e6 100644
|
|
||||||
--- a/drivers/acpi/scan.c
|
|
||||||
+++ b/drivers/acpi/scan.c
|
|
||||||
@@ -1119,9 +1119,6 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
|
|
||||||
"support\n"));
|
|
||||||
*cap |= ACPI_VIDEO_BACKLIGHT;
|
|
||||||
- if (!acpi_has_method(handle, "_BQC"))
|
|
||||||
- printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
|
|
||||||
- "cannot determine initial brightness\n");
|
|
||||||
/* We have backlight support, no need to scan further */
|
|
||||||
return AE_CTRL_TERMINATE;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
Devicetree is enabled on 32bit kernels for OLPC support,
|
|
||||||
but this causes error messages:
|
|
||||||
|
|
||||||
'Failed to find cpu0 device node' that breaks bootsplash.
|
|
||||||
|
|
||||||
https://bugs.mageia.org/show_bug.cgi?id=16655#c39
|
|
||||||
https://bugs.mageia.org/show_bug.cgi?id=17010
|
|
||||||
|
|
||||||
So hide them behind debug for cleaner boot.
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
|
||||||
|
|
||||||
|
|
||||||
--- linux/drivers/base/cacheinfo.c.orig
|
|
||||||
+++ linux/drivers/base/cacheinfo.c
|
|
||||||
@@ -53,12 +53,12 @@
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!cpu_dev) {
|
|
||||||
- pr_err("No cpu device for CPU %d\n", cpu);
|
|
||||||
+ pr_debug("No cpu device for CPU %d\n", cpu);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
np = cpu_dev->of_node;
|
|
||||||
if (!np) {
|
|
||||||
- pr_err("Failed to find cpu%d device node\n", cpu);
|
|
||||||
+ pr_debug("Failed to find cpu%d device node\n", cpu);
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@
|
|
||||||
*/
|
|
||||||
ret = cache_shared_cpu_map_setup(cpu);
|
|
||||||
if (ret) {
|
|
||||||
- pr_warn("Unable to detect cache hierarchy from DT for CPU %d\n",
|
|
||||||
+ pr_debug("Unable to detect cache hierarchy from DT for CPU %d\n",
|
|
||||||
cpu);
|
|
||||||
goto free_ci;
|
|
||||||
}
|
|
||||||
@@ -540,7 +540,7 @@
|
|
||||||
rc = cache_add_dev(cpu);
|
|
||||||
if (rc) {
|
|
||||||
free_cache_attributes(cpu);
|
|
||||||
- pr_err("error populating cacheinfo..cpu%d\n", cpu);
|
|
||||||
+ pr_debug("error populating cacheinfo..cpu%d\n", cpu);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
From 41c0126b3f22ef36b97b3c38b8f29569848a5ce2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tahsin Erdogan <tahsin@google.com>
|
|
||||||
Date: Tue, 19 May 2015 13:55:21 -0700
|
|
||||||
Subject: block: Make CFQ default to IOPS mode on SSDs
|
|
||||||
|
|
||||||
CFQ idling causes reduced IOPS throughput on non-rotational disks.
|
|
||||||
Since disk head seeking is not applicable to SSDs, it doesn't really
|
|
||||||
help performance by anticipating future near-by IO requests.
|
|
||||||
|
|
||||||
By turning off idling (and switching to IOPS mode), we allow other
|
|
||||||
processes to dispatch IO requests down to the driver and so increase IO
|
|
||||||
throughput.
|
|
||||||
|
|
||||||
Following FIO benchmark results were taken on a cloud SSD offering with
|
|
||||||
idling on and off:
|
|
||||||
|
|
||||||
Idling iops avg-lat(ms) stddev bw
|
|
||||||
------------------------------------------------------
|
|
||||||
On 7054 90.107 38.697 28217KB/s
|
|
||||||
Off 29255 21.836 11.730 117022KB/s
|
|
||||||
|
|
||||||
fio --name=temp --size=100G --time_based --ioengine=libaio \
|
|
||||||
--randrepeat=0 --direct=1 --invalidate=1 --verify=0 \
|
|
||||||
--verify_fatal=0 --rw=randread --blocksize=4k --group_reporting=1 \
|
|
||||||
--filename=/dev/sdb --runtime=10 --iodepth=64 --numjobs=10
|
|
||||||
|
|
||||||
And the following is from a local SSD run:
|
|
||||||
|
|
||||||
Idling iops avg-lat(ms) stddev bw
|
|
||||||
------------------------------------------------------
|
|
||||||
On 19320 33.043 14.068 77281KB/s
|
|
||||||
Off 21626 29.465 12.662 86507KB/s
|
|
||||||
|
|
||||||
fio --name=temp --size=5G --time_based --ioengine=libaio \
|
|
||||||
--randrepeat=0 --direct=1 --invalidate=1 --verify=0 \
|
|
||||||
--verify_fatal=0 --rw=randread --blocksize=4k --group_reporting=1 \
|
|
||||||
--filename=/fio_data --runtime=10 --iodepth=64 --numjobs=10
|
|
||||||
|
|
||||||
Reviewed-by: Nauman Rafique <nauman@google.com>
|
|
||||||
Signed-off-by: Tahsin Erdogan <tahsin@google.com>
|
|
||||||
Signed-off-by: Jens Axboe <axboe@fb.com>
|
|
||||||
|
|
||||||
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
|
|
||||||
index 5da8e6e..402be01 100644
|
|
||||||
--- a/block/cfq-iosched.c
|
|
||||||
+++ b/block/cfq-iosched.c
|
|
||||||
@@ -4460,7 +4460,7 @@ static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
|
|
||||||
cfqd->cfq_slice[1] = cfq_slice_sync;
|
|
||||||
cfqd->cfq_target_latency = cfq_target_latency;
|
|
||||||
cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
|
|
||||||
- cfqd->cfq_slice_idle = cfq_slice_idle;
|
|
||||||
+ cfqd->cfq_slice_idle = blk_queue_nonrot(q) ? 0 : cfq_slice_idle;
|
|
||||||
cfqd->cfq_group_idle = cfq_group_idle;
|
|
||||||
cfqd->cfq_latency = 1;
|
|
||||||
cfqd->hw_tag = -1;
|
|
||||||
--
|
|
||||||
cgit v0.10.2
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
-1101
File diff suppressed because it is too large
Load Diff
+107
@@ -0,0 +1,107 @@
|
|||||||
|
From 614822f81f606e0064acdae11d9ec1efd3db4190 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Date: Mon, 13 Nov 2017 07:34:08 +0100
|
||||||
|
Subject: [PATCH] block, bfq: add missing invocations of
|
||||||
|
bfqg_stats_update_io_add/remove
|
||||||
|
|
||||||
|
bfqg_stats_update_io_add and bfqg_stats_update_io_remove are to be
|
||||||
|
invoked, respectively, when an I/O request enters and when an I/O
|
||||||
|
request exits the scheduler. Unfortunately, bfq does not fully comply
|
||||||
|
with this scheme, because it does not invoke these functions for
|
||||||
|
requests that are inserted into or extracted from its priority
|
||||||
|
dispatch list. This commit fixes this mistake.
|
||||||
|
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 21 ++++++++++++++++++---
|
||||||
|
1 file changed, 18 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 889a8549d97f..91703eba63f0 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -1359,7 +1359,6 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
|
||||||
|
bfqq->ttime.last_end_request +
|
||||||
|
bfqd->bfq_slice_idle * 3;
|
||||||
|
|
||||||
|
- bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq, rq->cmd_flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bfqq deserves to be weight-raised if:
|
||||||
|
@@ -1633,7 +1632,6 @@ static void bfq_remove_request(struct request_queue *q,
|
||||||
|
if (rq->cmd_flags & REQ_META)
|
||||||
|
bfqq->meta_pending--;
|
||||||
|
|
||||||
|
- bfqg_stats_update_io_remove(bfqq_group(bfqq), rq->cmd_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bfq_bio_merge(struct blk_mq_hw_ctx *hctx, struct bio *bio)
|
||||||
|
@@ -1746,6 +1744,7 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq,
|
||||||
|
bfqq->next_rq = rq;
|
||||||
|
|
||||||
|
bfq_remove_request(q, next);
|
||||||
|
+ bfqg_stats_update_io_remove(bfqq_group(bfqq), next->cmd_flags);
|
||||||
|
|
||||||
|
spin_unlock_irq(&bfqq->bfqd->lock);
|
||||||
|
end:
|
||||||
|
@@ -3700,6 +3699,9 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
rq = __bfq_dispatch_request(hctx);
|
||||||
|
+ if (rq && RQ_BFQQ(rq))
|
||||||
|
+ bfqg_stats_update_io_remove(bfqq_group(RQ_BFQQ(rq)),
|
||||||
|
+ rq->cmd_flags);
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
return rq;
|
||||||
|
@@ -4224,6 +4226,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
{
|
||||||
|
struct request_queue *q = hctx->queue;
|
||||||
|
struct bfq_data *bfqd = q->elevator->elevator_data;
|
||||||
|
+ struct bfq_queue *bfqq = RQ_BFQQ(rq);
|
||||||
|
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
if (blk_mq_sched_try_insert_merge(q, rq)) {
|
||||||
|
@@ -4243,6 +4246,12 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
list_add_tail(&rq->queuelist, &bfqd->dispatch);
|
||||||
|
} else {
|
||||||
|
__bfq_insert_request(bfqd, rq);
|
||||||
|
+ /*
|
||||||
|
+ * Update bfqq, because, if a queue merge has occurred
|
||||||
|
+ * in __bfq_insert_request, then rq has been
|
||||||
|
+ * redirected into a new queue.
|
||||||
|
+ */
|
||||||
|
+ bfqq = RQ_BFQQ(rq);
|
||||||
|
|
||||||
|
if (rq_mergeable(rq)) {
|
||||||
|
elv_rqhash_add(q, rq);
|
||||||
|
@@ -4251,6 +4260,9 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (bfqq)
|
||||||
|
+ bfqg_stats_update_io_add(bfqq_group(bfqq), bfqq, rq->cmd_flags);
|
||||||
|
+
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4428,8 +4440,11 @@ static void bfq_finish_request(struct request *rq)
|
||||||
|
* lock is held.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (!RB_EMPTY_NODE(&rq->rb_node))
|
||||||
|
+ if (!RB_EMPTY_NODE(&rq->rb_node)) {
|
||||||
|
bfq_remove_request(rq->q, rq);
|
||||||
|
+ bfqg_stats_update_io_remove(bfqq_group(bfqq),
|
||||||
|
+ rq->cmd_flags);
|
||||||
|
+ }
|
||||||
|
bfq_put_rq_priv_body(bfqq);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
From 05e90283561648301e30232fe0c91bd345ceba03 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Wed, 20 Dec 2017 12:38:31 +0100
|
||||||
|
Subject: [PATCH] block, bfq: add missing rq_pos_tree update on rq removal
|
||||||
|
|
||||||
|
If two processes do I/O close to each other, then BFQ merges the
|
||||||
|
bfq_queues associated with these processes, to get a more sequential
|
||||||
|
I/O, and thus a higher throughput. In this respect, to detect whether
|
||||||
|
two processes are doing I/O close to each other, BFQ keeps a list of
|
||||||
|
the head-of-line I/O requests of all active bfq_queues. The list is
|
||||||
|
ordered by initial sectors, and implemented through a red-black tree
|
||||||
|
(rq_pos_tree).
|
||||||
|
|
||||||
|
Unfortunately, the update of the rq_pos_tree was incomplete, because
|
||||||
|
the tree was not updated on the removal of the head-of-line I/O
|
||||||
|
request of a bfq_queue, in case the queue did not remain empty. This
|
||||||
|
commit adds the missing update.
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 0f48583b9380..fa395a260a23 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -1627,6 +1627,8 @@ static void bfq_remove_request(struct request_queue *q,
|
||||||
|
rb_erase(&bfqq->pos_node, bfqq->pos_root);
|
||||||
|
bfqq->pos_root = NULL;
|
||||||
|
}
|
||||||
|
+ } else {
|
||||||
|
+ bfq_pos_tree_add_move(bfqd, bfqq);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rq->cmd_flags & REQ_META)
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+163
@@ -0,0 +1,163 @@
|
|||||||
|
From 3e2bdd6dff239afd8386e8758eee69ad61e5a3d6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Thu, 21 Sep 2017 11:04:01 +0200
|
||||||
|
Subject: [PATCH] block, bfq: check and switch back to interactive wr also on
|
||||||
|
queue split
|
||||||
|
|
||||||
|
As already explained in the message of commit "block, bfq: fix
|
||||||
|
wrong init of saved start time for weight raising", if a soft
|
||||||
|
real-time weight-raising period happens to be nested in a larger
|
||||||
|
interactive weight-raising period, then BFQ restores the interactive
|
||||||
|
weight raising at the end of the soft real-time weight raising. In
|
||||||
|
particular, BFQ checks whether the latter has ended only on request
|
||||||
|
dispatches.
|
||||||
|
|
||||||
|
Unfortunately, the above scheme fails to restore interactive weight
|
||||||
|
raising in the following corner case: if a bfq_queue, say Q,
|
||||||
|
1) Is merged with another bfq_queue while it is in a nested soft
|
||||||
|
real-time weight-raising period. The weight-raising state of Q is
|
||||||
|
then saved, and not considered any longer until a split occurs.
|
||||||
|
2) Is split from the other bfq_queue(s) at a time instant when its
|
||||||
|
soft real-time weight raising is already finished.
|
||||||
|
On the split, while resuming the previous, soft real-time
|
||||||
|
weight-raised state of the bfq_queue Q, BFQ checks whether the
|
||||||
|
current soft real-time weight-raising period is actually over. If so,
|
||||||
|
BFQ switches weight raising off for Q, *without* checking whether the
|
||||||
|
soft real-time period was actually nested in a non-yet-finished
|
||||||
|
interactive weight-raising period.
|
||||||
|
|
||||||
|
This commit addresses this issue by adding the above missing check in
|
||||||
|
bfq_queue splits, and restoring interactive weight raising if needed.
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Tested-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Tested-by: Mirko Montanari <mirkomontanari91@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 87 ++++++++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 49 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index c25955c25e03..33b63bc4a64b 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -724,6 +724,44 @@ static void bfq_updated_next_req(struct bfq_data *bfqd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
|
||||||
|
+{
|
||||||
|
+ u64 dur;
|
||||||
|
+
|
||||||
|
+ if (bfqd->bfq_wr_max_time > 0)
|
||||||
|
+ return bfqd->bfq_wr_max_time;
|
||||||
|
+
|
||||||
|
+ dur = bfqd->RT_prod;
|
||||||
|
+ do_div(dur, bfqd->peak_rate);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Limit duration between 3 and 13 seconds. Tests show that
|
||||||
|
+ * higher values than 13 seconds often yield the opposite of
|
||||||
|
+ * the desired result, i.e., worsen responsiveness by letting
|
||||||
|
+ * non-interactive and non-soft-real-time applications
|
||||||
|
+ * preserve weight raising for a too long time interval.
|
||||||
|
+ *
|
||||||
|
+ * On the other end, lower values than 3 seconds make it
|
||||||
|
+ * difficult for most interactive tasks to complete their jobs
|
||||||
|
+ * before weight-raising finishes.
|
||||||
|
+ */
|
||||||
|
+ if (dur > msecs_to_jiffies(13000))
|
||||||
|
+ dur = msecs_to_jiffies(13000);
|
||||||
|
+ else if (dur < msecs_to_jiffies(3000))
|
||||||
|
+ dur = msecs_to_jiffies(3000);
|
||||||
|
+
|
||||||
|
+ return dur;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* switch back from soft real-time to interactive weight raising */
|
||||||
|
+static void switch_back_to_interactive_wr(struct bfq_queue *bfqq,
|
||||||
|
+ struct bfq_data *bfqd)
|
||||||
|
+{
|
||||||
|
+ bfqq->wr_coeff = bfqd->bfq_wr_coeff;
|
||||||
|
+ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
|
||||||
|
+ bfqq->last_wr_start_finish = bfqq->wr_start_at_switch_to_srt;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
|
||||||
|
struct bfq_io_cq *bic, bool bfq_already_existing)
|
||||||
|
@@ -750,10 +788,16 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
|
||||||
|
if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) ||
|
||||||
|
time_is_before_jiffies(bfqq->last_wr_start_finish +
|
||||||
|
bfqq->wr_cur_max_time))) {
|
||||||
|
- bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||||
|
- "resume state: switching off wr");
|
||||||
|
-
|
||||||
|
- bfqq->wr_coeff = 1;
|
||||||
|
+ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time &&
|
||||||
|
+ !bfq_bfqq_in_large_burst(bfqq) &&
|
||||||
|
+ time_is_after_eq_jiffies(bfqq->wr_start_at_switch_to_srt +
|
||||||
|
+ bfq_wr_duration(bfqd))) {
|
||||||
|
+ switch_back_to_interactive_wr(bfqq, bfqd);
|
||||||
|
+ } else {
|
||||||
|
+ bfqq->wr_coeff = 1;
|
||||||
|
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||||
|
+ "resume state: switching off wr");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure weight will be updated, however we got here */
|
||||||
|
@@ -1173,35 +1217,6 @@ static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd,
|
||||||
|
return wr_or_deserves_wr;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
|
||||||
|
-{
|
||||||
|
- u64 dur;
|
||||||
|
-
|
||||||
|
- if (bfqd->bfq_wr_max_time > 0)
|
||||||
|
- return bfqd->bfq_wr_max_time;
|
||||||
|
-
|
||||||
|
- dur = bfqd->RT_prod;
|
||||||
|
- do_div(dur, bfqd->peak_rate);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Limit duration between 3 and 13 seconds. Tests show that
|
||||||
|
- * higher values than 13 seconds often yield the opposite of
|
||||||
|
- * the desired result, i.e., worsen responsiveness by letting
|
||||||
|
- * non-interactive and non-soft-real-time applications
|
||||||
|
- * preserve weight raising for a too long time interval.
|
||||||
|
- *
|
||||||
|
- * On the other end, lower values than 3 seconds make it
|
||||||
|
- * difficult for most interactive tasks to complete their jobs
|
||||||
|
- * before weight-raising finishes.
|
||||||
|
- */
|
||||||
|
- if (dur > msecs_to_jiffies(13000))
|
||||||
|
- dur = msecs_to_jiffies(13000);
|
||||||
|
- else if (dur < msecs_to_jiffies(3000))
|
||||||
|
- dur = msecs_to_jiffies(3000);
|
||||||
|
-
|
||||||
|
- return dur;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Return the farthest future time instant according to jiffies
|
||||||
|
* macros.
|
||||||
|
@@ -3501,11 +3516,7 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||||
|
bfq_wr_duration(bfqd)))
|
||||||
|
bfq_bfqq_end_wr(bfqq);
|
||||||
|
else {
|
||||||
|
- /* switch back to interactive wr */
|
||||||
|
- bfqq->wr_coeff = bfqd->bfq_wr_coeff;
|
||||||
|
- bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
|
||||||
|
- bfqq->last_wr_start_finish =
|
||||||
|
- bfqq->wr_start_at_switch_to_srt;
|
||||||
|
+ switch_back_to_interactive_wr(bfqq, bfqd);
|
||||||
|
bfqq->entity.prio_changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
From 1be6e8a964ee9aa8d4daac523ce29e5f486dd756 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Date: Wed, 20 Dec 2017 12:38:32 +0100
|
||||||
|
Subject: [PATCH] block, bfq: check low_latency flag in bfq_bfqq_save_state()
|
||||||
|
|
||||||
|
A just-created bfq_queue will certainly be deemed as interactive on
|
||||||
|
the arrival of its first I/O request, if the low_latency flag is
|
||||||
|
set. Yet, if the queue is merged with another queue on the arrival of
|
||||||
|
its first I/O request, it will not have the chance to be flagged as
|
||||||
|
interactive. Nevertheless, if the queue is then split soon enough, it
|
||||||
|
has to be flagged as interactive after the split.
|
||||||
|
|
||||||
|
To handle this early-merge scenario correctly, BFQ saves the state of
|
||||||
|
the queue, on the merge, as if the latter had already been deemed
|
||||||
|
interactive. So, if the queue is split soon, it will get
|
||||||
|
weight-raised, because the previous state of the queue is resumed on
|
||||||
|
the split.
|
||||||
|
|
||||||
|
Unfortunately, in the act of saving the state of the newly-created
|
||||||
|
queue, BFQ doesn't check whether the low_latency flag is set, and this
|
||||||
|
causes early-merged queues to be then weight-raised, on queue splits,
|
||||||
|
even if low_latency is off. This commit addresses this problem by
|
||||||
|
adding the missing check.
|
||||||
|
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index fa395a260a23..2cf395daee80 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -2064,7 +2064,8 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
|
||||||
|
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
|
||||||
|
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
|
||||||
|
if (unlikely(bfq_bfqq_just_created(bfqq) &&
|
||||||
|
- !bfq_bfqq_in_large_burst(bfqq))) {
|
||||||
|
+ !bfq_bfqq_in_large_burst(bfqq) &&
|
||||||
|
+ bfqq->bfqd->low_latency)) {
|
||||||
|
/*
|
||||||
|
* bfqq being merged right after being created: bfqq
|
||||||
|
* would have deserved interactive weight raising, but
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+206
@@ -0,0 +1,206 @@
|
|||||||
|
From a34b024448eb71b0e51ad011fa1862236e366034 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Fri, 15 Dec 2017 07:23:12 +0100
|
||||||
|
Subject: [PATCH] block, bfq: consider also past I/O in soft real-time
|
||||||
|
detection
|
||||||
|
|
||||||
|
BFQ privileges the I/O of soft real-time applications, such as video
|
||||||
|
players, to guarantee to these application a high bandwidth and a low
|
||||||
|
latency. In this respect, it is not easy to correctly detect when an
|
||||||
|
application is soft real-time. A particularly nasty false positive is
|
||||||
|
that of an I/O-bound application that occasionally happens to meet all
|
||||||
|
requirements to be deemed as soft real-time. After being detected as
|
||||||
|
soft real-time, such an application monopolizes the device. Fortunately,
|
||||||
|
BFQ will realize soon that the application is actually not soft
|
||||||
|
real-time and suspend every privilege. Yet, the application may happen
|
||||||
|
again to be wrongly detected as soft real-time, and so on.
|
||||||
|
|
||||||
|
As highlighted by our tests, this problem causes BFQ to occasionally
|
||||||
|
fail to guarantee a high responsiveness, in the presence of heavy
|
||||||
|
background I/O workloads. The reason is that the background workload
|
||||||
|
happens to be detected as soft real-time, more or less frequently,
|
||||||
|
during the execution of the interactive task under test. To give an
|
||||||
|
idea, because of this problem, Libreoffice Writer occasionally takes 8
|
||||||
|
seconds, instead of 3, to start up, if there are sequential reads and
|
||||||
|
writes in the background, on a Kingston SSDNow V300.
|
||||||
|
|
||||||
|
This commit addresses this issue by leveraging the following facts.
|
||||||
|
|
||||||
|
The reason why some applications are detected as soft real-time despite
|
||||||
|
all BFQ checks to avoid false positives, is simply that, during high
|
||||||
|
CPU or storage-device load, I/O-bound applications may happen to do
|
||||||
|
I/O slowly enough to meet all soft real-time requirements, and pass
|
||||||
|
all BFQ extra checks. Yet, this happens only for limited time periods:
|
||||||
|
slow-speed time intervals are usually interspersed between other time
|
||||||
|
intervals during which these applications do I/O at a very high speed.
|
||||||
|
To exploit these facts, this commit introduces a little change, in the
|
||||||
|
detection of soft real-time behavior, to systematically consider also
|
||||||
|
the recent past: the higher the speed was in the recent past, the
|
||||||
|
later next I/O should arrive for the application to be considered as
|
||||||
|
soft real-time. At the beginning of a slow-speed interval, the minimum
|
||||||
|
arrival time allowed for the next I/O usually happens to still be so
|
||||||
|
high, to fall *after* the end of the slow-speed period itself. As a
|
||||||
|
consequence, the application does not risk to be deemed as soft
|
||||||
|
real-time during the slow-speed interval. Then, during the next
|
||||||
|
high-speed interval, the application cannot, evidently, be deemed as
|
||||||
|
soft real-time (exactly because of its speed), and so on.
|
||||||
|
|
||||||
|
This extra filtering proved to be rather effective: in the above test,
|
||||||
|
the frequency of false positives became so low that the start-up time
|
||||||
|
was 3 seconds in all iterations (apart from occasional outliers,
|
||||||
|
caused by page-cache-management issues, which are out of the scope of
|
||||||
|
this commit, and cannot be solved by an I/O scheduler).
|
||||||
|
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 115 ++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
1 file changed, 81 insertions(+), 34 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 9625550b2f85..e33c5c4c9856 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -2940,45 +2940,87 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
* whereas soft_rt_next_start is set to infinity for applications that do
|
||||||
|
* not.
|
||||||
|
*
|
||||||
|
- * Unfortunately, even a greedy application may happen to behave in an
|
||||||
|
- * isochronous way if the CPU load is high. In fact, the application may
|
||||||
|
- * stop issuing requests while the CPUs are busy serving other processes,
|
||||||
|
- * then restart, then stop again for a while, and so on. In addition, if
|
||||||
|
- * the disk achieves a low enough throughput with the request pattern
|
||||||
|
- * issued by the application (e.g., because the request pattern is random
|
||||||
|
- * and/or the device is slow), then the application may meet the above
|
||||||
|
- * bandwidth requirement too. To prevent such a greedy application to be
|
||||||
|
- * deemed as soft real-time, a further rule is used in the computation of
|
||||||
|
- * soft_rt_next_start: soft_rt_next_start must be higher than the current
|
||||||
|
- * time plus the maximum time for which the arrival of a request is waited
|
||||||
|
- * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle.
|
||||||
|
- * This filters out greedy applications, as the latter issue instead their
|
||||||
|
- * next request as soon as possible after the last one has been completed
|
||||||
|
- * (in contrast, when a batch of requests is completed, a soft real-time
|
||||||
|
- * application spends some time processing data).
|
||||||
|
+ * Unfortunately, even a greedy (i.e., I/O-bound) application may
|
||||||
|
+ * happen to meet, occasionally or systematically, both the above
|
||||||
|
+ * bandwidth and isochrony requirements. This may happen at least in
|
||||||
|
+ * the following circumstances. First, if the CPU load is high. The
|
||||||
|
+ * application may stop issuing requests while the CPUs are busy
|
||||||
|
+ * serving other processes, then restart, then stop again for a while,
|
||||||
|
+ * and so on. The other circumstances are related to the storage
|
||||||
|
+ * device: the storage device is highly loaded or reaches a low-enough
|
||||||
|
+ * throughput with the I/O of the application (e.g., because the I/O
|
||||||
|
+ * is random and/or the device is slow). In all these cases, the
|
||||||
|
+ * I/O of the application may be simply slowed down enough to meet
|
||||||
|
+ * the bandwidth and isochrony requirements. To reduce the probability
|
||||||
|
+ * that greedy applications are deemed as soft real-time in these
|
||||||
|
+ * corner cases, a further rule is used in the computation of
|
||||||
|
+ * soft_rt_next_start: the return value of this function is forced to
|
||||||
|
+ * be higher than the maximum between the following two quantities.
|
||||||
|
*
|
||||||
|
- * Unfortunately, the last filter may easily generate false positives if
|
||||||
|
- * only bfqd->bfq_slice_idle is used as a reference time interval and one
|
||||||
|
- * or both the following cases occur:
|
||||||
|
- * 1) HZ is so low that the duration of a jiffy is comparable to or higher
|
||||||
|
- * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with
|
||||||
|
- * HZ=100.
|
||||||
|
+ * (a) Current time plus: (1) the maximum time for which the arrival
|
||||||
|
+ * of a request is waited for when a sync queue becomes idle,
|
||||||
|
+ * namely bfqd->bfq_slice_idle, and (2) a few extra jiffies. We
|
||||||
|
+ * postpone for a moment the reason for adding a few extra
|
||||||
|
+ * jiffies; we get back to it after next item (b). Lower-bounding
|
||||||
|
+ * the return value of this function with the current time plus
|
||||||
|
+ * bfqd->bfq_slice_idle tends to filter out greedy applications,
|
||||||
|
+ * because the latter issue their next request as soon as possible
|
||||||
|
+ * after the last one has been completed. In contrast, a soft
|
||||||
|
+ * real-time application spends some time processing data, after a
|
||||||
|
+ * batch of its requests has been completed.
|
||||||
|
+ *
|
||||||
|
+ * (b) Current value of bfqq->soft_rt_next_start. As pointed out
|
||||||
|
+ * above, greedy applications may happen to meet both the
|
||||||
|
+ * bandwidth and isochrony requirements under heavy CPU or
|
||||||
|
+ * storage-device load. In more detail, in these scenarios, these
|
||||||
|
+ * applications happen, only for limited time periods, to do I/O
|
||||||
|
+ * slowly enough to meet all the requirements described so far,
|
||||||
|
+ * including the filtering in above item (a). These slow-speed
|
||||||
|
+ * time intervals are usually interspersed between other time
|
||||||
|
+ * intervals during which these applications do I/O at a very high
|
||||||
|
+ * speed. Fortunately, exactly because of the high speed of the
|
||||||
|
+ * I/O in the high-speed intervals, the values returned by this
|
||||||
|
+ * function happen to be so high, near the end of any such
|
||||||
|
+ * high-speed interval, to be likely to fall *after* the end of
|
||||||
|
+ * the low-speed time interval that follows. These high values are
|
||||||
|
+ * stored in bfqq->soft_rt_next_start after each invocation of
|
||||||
|
+ * this function. As a consequence, if the last value of
|
||||||
|
+ * bfqq->soft_rt_next_start is constantly used to lower-bound the
|
||||||
|
+ * next value that this function may return, then, from the very
|
||||||
|
+ * beginning of a low-speed interval, bfqq->soft_rt_next_start is
|
||||||
|
+ * likely to be constantly kept so high that any I/O request
|
||||||
|
+ * issued during the low-speed interval is considered as arriving
|
||||||
|
+ * to soon for the application to be deemed as soft
|
||||||
|
+ * real-time. Then, in the high-speed interval that follows, the
|
||||||
|
+ * application will not be deemed as soft real-time, just because
|
||||||
|
+ * it will do I/O at a high speed. And so on.
|
||||||
|
+ *
|
||||||
|
+ * Getting back to the filtering in item (a), in the following two
|
||||||
|
+ * cases this filtering might be easily passed by a greedy
|
||||||
|
+ * application, if the reference quantity was just
|
||||||
|
+ * bfqd->bfq_slice_idle:
|
||||||
|
+ * 1) HZ is so low that the duration of a jiffy is comparable to or
|
||||||
|
+ * higher than bfqd->bfq_slice_idle. This happens, e.g., on slow
|
||||||
|
+ * devices with HZ=100. The time granularity may be so coarse
|
||||||
|
+ * that the approximation, in jiffies, of bfqd->bfq_slice_idle
|
||||||
|
+ * is rather lower than the exact value.
|
||||||
|
* 2) jiffies, instead of increasing at a constant rate, may stop increasing
|
||||||
|
* for a while, then suddenly 'jump' by several units to recover the lost
|
||||||
|
* increments. This seems to happen, e.g., inside virtual machines.
|
||||||
|
- * To address this issue, we do not use as a reference time interval just
|
||||||
|
- * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In
|
||||||
|
- * particular we add the minimum number of jiffies for which the filter
|
||||||
|
- * seems to be quite precise also in embedded systems and KVM/QEMU virtual
|
||||||
|
- * machines.
|
||||||
|
+ * To address this issue, in the filtering in (a) we do not use as a
|
||||||
|
+ * reference time interval just bfqd->bfq_slice_idle, but
|
||||||
|
+ * bfqd->bfq_slice_idle plus a few jiffies. In particular, we add the
|
||||||
|
+ * minimum number of jiffies for which the filter seems to be quite
|
||||||
|
+ * precise also in embedded systems and KVM/QEMU virtual machines.
|
||||||
|
*/
|
||||||
|
static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
|
||||||
|
struct bfq_queue *bfqq)
|
||||||
|
{
|
||||||
|
- return max(bfqq->last_idle_bklogged +
|
||||||
|
- HZ * bfqq->service_from_backlogged /
|
||||||
|
- bfqd->bfq_wr_max_softrt_rate,
|
||||||
|
- jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4);
|
||||||
|
+ return max3(bfqq->soft_rt_next_start,
|
||||||
|
+ bfqq->last_idle_bklogged +
|
||||||
|
+ HZ * bfqq->service_from_backlogged /
|
||||||
|
+ bfqd->bfq_wr_max_softrt_rate,
|
||||||
|
+ jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -4014,10 +4056,15 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
bfqq->split_time = bfq_smallest_from_now();
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Set to the value for which bfqq will not be deemed as
|
||||||
|
- * soft rt when it becomes backlogged.
|
||||||
|
+ * To not forget the possibly high bandwidth consumed by a
|
||||||
|
+ * process/queue in the recent past,
|
||||||
|
+ * bfq_bfqq_softrt_next_start() returns a value at least equal
|
||||||
|
+ * to the current value of bfqq->soft_rt_next_start (see
|
||||||
|
+ * comments on bfq_bfqq_softrt_next_start). Set
|
||||||
|
+ * soft_rt_next_start to now, to mean that bfqq has consumed
|
||||||
|
+ * no bandwidth so far.
|
||||||
|
*/
|
||||||
|
- bfqq->soft_rt_next_start = bfq_greatest_from_now();
|
||||||
|
+ bfqq->soft_rt_next_start = jiffies;
|
||||||
|
|
||||||
|
/* first request is almost certainly seeky */
|
||||||
|
bfqq->seek_history = 1;
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
From 7cb04004fa371a626c1a5ebe6d977f70285759ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Thu, 21 Sep 2017 11:04:03 +0200
|
||||||
|
Subject: [PATCH] block, bfq: decrease burst size when queues in burst exit
|
||||||
|
|
||||||
|
If many queues belonging to the same group happen to be created
|
||||||
|
shortly after each other, then the concurrent processes associated
|
||||||
|
with these queues have typically a common goal, and they get it done
|
||||||
|
as soon as possible if not hampered by device idling. Examples are
|
||||||
|
processes spawned by git grep, or by systemd during boot. As for
|
||||||
|
device idling, this mechanism is currently necessary for weight
|
||||||
|
raising to succeed in its goal: privileging I/O. In view of these
|
||||||
|
facts, BFQ does not provide the above queues with either weight
|
||||||
|
raising or device idling.
|
||||||
|
|
||||||
|
On the other hand, a burst of queue creations may be caused also by
|
||||||
|
the start-up of a complex application. In this case, these queues need
|
||||||
|
usually to be served one after the other, and as quickly as possible,
|
||||||
|
to maximise responsiveness. Therefore, in this case the best strategy
|
||||||
|
is to weight-raise all the queues created during the burst, i.e., the
|
||||||
|
exact opposite of the strategy for the above case.
|
||||||
|
|
||||||
|
To distinguish between the two cases, BFQ uses an empirical burst-size
|
||||||
|
threshold, found through extensive tests and monitoring of daily
|
||||||
|
usage. Only large bursts, i.e., burst with a size above this
|
||||||
|
threshold, are considered as generated by a high number of parallel
|
||||||
|
processes. In this respect, upstart-based boot proved to be rather
|
||||||
|
hard to detect as generating a large burst of queue creations, because
|
||||||
|
with upstart most of the queues created in a burst exit *before* the
|
||||||
|
next queues in the same burst are created. To address this issue, I
|
||||||
|
changed the burst-detection mechanism so as to not decrease the size
|
||||||
|
of the current burst even if one of the queues in the burst is
|
||||||
|
eliminated.
|
||||||
|
|
||||||
|
Unfortunately, this missing decrease causes false positives on very
|
||||||
|
fast systems: on the start-up of a complex application, such as
|
||||||
|
libreoffice writer, so many queues are created, served and exited
|
||||||
|
shortly after each other, that a large burst of queue creations is
|
||||||
|
wrongly detected as occurring. These false positives just disappear if
|
||||||
|
the size of a burst is decreased when one of the queues in the burst
|
||||||
|
exits. This commit restores the missing burst-size decrease, relying
|
||||||
|
of the fact that upstart is apparently unlikely to be used on systems
|
||||||
|
running this and future versions of the kernel.
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Mauro Andreolini <mauro.andreolini@unimore.it>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Tested-by: Mirko Montanari <mirkomontanari91@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 12 +++---------
|
||||||
|
1 file changed, 3 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 115747fe43c8..70f9177c4f5b 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -3725,16 +3725,10 @@ void bfq_put_queue(struct bfq_queue *bfqq)
|
||||||
|
if (bfqq->ref)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (bfq_bfqq_sync(bfqq))
|
||||||
|
- /*
|
||||||
|
- * The fact that this queue is being destroyed does not
|
||||||
|
- * invalidate the fact that this queue may have been
|
||||||
|
- * activated during the current burst. As a consequence,
|
||||||
|
- * although the queue does not exist anymore, and hence
|
||||||
|
- * needs to be removed from the burst list if there,
|
||||||
|
- * the burst size has not to be decremented.
|
||||||
|
- */
|
||||||
|
+ if (bfq_bfqq_sync(bfqq) && !hlist_unhashed(&bfqq->burst_list_node)) {
|
||||||
|
hlist_del_init(&bfqq->burst_list_node);
|
||||||
|
+ bfqq->bfqd->burst_size--;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
kmem_cache_free(bfq_pool, bfqq);
|
||||||
|
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
From 8993d445df388e3541f48920a2353cfc904b220a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chiara Bruschi <bruschi.chiara@outlook.it>
|
||||||
|
Date: Mon, 18 Dec 2017 16:21:59 +0000
|
||||||
|
Subject: [PATCH] block, bfq: fix occurrences of request finish method's old
|
||||||
|
name
|
||||||
|
|
||||||
|
Commit '7b9e93616399' ("blk-mq-sched: unify request finished methods")
|
||||||
|
changed the old name of current bfq_finish_request method, but left it
|
||||||
|
unchanged elsewhere in the code (related comments, part of function
|
||||||
|
name bfq_put_rq_priv_body).
|
||||||
|
|
||||||
|
This commit fixes all occurrences of the old name of this method by
|
||||||
|
changing them into the current name.
|
||||||
|
|
||||||
|
Fixes: 7b9e93616399 ("blk-mq-sched: unify request finished methods")
|
||||||
|
Reviewed-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Federico Motta <federico@willer.it>
|
||||||
|
Signed-off-by: Chiara Bruschi <bruschi.chiara@outlook.it>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 26 +++++++++++++-------------
|
||||||
|
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 5e6f837f663e..f352b1677143 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -3684,8 +3684,8 @@ static struct request *__bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * We exploit the put_rq_private hook to decrement
|
||||||
|
- * rq_in_driver, but put_rq_private will not be
|
||||||
|
+ * We exploit the bfq_finish_request hook to decrement
|
||||||
|
+ * rq_in_driver, but bfq_finish_request will not be
|
||||||
|
* invoked on this request. So, to avoid unbalance,
|
||||||
|
* just start this request, without incrementing
|
||||||
|
* rq_in_driver. As a negative consequence,
|
||||||
|
@@ -3694,14 +3694,14 @@ static struct request *__bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
* bfq_schedule_dispatch to be invoked uselessly.
|
||||||
|
*
|
||||||
|
* As for implementing an exact solution, the
|
||||||
|
- * put_request hook, if defined, is probably invoked
|
||||||
|
- * also on this request. So, by exploiting this hook,
|
||||||
|
- * we could 1) increment rq_in_driver here, and 2)
|
||||||
|
- * decrement it in put_request. Such a solution would
|
||||||
|
- * let the value of the counter be always accurate,
|
||||||
|
- * but it would entail using an extra interface
|
||||||
|
- * function. This cost seems higher than the benefit,
|
||||||
|
- * being the frequency of non-elevator-private
|
||||||
|
+ * bfq_finish_request hook, if defined, is probably
|
||||||
|
+ * invoked also on this request. So, by exploiting
|
||||||
|
+ * this hook, we could 1) increment rq_in_driver here,
|
||||||
|
+ * and 2) decrement it in bfq_finish_request. Such a
|
||||||
|
+ * solution would let the value of the counter be
|
||||||
|
+ * always accurate, but it would entail using an extra
|
||||||
|
+ * interface function. This cost seems higher than the
|
||||||
|
+ * benefit, being the frequency of non-elevator-private
|
||||||
|
* requests very low.
|
||||||
|
*/
|
||||||
|
goto start_rq;
|
||||||
|
@@ -4558,7 +4558,7 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd)
|
||||||
|
bfq_schedule_dispatch(bfqd);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void bfq_put_rq_priv_body(struct bfq_queue *bfqq)
|
||||||
|
+static void bfq_finish_request_body(struct bfq_queue *bfqq)
|
||||||
|
{
|
||||||
|
bfqq->allocated--;
|
||||||
|
|
||||||
|
@@ -4588,7 +4588,7 @@ static void bfq_finish_request(struct request *rq)
|
||||||
|
spin_lock_irqsave(&bfqd->lock, flags);
|
||||||
|
|
||||||
|
bfq_completed_request(bfqq, bfqd);
|
||||||
|
- bfq_put_rq_priv_body(bfqq);
|
||||||
|
+ bfq_finish_request_body(bfqq);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&bfqd->lock, flags);
|
||||||
|
} else {
|
||||||
|
@@ -4609,7 +4609,7 @@ static void bfq_finish_request(struct request *rq)
|
||||||
|
bfqg_stats_update_io_remove(bfqq_group(bfqq),
|
||||||
|
rq->cmd_flags);
|
||||||
|
}
|
||||||
|
- bfq_put_rq_priv_body(bfqq);
|
||||||
|
+ bfq_finish_request_body(bfqq);
|
||||||
|
}
|
||||||
|
|
||||||
|
rq->elv.priv[0] = NULL;
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
From 99fead8d38e5302b1be9403d4de815ce9174a3df Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Mon, 9 Oct 2017 13:11:23 +0200
|
||||||
|
Subject: [PATCH] block, bfq: fix unbalanced decrements of burst size
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The commit "block, bfq: decrease burst size when queues in burst
|
||||||
|
exit" introduced the decrement of burst_size on the removal of a
|
||||||
|
bfq_queue from the burst list. Unfortunately, this decrement can
|
||||||
|
happen to be performed even when burst size is already equal to 0,
|
||||||
|
because of unbalanced decrements. A description follows of the cause
|
||||||
|
of these unbalanced decrements, namely a wrong assumption, and of the
|
||||||
|
way how this wrong assumption leads to unbalanced decrements.
|
||||||
|
|
||||||
|
The wrong assumption is that a bfq_queue can exit only if the process
|
||||||
|
associated with the bfq_queue has exited. This is false, because a
|
||||||
|
bfq_queue, say Q, may exit also as a consequence of a merge with
|
||||||
|
another bfq_queue. In this case, Q exits because the I/O of its
|
||||||
|
associated process has been redirected to another bfq_queue.
|
||||||
|
|
||||||
|
The decrement unbalance occurs because Q may then be re-created after
|
||||||
|
a split, and added back to the current burst list, *without*
|
||||||
|
incrementing burst_size. burst_size is not incremented because Q is
|
||||||
|
not a new bfq_queue added to the burst list, but a bfq_queue only
|
||||||
|
temporarily removed from the list, and, before the commit "bfq-sq,
|
||||||
|
bfq-mq: decrease burst size when queues in burst exit", burst_size was
|
||||||
|
not decremented when Q was removed.
|
||||||
|
|
||||||
|
This commit addresses this issue by just checking whether the exiting
|
||||||
|
bfq_queue is a merged bfq_queue, and, in that case, not decrementing
|
||||||
|
burst_size. Unfortunately, this still leaves room for unbalanced
|
||||||
|
decrements, in the following rarer case: on a split, the bfq_queue
|
||||||
|
happens to be inserted into a different burst list than that it was
|
||||||
|
removed from when merged. If this happens, the number of elements in
|
||||||
|
the new burst list becomes higher than burst_size (by one). When the
|
||||||
|
bfq_queue then exits, it is of course not in a merged state any
|
||||||
|
longer, thus burst_size is decremented, which results in an unbalanced
|
||||||
|
decrement. To handle this sporadic, unlucky case in a simple way,
|
||||||
|
this commit also checks that burst_size is larger than 0 before
|
||||||
|
decrementing it.
|
||||||
|
|
||||||
|
Finally, this commit removes an useless, extra check: the check that
|
||||||
|
the bfq_queue is sync, performed before checking whether the bfq_queue
|
||||||
|
is in the burst list. This extra check is redundant, because only sync
|
||||||
|
bfq_queues can be inserted into the burst list.
|
||||||
|
|
||||||
|
Fixes: 7cb04004fa37 ("block, bfq: decrease burst size when queues in burst exit")
|
||||||
|
Reported-by: Philip Müller <philm@manjaro.org>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Tested-by: Philip Müller <philm@manjaro.org>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 57 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 261f98695910..889a8549d97f 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -3726,9 +3726,36 @@ void bfq_put_queue(struct bfq_queue *bfqq)
|
||||||
|
if (bfqq->ref)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (bfq_bfqq_sync(bfqq) && !hlist_unhashed(&bfqq->burst_list_node)) {
|
||||||
|
+ if (!hlist_unhashed(&bfqq->burst_list_node)) {
|
||||||
|
hlist_del_init(&bfqq->burst_list_node);
|
||||||
|
- bfqq->bfqd->burst_size--;
|
||||||
|
+ /*
|
||||||
|
+ * Decrement also burst size after the removal, if the
|
||||||
|
+ * process associated with bfqq is exiting, and thus
|
||||||
|
+ * does not contribute to the burst any longer. This
|
||||||
|
+ * decrement helps filter out false positives of large
|
||||||
|
+ * bursts, when some short-lived process (often due to
|
||||||
|
+ * the execution of commands by some service) happens
|
||||||
|
+ * to start and exit while a complex application is
|
||||||
|
+ * starting, and thus spawning several processes that
|
||||||
|
+ * do I/O (and that *must not* be treated as a large
|
||||||
|
+ * burst, see comments on bfq_handle_burst).
|
||||||
|
+ *
|
||||||
|
+ * In particular, the decrement is performed only if:
|
||||||
|
+ * 1) bfqq is not a merged queue, because, if it is,
|
||||||
|
+ * then this free of bfqq is not triggered by the exit
|
||||||
|
+ * of the process bfqq is associated with, but exactly
|
||||||
|
+ * by the fact that bfqq has just been merged.
|
||||||
|
+ * 2) burst_size is greater than 0, to handle
|
||||||
|
+ * unbalanced decrements. Unbalanced decrements may
|
||||||
|
+ * happen in te following case: bfqq is inserted into
|
||||||
|
+ * the current burst list--without incrementing
|
||||||
|
+ * bust_size--because of a split, but the current
|
||||||
|
+ * burst list is not the burst list bfqq belonged to
|
||||||
|
+ * (see comments on the case of a split in
|
||||||
|
+ * bfq_set_request).
|
||||||
|
+ */
|
||||||
|
+ if (bfqq->bic && bfqq->bfqd->burst_size > 0)
|
||||||
|
+ bfqq->bfqd->burst_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmem_cache_free(bfq_pool, bfqq);
|
||||||
|
@@ -4460,6 +4487,34 @@ static struct bfq_queue *bfq_get_bfqq_handle_split(struct bfq_data *bfqd,
|
||||||
|
else {
|
||||||
|
bfq_clear_bfqq_in_large_burst(bfqq);
|
||||||
|
if (bic->was_in_burst_list)
|
||||||
|
+ /*
|
||||||
|
+ * If bfqq was in the current
|
||||||
|
+ * burst list before being
|
||||||
|
+ * merged, then we have to add
|
||||||
|
+ * it back. And we do not need
|
||||||
|
+ * to increase burst_size, as
|
||||||
|
+ * we did not decrement
|
||||||
|
+ * burst_size when we removed
|
||||||
|
+ * bfqq from the burst list as
|
||||||
|
+ * a consequence of a merge
|
||||||
|
+ * (see comments in
|
||||||
|
+ * bfq_put_queue). In this
|
||||||
|
+ * respect, it would be rather
|
||||||
|
+ * costly to know whether the
|
||||||
|
+ * current burst list is still
|
||||||
|
+ * the same burst list from
|
||||||
|
+ * which bfqq was removed on
|
||||||
|
+ * the merge. To avoid this
|
||||||
|
+ * cost, if bfqq was in a
|
||||||
|
+ * burst list, then we add
|
||||||
|
+ * bfqq to the current burst
|
||||||
|
+ * list without any further
|
||||||
|
+ * check. This can cause
|
||||||
|
+ * inappropriate insertions,
|
||||||
|
+ * but rarely enough to not
|
||||||
|
+ * harm the detection of large
|
||||||
|
+ * bursts significantly.
|
||||||
|
+ */
|
||||||
|
hlist_add_head(&bfqq->burst_list_node,
|
||||||
|
&bfqd->burst_list);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
From 4baa8bb13f41307f3eb62fe91f93a1a798ebef53 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Thu, 21 Sep 2017 11:04:00 +0200
|
||||||
|
Subject: [PATCH] block, bfq: fix wrong init of saved start time for weight
|
||||||
|
raising
|
||||||
|
|
||||||
|
This commit fixes a bug that causes bfq to fail to guarantee a high
|
||||||
|
responsiveness on some drives, if there is heavy random read+write I/O
|
||||||
|
in the background. More precisely, such a failure allowed this bug to
|
||||||
|
be found [1], but the bug may well cause other yet unreported
|
||||||
|
anomalies.
|
||||||
|
|
||||||
|
BFQ raises the weight of the bfq_queues associated with soft real-time
|
||||||
|
applications, to privilege the I/O, and thus reduce latency, for these
|
||||||
|
applications. This mechanism is named soft-real-time weight raising in
|
||||||
|
BFQ. A soft real-time period may happen to be nested into an
|
||||||
|
interactive weight raising period, i.e., it may happen that, when a
|
||||||
|
bfq_queue switches to a soft real-time weight-raised state, the
|
||||||
|
bfq_queue is already being weight-raised because deemed interactive
|
||||||
|
too. In this case, BFQ saves in a special variable
|
||||||
|
wr_start_at_switch_to_srt, the time instant when the interactive
|
||||||
|
weight-raising period started for the bfq_queue, i.e., the time
|
||||||
|
instant when BFQ started to deem the bfq_queue interactive. This value
|
||||||
|
is then used to check whether the interactive weight-raising period
|
||||||
|
would still be in progress when the soft real-time weight-raising
|
||||||
|
period ends. If so, interactive weight raising is restored for the
|
||||||
|
bfq_queue. This restore is useful, in particular, because it prevents
|
||||||
|
bfq_queues from losing their interactive weight raising prematurely,
|
||||||
|
as a consequence of spurious, short-lived soft real-time
|
||||||
|
weight-raising periods caused by wrong detections as soft real-time.
|
||||||
|
|
||||||
|
If, instead, a bfq_queue switches to soft-real-time weight raising
|
||||||
|
while it *is not* already in an interactive weight-raising period,
|
||||||
|
then the variable wr_start_at_switch_to_srt has no meaning during the
|
||||||
|
following soft real-time weight-raising period. Unfortunately the
|
||||||
|
handling of this case is wrong in BFQ: not only the variable is not
|
||||||
|
flagged somehow as meaningless, but it is also set to the time when
|
||||||
|
the switch to soft real-time weight-raising occurs. This may cause an
|
||||||
|
interactive weight-raising period to be considered mistakenly as still
|
||||||
|
in progress, and thus a spurious interactive weight-raising period to
|
||||||
|
start for the bfq_queue, at the end of the soft-real-time
|
||||||
|
weight-raising period. In particular the spurious interactive
|
||||||
|
weight-raising period will be considered as still in progress, if the
|
||||||
|
soft-real-time weight-raising period does not last very long. The
|
||||||
|
bfq_queue will then be wrongly privileged and, if I/O bound, will
|
||||||
|
unjustly steal bandwidth to truly interactive or soft real-time
|
||||||
|
bfq_queues, harming responsiveness and low latency.
|
||||||
|
|
||||||
|
This commit fixes this issue by just setting wr_start_at_switch_to_srt
|
||||||
|
to minus infinity (farthest past time instant according to jiffies
|
||||||
|
macros): when the soft-real-time weight-raising period ends, certainly
|
||||||
|
no interactive weight-raising period will be considered as still in
|
||||||
|
progress.
|
||||||
|
|
||||||
|
[1] Background I/O Type: Random - Background I/O mix: Reads and writes
|
||||||
|
- Application to start: LibreOffice Writer in
|
||||||
|
http://www.phoronix.com/scan.php?page=news_item&px=Linux-4.13-IO-Laptop
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Tested-by: Mirko Montanari <mirkomontanari91@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 50 +++++++++++++++++++++++++++++++-------------------
|
||||||
|
1 file changed, 31 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index a4783da90ba8..c25955c25e03 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -1202,6 +1202,24 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
|
||||||
|
return dur;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Return the farthest future time instant according to jiffies
|
||||||
|
+ * macros.
|
||||||
|
+ */
|
||||||
|
+static unsigned long bfq_greatest_from_now(void)
|
||||||
|
+{
|
||||||
|
+ return jiffies + MAX_JIFFY_OFFSET;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Return the farthest past time instant according to jiffies
|
||||||
|
+ * macros.
|
||||||
|
+ */
|
||||||
|
+static unsigned long bfq_smallest_from_now(void)
|
||||||
|
+{
|
||||||
|
+ return jiffies - MAX_JIFFY_OFFSET;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd,
|
||||||
|
struct bfq_queue *bfqq,
|
||||||
|
unsigned int old_wr_coeff,
|
||||||
|
@@ -1216,7 +1234,19 @@ static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd,
|
||||||
|
bfqq->wr_coeff = bfqd->bfq_wr_coeff;
|
||||||
|
bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
|
||||||
|
} else {
|
||||||
|
- bfqq->wr_start_at_switch_to_srt = jiffies;
|
||||||
|
+ /*
|
||||||
|
+ * No interactive weight raising in progress
|
||||||
|
+ * here: assign minus infinity to
|
||||||
|
+ * wr_start_at_switch_to_srt, to make sure
|
||||||
|
+ * that, at the end of the soft-real-time
|
||||||
|
+ * weight raising periods that is starting
|
||||||
|
+ * now, no interactive weight-raising period
|
||||||
|
+ * may be wrongly considered as still in
|
||||||
|
+ * progress (and thus actually started by
|
||||||
|
+ * mistake).
|
||||||
|
+ */
|
||||||
|
+ bfqq->wr_start_at_switch_to_srt =
|
||||||
|
+ bfq_smallest_from_now();
|
||||||
|
bfqq->wr_coeff = bfqd->bfq_wr_coeff *
|
||||||
|
BFQ_SOFTRT_WEIGHT_FACTOR;
|
||||||
|
bfqq->wr_cur_max_time =
|
||||||
|
@@ -2897,24 +2927,6 @@ static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
|
||||||
|
jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Return the farthest future time instant according to jiffies
|
||||||
|
- * macros.
|
||||||
|
- */
|
||||||
|
-static unsigned long bfq_greatest_from_now(void)
|
||||||
|
-{
|
||||||
|
- return jiffies + MAX_JIFFY_OFFSET;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * Return the farthest past time instant according to jiffies
|
||||||
|
- * macros.
|
||||||
|
- */
|
||||||
|
-static unsigned long bfq_smallest_from_now(void)
|
||||||
|
-{
|
||||||
|
- return jiffies - MAX_JIFFY_OFFSET;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* bfq_bfqq_expire - expire a queue.
|
||||||
|
* @bfqd: device owning the queue.
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
From f0ba5ea2fe45c0ad24a7dedae84a97f7aa046494 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Wed, 20 Dec 2017 17:27:36 +0100
|
||||||
|
Subject: [PATCH] block, bfq: increase threshold to deem I/O as random
|
||||||
|
|
||||||
|
If two processes do I/O close to each other, i.e., are cooperating
|
||||||
|
processes in BFQ (and CFQ'S) nomenclature, then BFQ merges their
|
||||||
|
associated bfq_queues, so as to get sequential I/O from the union of
|
||||||
|
the I/O requests of the processes, and thus reach a higher
|
||||||
|
throughput. A merged queue is then split if its I/O stops being
|
||||||
|
sequential. In this respect, BFQ deems the I/O of a bfq_queue as
|
||||||
|
(mostly) sequential only if less than 4 I/O requests are random, out
|
||||||
|
of the last 32 requests inserted into the queue.
|
||||||
|
|
||||||
|
Unfortunately, extensive testing (with the interleaved_io benchmark of
|
||||||
|
the S suite [1], and with real applications spawning cooperating
|
||||||
|
processes) has clearly shown that, with such a low threshold, only a
|
||||||
|
rather low I/O throughput may be reached when several cooperating
|
||||||
|
processes do I/O. In particular, the outcome of each test run was
|
||||||
|
bimodal: if queue merging occurred and was stable during the test,
|
||||||
|
then the throughput was close to the peak rate of the storage device,
|
||||||
|
otherwise the throughput was arbitrarily low (usually around 1/10 of
|
||||||
|
the peak rate with a rotational device). The probability to get the
|
||||||
|
unlucky outcomes grew with the number of cooperating processes: it was
|
||||||
|
already significant with 5 processes, and close to one with 7 or more
|
||||||
|
processes.
|
||||||
|
|
||||||
|
The cause of the low throughput in the unlucky runs was that the
|
||||||
|
merged queues containing the I/O of these cooperating processes were
|
||||||
|
soon split, because they contained more random I/O requests than those
|
||||||
|
tolerated by the 4/32 threshold, but
|
||||||
|
- that I/O would have however allowed the storage device to reach
|
||||||
|
peak throughput or almost peak throughput;
|
||||||
|
- in contrast, the I/O of these processes, if served individually
|
||||||
|
(from separate queues) yielded a rather low throughput.
|
||||||
|
|
||||||
|
So we repeated our tests with increasing values of the threshold,
|
||||||
|
until we found the minimum value (19) for which we obtained maximum
|
||||||
|
throughput, reliably, with at least up to 9 cooperating
|
||||||
|
processes. Then we checked that the use of that higher threshold value
|
||||||
|
did not cause any regression for any other benchmark in the suite [1].
|
||||||
|
This commit raises the threshold to such a higher value.
|
||||||
|
|
||||||
|
[1] https://github.com/Algodev-github/S
|
||||||
|
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index bcb6d21baf12..0f48583b9380 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -178,7 +178,7 @@ static struct kmem_cache *bfq_pool;
|
||||||
|
#define BFQQ_SEEK_THR (sector_t)(8 * 100)
|
||||||
|
#define BFQQ_SECT_THR_NONROT (sector_t)(2 * 32)
|
||||||
|
#define BFQQ_CLOSE_THR (sector_t)(8 * 1024)
|
||||||
|
-#define BFQQ_SEEKY(bfqq) (hweight32(bfqq->seek_history) > 32/8)
|
||||||
|
+#define BFQQ_SEEKY(bfqq) (hweight32(bfqq->seek_history) > 19)
|
||||||
|
|
||||||
|
/* Min number of samples required to perform peak-rate update */
|
||||||
|
#define BFQ_RATE_MIN_SAMPLES 32
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
From 8abef10b3de1144cfe968f454946f13eb1ac3d0a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jens Axboe <axboe@kernel.dk>
|
||||||
|
Date: Tue, 9 Jan 2018 12:20:51 -0700
|
||||||
|
Subject: [PATCH] bfq-iosched: don't call bfqg_and_blkg_put for
|
||||||
|
!CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
|
||||||
|
It's not available if we don't have group io scheduling set, and
|
||||||
|
there's no need to call it.
|
||||||
|
|
||||||
|
Fixes: 0d52af590552 ("block, bfq: release oom-queue ref to root group on exit")
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 7c0b7f60811c..5e6f837f663e 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -4893,10 +4893,10 @@ static void bfq_exit_queue(struct elevator_queue *e)
|
||||||
|
|
||||||
|
hrtimer_cancel(&bfqd->idle_slice_timer);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
/* release oom-queue reference to root group */
|
||||||
|
bfqg_and_blkg_put(bfqd->root_group);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
blkcg_deactivate_policy(bfqd->queue, &blkcg_policy_bfq);
|
||||||
|
#else
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
+186
@@ -0,0 +1,186 @@
|
|||||||
|
From 7b8fa3b900a087bc03b11329a92398fde563ba37 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Wed, 20 Dec 2017 12:38:33 +0100
|
||||||
|
Subject: [PATCH] block, bfq: let a queue be merged only shortly after starting
|
||||||
|
I/O
|
||||||
|
|
||||||
|
In BFQ and CFQ, two processes are said to be cooperating if they do
|
||||||
|
I/O in such a way that the union of their I/O requests yields a
|
||||||
|
sequential I/O pattern. To get such a sequential I/O pattern out of
|
||||||
|
the non-sequential pattern of each cooperating process, BFQ and CFQ
|
||||||
|
merge the queues associated with these processes. In more detail,
|
||||||
|
cooperating processes, and thus their associated queues, usually
|
||||||
|
start, or restart, to do I/O shortly after each other. This is the
|
||||||
|
case, e.g., for the I/O threads of KVM/QEMU and of the dump
|
||||||
|
utility. Basing on this assumption, this commit allows a bfq_queue to
|
||||||
|
be merged only during a short time interval (100ms) after it starts,
|
||||||
|
or re-starts, to do I/O. This filtering provides two important
|
||||||
|
benefits.
|
||||||
|
|
||||||
|
First, it greatly reduces the probability that two non-cooperating
|
||||||
|
processes have their queues merged by mistake, if they just happen to
|
||||||
|
do I/O close to each other for a short time interval. These spurious
|
||||||
|
merges cause loss of service guarantees. A low-weight bfq_queue may
|
||||||
|
unjustly get more than its expected share of the throughput: if such a
|
||||||
|
low-weight queue is merged with a high-weight queue, then the I/O for
|
||||||
|
the low-weight queue is served as if the queue had a high weight. This
|
||||||
|
may damage other high-weight queues unexpectedly. For instance,
|
||||||
|
because of this issue, lxterminal occasionally took 7.5 seconds to
|
||||||
|
start, instead of 6.5 seconds, when some sequential readers and
|
||||||
|
writers did I/O in the background on a FUJITSU MHX2300BT HDD. The
|
||||||
|
reason is that the bfq_queues associated with some of the readers or
|
||||||
|
the writers were merged with the high-weight queues of some processes
|
||||||
|
that had to do some urgent but little I/O. The readers then exploited
|
||||||
|
the inherited high weight for all or most of their I/O, during the
|
||||||
|
start-up of terminal. The filtering introduced by this commit
|
||||||
|
eliminated any outlier caused by spurious queue merges in our start-up
|
||||||
|
time tests.
|
||||||
|
|
||||||
|
This filtering also provides a little boost of the throughput
|
||||||
|
sustainable by BFQ: 3-4%, depending on the CPU. The reason is that,
|
||||||
|
once a bfq_queue cannot be merged any longer, this commit makes BFQ
|
||||||
|
stop updating the data needed to handle merging for the queue.
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----------
|
||||||
|
block/bfq-iosched.h | 2 ++
|
||||||
|
block/bfq-wf2q.c | 4 ++++
|
||||||
|
3 files changed, 52 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 2cf395daee80..7066d90f09df 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -166,6 +166,20 @@ static const int bfq_async_charge_factor = 10;
|
||||||
|
/* Default timeout values, in jiffies, approximating CFQ defaults. */
|
||||||
|
const int bfq_timeout = HZ / 8;
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Time limit for merging (see comments in bfq_setup_cooperator). Set
|
||||||
|
+ * to the slowest value that, in our tests, proved to be effective in
|
||||||
|
+ * removing false positives, while not causing true positives to miss
|
||||||
|
+ * queue merging.
|
||||||
|
+ *
|
||||||
|
+ * As can be deduced from the low time limit below, queue merging, if
|
||||||
|
+ * successful, happens at the very beggining of the I/O of the involved
|
||||||
|
+ * cooperating processes, as a consequence of the arrival of the very
|
||||||
|
+ * first requests from each cooperator. After that, there is very
|
||||||
|
+ * little chance to find cooperators.
|
||||||
|
+ */
|
||||||
|
+static const unsigned long bfq_merge_time_limit = HZ/10;
|
||||||
|
+
|
||||||
|
static struct kmem_cache *bfq_pool;
|
||||||
|
|
||||||
|
/* Below this threshold (in ns), we consider thinktime immediate. */
|
||||||
|
@@ -444,6 +458,13 @@ bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
|
||||||
|
return bfqq;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool bfq_too_late_for_merging(struct bfq_queue *bfqq)
|
||||||
|
+{
|
||||||
|
+ return bfqq->service_from_backlogged > 0 &&
|
||||||
|
+ time_is_before_jiffies(bfqq->first_IO_time +
|
||||||
|
+ bfq_merge_time_limit);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||||
|
{
|
||||||
|
struct rb_node **p, *parent;
|
||||||
|
@@ -454,6 +475,14 @@ void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||||
|
bfqq->pos_root = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * bfqq cannot be merged any longer (see comments in
|
||||||
|
+ * bfq_setup_cooperator): no point in adding bfqq into the
|
||||||
|
+ * position tree.
|
||||||
|
+ */
|
||||||
|
+ if (bfq_too_late_for_merging(bfqq))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (bfq_class_idle(bfqq))
|
||||||
|
return;
|
||||||
|
if (!bfqq->next_rq)
|
||||||
|
@@ -1935,6 +1964,9 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
|
||||||
|
static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
|
||||||
|
struct bfq_queue *new_bfqq)
|
||||||
|
{
|
||||||
|
+ if (bfq_too_late_for_merging(new_bfqq))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (bfq_class_idle(bfqq) || bfq_class_idle(new_bfqq) ||
|
||||||
|
(bfqq->ioprio_class != new_bfqq->ioprio_class))
|
||||||
|
return false;
|
||||||
|
@@ -2003,6 +2035,20 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
{
|
||||||
|
struct bfq_queue *in_service_bfqq, *new_bfqq;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Prevent bfqq from being merged if it has been created too
|
||||||
|
+ * long ago. The idea is that true cooperating processes, and
|
||||||
|
+ * thus their associated bfq_queues, are supposed to be
|
||||||
|
+ * created shortly after each other. This is the case, e.g.,
|
||||||
|
+ * for KVM/QEMU and dump I/O threads. Basing on this
|
||||||
|
+ * assumption, the following filtering greatly reduces the
|
||||||
|
+ * probability that two non-cooperating processes, which just
|
||||||
|
+ * happen to do close I/O for some short time interval, have
|
||||||
|
+ * their queues merged by mistake.
|
||||||
|
+ */
|
||||||
|
+ if (bfq_too_late_for_merging(bfqq))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
if (bfqq->new_bfqq)
|
||||||
|
return bfqq->new_bfqq;
|
||||||
|
|
||||||
|
@@ -3002,17 +3048,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
|
||||||
|
*/
|
||||||
|
slow = bfq_bfqq_is_slow(bfqd, bfqq, compensate, reason, &delta);
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Increase service_from_backlogged before next statement,
|
||||||
|
- * because the possible next invocation of
|
||||||
|
- * bfq_bfqq_charge_time would likely inflate
|
||||||
|
- * entity->service. In contrast, service_from_backlogged must
|
||||||
|
- * contain real service, to enable the soft real-time
|
||||||
|
- * heuristic to correctly compute the bandwidth consumed by
|
||||||
|
- * bfqq.
|
||||||
|
- */
|
||||||
|
- bfqq->service_from_backlogged += entity->service;
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* As above explained, charge slow (typically seeky) and
|
||||||
|
* timed-out queues with the time and not the service
|
||||||
|
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
|
||||||
|
index 91c4390903a1..5d47b58d5fc8 100644
|
||||||
|
--- a/block/bfq-iosched.h
|
||||||
|
+++ b/block/bfq-iosched.h
|
||||||
|
@@ -344,6 +344,8 @@ struct bfq_queue {
|
||||||
|
unsigned long wr_start_at_switch_to_srt;
|
||||||
|
|
||||||
|
unsigned long split_time; /* time of last split */
|
||||||
|
+
|
||||||
|
+ unsigned long first_IO_time; /* time of first I/O for this queue */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
|
||||||
|
index e495d3f9b4b0..4456eda34e48 100644
|
||||||
|
--- a/block/bfq-wf2q.c
|
||||||
|
+++ b/block/bfq-wf2q.c
|
||||||
|
@@ -835,6 +835,10 @@ void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||||
|
struct bfq_entity *entity = &bfqq->entity;
|
||||||
|
struct bfq_service_tree *st;
|
||||||
|
|
||||||
|
+ if (!bfqq->service_from_backlogged)
|
||||||
|
+ bfqq->first_IO_time = jiffies;
|
||||||
|
+
|
||||||
|
+ bfqq->service_from_backlogged += served;
|
||||||
|
for_each_entity(entity) {
|
||||||
|
st = bfq_entity_service_tree(entity);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
From 894df937e06a56ed6f054a75a416aff84147c5a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Thu, 21 Sep 2017 11:04:02 +0200
|
||||||
|
Subject: [PATCH] block, bfq: let early-merged queues be weight-raised on split
|
||||||
|
too
|
||||||
|
|
||||||
|
A just-created bfq_queue, say Q, may happen to be merged with another
|
||||||
|
bfq_queue on the very first invocation of the function
|
||||||
|
__bfq_insert_request. In such a case, even if Q would clearly deserve
|
||||||
|
interactive weight raising (as it has just been created), the function
|
||||||
|
bfq_add_request does not make it to be invoked for Q, and thus to
|
||||||
|
activate weight raising for Q. As a consequence, when the state of Q
|
||||||
|
is saved for a possible future restore, after a split of Q from the
|
||||||
|
other bfq_queue(s), such a state happens to be (unjustly)
|
||||||
|
non-weight-raised. Then the bfq_queue will not enjoy any weight
|
||||||
|
raising on the split, even if should still be in an interactive
|
||||||
|
weight-raising period when the split occurs.
|
||||||
|
|
||||||
|
This commit solves this problem as follows, for a just-created
|
||||||
|
bfq_queue that is being early-merged: it stores directly, in the saved
|
||||||
|
state of the bfq_queue, the weight-raising state that would have been
|
||||||
|
assigned to the bfq_queue if not early-merged.
|
||||||
|
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Tested-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Tested-by: Mirko Montanari <mirkomontanari91@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 28 +++++++++++++++++++++++-----
|
||||||
|
1 file changed, 23 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 33b63bc4a64b..115747fe43c8 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -2061,10 +2061,27 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
|
||||||
|
bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
|
||||||
|
bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
|
||||||
|
bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
|
||||||
|
- bic->saved_wr_coeff = bfqq->wr_coeff;
|
||||||
|
- bic->saved_wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt;
|
||||||
|
- bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish;
|
||||||
|
- bic->saved_wr_cur_max_time = bfqq->wr_cur_max_time;
|
||||||
|
+ if (unlikely(bfq_bfqq_just_created(bfqq) &&
|
||||||
|
+ !bfq_bfqq_in_large_burst(bfqq))) {
|
||||||
|
+ /*
|
||||||
|
+ * bfqq being merged right after being created: bfqq
|
||||||
|
+ * would have deserved interactive weight raising, but
|
||||||
|
+ * did not make it to be set in a weight-raised state,
|
||||||
|
+ * because of this early merge. Store directly the
|
||||||
|
+ * weight-raising state that would have been assigned
|
||||||
|
+ * to bfqq, so that to avoid that bfqq unjustly fails
|
||||||
|
+ * to enjoy weight raising if split soon.
|
||||||
|
+ */
|
||||||
|
+ bic->saved_wr_coeff = bfqq->bfqd->bfq_wr_coeff;
|
||||||
|
+ bic->saved_wr_cur_max_time = bfq_wr_duration(bfqq->bfqd);
|
||||||
|
+ bic->saved_last_wr_start_finish = jiffies;
|
||||||
|
+ } else {
|
||||||
|
+ bic->saved_wr_coeff = bfqq->wr_coeff;
|
||||||
|
+ bic->saved_wr_start_at_switch_to_srt =
|
||||||
|
+ bfqq->wr_start_at_switch_to_srt;
|
||||||
|
+ bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish;
|
||||||
|
+ bic->saved_wr_cur_max_time = bfqq->wr_cur_max_time;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -4150,7 +4167,6 @@ static void __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
new_bfqq->allocated++;
|
||||||
|
bfqq->allocated--;
|
||||||
|
new_bfqq->ref++;
|
||||||
|
- bfq_clear_bfqq_just_created(bfqq);
|
||||||
|
/*
|
||||||
|
* If the bic associated with the process
|
||||||
|
* issuing this request still points to bfqq
|
||||||
|
@@ -4162,6 +4178,8 @@ static void __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
|
||||||
|
bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
|
||||||
|
bfqq, new_bfqq);
|
||||||
|
+
|
||||||
|
+ bfq_clear_bfqq_just_created(bfqq);
|
||||||
|
/*
|
||||||
|
* rq is about to be enqueued into new_bfqq,
|
||||||
|
* release rq reference on bfqq
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+202
@@ -0,0 +1,202 @@
|
|||||||
|
From 8a8747dc01cee6f92a52c03ba686e9f60cb46c87 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Sat, 13 Jan 2018 12:05:18 +0100
|
||||||
|
Subject: [PATCH] block, bfq: limit sectors served with interactive weight
|
||||||
|
raising
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
To maximise responsiveness, BFQ raises the weight, and performs device
|
||||||
|
idling, for bfq_queues associated with processes deemed as
|
||||||
|
interactive. In particular, weight raising has a maximum duration,
|
||||||
|
equal to the time needed to start a large application. If a
|
||||||
|
weight-raised process goes on doing I/O beyond this maximum duration,
|
||||||
|
it loses weight-raising.
|
||||||
|
|
||||||
|
This mechanism is evidently vulnerable to the following false
|
||||||
|
positives: I/O-bound applications that will go on doing I/O for much
|
||||||
|
longer than the duration of weight-raising. These applications have
|
||||||
|
basically no benefit from being weight-raised at the beginning of
|
||||||
|
their I/O. On the opposite end, while being weight-raised, these
|
||||||
|
applications
|
||||||
|
a) unjustly steal throughput to applications that may truly need
|
||||||
|
low latency;
|
||||||
|
b) make BFQ uselessly perform device idling; device idling results
|
||||||
|
in loss of device throughput with most flash-based storage, and may
|
||||||
|
increase latencies when used purposelessly.
|
||||||
|
|
||||||
|
This commit adds a countermeasure to reduce both the above
|
||||||
|
problems. To introduce this countermeasure, we provide the following
|
||||||
|
extra piece of information (full details in the comments added by this
|
||||||
|
commit). During the start-up of the large application used as a
|
||||||
|
reference to set the duration of weight-raising, involved processes
|
||||||
|
transfer at most ~110K sectors each. Accordingly, a process initially
|
||||||
|
deemed as interactive has no right to be weight-raised any longer,
|
||||||
|
once transferred 110K sectors or more.
|
||||||
|
|
||||||
|
Basing on this consideration, this commit early-ends weight-raising
|
||||||
|
for a bfq_queue if the latter happens to have received an amount of
|
||||||
|
service at least equal to 110K sectors (actually, a little bit more,
|
||||||
|
to keep a safety margin). I/O-bound applications that reach a high
|
||||||
|
throughput, such as file copy, get to this threshold much before the
|
||||||
|
allowed weight-raising period finishes. Thus this early ending of
|
||||||
|
weight-raising reduces the amount of time during which these
|
||||||
|
applications cause the problems described above.
|
||||||
|
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
block/bfq-iosched.h | 5 ++++
|
||||||
|
block/bfq-wf2q.c | 3 ++
|
||||||
|
3 files changed, 80 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index a7ab0cb50733..47e6ec7427c4 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -209,15 +209,17 @@ static struct kmem_cache *bfq_pool;
|
||||||
|
* interactive applications automatically, using the following formula:
|
||||||
|
* duration = (R / r) * T, where r is the peak rate of the device, and
|
||||||
|
* R and T are two reference parameters.
|
||||||
|
- * In particular, R is the peak rate of the reference device (see below),
|
||||||
|
- * and T is a reference time: given the systems that are likely to be
|
||||||
|
- * installed on the reference device according to its speed class, T is
|
||||||
|
- * about the maximum time needed, under BFQ and while reading two files in
|
||||||
|
- * parallel, to load typical large applications on these systems.
|
||||||
|
- * In practice, the slower/faster the device at hand is, the more/less it
|
||||||
|
- * takes to load applications with respect to the reference device.
|
||||||
|
- * Accordingly, the longer/shorter BFQ grants weight raising to interactive
|
||||||
|
- * applications.
|
||||||
|
+ * In particular, R is the peak rate of the reference device (see
|
||||||
|
+ * below), and T is a reference time: given the systems that are
|
||||||
|
+ * likely to be installed on the reference device according to its
|
||||||
|
+ * speed class, T is about the maximum time needed, under BFQ and
|
||||||
|
+ * while reading two files in parallel, to load typical large
|
||||||
|
+ * applications on these systems (see the comments on
|
||||||
|
+ * max_service_from_wr below, for more details on how T is obtained).
|
||||||
|
+ * In practice, the slower/faster the device at hand is, the more/less
|
||||||
|
+ * it takes to load applications with respect to the reference device.
|
||||||
|
+ * Accordingly, the longer/shorter BFQ grants weight raising to
|
||||||
|
+ * interactive applications.
|
||||||
|
*
|
||||||
|
* BFQ uses four different reference pairs (R, T), depending on:
|
||||||
|
* . whether the device is rotational or non-rotational;
|
||||||
|
@@ -254,6 +256,60 @@ static int T_slow[2];
|
||||||
|
static int T_fast[2];
|
||||||
|
static int device_speed_thresh[2];
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * BFQ uses the above-detailed, time-based weight-raising mechanism to
|
||||||
|
+ * privilege interactive tasks. This mechanism is vulnerable to the
|
||||||
|
+ * following false positives: I/O-bound applications that will go on
|
||||||
|
+ * doing I/O for much longer than the duration of weight
|
||||||
|
+ * raising. These applications have basically no benefit from being
|
||||||
|
+ * weight-raised at the beginning of their I/O. On the opposite end,
|
||||||
|
+ * while being weight-raised, these applications
|
||||||
|
+ * a) unjustly steal throughput to applications that may actually need
|
||||||
|
+ * low latency;
|
||||||
|
+ * b) make BFQ uselessly perform device idling; device idling results
|
||||||
|
+ * in loss of device throughput with most flash-based storage, and may
|
||||||
|
+ * increase latencies when used purposelessly.
|
||||||
|
+ *
|
||||||
|
+ * BFQ tries to reduce these problems, by adopting the following
|
||||||
|
+ * countermeasure. To introduce this countermeasure, we need first to
|
||||||
|
+ * finish explaining how the duration of weight-raising for
|
||||||
|
+ * interactive tasks is computed.
|
||||||
|
+ *
|
||||||
|
+ * For a bfq_queue deemed as interactive, the duration of weight
|
||||||
|
+ * raising is dynamically adjusted, as a function of the estimated
|
||||||
|
+ * peak rate of the device, so as to be equal to the time needed to
|
||||||
|
+ * execute the 'largest' interactive task we benchmarked so far. By
|
||||||
|
+ * largest task, we mean the task for which each involved process has
|
||||||
|
+ * to do more I/O than for any of the other tasks we benchmarked. This
|
||||||
|
+ * reference interactive task is the start-up of LibreOffice Writer,
|
||||||
|
+ * and in this task each process/bfq_queue needs to have at most ~110K
|
||||||
|
+ * sectors transferred.
|
||||||
|
+ *
|
||||||
|
+ * This last piece of information enables BFQ to reduce the actual
|
||||||
|
+ * duration of weight-raising for at least one class of I/O-bound
|
||||||
|
+ * applications: those doing sequential or quasi-sequential I/O. An
|
||||||
|
+ * example is file copy. In fact, once started, the main I/O-bound
|
||||||
|
+ * processes of these applications usually consume the above 110K
|
||||||
|
+ * sectors in much less time than the processes of an application that
|
||||||
|
+ * is starting, because these I/O-bound processes will greedily devote
|
||||||
|
+ * almost all their CPU cycles only to their target,
|
||||||
|
+ * throughput-friendly I/O operations. This is even more true if BFQ
|
||||||
|
+ * happens to be underestimating the device peak rate, and thus
|
||||||
|
+ * overestimating the duration of weight raising. But, according to
|
||||||
|
+ * our measurements, once transferred 110K sectors, these processes
|
||||||
|
+ * have no right to be weight-raised any longer.
|
||||||
|
+ *
|
||||||
|
+ * Basing on the last consideration, BFQ ends weight-raising for a
|
||||||
|
+ * bfq_queue if the latter happens to have received an amount of
|
||||||
|
+ * service at least equal to the following constant. The constant is
|
||||||
|
+ * set to slightly more than 110K, to have a minimum safety margin.
|
||||||
|
+ *
|
||||||
|
+ * This early ending of weight-raising reduces the amount of time
|
||||||
|
+ * during which interactive false positives cause the two problems
|
||||||
|
+ * described at the beginning of these comments.
|
||||||
|
+ */
|
||||||
|
+static const unsigned long max_service_from_wr = 120000;
|
||||||
|
+
|
||||||
|
#define RQ_BIC(rq) icq_to_bic((rq)->elv.priv[0])
|
||||||
|
#define RQ_BFQQ(rq) ((rq)->elv.priv[1])
|
||||||
|
|
||||||
|
@@ -1352,6 +1408,7 @@ static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd,
|
||||||
|
if (old_wr_coeff == 1 && wr_or_deserves_wr) {
|
||||||
|
/* start a weight-raising period */
|
||||||
|
if (interactive) {
|
||||||
|
+ bfqq->service_from_wr = 0;
|
||||||
|
bfqq->wr_coeff = bfqd->bfq_wr_coeff;
|
||||||
|
bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
|
||||||
|
} else {
|
||||||
|
@@ -3665,6 +3722,12 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
|
||||||
|
bfqq->entity.prio_changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (bfqq->wr_coeff > 1 &&
|
||||||
|
+ bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time &&
|
||||||
|
+ bfqq->service_from_wr > max_service_from_wr) {
|
||||||
|
+ /* see comments on max_service_from_wr */
|
||||||
|
+ bfq_bfqq_end_wr(bfqq);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* To improve latency (for this or other queues), immediately
|
||||||
|
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
|
||||||
|
index fcd941008127..350c39ae2896 100644
|
||||||
|
--- a/block/bfq-iosched.h
|
||||||
|
+++ b/block/bfq-iosched.h
|
||||||
|
@@ -337,6 +337,11 @@ struct bfq_queue {
|
||||||
|
* last transition from idle to backlogged.
|
||||||
|
*/
|
||||||
|
unsigned long service_from_backlogged;
|
||||||
|
+ /*
|
||||||
|
+ * Cumulative service received from the @bfq_queue since its
|
||||||
|
+ * last transition to weight-raised state.
|
||||||
|
+ */
|
||||||
|
+ unsigned long service_from_wr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Value of wr start time when switching to soft rt
|
||||||
|
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
|
||||||
|
index 4456eda34e48..4498c43245e2 100644
|
||||||
|
--- a/block/bfq-wf2q.c
|
||||||
|
+++ b/block/bfq-wf2q.c
|
||||||
|
@@ -838,6 +838,9 @@ void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||||
|
if (!bfqq->service_from_backlogged)
|
||||||
|
bfqq->first_IO_time = jiffies;
|
||||||
|
|
||||||
|
+ if (bfqq->wr_coeff > 1)
|
||||||
|
+ bfqq->service_from_wr += served;
|
||||||
|
+
|
||||||
|
bfqq->service_from_backlogged += served;
|
||||||
|
for_each_entity(entity) {
|
||||||
|
st = bfq_entity_service_tree(entity);
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
From a52a69ea89dc12e6f4572f554940789c1ab23c7a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Sat, 13 Jan 2018 12:05:17 +0100
|
||||||
|
Subject: [PATCH] block, bfq: limit tags for writes and async I/O
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Asynchronous I/O can easily starve synchronous I/O (both sync reads
|
||||||
|
and sync writes), by consuming all request tags. Similarly, storms of
|
||||||
|
synchronous writes, such as those that sync(2) may trigger, can starve
|
||||||
|
synchronous reads. In their turn, these two problems may also cause
|
||||||
|
BFQ to loose control on latency for interactive and soft real-time
|
||||||
|
applications. For example, on a PLEXTOR PX-256M5S SSD, LibreOffice
|
||||||
|
Writer takes 0.6 seconds to start if the device is idle, but it takes
|
||||||
|
more than 45 seconds (!) if there are sequential writes in the
|
||||||
|
background.
|
||||||
|
|
||||||
|
This commit addresses this issue by limiting the maximum percentage of
|
||||||
|
tags that asynchronous I/O requests and synchronous write requests can
|
||||||
|
consume. In particular, this commit grants a higher threshold to
|
||||||
|
synchronous writes, to prevent the latter from being starved by
|
||||||
|
asynchronous I/O.
|
||||||
|
|
||||||
|
According to the above test, LibreOffice Writer now starts in about
|
||||||
|
1.2 seconds on average, regardless of the background workload, and
|
||||||
|
apart from some rare outlier. To check this improvement, run, e.g.,
|
||||||
|
sudo ./comm_startup_lat.sh bfq 5 5 seq 10 "lowriter --terminate_after_init"
|
||||||
|
for the comm_startup_lat benchmark in the S suite [1].
|
||||||
|
|
||||||
|
[1] https://github.com/Algodev-github/S
|
||||||
|
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
block/bfq-iosched.h | 12 +++++++++
|
||||||
|
2 files changed, 89 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index f352b1677143..a7ab0cb50733 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -417,6 +417,82 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * See the comments on bfq_limit_depth for the purpose of
|
||||||
|
+ * the depths set in the function.
|
||||||
|
+ */
|
||||||
|
+static void bfq_update_depths(struct bfq_data *bfqd, struct sbitmap_queue *bt)
|
||||||
|
+{
|
||||||
|
+ bfqd->sb_shift = bt->sb.shift;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * In-word depths if no bfq_queue is being weight-raised:
|
||||||
|
+ * leaving 25% of tags only for sync reads.
|
||||||
|
+ *
|
||||||
|
+ * In next formulas, right-shift the value
|
||||||
|
+ * (1U<<bfqd->sb_shift), instead of computing directly
|
||||||
|
+ * (1U<<(bfqd->sb_shift - something)), to be robust against
|
||||||
|
+ * any possible value of bfqd->sb_shift, without having to
|
||||||
|
+ * limit 'something'.
|
||||||
|
+ */
|
||||||
|
+ /* no more than 50% of tags for async I/O */
|
||||||
|
+ bfqd->word_depths[0][0] = max((1U<<bfqd->sb_shift)>>1, 1U);
|
||||||
|
+ /*
|
||||||
|
+ * no more than 75% of tags for sync writes (25% extra tags
|
||||||
|
+ * w.r.t. async I/O, to prevent async I/O from starving sync
|
||||||
|
+ * writes)
|
||||||
|
+ */
|
||||||
|
+ bfqd->word_depths[0][1] = max(((1U<<bfqd->sb_shift) * 3)>>2, 1U);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * In-word depths in case some bfq_queue is being weight-
|
||||||
|
+ * raised: leaving ~63% of tags for sync reads. This is the
|
||||||
|
+ * highest percentage for which, in our tests, application
|
||||||
|
+ * start-up times didn't suffer from any regression due to tag
|
||||||
|
+ * shortage.
|
||||||
|
+ */
|
||||||
|
+ /* no more than ~18% of tags for async I/O */
|
||||||
|
+ bfqd->word_depths[1][0] = max(((1U<<bfqd->sb_shift) * 3)>>4, 1U);
|
||||||
|
+ /* no more than ~37% of tags for sync writes (~20% extra tags) */
|
||||||
|
+ bfqd->word_depths[1][1] = max(((1U<<bfqd->sb_shift) * 6)>>4, 1U);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Async I/O can easily starve sync I/O (both sync reads and sync
|
||||||
|
+ * writes), by consuming all tags. Similarly, storms of sync writes,
|
||||||
|
+ * such as those that sync(2) may trigger, can starve sync reads.
|
||||||
|
+ * Limit depths of async I/O and sync writes so as to counter both
|
||||||
|
+ * problems.
|
||||||
|
+ */
|
||||||
|
+static void bfq_limit_depth(unsigned int op, struct blk_mq_alloc_data *data)
|
||||||
|
+{
|
||||||
|
+ struct blk_mq_tags *tags = blk_mq_tags_from_data(data);
|
||||||
|
+ struct bfq_data *bfqd = data->q->elevator->elevator_data;
|
||||||
|
+ struct sbitmap_queue *bt;
|
||||||
|
+
|
||||||
|
+ if (op_is_sync(op) && !op_is_write(op))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (data->flags & BLK_MQ_REQ_RESERVED) {
|
||||||
|
+ if (unlikely(!tags->nr_reserved_tags)) {
|
||||||
|
+ WARN_ON_ONCE(1);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ bt = &tags->breserved_tags;
|
||||||
|
+ } else
|
||||||
|
+ bt = &tags->bitmap_tags;
|
||||||
|
+
|
||||||
|
+ if (unlikely(bfqd->sb_shift != bt->sb.shift))
|
||||||
|
+ bfq_update_depths(bfqd, bt);
|
||||||
|
+
|
||||||
|
+ data->shallow_depth =
|
||||||
|
+ bfqd->word_depths[!!bfqd->wr_busy_queues][op_is_sync(op)];
|
||||||
|
+
|
||||||
|
+ bfq_log(bfqd, "[%s] wr_busy %d sync %d depth %u",
|
||||||
|
+ __func__, bfqd->wr_busy_queues, op_is_sync(op),
|
||||||
|
+ data->shallow_depth);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct bfq_queue *
|
||||||
|
bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
|
||||||
|
sector_t sector, struct rb_node **ret_parent,
|
||||||
|
@@ -5285,6 +5361,7 @@ static struct elv_fs_entry bfq_attrs[] = {
|
||||||
|
|
||||||
|
static struct elevator_type iosched_bfq_mq = {
|
||||||
|
.ops.mq = {
|
||||||
|
+ .limit_depth = bfq_limit_depth,
|
||||||
|
.prepare_request = bfq_prepare_request,
|
||||||
|
.finish_request = bfq_finish_request,
|
||||||
|
.exit_icq = bfq_exit_icq,
|
||||||
|
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
|
||||||
|
index 5d47b58d5fc8..fcd941008127 100644
|
||||||
|
--- a/block/bfq-iosched.h
|
||||||
|
+++ b/block/bfq-iosched.h
|
||||||
|
@@ -629,6 +629,18 @@ struct bfq_data {
|
||||||
|
struct bfq_io_cq *bio_bic;
|
||||||
|
/* bfqq associated with the task issuing current bio for merging */
|
||||||
|
struct bfq_queue *bio_bfqq;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Cached sbitmap shift, used to compute depth limits in
|
||||||
|
+ * bfq_update_depths.
|
||||||
|
+ */
|
||||||
|
+ unsigned int sb_shift;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Depth limits used in bfq_limit_depth (see comments on the
|
||||||
|
+ * function)
|
||||||
|
+ */
|
||||||
|
+ unsigned int word_depths[2][2];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bfqq_state_flags {
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
+467
@@ -0,0 +1,467 @@
|
|||||||
|
From a33801e8b4735b8d473f963e5854172f9cde3e8b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Date: Mon, 13 Nov 2017 07:34:10 +0100
|
||||||
|
Subject: [PATCH] block, bfq: move debug blkio stats behind
|
||||||
|
CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
|
||||||
|
BFQ currently creates, and updates, its own instance of the whole
|
||||||
|
set of blkio statistics that cfq creates. Yet, from the comments
|
||||||
|
of Tejun Heo in [1], it turned out that most of these statistics
|
||||||
|
are meant/useful only for debugging. This commit makes BFQ create
|
||||||
|
the latter, debugging statistics only if the option
|
||||||
|
CONFIG_DEBUG_BLK_CGROUP is set.
|
||||||
|
|
||||||
|
By doing so, this commit also enables BFQ to enjoy a high perfomance
|
||||||
|
boost. The reason is that, if CONFIG_DEBUG_BLK_CGROUP is not set, then
|
||||||
|
BFQ has to update far fewer statistics, and, in particular, not the
|
||||||
|
heaviest to update. To give an idea of the benefits, if
|
||||||
|
CONFIG_DEBUG_BLK_CGROUP is not set, then, on an Intel i7-4850HQ, and
|
||||||
|
with 8 threads doing random I/O in parallel on null_blk (configured
|
||||||
|
with 0 latency), the throughput of BFQ grows from 310 to 400 KIOPS
|
||||||
|
(+30%). We have measured similar or even much higher boosts with other
|
||||||
|
CPUs: e.g., +45% with an ARM CortexTM-A53 Octa-core. Our results have
|
||||||
|
been obtained and can be reproduced very easily with the script in [1].
|
||||||
|
|
||||||
|
[1] https://www.spinics.net/lists/linux-block/msg18943.html
|
||||||
|
|
||||||
|
Suggested-by: Tejun Heo <tj@kernel.org>
|
||||||
|
Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Signed-off-by: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
Documentation/block/bfq-iosched.txt | 38 +++++++--
|
||||||
|
block/bfq-cgroup.c | 148 ++++++++++++++++++++----------------
|
||||||
|
block/bfq-iosched.c | 14 ++--
|
||||||
|
block/bfq-iosched.h | 4 +-
|
||||||
|
4 files changed, 125 insertions(+), 79 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/block/bfq-iosched.txt b/Documentation/block/bfq-iosched.txt
|
||||||
|
index 7fad6c061470..8d8d8f06cab2 100644
|
||||||
|
--- a/Documentation/block/bfq-iosched.txt
|
||||||
|
+++ b/Documentation/block/bfq-iosched.txt
|
||||||
|
@@ -20,12 +20,22 @@ for that device, by setting low_latency to 0. See Section 3 for
|
||||||
|
details on how to configure BFQ for the desired tradeoff between
|
||||||
|
latency and throughput, or on how to maximize throughput.
|
||||||
|
|
||||||
|
-BFQ has a non-null overhead, which limits the maximum IOPS that the
|
||||||
|
-CPU can process for a device scheduled with BFQ. To give an idea of
|
||||||
|
-the limits on slow or average CPUs, here are BFQ limits for three
|
||||||
|
-different CPUs, on, respectively, an average laptop, an old desktop,
|
||||||
|
-and a cheap embedded system, in case full hierarchical support is
|
||||||
|
-enabled (i.e., CONFIG_BFQ_GROUP_IOSCHED is set):
|
||||||
|
+BFQ has a non-null overhead, which limits the maximum IOPS that a CPU
|
||||||
|
+can process for a device scheduled with BFQ. To give an idea of the
|
||||||
|
+limits on slow or average CPUs, here are, first, the limits of BFQ for
|
||||||
|
+three different CPUs, on, respectively, an average laptop, an old
|
||||||
|
+desktop, and a cheap embedded system, in case full hierarchical
|
||||||
|
+support is enabled (i.e., CONFIG_BFQ_GROUP_IOSCHED is set), but
|
||||||
|
+CONFIG_DEBUG_BLK_CGROUP is not set (Section 4-2):
|
||||||
|
+- Intel i7-4850HQ: 400 KIOPS
|
||||||
|
+- AMD A8-3850: 250 KIOPS
|
||||||
|
+- ARM CortexTM-A53 Octa-core: 80 KIOPS
|
||||||
|
+
|
||||||
|
+If CONFIG_DEBUG_BLK_CGROUP is set (and of course full hierarchical
|
||||||
|
+support is enabled), then the sustainable throughput with BFQ
|
||||||
|
+decreases, because all blkio.bfq* statistics are created and updated
|
||||||
|
+(Section 4-2). For BFQ, this leads to the following maximum
|
||||||
|
+sustainable throughputs, on the same systems as above:
|
||||||
|
- Intel i7-4850HQ: 310 KIOPS
|
||||||
|
- AMD A8-3850: 200 KIOPS
|
||||||
|
- ARM CortexTM-A53 Octa-core: 56 KIOPS
|
||||||
|
@@ -505,6 +515,22 @@ BFQ-specific files is "blkio.bfq." or "io.bfq." For example, the group
|
||||||
|
parameter to set the weight of a group with BFQ is blkio.bfq.weight
|
||||||
|
or io.bfq.weight.
|
||||||
|
|
||||||
|
+As for cgroups-v1 (blkio controller), the exact set of stat files
|
||||||
|
+created, and kept up-to-date by bfq, depends on whether
|
||||||
|
+CONFIG_DEBUG_BLK_CGROUP is set. If it is set, then bfq creates all
|
||||||
|
+the stat files documented in
|
||||||
|
+Documentation/cgroup-v1/blkio-controller.txt. If, instead,
|
||||||
|
+CONFIG_DEBUG_BLK_CGROUP is not set, then bfq creates only the files
|
||||||
|
+blkio.bfq.io_service_bytes
|
||||||
|
+blkio.bfq.io_service_bytes_recursive
|
||||||
|
+blkio.bfq.io_serviced
|
||||||
|
+blkio.bfq.io_serviced_recursive
|
||||||
|
+
|
||||||
|
+The value of CONFIG_DEBUG_BLK_CGROUP greatly influences the maximum
|
||||||
|
+throughput sustainable with bfq, because updating the blkio.bfq.*
|
||||||
|
+stats is rather costly, especially for some of the stats enabled by
|
||||||
|
+CONFIG_DEBUG_BLK_CGROUP.
|
||||||
|
+
|
||||||
|
Parameters to set
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
|
||||||
|
index ceefb9a706d6..da1525ec4c87 100644
|
||||||
|
--- a/block/bfq-cgroup.c
|
||||||
|
+++ b/block/bfq-cgroup.c
|
||||||
|
@@ -24,7 +24,7 @@
|
||||||
|
|
||||||
|
#include "bfq-iosched.h"
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
|
||||||
|
/* bfqg stats flags */
|
||||||
|
enum bfqg_stats_flags {
|
||||||
|
@@ -152,6 +152,57 @@ void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg)
|
||||||
|
bfqg_stats_update_group_wait_time(stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||||
|
+ unsigned int op)
|
||||||
|
+{
|
||||||
|
+ blkg_rwstat_add(&bfqg->stats.queued, op, 1);
|
||||||
|
+ bfqg_stats_end_empty_time(&bfqg->stats);
|
||||||
|
+ if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue))
|
||||||
|
+ bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op)
|
||||||
|
+{
|
||||||
|
+ blkg_rwstat_add(&bfqg->stats.queued, op, -1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op)
|
||||||
|
+{
|
||||||
|
+ blkg_rwstat_add(&bfqg->stats.merged, op, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void bfqg_stats_update_completion(struct bfq_group *bfqg, uint64_t start_time,
|
||||||
|
+ uint64_t io_start_time, unsigned int op)
|
||||||
|
+{
|
||||||
|
+ struct bfqg_stats *stats = &bfqg->stats;
|
||||||
|
+ unsigned long long now = sched_clock();
|
||||||
|
+
|
||||||
|
+ if (time_after64(now, io_start_time))
|
||||||
|
+ blkg_rwstat_add(&stats->service_time, op,
|
||||||
|
+ now - io_start_time);
|
||||||
|
+ if (time_after64(io_start_time, start_time))
|
||||||
|
+ blkg_rwstat_add(&stats->wait_time, op,
|
||||||
|
+ io_start_time - start_time);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#else /* CONFIG_BFQ_GROUP_IOSCHED && CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
+
|
||||||
|
+void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||||
|
+ unsigned int op) { }
|
||||||
|
+void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op) { }
|
||||||
|
+void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op) { }
|
||||||
|
+void bfqg_stats_update_completion(struct bfq_group *bfqg, uint64_t start_time,
|
||||||
|
+ uint64_t io_start_time, unsigned int op) { }
|
||||||
|
+void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { }
|
||||||
|
+void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { }
|
||||||
|
+void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
|
||||||
|
+void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
|
||||||
|
+void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
|
||||||
|
+
|
||||||
|
+#endif /* CONFIG_BFQ_GROUP_IOSCHED && CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* blk-cgroup policy-related handlers
|
||||||
|
* The following functions help in converting between blk-cgroup
|
||||||
|
@@ -229,42 +280,10 @@ void bfqg_and_blkg_put(struct bfq_group *bfqg)
|
||||||
|
blkg_put(bfqg_to_blkg(bfqg));
|
||||||
|
}
|
||||||
|
|
||||||
|
-void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||||
|
- unsigned int op)
|
||||||
|
-{
|
||||||
|
- blkg_rwstat_add(&bfqg->stats.queued, op, 1);
|
||||||
|
- bfqg_stats_end_empty_time(&bfqg->stats);
|
||||||
|
- if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue))
|
||||||
|
- bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op)
|
||||||
|
-{
|
||||||
|
- blkg_rwstat_add(&bfqg->stats.queued, op, -1);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op)
|
||||||
|
-{
|
||||||
|
- blkg_rwstat_add(&bfqg->stats.merged, op, 1);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void bfqg_stats_update_completion(struct bfq_group *bfqg, uint64_t start_time,
|
||||||
|
- uint64_t io_start_time, unsigned int op)
|
||||||
|
-{
|
||||||
|
- struct bfqg_stats *stats = &bfqg->stats;
|
||||||
|
- unsigned long long now = sched_clock();
|
||||||
|
-
|
||||||
|
- if (time_after64(now, io_start_time))
|
||||||
|
- blkg_rwstat_add(&stats->service_time, op,
|
||||||
|
- now - io_start_time);
|
||||||
|
- if (time_after64(io_start_time, start_time))
|
||||||
|
- blkg_rwstat_add(&stats->wait_time, op,
|
||||||
|
- io_start_time - start_time);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* @stats = 0 */
|
||||||
|
static void bfqg_stats_reset(struct bfqg_stats *stats)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
/* queued stats shouldn't be cleared */
|
||||||
|
blkg_rwstat_reset(&stats->merged);
|
||||||
|
blkg_rwstat_reset(&stats->service_time);
|
||||||
|
@@ -276,6 +295,7 @@ static void bfqg_stats_reset(struct bfqg_stats *stats)
|
||||||
|
blkg_stat_reset(&stats->group_wait_time);
|
||||||
|
blkg_stat_reset(&stats->idle_time);
|
||||||
|
blkg_stat_reset(&stats->empty_time);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @to += @from */
|
||||||
|
@@ -284,6 +304,7 @@ static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from)
|
||||||
|
if (!to || !from)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
/* queued stats shouldn't be cleared */
|
||||||
|
blkg_rwstat_add_aux(&to->merged, &from->merged);
|
||||||
|
blkg_rwstat_add_aux(&to->service_time, &from->service_time);
|
||||||
|
@@ -296,6 +317,7 @@ static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from)
|
||||||
|
blkg_stat_add_aux(&to->group_wait_time, &from->group_wait_time);
|
||||||
|
blkg_stat_add_aux(&to->idle_time, &from->idle_time);
|
||||||
|
blkg_stat_add_aux(&to->empty_time, &from->empty_time);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -342,6 +364,7 @@ void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg)
|
||||||
|
|
||||||
|
static void bfqg_stats_exit(struct bfqg_stats *stats)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
blkg_rwstat_exit(&stats->merged);
|
||||||
|
blkg_rwstat_exit(&stats->service_time);
|
||||||
|
blkg_rwstat_exit(&stats->wait_time);
|
||||||
|
@@ -353,10 +376,12 @@ static void bfqg_stats_exit(struct bfqg_stats *stats)
|
||||||
|
blkg_stat_exit(&stats->group_wait_time);
|
||||||
|
blkg_stat_exit(&stats->idle_time);
|
||||||
|
blkg_stat_exit(&stats->empty_time);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
if (blkg_rwstat_init(&stats->merged, gfp) ||
|
||||||
|
blkg_rwstat_init(&stats->service_time, gfp) ||
|
||||||
|
blkg_rwstat_init(&stats->wait_time, gfp) ||
|
||||||
|
@@ -371,6 +396,7 @@ static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
|
||||||
|
bfqg_stats_exit(stats);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -887,6 +913,7 @@ static ssize_t bfq_io_set_weight(struct kernfs_open_file *of,
|
||||||
|
return bfq_io_set_weight_legacy(of_css(of), NULL, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
static int bfqg_print_stat(struct seq_file *sf, void *v)
|
||||||
|
{
|
||||||
|
blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat,
|
||||||
|
@@ -991,6 +1018,7 @@ static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v)
|
||||||
|
0, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+#endif /* CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
|
||||||
|
struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
|
||||||
|
{
|
||||||
|
@@ -1028,15 +1056,6 @@ struct cftype bfq_blkcg_legacy_files[] = {
|
||||||
|
},
|
||||||
|
|
||||||
|
/* statistics, covers only the tasks in the bfqg */
|
||||||
|
- {
|
||||||
|
- .name = "bfq.time",
|
||||||
|
- .private = offsetof(struct bfq_group, stats.time),
|
||||||
|
- .seq_show = bfqg_print_stat,
|
||||||
|
- },
|
||||||
|
- {
|
||||||
|
- .name = "bfq.sectors",
|
||||||
|
- .seq_show = bfqg_print_stat_sectors,
|
||||||
|
- },
|
||||||
|
{
|
||||||
|
.name = "bfq.io_service_bytes",
|
||||||
|
.private = (unsigned long)&blkcg_policy_bfq,
|
||||||
|
@@ -1047,6 +1066,16 @@ struct cftype bfq_blkcg_legacy_files[] = {
|
||||||
|
.private = (unsigned long)&blkcg_policy_bfq,
|
||||||
|
.seq_show = blkg_print_stat_ios,
|
||||||
|
},
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
+ {
|
||||||
|
+ .name = "bfq.time",
|
||||||
|
+ .private = offsetof(struct bfq_group, stats.time),
|
||||||
|
+ .seq_show = bfqg_print_stat,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "bfq.sectors",
|
||||||
|
+ .seq_show = bfqg_print_stat_sectors,
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
.name = "bfq.io_service_time",
|
||||||
|
.private = offsetof(struct bfq_group, stats.service_time),
|
||||||
|
@@ -1067,17 +1096,9 @@ struct cftype bfq_blkcg_legacy_files[] = {
|
||||||
|
.private = offsetof(struct bfq_group, stats.queued),
|
||||||
|
.seq_show = bfqg_print_rwstat,
|
||||||
|
},
|
||||||
|
+#endif /* CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
|
||||||
|
/* the same statictics which cover the bfqg and its descendants */
|
||||||
|
- {
|
||||||
|
- .name = "bfq.time_recursive",
|
||||||
|
- .private = offsetof(struct bfq_group, stats.time),
|
||||||
|
- .seq_show = bfqg_print_stat_recursive,
|
||||||
|
- },
|
||||||
|
- {
|
||||||
|
- .name = "bfq.sectors_recursive",
|
||||||
|
- .seq_show = bfqg_print_stat_sectors_recursive,
|
||||||
|
- },
|
||||||
|
{
|
||||||
|
.name = "bfq.io_service_bytes_recursive",
|
||||||
|
.private = (unsigned long)&blkcg_policy_bfq,
|
||||||
|
@@ -1088,6 +1109,16 @@ struct cftype bfq_blkcg_legacy_files[] = {
|
||||||
|
.private = (unsigned long)&blkcg_policy_bfq,
|
||||||
|
.seq_show = blkg_print_stat_ios_recursive,
|
||||||
|
},
|
||||||
|
+#ifdef CONFIG_DEBUG_BLK_CGROUP
|
||||||
|
+ {
|
||||||
|
+ .name = "bfq.time_recursive",
|
||||||
|
+ .private = offsetof(struct bfq_group, stats.time),
|
||||||
|
+ .seq_show = bfqg_print_stat_recursive,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "bfq.sectors_recursive",
|
||||||
|
+ .seq_show = bfqg_print_stat_sectors_recursive,
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
.name = "bfq.io_service_time_recursive",
|
||||||
|
.private = offsetof(struct bfq_group, stats.service_time),
|
||||||
|
@@ -1132,6 +1163,7 @@ struct cftype bfq_blkcg_legacy_files[] = {
|
||||||
|
.private = offsetof(struct bfq_group, stats.dequeue),
|
||||||
|
.seq_show = bfqg_print_stat,
|
||||||
|
},
|
||||||
|
+#endif /* CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
{ } /* terminate */
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -1147,18 +1179,6 @@ struct cftype bfq_blkg_files[] = {
|
||||||
|
|
||||||
|
#else /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||||
|
|
||||||
|
-void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
|
||||||
|
- unsigned int op) { }
|
||||||
|
-void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op) { }
|
||||||
|
-void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op) { }
|
||||||
|
-void bfqg_stats_update_completion(struct bfq_group *bfqg, uint64_t start_time,
|
||||||
|
- uint64_t io_start_time, unsigned int op) { }
|
||||||
|
-void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { }
|
||||||
|
-void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { }
|
||||||
|
-void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
|
||||||
|
-void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
|
||||||
|
-void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
|
||||||
|
-
|
||||||
|
void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
struct bfq_group *bfqg) {}
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 69e05f861daf..bcb6d21baf12 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -3693,14 +3693,14 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
{
|
||||||
|
struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
|
||||||
|
struct request *rq;
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
struct bfq_queue *in_serv_queue, *bfqq;
|
||||||
|
bool waiting_rq, idle_timer_disabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
in_serv_queue = bfqd->in_service_queue;
|
||||||
|
waiting_rq = in_serv_queue && bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
|
||||||
|
@@ -3714,7 +3714,7 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
#endif
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
bfqq = rq ? RQ_BFQQ(rq) : NULL;
|
||||||
|
if (!idle_timer_disabled && !bfqq)
|
||||||
|
return rq;
|
||||||
|
@@ -4281,7 +4281,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
{
|
||||||
|
struct request_queue *q = hctx->queue;
|
||||||
|
struct bfq_data *bfqd = q->elevator->elevator_data;
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
struct bfq_queue *bfqq = RQ_BFQQ(rq);
|
||||||
|
bool idle_timer_disabled = false;
|
||||||
|
unsigned int cmd_flags;
|
||||||
|
@@ -4304,7 +4304,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
else
|
||||||
|
list_add_tail(&rq->queuelist, &bfqd->dispatch);
|
||||||
|
} else {
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
idle_timer_disabled = __bfq_insert_request(bfqd, rq);
|
||||||
|
/*
|
||||||
|
* Update bfqq, because, if a queue merge has occurred
|
||||||
|
@@ -4323,7 +4323,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
/*
|
||||||
|
* Cache cmd_flags before releasing scheduler lock, because rq
|
||||||
|
* may disappear afterwards (for example, because of a request
|
||||||
|
@@ -4333,7 +4333,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
#endif
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
if (!bfqq)
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
|
||||||
|
index ac0809c72c98..91c4390903a1 100644
|
||||||
|
--- a/block/bfq-iosched.h
|
||||||
|
+++ b/block/bfq-iosched.h
|
||||||
|
@@ -689,7 +689,7 @@ enum bfqq_expiration {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bfqg_stats {
|
||||||
|
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
/* number of ios merged */
|
||||||
|
struct blkg_rwstat merged;
|
||||||
|
/* total time spent on device in ns, may not be accurate w/ queueing */
|
||||||
|
@@ -717,7 +717,7 @@ struct bfqg_stats {
|
||||||
|
uint64_t start_idle_time;
|
||||||
|
uint64_t start_empty_time;
|
||||||
|
uint16_t flags;
|
||||||
|
-#endif /* CONFIG_BFQ_GROUP_IOSCHED */
|
||||||
|
+#endif /* CONFIG_BFQ_GROUP_IOSCHED && CONFIG_DEBUG_BLK_CGROUP */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
From 0d52af590552473666da5b6111e7182d6cd23f92 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Tue, 9 Jan 2018 10:27:59 +0100
|
||||||
|
Subject: [PATCH] block, bfq: release oom-queue ref to root group on exit
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
On scheduler init, a reference to the root group, and a reference to
|
||||||
|
its corresponding blkg are taken for the oom queue. Yet these
|
||||||
|
references are not released on scheduler exit, which prevents these
|
||||||
|
objects from be freed. This commit adds the missing reference
|
||||||
|
releases.
|
||||||
|
|
||||||
|
Reported-by: Davide Ferrari <davideferrari8@gmail.com>
|
||||||
|
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 7bd789da7a29..7c0b7f60811c 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -4893,6 +4893,9 @@ static void bfq_exit_queue(struct elevator_queue *e)
|
||||||
|
|
||||||
|
hrtimer_cancel(&bfqd->idle_slice_timer);
|
||||||
|
|
||||||
|
+ /* release oom-queue reference to root group */
|
||||||
|
+ bfqg_and_blkg_put(bfqd->root_group);
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
blkcg_deactivate_policy(bfqd->queue, &blkcg_policy_bfq);
|
||||||
|
#else
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
+225
@@ -0,0 +1,225 @@
|
|||||||
|
From 9b25bd0368d562d1929059e8eb9de4102567b923 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Mon, 4 Dec 2017 11:42:05 +0100
|
||||||
|
Subject: [PATCH] block, bfq: remove batches of confusing ifdefs
|
||||||
|
|
||||||
|
Commit a33801e8b473 ("block, bfq: move debug blkio stats behind
|
||||||
|
CONFIG_DEBUG_BLK_CGROUP") introduced two batches of confusing ifdefs:
|
||||||
|
one reported in [1], plus a similar one in another function. This
|
||||||
|
commit removes both batches, in the way suggested in [1].
|
||||||
|
|
||||||
|
[1] https://www.spinics.net/lists/linux-block/msg20043.html
|
||||||
|
|
||||||
|
Fixes: a33801e8b473 ("block, bfq: move debug blkio stats behind CONFIG_DEBUG_BLK_CGROUP")
|
||||||
|
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||||
|
Tested-by: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 127 +++++++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 72 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index e33c5c4c9856..7bd789da7a29 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -3743,35 +3743,16 @@ static struct request *__bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
return rq;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
-{
|
||||||
|
- struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
|
||||||
|
- struct request *rq;
|
||||||
|
#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
- struct bfq_queue *in_serv_queue, *bfqq;
|
||||||
|
- bool waiting_rq, idle_timer_disabled;
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- spin_lock_irq(&bfqd->lock);
|
||||||
|
-
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
- in_serv_queue = bfqd->in_service_queue;
|
||||||
|
- waiting_rq = in_serv_queue && bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
-
|
||||||
|
- rq = __bfq_dispatch_request(hctx);
|
||||||
|
-
|
||||||
|
- idle_timer_disabled =
|
||||||
|
- waiting_rq && !bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
-
|
||||||
|
-#else
|
||||||
|
- rq = __bfq_dispatch_request(hctx);
|
||||||
|
-#endif
|
||||||
|
- spin_unlock_irq(&bfqd->lock);
|
||||||
|
+static void bfq_update_dispatch_stats(struct request_queue *q,
|
||||||
|
+ struct request *rq,
|
||||||
|
+ struct bfq_queue *in_serv_queue,
|
||||||
|
+ bool idle_timer_disabled)
|
||||||
|
+{
|
||||||
|
+ struct bfq_queue *bfqq = rq ? RQ_BFQQ(rq) : NULL;
|
||||||
|
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
- bfqq = rq ? RQ_BFQQ(rq) : NULL;
|
||||||
|
if (!idle_timer_disabled && !bfqq)
|
||||||
|
- return rq;
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rq and bfqq are guaranteed to exist until this function
|
||||||
|
@@ -3786,7 +3767,7 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
* In addition, the following queue lock guarantees that
|
||||||
|
* bfqq_group(bfqq) exists as well.
|
||||||
|
*/
|
||||||
|
- spin_lock_irq(hctx->queue->queue_lock);
|
||||||
|
+ spin_lock_irq(q->queue_lock);
|
||||||
|
if (idle_timer_disabled)
|
||||||
|
/*
|
||||||
|
* Since the idle timer has been disabled,
|
||||||
|
@@ -3805,9 +3786,37 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
bfqg_stats_set_start_empty_time(bfqg);
|
||||||
|
bfqg_stats_update_io_remove(bfqg, rq->cmd_flags);
|
||||||
|
}
|
||||||
|
- spin_unlock_irq(hctx->queue->queue_lock);
|
||||||
|
+ spin_unlock_irq(q->queue_lock);
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static inline void bfq_update_dispatch_stats(struct request_queue *q,
|
||||||
|
+ struct request *rq,
|
||||||
|
+ struct bfq_queue *in_serv_queue,
|
||||||
|
+ bool idle_timer_disabled) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
+{
|
||||||
|
+ struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
|
||||||
|
+ struct request *rq;
|
||||||
|
+ struct bfq_queue *in_serv_queue;
|
||||||
|
+ bool waiting_rq, idle_timer_disabled;
|
||||||
|
+
|
||||||
|
+ spin_lock_irq(&bfqd->lock);
|
||||||
|
+
|
||||||
|
+ in_serv_queue = bfqd->in_service_queue;
|
||||||
|
+ waiting_rq = in_serv_queue && bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
+
|
||||||
|
+ rq = __bfq_dispatch_request(hctx);
|
||||||
|
+
|
||||||
|
+ idle_timer_disabled =
|
||||||
|
+ waiting_rq && !bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
+
|
||||||
|
+ spin_unlock_irq(&bfqd->lock);
|
||||||
|
+
|
||||||
|
+ bfq_update_dispatch_stats(hctx->queue, rq, in_serv_queue,
|
||||||
|
+ idle_timer_disabled);
|
||||||
|
+
|
||||||
|
return rq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4335,16 +4344,46 @@ static bool __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
return idle_timer_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
+static void bfq_update_insert_stats(struct request_queue *q,
|
||||||
|
+ struct bfq_queue *bfqq,
|
||||||
|
+ bool idle_timer_disabled,
|
||||||
|
+ unsigned int cmd_flags)
|
||||||
|
+{
|
||||||
|
+ if (!bfqq)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * bfqq still exists, because it can disappear only after
|
||||||
|
+ * either it is merged with another queue, or the process it
|
||||||
|
+ * is associated with exits. But both actions must be taken by
|
||||||
|
+ * the same process currently executing this flow of
|
||||||
|
+ * instructions.
|
||||||
|
+ *
|
||||||
|
+ * In addition, the following queue lock guarantees that
|
||||||
|
+ * bfqq_group(bfqq) exists as well.
|
||||||
|
+ */
|
||||||
|
+ spin_lock_irq(q->queue_lock);
|
||||||
|
+ bfqg_stats_update_io_add(bfqq_group(bfqq), bfqq, cmd_flags);
|
||||||
|
+ if (idle_timer_disabled)
|
||||||
|
+ bfqg_stats_update_idle_time(bfqq_group(bfqq));
|
||||||
|
+ spin_unlock_irq(q->queue_lock);
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static inline void bfq_update_insert_stats(struct request_queue *q,
|
||||||
|
+ struct bfq_queue *bfqq,
|
||||||
|
+ bool idle_timer_disabled,
|
||||||
|
+ unsigned int cmd_flags) {}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
bool at_head)
|
||||||
|
{
|
||||||
|
struct request_queue *q = hctx->queue;
|
||||||
|
struct bfq_data *bfqd = q->elevator->elevator_data;
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
struct bfq_queue *bfqq = RQ_BFQQ(rq);
|
||||||
|
bool idle_timer_disabled = false;
|
||||||
|
unsigned int cmd_flags;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
if (blk_mq_sched_try_insert_merge(q, rq)) {
|
||||||
|
@@ -4363,7 +4402,6 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
else
|
||||||
|
list_add_tail(&rq->queuelist, &bfqd->dispatch);
|
||||||
|
} else {
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
idle_timer_disabled = __bfq_insert_request(bfqd, rq);
|
||||||
|
/*
|
||||||
|
* Update bfqq, because, if a queue merge has occurred
|
||||||
|
@@ -4371,9 +4409,6 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
* redirected into a new queue.
|
||||||
|
*/
|
||||||
|
bfqq = RQ_BFQQ(rq);
|
||||||
|
-#else
|
||||||
|
- __bfq_insert_request(bfqd, rq);
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
if (rq_mergeable(rq)) {
|
||||||
|
elv_rqhash_add(q, rq);
|
||||||
|
@@ -4382,35 +4417,17 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
/*
|
||||||
|
* Cache cmd_flags before releasing scheduler lock, because rq
|
||||||
|
* may disappear afterwards (for example, because of a request
|
||||||
|
* merge).
|
||||||
|
*/
|
||||||
|
cmd_flags = rq->cmd_flags;
|
||||||
|
-#endif
|
||||||
|
+
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
-#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
|
||||||
|
- if (!bfqq)
|
||||||
|
- return;
|
||||||
|
- /*
|
||||||
|
- * bfqq still exists, because it can disappear only after
|
||||||
|
- * either it is merged with another queue, or the process it
|
||||||
|
- * is associated with exits. But both actions must be taken by
|
||||||
|
- * the same process currently executing this flow of
|
||||||
|
- * instruction.
|
||||||
|
- *
|
||||||
|
- * In addition, the following queue lock guarantees that
|
||||||
|
- * bfqq_group(bfqq) exists as well.
|
||||||
|
- */
|
||||||
|
- spin_lock_irq(q->queue_lock);
|
||||||
|
- bfqg_stats_update_io_add(bfqq_group(bfqq), bfqq, cmd_flags);
|
||||||
|
- if (idle_timer_disabled)
|
||||||
|
- bfqg_stats_update_idle_time(bfqq_group(bfqq));
|
||||||
|
- spin_unlock_irq(q->queue_lock);
|
||||||
|
-#endif
|
||||||
|
+ bfq_update_insert_stats(q, bfqq, idle_timer_disabled,
|
||||||
|
+ cmd_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bfq_insert_requests(struct blk_mq_hw_ctx *hctx,
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+112
@@ -0,0 +1,112 @@
|
|||||||
|
From 4403e4e467c365b4189e3e3d3ad35cf67b8c36ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Date: Wed, 20 Dec 2017 12:38:34 +0100
|
||||||
|
Subject: [PATCH] block, bfq: remove superfluous check in queue-merging setup
|
||||||
|
|
||||||
|
When two or more processes do I/O in a way that the their requests are
|
||||||
|
sequential in respect to one another, BFQ merges the bfq_queues associated
|
||||||
|
with the processes. This way the overall I/O pattern becomes sequential,
|
||||||
|
and thus there is a boost in througput.
|
||||||
|
These cooperating processes usually start or restart to do I/O shortly
|
||||||
|
after each other. So, in order to avoid merging non-cooperating processes,
|
||||||
|
BFQ ensures that none of these queues has been in weight raising for too
|
||||||
|
long.
|
||||||
|
|
||||||
|
In this respect, from commit "block, bfq-sq, bfq-mq: let a queue be merged
|
||||||
|
only shortly after being created", BFQ checks whether any queue (and not
|
||||||
|
only weight-raised ones) is doing I/O continuously from too long to be
|
||||||
|
merged.
|
||||||
|
|
||||||
|
This new additional check makes the first one useless: a queue doing
|
||||||
|
I/O from long enough, if being weight-raised, is also a queue in
|
||||||
|
weight raising for too long to be merged. Accordingly, this commit
|
||||||
|
removes the first check.
|
||||||
|
|
||||||
|
Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
block/bfq-iosched.c | 36 +++++-------------------------------
|
||||||
|
1 file changed, 5 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 7066d90f09df..9625550b2f85 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -1990,20 +1990,6 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * If this function returns true, then bfqq cannot be merged. The idea
|
||||||
|
- * is that true cooperation happens very early after processes start
|
||||||
|
- * to do I/O. Usually, late cooperations are just accidental false
|
||||||
|
- * positives. In case bfqq is weight-raised, such false positives
|
||||||
|
- * would evidently degrade latency guarantees for bfqq.
|
||||||
|
- */
|
||||||
|
-static bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||||
|
-{
|
||||||
|
- return bfqq->wr_coeff > 1 &&
|
||||||
|
- time_is_before_jiffies(bfqq->last_wr_start_finish +
|
||||||
|
- msecs_to_jiffies(100));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Attempt to schedule a merge of bfqq with the currently in-service
|
||||||
|
* queue or with a close queue among the scheduled queues. Return
|
||||||
|
@@ -2017,11 +2003,6 @@ static bool wr_from_too_long(struct bfq_queue *bfqq)
|
||||||
|
* to maintain. Besides, in such a critical condition as an out of memory,
|
||||||
|
* the benefits of queue merging may be little relevant, or even negligible.
|
||||||
|
*
|
||||||
|
- * Weight-raised queues can be merged only if their weight-raising
|
||||||
|
- * period has just started. In fact cooperating processes are usually
|
||||||
|
- * started together. Thus, with this filter we avoid false positives
|
||||||
|
- * that would jeopardize low-latency guarantees.
|
||||||
|
- *
|
||||||
|
* WARNING: queue merging may impair fairness among non-weight raised
|
||||||
|
* queues, for at least two reasons: 1) the original weight of a
|
||||||
|
* merged queue may change during the merged state, 2) even being the
|
||||||
|
@@ -2052,9 +2033,7 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
if (bfqq->new_bfqq)
|
||||||
|
return bfqq->new_bfqq;
|
||||||
|
|
||||||
|
- if (!io_struct ||
|
||||||
|
- wr_from_too_long(bfqq) ||
|
||||||
|
- unlikely(bfqq == &bfqd->oom_bfqq))
|
||||||
|
+ if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* If there is only one backlogged queue, don't search. */
|
||||||
|
@@ -2063,12 +2042,9 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
|
||||||
|
in_service_bfqq = bfqd->in_service_queue;
|
||||||
|
|
||||||
|
- if (!in_service_bfqq || in_service_bfqq == bfqq
|
||||||
|
- || wr_from_too_long(in_service_bfqq) ||
|
||||||
|
- unlikely(in_service_bfqq == &bfqd->oom_bfqq))
|
||||||
|
- goto check_scheduled;
|
||||||
|
-
|
||||||
|
- if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
|
||||||
|
+ if (in_service_bfqq && in_service_bfqq != bfqq &&
|
||||||
|
+ likely(in_service_bfqq != &bfqd->oom_bfqq) &&
|
||||||
|
+ bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
|
||||||
|
bfqq->entity.parent == in_service_bfqq->entity.parent &&
|
||||||
|
bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) {
|
||||||
|
new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
|
||||||
|
@@ -2080,12 +2056,10 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
* queues. The only thing we need is that the bio/request is not
|
||||||
|
* NULL, as we need it to establish whether a cooperator exists.
|
||||||
|
*/
|
||||||
|
-check_scheduled:
|
||||||
|
new_bfqq = bfq_find_close_cooperator(bfqd, bfqq,
|
||||||
|
bfq_io_struct_pos(io_struct, request));
|
||||||
|
|
||||||
|
- if (new_bfqq && !wr_from_too_long(new_bfqq) &&
|
||||||
|
- likely(new_bfqq != &bfqd->oom_bfqq) &&
|
||||||
|
+ if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq) &&
|
||||||
|
bfq_may_be_close_cooperator(bfqq, new_bfqq))
|
||||||
|
return bfq_setup_merge(bfqq, new_bfqq);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
+283
@@ -0,0 +1,283 @@
|
|||||||
|
From 24bfd19bb7890255693ee5cb6dc100d8d215d00b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Mon, 13 Nov 2017 07:34:09 +0100
|
||||||
|
Subject: [PATCH] block, bfq: update blkio stats outside the scheduler lock
|
||||||
|
|
||||||
|
bfq invokes various blkg_*stats_* functions to update the statistics
|
||||||
|
contained in the special files blkio.bfq.* in the blkio controller
|
||||||
|
groups, i.e., the I/O accounting related to the proportional-share
|
||||||
|
policy provided by bfq. The execution of these functions takes a
|
||||||
|
considerable percentage, about 40%, of the total per-request execution
|
||||||
|
time of bfq (i.e., of the sum of the execution time of all the bfq
|
||||||
|
functions that have to be executed to process an I/O request from its
|
||||||
|
creation to its destruction). This reduces the request-processing
|
||||||
|
rate sustainable by bfq noticeably, even on a multicore CPU. In fact,
|
||||||
|
the bfq functions that invoke blkg_*stats_* functions cannot be
|
||||||
|
executed in parallel with the rest of the code of bfq, because both
|
||||||
|
are executed under the same same per-device scheduler lock.
|
||||||
|
|
||||||
|
To reduce this slowdown, this commit moves, wherever possible, the
|
||||||
|
invocation of these functions (more precisely, of the bfq functions
|
||||||
|
that invoke blkg_*stats_* functions) outside the critical sections
|
||||||
|
protected by the scheduler lock.
|
||||||
|
|
||||||
|
With this change, and with all blkio.bfq.* statistics enabled, the
|
||||||
|
throughput grows, e.g., from 250 to 310 KIOPS (+25%) on an Intel
|
||||||
|
i7-4850HQ, in case of 8 threads doing random I/O in parallel on
|
||||||
|
null_blk, with the latter configured with 0 latency. We obtained the
|
||||||
|
same or higher throughput boosts, up to +30%, with other processors
|
||||||
|
(some figures are reported in the documentation). For our tests, we
|
||||||
|
used the script [1], with which our results can be easily reproduced.
|
||||||
|
|
||||||
|
NOTE. This commit still protects the invocation of blkg_*stats_*
|
||||||
|
functions with the request_queue lock, because the group these
|
||||||
|
functions are invoked on may otherwise disappear before or while these
|
||||||
|
functions are executed. Fortunately, tests without even this lock
|
||||||
|
show, by difference, that the serialization caused by this lock has a
|
||||||
|
little impact (at most ~5% of throughput reduction).
|
||||||
|
|
||||||
|
[1] https://github.com/Algodev-github/IOSpeed
|
||||||
|
|
||||||
|
Tested-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
Documentation/block/bfq-iosched.txt | 6 +-
|
||||||
|
block/bfq-iosched.c | 110 ++++++++++++++++++++++++++++++++----
|
||||||
|
block/bfq-wf2q.c | 1 -
|
||||||
|
3 files changed, 102 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/block/bfq-iosched.txt b/Documentation/block/bfq-iosched.txt
|
||||||
|
index 7a9361508157..7fad6c061470 100644
|
||||||
|
--- a/Documentation/block/bfq-iosched.txt
|
||||||
|
+++ b/Documentation/block/bfq-iosched.txt
|
||||||
|
@@ -26,9 +26,9 @@ the limits on slow or average CPUs, here are BFQ limits for three
|
||||||
|
different CPUs, on, respectively, an average laptop, an old desktop,
|
||||||
|
and a cheap embedded system, in case full hierarchical support is
|
||||||
|
enabled (i.e., CONFIG_BFQ_GROUP_IOSCHED is set):
|
||||||
|
-- Intel i7-4850HQ: 250 KIOPS
|
||||||
|
-- AMD A8-3850: 170 KIOPS
|
||||||
|
-- ARM CortexTM-A53 Octa-core: 45 KIOPS
|
||||||
|
+- Intel i7-4850HQ: 310 KIOPS
|
||||||
|
+- AMD A8-3850: 200 KIOPS
|
||||||
|
+- ARM CortexTM-A53 Octa-core: 56 KIOPS
|
||||||
|
|
||||||
|
BFQ works for multi-queue devices too.
|
||||||
|
|
||||||
|
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
|
||||||
|
index 91703eba63f0..69e05f861daf 100644
|
||||||
|
--- a/block/bfq-iosched.c
|
||||||
|
+++ b/block/bfq-iosched.c
|
||||||
|
@@ -2228,7 +2228,6 @@ static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
|
||||||
|
struct bfq_queue *bfqq)
|
||||||
|
{
|
||||||
|
if (bfqq) {
|
||||||
|
- bfqg_stats_update_avg_queue_size(bfqq_group(bfqq));
|
||||||
|
bfq_clear_bfqq_fifo_expire(bfqq);
|
||||||
|
|
||||||
|
bfqd->budgets_assigned = (bfqd->budgets_assigned * 7 + 256) / 8;
|
||||||
|
@@ -3469,7 +3468,6 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
|
||||||
|
*/
|
||||||
|
bfq_clear_bfqq_wait_request(bfqq);
|
||||||
|
hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
|
||||||
|
- bfqg_stats_update_idle_time(bfqq_group(bfqq));
|
||||||
|
}
|
||||||
|
goto keep_queue;
|
||||||
|
}
|
||||||
|
@@ -3695,15 +3693,67 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
|
||||||
|
{
|
||||||
|
struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
|
||||||
|
struct request *rq;
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ struct bfq_queue *in_serv_queue, *bfqq;
|
||||||
|
+ bool waiting_rq, idle_timer_disabled;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ in_serv_queue = bfqd->in_service_queue;
|
||||||
|
+ waiting_rq = in_serv_queue && bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
+
|
||||||
|
+ rq = __bfq_dispatch_request(hctx);
|
||||||
|
+
|
||||||
|
+ idle_timer_disabled =
|
||||||
|
+ waiting_rq && !bfq_bfqq_wait_request(in_serv_queue);
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
rq = __bfq_dispatch_request(hctx);
|
||||||
|
- if (rq && RQ_BFQQ(rq))
|
||||||
|
- bfqg_stats_update_io_remove(bfqq_group(RQ_BFQQ(rq)),
|
||||||
|
- rq->cmd_flags);
|
||||||
|
+#endif
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ bfqq = rq ? RQ_BFQQ(rq) : NULL;
|
||||||
|
+ if (!idle_timer_disabled && !bfqq)
|
||||||
|
+ return rq;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * rq and bfqq are guaranteed to exist until this function
|
||||||
|
+ * ends, for the following reasons. First, rq can be
|
||||||
|
+ * dispatched to the device, and then can be completed and
|
||||||
|
+ * freed, only after this function ends. Second, rq cannot be
|
||||||
|
+ * merged (and thus freed because of a merge) any longer,
|
||||||
|
+ * because it has already started. Thus rq cannot be freed
|
||||||
|
+ * before this function ends, and, since rq has a reference to
|
||||||
|
+ * bfqq, the same guarantee holds for bfqq too.
|
||||||
|
+ *
|
||||||
|
+ * In addition, the following queue lock guarantees that
|
||||||
|
+ * bfqq_group(bfqq) exists as well.
|
||||||
|
+ */
|
||||||
|
+ spin_lock_irq(hctx->queue->queue_lock);
|
||||||
|
+ if (idle_timer_disabled)
|
||||||
|
+ /*
|
||||||
|
+ * Since the idle timer has been disabled,
|
||||||
|
+ * in_serv_queue contained some request when
|
||||||
|
+ * __bfq_dispatch_request was invoked above, which
|
||||||
|
+ * implies that rq was picked exactly from
|
||||||
|
+ * in_serv_queue. Thus in_serv_queue == bfqq, and is
|
||||||
|
+ * therefore guaranteed to exist because of the above
|
||||||
|
+ * arguments.
|
||||||
|
+ */
|
||||||
|
+ bfqg_stats_update_idle_time(bfqq_group(in_serv_queue));
|
||||||
|
+ if (bfqq) {
|
||||||
|
+ struct bfq_group *bfqg = bfqq_group(bfqq);
|
||||||
|
+
|
||||||
|
+ bfqg_stats_update_avg_queue_size(bfqg);
|
||||||
|
+ bfqg_stats_set_start_empty_time(bfqg);
|
||||||
|
+ bfqg_stats_update_io_remove(bfqg, rq->cmd_flags);
|
||||||
|
+ }
|
||||||
|
+ spin_unlock_irq(hctx->queue->queue_lock);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
return rq;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4161,7 +4211,6 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
*/
|
||||||
|
bfq_clear_bfqq_wait_request(bfqq);
|
||||||
|
hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
|
||||||
|
- bfqg_stats_update_idle_time(bfqq_group(bfqq));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The queue is not empty, because a new request just
|
||||||
|
@@ -4176,10 +4225,12 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
+/* returns true if it causes the idle timer to be disabled */
|
||||||
|
+static bool __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
{
|
||||||
|
struct bfq_queue *bfqq = RQ_BFQQ(rq),
|
||||||
|
*new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true);
|
||||||
|
+ bool waiting, idle_timer_disabled = false;
|
||||||
|
|
||||||
|
if (new_bfqq) {
|
||||||
|
if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq)
|
||||||
|
@@ -4213,12 +4264,16 @@ static void __bfq_insert_request(struct bfq_data *bfqd, struct request *rq)
|
||||||
|
bfqq = new_bfqq;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ waiting = bfqq && bfq_bfqq_wait_request(bfqq);
|
||||||
|
bfq_add_request(rq);
|
||||||
|
+ idle_timer_disabled = waiting && !bfq_bfqq_wait_request(bfqq);
|
||||||
|
|
||||||
|
rq->fifo_time = ktime_get_ns() + bfqd->bfq_fifo_expire[rq_is_sync(rq)];
|
||||||
|
list_add_tail(&rq->queuelist, &bfqq->fifo);
|
||||||
|
|
||||||
|
bfq_rq_enqueued(bfqd, bfqq, rq);
|
||||||
|
+
|
||||||
|
+ return idle_timer_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
@@ -4226,7 +4281,11 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
{
|
||||||
|
struct request_queue *q = hctx->queue;
|
||||||
|
struct bfq_data *bfqd = q->elevator->elevator_data;
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
struct bfq_queue *bfqq = RQ_BFQQ(rq);
|
||||||
|
+ bool idle_timer_disabled = false;
|
||||||
|
+ unsigned int cmd_flags;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
spin_lock_irq(&bfqd->lock);
|
||||||
|
if (blk_mq_sched_try_insert_merge(q, rq)) {
|
||||||
|
@@ -4245,13 +4304,17 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
else
|
||||||
|
list_add_tail(&rq->queuelist, &bfqd->dispatch);
|
||||||
|
} else {
|
||||||
|
- __bfq_insert_request(bfqd, rq);
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ idle_timer_disabled = __bfq_insert_request(bfqd, rq);
|
||||||
|
/*
|
||||||
|
* Update bfqq, because, if a queue merge has occurred
|
||||||
|
* in __bfq_insert_request, then rq has been
|
||||||
|
* redirected into a new queue.
|
||||||
|
*/
|
||||||
|
bfqq = RQ_BFQQ(rq);
|
||||||
|
+#else
|
||||||
|
+ __bfq_insert_request(bfqd, rq);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (rq_mergeable(rq)) {
|
||||||
|
elv_rqhash_add(q, rq);
|
||||||
|
@@ -4260,10 +4323,35 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (bfqq)
|
||||||
|
- bfqg_stats_update_io_add(bfqq_group(bfqq), bfqq, rq->cmd_flags);
|
||||||
|
-
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ /*
|
||||||
|
+ * Cache cmd_flags before releasing scheduler lock, because rq
|
||||||
|
+ * may disappear afterwards (for example, because of a request
|
||||||
|
+ * merge).
|
||||||
|
+ */
|
||||||
|
+ cmd_flags = rq->cmd_flags;
|
||||||
|
+#endif
|
||||||
|
spin_unlock_irq(&bfqd->lock);
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
|
||||||
|
+ if (!bfqq)
|
||||||
|
+ return;
|
||||||
|
+ /*
|
||||||
|
+ * bfqq still exists, because it can disappear only after
|
||||||
|
+ * either it is merged with another queue, or the process it
|
||||||
|
+ * is associated with exits. But both actions must be taken by
|
||||||
|
+ * the same process currently executing this flow of
|
||||||
|
+ * instruction.
|
||||||
|
+ *
|
||||||
|
+ * In addition, the following queue lock guarantees that
|
||||||
|
+ * bfqq_group(bfqq) exists as well.
|
||||||
|
+ */
|
||||||
|
+ spin_lock_irq(q->queue_lock);
|
||||||
|
+ bfqg_stats_update_io_add(bfqq_group(bfqq), bfqq, cmd_flags);
|
||||||
|
+ if (idle_timer_disabled)
|
||||||
|
+ bfqg_stats_update_idle_time(bfqq_group(bfqq));
|
||||||
|
+ spin_unlock_irq(q->queue_lock);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bfq_insert_requests(struct blk_mq_hw_ctx *hctx,
|
||||||
|
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
|
||||||
|
index 414ba686a847..e495d3f9b4b0 100644
|
||||||
|
--- a/block/bfq-wf2q.c
|
||||||
|
+++ b/block/bfq-wf2q.c
|
||||||
|
@@ -843,7 +843,6 @@ void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
|
||||||
|
st->vtime += bfq_delta(served, st->wsum);
|
||||||
|
bfq_forget_idle(st);
|
||||||
|
}
|
||||||
|
- bfqg_stats_set_start_empty_time(bfqq_group(bfqq));
|
||||||
|
bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs", served);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.15.1
|
||||||
|
|
||||||
-103
@@ -1,103 +0,0 @@
|
|||||||
From 465ed48c05de63f5bdd34d83915f1b8998a62134 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Paolo Valente <paolo.valente@unimore.it>
|
|
||||||
Date: Tue, 7 Apr 2015 13:39:12 +0200
|
|
||||||
Subject: [PATCH 1/4] block: cgroups, kconfig, build bits for BFQ-v7r11-4.5.0
|
|
||||||
|
|
||||||
Update Kconfig.iosched and do the related Makefile changes to include
|
|
||||||
kernel configuration options for BFQ. Also increase the number of
|
|
||||||
policies supported by the blkio controller so that BFQ can add its
|
|
||||||
own.
|
|
||||||
|
|
||||||
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
|
|
||||||
Signed-off-by: Arianna Avanzini <avanzini@google.com>
|
|
||||||
---
|
|
||||||
block/Kconfig.iosched | 32 ++++++++++++++++++++++++++++++++
|
|
||||||
block/Makefile | 1 +
|
|
||||||
include/linux/blkdev.h | 2 +-
|
|
||||||
3 files changed, 34 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
|
|
||||||
index 421bef9..0ee5f0f 100644
|
|
||||||
--- a/block/Kconfig.iosched
|
|
||||||
+++ b/block/Kconfig.iosched
|
|
||||||
@@ -39,6 +39,27 @@ config CFQ_GROUP_IOSCHED
|
|
||||||
---help---
|
|
||||||
Enable group IO scheduling in CFQ.
|
|
||||||
|
|
||||||
+config IOSCHED_BFQ
|
|
||||||
+ tristate "BFQ I/O scheduler"
|
|
||||||
+ default n
|
|
||||||
+ ---help---
|
|
||||||
+ The BFQ I/O scheduler tries to distribute bandwidth among
|
|
||||||
+ all processes according to their weights.
|
|
||||||
+ It aims at distributing the bandwidth as desired, independently of
|
|
||||||
+ the disk parameters and with any workload. It also tries to
|
|
||||||
+ guarantee low latency to interactive and soft real-time
|
|
||||||
+ applications. If compiled built-in (saying Y here), BFQ can
|
|
||||||
+ be configured to support hierarchical scheduling.
|
|
||||||
+
|
|
||||||
+config CGROUP_BFQIO
|
|
||||||
+ bool "BFQ hierarchical scheduling support"
|
|
||||||
+ depends on CGROUPS && IOSCHED_BFQ=y
|
|
||||||
+ default n
|
|
||||||
+ ---help---
|
|
||||||
+ Enable hierarchical scheduling in BFQ, using the cgroups
|
|
||||||
+ filesystem interface. The name of the subsystem will be
|
|
||||||
+ bfqio.
|
|
||||||
+
|
|
||||||
choice
|
|
||||||
prompt "Default I/O scheduler"
|
|
||||||
default DEFAULT_CFQ
|
|
||||||
@@ -52,6 +73,16 @@ choice
|
|
||||||
config DEFAULT_CFQ
|
|
||||||
bool "CFQ" if IOSCHED_CFQ=y
|
|
||||||
|
|
||||||
+ config DEFAULT_BFQ
|
|
||||||
+ bool "BFQ" if IOSCHED_BFQ=y
|
|
||||||
+ help
|
|
||||||
+ Selects BFQ as the default I/O scheduler which will be
|
|
||||||
+ used by default for all block devices.
|
|
||||||
+ The BFQ I/O scheduler aims at distributing the bandwidth
|
|
||||||
+ as desired, independently of the disk parameters and with
|
|
||||||
+ any workload. It also tries to guarantee low latency to
|
|
||||||
+ interactive and soft real-time applications.
|
|
||||||
+
|
|
||||||
config DEFAULT_NOOP
|
|
||||||
bool "No-op"
|
|
||||||
|
|
||||||
@@ -61,6 +92,7 @@ config DEFAULT_IOSCHED
|
|
||||||
string
|
|
||||||
default "deadline" if DEFAULT_DEADLINE
|
|
||||||
default "cfq" if DEFAULT_CFQ
|
|
||||||
+ default "bfq" if DEFAULT_BFQ
|
|
||||||
default "noop" if DEFAULT_NOOP
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
diff --git a/block/Makefile b/block/Makefile
|
|
||||||
index 36acdd7..736e91a 100644
|
|
||||||
--- a/block/Makefile
|
|
||||||
+++ b/block/Makefile
|
|
||||||
@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
|
|
||||||
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
|
|
||||||
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
|
|
||||||
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
|
|
||||||
+obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
|
|
||||||
obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
|
|
||||||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
|
|
||||||
index c47c358..1047d99 100644
|
|
||||||
--- a/include/linux/blkdev.h
|
|
||||||
+++ b/include/linux/blkdev.h
|
|
||||||
@@ -45,7 +45,7 @@ struct pr_ops;
|
|
||||||
* Maximum number of blkcg policies allowed to be registered concurrently.
|
|
||||||
* Defined here to simplify include dependency.
|
|
||||||
*/
|
|
||||||
-#define BLKCG_MAX_POLS 2
|
|
||||||
+#define BLKCG_MAX_POLS 3
|
|
||||||
|
|
||||||
typedef void (rq_end_io_fn)(struct request *, int);
|
|
||||||
|
|
||||||
--
|
|
||||||
2.10.0
|
|
||||||
|
|
||||||
-7109
File diff suppressed because it is too large
Load Diff
-34
@@ -1,34 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
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>
|
|
||||||
@@ -1,729 +0,0 @@
|
|||||||
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
|
|
||||||
-115
@@ -1,115 +0,0 @@
|
|||||||
From bc33c5df710c0aae6db396146194108634ef6f60 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Winkler, Tomas" <tomas.winkler@intel.com>
|
|
||||||
Date: Mon, 12 Sep 2016 16:04:19 +0300
|
|
||||||
Subject: [PATCH] tmp/tpm_crb: fix Intel PTT hw bug during idle state
|
|
||||||
|
|
||||||
There is a HW bug in Skylake, and Broxton PCH Intel PTT device, where
|
|
||||||
most of the registers in the control area except START, REQUEST, CANCEL,
|
|
||||||
and LOC_CTRL lost retention when the device is in the idle state. Hence
|
|
||||||
we need to bring the device to ready state before accessing the other
|
|
||||||
registers. The fix brings device to ready state before trying to read
|
|
||||||
command and response buffer addresses in order to remap the for access.
|
|
||||||
|
|
||||||
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
|
|
||||||
Tested-by: Jarkko Sakkinen <jarkko.sakkinn@linux.intel.com>
|
|
||||||
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinn@linux.intel.com>
|
|
||||||
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
---
|
|
||||||
drivers/char/tpm/tpm_crb.c | 47 ++++++++++++++++++++++++++++++++++++++--------
|
|
||||||
1 file changed, 39 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
|
|
||||||
index 8dd0f20..ff0d505 100644
|
|
||||||
--- a/drivers/char/tpm/tpm_crb.c
|
|
||||||
+++ b/drivers/char/tpm/tpm_crb.c
|
|
||||||
@@ -315,6 +315,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
|
|
||||||
struct list_head resources;
|
|
||||||
struct resource io_res;
|
|
||||||
struct device *dev = &device->dev;
|
|
||||||
+ u32 pa_high, pa_low;
|
|
||||||
u64 cmd_pa;
|
|
||||||
u32 cmd_size;
|
|
||||||
u64 rsp_pa;
|
|
||||||
@@ -342,12 +343,27 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
|
|
||||||
if (IS_ERR(priv->cca))
|
|
||||||
return PTR_ERR(priv->cca);
|
|
||||||
|
|
||||||
- cmd_pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) |
|
|
||||||
- (u64) ioread32(&priv->cca->cmd_pa_low);
|
|
||||||
+ /*
|
|
||||||
+ * PTT HW bug w/a: wake up the device to access
|
|
||||||
+ * possibly not retained registers.
|
|
||||||
+ */
|
|
||||||
+ ret = crb_cmd_ready(dev, priv);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ pa_high = ioread32(&priv->cca->cmd_pa_high);
|
|
||||||
+ pa_low = ioread32(&priv->cca->cmd_pa_low);
|
|
||||||
+ cmd_pa = ((u64)pa_high << 32) | pa_low;
|
|
||||||
cmd_size = ioread32(&priv->cca->cmd_size);
|
|
||||||
+
|
|
||||||
+ dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n",
|
|
||||||
+ pa_high, pa_low, cmd_size);
|
|
||||||
+
|
|
||||||
priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size);
|
|
||||||
- if (IS_ERR(priv->cmd))
|
|
||||||
- return PTR_ERR(priv->cmd);
|
|
||||||
+ if (IS_ERR(priv->cmd)) {
|
|
||||||
+ ret = PTR_ERR(priv->cmd);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
|
|
||||||
rsp_pa = le64_to_cpu(rsp_pa);
|
|
||||||
@@ -355,7 +371,8 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
|
|
||||||
|
|
||||||
if (cmd_pa != rsp_pa) {
|
|
||||||
priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
|
|
||||||
- return PTR_ERR_OR_ZERO(priv->rsp);
|
|
||||||
+ ret = PTR_ERR_OR_ZERO(priv->rsp);
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* According to the PTP specification, overlapping command and response
|
|
||||||
@@ -363,12 +380,18 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
|
|
||||||
*/
|
|
||||||
if (cmd_size != rsp_size) {
|
|
||||||
dev_err(dev, FW_BUG "overlapping command and response buffer sizes are not identical");
|
|
||||||
- return -EINVAL;
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
priv->cmd_size = cmd_size;
|
|
||||||
|
|
||||||
priv->rsp = priv->cmd;
|
|
||||||
- return 0;
|
|
||||||
+
|
|
||||||
+out:
|
|
||||||
+ crb_go_idle(dev, priv);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int crb_acpi_add(struct acpi_device *device)
|
|
||||||
@@ -412,7 +435,15 @@ static int crb_acpi_add(struct acpi_device *device)
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
- return crb_init(device, priv);
|
|
||||||
+ rc = crb_cmd_ready(dev, priv);
|
|
||||||
+ if (rc)
|
|
||||||
+ return rc;
|
|
||||||
+
|
|
||||||
+ rc = crb_init(device, priv);
|
|
||||||
+ if (rc)
|
|
||||||
+ crb_go_idle(dev, priv);
|
|
||||||
+
|
|
||||||
+ return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int crb_acpi_remove(struct acpi_device *device)
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
-134
@@ -1,134 +0,0 @@
|
|||||||
From e74f2f76c13770bb8e004475a933923e9c92723d Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Winkler, Tomas" <tomas.winkler@intel.com>
|
|
||||||
Date: Sat, 8 Oct 2016 14:59:39 +0300
|
|
||||||
Subject: [PATCH] tmp/tpm_crb: implement runtime pm for tpm_crb
|
|
||||||
|
|
||||||
Utilize runtime_pm for driving tpm crb idle states.
|
|
||||||
The framework calls cmd_ready from the pm_runtime_resume handler
|
|
||||||
and go idle from the pm_runtime_suspend handler.
|
|
||||||
The TPM framework should wake the device before transmit and receive.
|
|
||||||
In case the runtime_pm framework is not compiled in or enabled, the device
|
|
||||||
will be in the permanent ready state.
|
|
||||||
|
|
||||||
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
|
|
||||||
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
---
|
|
||||||
drivers/char/tpm/tpm-interface.c | 5 +++++
|
|
||||||
drivers/char/tpm/tpm_crb.c | 42 ++++++++++++++++++++++++++++++++++++----
|
|
||||||
2 files changed, 43 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
|
|
||||||
index 3a9149c..cb0e57e 100644
|
|
||||||
--- a/drivers/char/tpm/tpm-interface.c
|
|
||||||
+++ b/drivers/char/tpm/tpm-interface.c
|
|
||||||
@@ -29,6 +29,7 @@
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/freezer.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
|
|
||||||
#include "tpm.h"
|
|
||||||
#include "tpm_eventlog.h"
|
|
||||||
@@ -356,6 +357,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
|
|
||||||
if (!(flags & TPM_TRANSMIT_UNLOCKED))
|
|
||||||
mutex_lock(&chip->tpm_mutex);
|
|
||||||
|
|
||||||
+ pm_runtime_get_sync(chip->dev.parent);
|
|
||||||
+
|
|
||||||
rc = chip->ops->send(chip, (u8 *) buf, count);
|
|
||||||
if (rc < 0) {
|
|
||||||
dev_err(&chip->dev,
|
|
||||||
@@ -397,6 +400,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
|
|
||||||
dev_err(&chip->dev,
|
|
||||||
"tpm_transmit: tpm_recv: error %zd\n", rc);
|
|
||||||
out:
|
|
||||||
+ pm_runtime_put_sync(chip->dev.parent);
|
|
||||||
+
|
|
||||||
if (!(flags & TPM_TRANSMIT_UNLOCKED))
|
|
||||||
mutex_unlock(&chip->tpm_mutex);
|
|
||||||
return rc;
|
|
||||||
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
|
|
||||||
index f579f1a..717b6b4 100644
|
|
||||||
--- a/drivers/char/tpm/tpm_crb.c
|
|
||||||
+++ b/drivers/char/tpm/tpm_crb.c
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
#include <linux/highmem.h>
|
|
||||||
#include <linux/rculist.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
#include "tpm.h"
|
|
||||||
|
|
||||||
#define ACPI_SIG_TPM2 "TPM2"
|
|
||||||
@@ -149,8 +150,6 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
|
|
||||||
-
|
|
||||||
static u8 crb_status(struct tpm_chip *chip)
|
|
||||||
{
|
|
||||||
struct crb_priv *priv = dev_get_drvdata(&chip->dev);
|
|
||||||
@@ -433,11 +432,21 @@ static int crb_acpi_add(struct acpi_device *device)
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
+ pm_runtime_get_noresume(dev);
|
|
||||||
+ pm_runtime_set_active(dev);
|
|
||||||
+ pm_runtime_enable(dev);
|
|
||||||
+
|
|
||||||
rc = tpm_chip_register(chip);
|
|
||||||
- if (rc)
|
|
||||||
+ if (rc) {
|
|
||||||
crb_go_idle(dev, priv);
|
|
||||||
+ pm_runtime_put_noidle(dev);
|
|
||||||
+ pm_runtime_disable(dev);
|
|
||||||
+ return rc;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- return rc;
|
|
||||||
+ pm_runtime_put(dev);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int crb_acpi_remove(struct acpi_device *device)
|
|
||||||
@@ -447,9 +456,34 @@ static int crb_acpi_remove(struct acpi_device *device)
|
|
||||||
|
|
||||||
tpm_chip_unregister(chip);
|
|
||||||
|
|
||||||
+ pm_runtime_disable(dev);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef CONFIG_PM
|
|
||||||
+static int crb_pm_runtime_suspend(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ struct tpm_chip *chip = dev_get_drvdata(dev);
|
|
||||||
+ struct crb_priv *priv = dev_get_drvdata(&chip->dev);
|
|
||||||
+
|
|
||||||
+ return crb_go_idle(dev, priv);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int crb_pm_runtime_resume(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ struct tpm_chip *chip = dev_get_drvdata(dev);
|
|
||||||
+ struct crb_priv *priv = dev_get_drvdata(&chip->dev);
|
|
||||||
+
|
|
||||||
+ return crb_cmd_ready(dev, priv);
|
|
||||||
+}
|
|
||||||
+#endif /* CONFIG_PM */
|
|
||||||
+
|
|
||||||
+static const struct dev_pm_ops crb_pm = {
|
|
||||||
+ SET_SYSTEM_SLEEP_PM_OPS(tpm_pm_suspend, tpm_pm_resume)
|
|
||||||
+ SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL)
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct acpi_device_id crb_device_ids[] = {
|
|
||||||
{"MSFT0101", 0},
|
|
||||||
{"", 0},
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
From ba5287b6ef6a2ee91dc6cc0829649cecf7b70253 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Winkler, Tomas" <tomas.winkler@intel.com>
|
|
||||||
Date: Thu, 15 Sep 2016 10:27:38 +0300
|
|
||||||
Subject: [PATCH] tpm/tpm_crb: implement tpm crb idle state
|
|
||||||
|
|
||||||
The register TPM_CRB_CTRL_REQ_x contains bits goIdle and cmdReady for
|
|
||||||
SW to indicate that the device can enter or should exit the idle state.
|
|
||||||
|
|
||||||
The legacy ACPI-start (SMI + DMA) based devices do not support these
|
|
||||||
bits and the idle state management is not exposed to the host SW.
|
|
||||||
Thus, this functionality only is enabled only for a CRB start (MMIO)
|
|
||||||
based devices.
|
|
||||||
|
|
||||||
Based on Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
original patch:
|
|
||||||
'tpm_crb: implement power tpm crb power management'
|
|
||||||
|
|
||||||
To keep the implementation local to the hw we don't use wait_for_tpm_stat
|
|
||||||
for polling the TPM_CRB_CTRL_REQ.
|
|
||||||
|
|
||||||
[jarkko.sakkinen@linux.intel.com: removed cmdReady debug trace on a
|
|
||||||
success case due the heavy amount of log traffic it causes.]
|
|
||||||
|
|
||||||
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
|
|
||||||
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
---
|
|
||||||
drivers/char/tpm/tpm_crb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 66 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
|
|
||||||
index a7c870a..8dd0f20 100644
|
|
||||||
--- a/drivers/char/tpm/tpm_crb.c
|
|
||||||
+++ b/drivers/char/tpm/tpm_crb.c
|
|
||||||
@@ -83,6 +83,72 @@ struct crb_priv {
|
|
||||||
u32 cmd_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * crb_go_idle - request tpm crb device to go the idle state
|
|
||||||
+ *
|
|
||||||
+ * @dev: crb device
|
|
||||||
+ * @priv: crb private data
|
|
||||||
+ *
|
|
||||||
+ * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
|
|
||||||
+ * The device should respond within TIMEOUT_C by clearing the bit.
|
|
||||||
+ * Anyhow, we do not wait here as a consequent CMD_READY request
|
|
||||||
+ * will be handled correctly even if idle was not completed.
|
|
||||||
+ *
|
|
||||||
+ * The function does nothing for devices with ACPI-start method.
|
|
||||||
+ *
|
|
||||||
+ * Return: 0 always
|
|
||||||
+ */
|
|
||||||
+static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
|
|
||||||
+{
|
|
||||||
+ if (priv->flags & CRB_FL_ACPI_START)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
|
|
||||||
+ /* we don't really care when this settles */
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * crb_cmd_ready - request tpm crb device to enter ready state
|
|
||||||
+ *
|
|
||||||
+ * @dev: crb device
|
|
||||||
+ * @priv: crb private data
|
|
||||||
+ *
|
|
||||||
+ * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
|
|
||||||
+ * and poll till the device acknowledge it by clearing the bit.
|
|
||||||
+ * The device should respond within TIMEOUT_C.
|
|
||||||
+ *
|
|
||||||
+ * The function does nothing for devices with ACPI-start method
|
|
||||||
+ *
|
|
||||||
+ * Return: 0 on success -ETIME on timeout;
|
|
||||||
+ */
|
|
||||||
+static int __maybe_unused crb_cmd_ready(struct device *dev,
|
|
||||||
+ struct crb_priv *priv)
|
|
||||||
+{
|
|
||||||
+ ktime_t stop, start;
|
|
||||||
+
|
|
||||||
+ if (priv->flags & CRB_FL_ACPI_START)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
|
|
||||||
+
|
|
||||||
+ start = ktime_get();
|
|
||||||
+ stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
|
|
||||||
+ do {
|
|
||||||
+ if (!(ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY))
|
|
||||||
+ return 0;
|
|
||||||
+ usleep_range(50, 100);
|
|
||||||
+ } while (ktime_before(ktime_get(), stop));
|
|
||||||
+
|
|
||||||
+ if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
|
|
||||||
+ dev_warn(dev, "cmdReady timed out\n");
|
|
||||||
+ return -ETIME;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
|
|
||||||
|
|
||||||
static u8 crb_status(struct tpm_chip *chip)
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
From c58bd34cec4c05f8e3362a79ae94de9f405c39b5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Winkler, Tomas" <tomas.winkler@intel.com>
|
|
||||||
Date: Mon, 12 Sep 2016 16:04:20 +0300
|
|
||||||
Subject: [PATCH] tpm/tpm_crb: open code the crb_init into acpi_add
|
|
||||||
|
|
||||||
This is preparation step for implementing tpm crb
|
|
||||||
runtime pm. We need to have tpm chip allocated
|
|
||||||
and populated before we access the runtime handlers.
|
|
||||||
|
|
||||||
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
|
|
||||||
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
|
||||||
---
|
|
||||||
drivers/char/tpm/tpm_crb.c | 26 ++++++++++----------------
|
|
||||||
1 file changed, 10 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
|
|
||||||
index ff0d505..f579f1a 100644
|
|
||||||
--- a/drivers/char/tpm/tpm_crb.c
|
|
||||||
+++ b/drivers/char/tpm/tpm_crb.c
|
|
||||||
@@ -262,21 +262,6 @@ static const struct tpm_class_ops tpm_crb = {
|
|
||||||
.req_complete_val = CRB_DRV_STS_COMPLETE,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static int crb_init(struct acpi_device *device, struct crb_priv *priv)
|
|
||||||
-{
|
|
||||||
- struct tpm_chip *chip;
|
|
||||||
-
|
|
||||||
- chip = tpmm_chip_alloc(&device->dev, &tpm_crb);
|
|
||||||
- if (IS_ERR(chip))
|
|
||||||
- return PTR_ERR(chip);
|
|
||||||
-
|
|
||||||
- dev_set_drvdata(&chip->dev, priv);
|
|
||||||
- chip->acpi_dev_handle = device->handle;
|
|
||||||
- chip->flags = TPM_CHIP_FLAG_TPM2;
|
|
||||||
-
|
|
||||||
- return tpm_chip_register(chip);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static int crb_check_resource(struct acpi_resource *ares, void *data)
|
|
||||||
{
|
|
||||||
struct resource *io_res = data;
|
|
||||||
@@ -398,6 +383,7 @@ static int crb_acpi_add(struct acpi_device *device)
|
|
||||||
{
|
|
||||||
struct acpi_table_tpm2 *buf;
|
|
||||||
struct crb_priv *priv;
|
|
||||||
+ struct tpm_chip *chip;
|
|
||||||
struct device *dev = &device->dev;
|
|
||||||
acpi_status status;
|
|
||||||
u32 sm;
|
|
||||||
@@ -435,11 +421,19 @@ static int crb_acpi_add(struct acpi_device *device)
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
+ chip = tpmm_chip_alloc(dev, &tpm_crb);
|
|
||||||
+ if (IS_ERR(chip))
|
|
||||||
+ return PTR_ERR(chip);
|
|
||||||
+
|
|
||||||
+ dev_set_drvdata(&chip->dev, priv);
|
|
||||||
+ chip->acpi_dev_handle = device->handle;
|
|
||||||
+ chip->flags = TPM_CHIP_FLAG_TPM2;
|
|
||||||
+
|
|
||||||
rc = crb_cmd_ready(dev, priv);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
- rc = crb_init(device, priv);
|
|
||||||
+ rc = tpm_chip_register(chip);
|
|
||||||
if (rc)
|
|
||||||
crb_go_idle(dev, priv);
|
|
||||||
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
From 68017e5d87a2477d40476f1a0a06f202ee79316b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Date: Mon, 13 Nov 2017 07:34:07 +0100
|
||||||
|
Subject: [PATCH] doc, block, bfq: update max IOPS sustainable with BFQ
|
||||||
|
|
||||||
|
We have investigated more deeply the performance of BFQ, in terms of
|
||||||
|
number of IOPS that can be processed by the CPU when BFQ is used as
|
||||||
|
I/O scheduler. In more detail, using the script [1], we have measured
|
||||||
|
the number of IOPS reached on top of a null block device configured
|
||||||
|
with zero latency, as a function of the workload (sequential read,
|
||||||
|
sequential write, random read, random write) and of the system (we
|
||||||
|
considered desktops, laptops and embedded systems).
|
||||||
|
|
||||||
|
Basing on the resulting figures, with this commit we update the
|
||||||
|
current, conservative IOPS range reported in BFQ documentation. In
|
||||||
|
particular, the documentation now reports, for each of three different
|
||||||
|
systems, the lowest number of IOPS obtained for that system with the
|
||||||
|
above test (namely, the value obtained with the workload leading to
|
||||||
|
the lowest IOPS).
|
||||||
|
|
||||||
|
[1] https://github.com/Algodev-github/IOSpeed
|
||||||
|
|
||||||
|
Reviewed-by: Lee Tibbert <lee.tibbert@gmail.com>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
|
||||||
|
Signed-off-by: Luca Miccio <lucmiccio@gmail.com>
|
||||||
|
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||||
|
---
|
||||||
|
Documentation/block/bfq-iosched.txt | 17 +++++++++++------
|
||||||
|
1 file changed, 11 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/block/bfq-iosched.txt b/Documentation/block/bfq-iosched.txt
|
||||||
|
index 3d6951d63489..7a9361508157 100644
|
||||||
|
--- a/Documentation/block/bfq-iosched.txt
|
||||||
|
+++ b/Documentation/block/bfq-iosched.txt
|
||||||
|
@@ -20,12 +20,17 @@ for that device, by setting low_latency to 0. See Section 3 for
|
||||||
|
details on how to configure BFQ for the desired tradeoff between
|
||||||
|
latency and throughput, or on how to maximize throughput.
|
||||||
|
|
||||||
|
-On average CPUs, the current version of BFQ can handle devices
|
||||||
|
-performing at most ~30K IOPS; at most ~50 KIOPS on faster CPUs. As a
|
||||||
|
-reference, 30-50 KIOPS correspond to very high bandwidths with
|
||||||
|
-sequential I/O (e.g., 8-12 GB/s if I/O requests are 256 KB large), and
|
||||||
|
-to 120-200 MB/s with 4KB random I/O. BFQ is currently being tested on
|
||||||
|
-multi-queue devices too.
|
||||||
|
+BFQ has a non-null overhead, which limits the maximum IOPS that the
|
||||||
|
+CPU can process for a device scheduled with BFQ. To give an idea of
|
||||||
|
+the limits on slow or average CPUs, here are BFQ limits for three
|
||||||
|
+different CPUs, on, respectively, an average laptop, an old desktop,
|
||||||
|
+and a cheap embedded system, in case full hierarchical support is
|
||||||
|
+enabled (i.e., CONFIG_BFQ_GROUP_IOSCHED is set):
|
||||||
|
+- Intel i7-4850HQ: 250 KIOPS
|
||||||
|
+- AMD A8-3850: 170 KIOPS
|
||||||
|
+- ARM CortexTM-A53 Octa-core: 45 KIOPS
|
||||||
|
+
|
||||||
|
+BFQ works for multi-queue devices too.
|
||||||
|
|
||||||
|
The table of contents follow. Impatients can just jump to Section 3.
|
||||||
|
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
|
||||||
|
fs/aufs/Kconfig | 2 +-
|
||||||
|
fs/dcache.c | 2 ++
|
||||||
|
fs/exec.c | 1 +
|
||||||
|
fs/fcntl.c | 1 +
|
||||||
|
fs/file_table.c | 4 ++++
|
||||||
|
fs/inode.c | 1 +
|
||||||
|
fs/namespace.c | 2 ++
|
||||||
|
fs/notify/group.c | 4 ++++
|
||||||
|
fs/notify/mark.c | 4 ++++
|
||||||
|
fs/open.c | 2 ++
|
||||||
|
fs/read_write.c | 4 ++++
|
||||||
|
fs/splice.c | 2 ++
|
||||||
|
fs/sync.c | 1 +
|
||||||
|
fs/xattr.c | 1 +
|
||||||
|
kernel/task_work.c | 1 +
|
||||||
|
security/commoncap.c | 2 ++
|
||||||
|
security/device_cgroup.c | 2 ++
|
||||||
|
security/security.c | 10 ++++++++++
|
||||||
|
18 files changed, 45 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/aufs/Kconfig linux-4.14.14-aufs.mod/fs/aufs/Kconfig
|
||||||
|
--- linux-4.14.14-aufs/fs/aufs/Kconfig 2018-01-17 11:17:42.191975391 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/aufs/Kconfig 2018-01-17 11:18:22.784556755 +0200
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
config AUFS_FS
|
||||||
|
- bool "Aufs (Advanced multi layered unification filesystem) support"
|
||||||
|
+ tristate "Aufs (Advanced multi layered unification filesystem) support"
|
||||||
|
help
|
||||||
|
Aufs is a stackable unification filesystem such as Unionfs,
|
||||||
|
which unifies several directories and provides a merged single
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/dcache.c linux-4.14.14-aufs.mod/fs/dcache.c
|
||||||
|
--- linux-4.14.14-aufs/fs/dcache.c 2018-01-17 11:17:42.200975519 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/dcache.c 2018-01-17 11:18:22.784556755 +0200
|
||||||
|
@@ -1305,6 +1305,7 @@ rename_retry:
|
||||||
|
seq = 1;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(d_walk);
|
||||||
|
|
||||||
|
struct check_mount {
|
||||||
|
struct vfsmount *mnt;
|
||||||
|
@@ -2894,6 +2895,7 @@ void d_exchange(struct dentry *dentry1,
|
||||||
|
|
||||||
|
write_sequnlock(&rename_lock);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(d_exchange);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* d_ancestor - search for an ancestor
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/exec.c linux-4.14.14-aufs.mod/fs/exec.c
|
||||||
|
--- linux-4.14.14-aufs/fs/exec.c 2018-01-17 11:08:18.957908605 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/exec.c 2018-01-17 11:18:22.785556770 +0200
|
||||||
|
@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path
|
||||||
|
return (path->mnt->mnt_flags & MNT_NOEXEC) ||
|
||||||
|
(path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(path_noexec);
|
||||||
|
|
||||||
|
#ifdef CONFIG_USELIB
|
||||||
|
/*
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/fcntl.c linux-4.14.14-aufs.mod/fs/fcntl.c
|
||||||
|
--- linux-4.14.14-aufs/fs/fcntl.c 2018-01-17 11:17:42.200975519 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/fcntl.c 2018-01-17 11:18:22.785556770 +0200
|
||||||
|
@@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, un
|
||||||
|
out:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(setfl);
|
||||||
|
|
||||||
|
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
|
||||||
|
int force)
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/file_table.c linux-4.14.14-aufs.mod/fs/file_table.c
|
||||||
|
--- linux-4.14.14-aufs/fs/file_table.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/file_table.c 2018-01-17 11:18:22.785556770 +0200
|
||||||
|
@@ -148,6 +148,7 @@ over:
|
||||||
|
}
|
||||||
|
return ERR_PTR(-ENFILE);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(get_empty_filp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alloc_file - allocate and initialize a 'struct file'
|
||||||
|
@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
|
||||||
|
{
|
||||||
|
delayed_fput(NULL);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(flush_delayed_fput);
|
||||||
|
|
||||||
|
static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
|
||||||
|
|
||||||
|
@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(fput);
|
||||||
|
+EXPORT_SYMBOL_GPL(__fput_sync);
|
||||||
|
|
||||||
|
void put_filp(struct file *file)
|
||||||
|
{
|
||||||
|
@@ -308,6 +311,7 @@ void put_filp(struct file *file)
|
||||||
|
file_free(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(put_filp);
|
||||||
|
|
||||||
|
void __init files_init(void)
|
||||||
|
{
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/inode.c linux-4.14.14-aufs.mod/fs/inode.c
|
||||||
|
--- linux-4.14.14-aufs/fs/inode.c 2018-01-17 11:17:42.200975519 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/inode.c 2018-01-17 11:18:22.785556770 +0200
|
||||||
|
@@ -1664,6 +1664,7 @@ int update_time(struct inode *inode, str
|
||||||
|
|
||||||
|
return update_time(inode, time, flags);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(update_time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* touch_atime - update the access time
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/namespace.c linux-4.14.14-aufs.mod/fs/namespace.c
|
||||||
|
--- linux-4.14.14-aufs/fs/namespace.c 2018-01-17 11:17:42.201975534 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/namespace.c 2018-01-17 11:18:22.785556770 +0200
|
||||||
|
@@ -517,6 +517,7 @@ void __mnt_drop_write(struct vfsmount *m
|
||||||
|
mnt_dec_writers(real_mount(mnt));
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(__mnt_drop_write);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mnt_drop_write - give up write access to a mount
|
||||||
|
@@ -1887,6 +1888,7 @@ int iterate_mounts(int (*f)(struct vfsmo
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(iterate_mounts);
|
||||||
|
|
||||||
|
static void cleanup_group_ids(struct mount *mnt, struct mount *end)
|
||||||
|
{
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/notify/group.c linux-4.14.14-aufs.mod/fs/notify/group.c
|
||||||
|
--- linux-4.14.14-aufs/fs/notify/group.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/notify/group.c 2018-01-17 11:18:22.786556784 +0200
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include <linux/srcu.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
|
||||||
|
#include <linux/fsnotify_backend.h>
|
||||||
|
#include "fsnotify.h"
|
||||||
|
@@ -109,6 +110,7 @@ void fsnotify_get_group(struct fsnotify_
|
||||||
|
{
|
||||||
|
atomic_inc(&group->refcnt);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_get_group);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop a reference to a group. Free it if it's through.
|
||||||
|
@@ -118,6 +120,7 @@ void fsnotify_put_group(struct fsnotify_
|
||||||
|
if (atomic_dec_and_test(&group->refcnt))
|
||||||
|
fsnotify_final_destroy_group(group);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_put_group);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new fsnotify_group and hold a reference for the group returned.
|
||||||
|
@@ -147,6 +150,7 @@ struct fsnotify_group *fsnotify_alloc_gr
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
|
||||||
|
|
||||||
|
int fsnotify_fasync(int fd, struct file *file, int on)
|
||||||
|
{
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/notify/mark.c linux-4.14.14-aufs.mod/fs/notify/mark.c
|
||||||
|
--- linux-4.14.14-aufs/fs/notify/mark.c 2018-01-17 11:08:18.963908691 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/notify/mark.c 2018-01-17 11:18:22.786556784 +0200
|
||||||
|
@@ -124,6 +124,7 @@ static void __fsnotify_recalc_mask(struc
|
||||||
|
else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT)
|
||||||
|
real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate mask of events for a list of marks. The caller must make sure
|
||||||
|
@@ -271,6 +272,7 @@ static bool fsnotify_get_mark_safe(struc
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Puts marks and wakes up group destruction if necessary.
|
||||||
|
@@ -428,6 +430,7 @@ int fsnotify_compare_groups(struct fsnot
|
||||||
|
return 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
|
||||||
|
|
||||||
|
static int fsnotify_attach_connector_to_object(
|
||||||
|
struct fsnotify_mark_connector __rcu **connp,
|
||||||
|
@@ -557,6 +560,7 @@ out_err:
|
||||||
|
spin_unlock(&mark->lock);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach an initialized mark to a given group and fs object.
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/open.c linux-4.14.14-aufs.mod/fs/open.c
|
||||||
|
--- linux-4.14.14-aufs/fs/open.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/open.c 2018-01-17 11:18:22.786556784 +0200
|
||||||
|
@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l
|
||||||
|
inode_unlock(dentry->d_inode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(do_truncate);
|
||||||
|
|
||||||
|
long vfs_truncate(const struct path *path, loff_t length)
|
||||||
|
{
|
||||||
|
@@ -691,6 +692,7 @@ int open_check_o_direct(struct file *f)
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(open_check_o_direct);
|
||||||
|
|
||||||
|
static int do_dentry_open(struct file *f,
|
||||||
|
struct inode *inode,
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/read_write.c linux-4.14.14-aufs.mod/fs/read_write.c
|
||||||
|
--- linux-4.14.14-aufs/fs/read_write.c 2018-01-17 11:17:42.201975534 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/read_write.c 2018-01-17 11:18:22.790556841 +0200
|
||||||
|
@@ -454,6 +454,7 @@ ssize_t vfs_read(struct file *file, char
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(vfs_read);
|
||||||
|
|
||||||
|
static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
|
||||||
|
{
|
||||||
|
@@ -494,6 +495,7 @@ vfs_readf_t vfs_readf(struct file *file)
|
||||||
|
return new_sync_read;
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(vfs_readf);
|
||||||
|
|
||||||
|
vfs_writef_t vfs_writef(struct file *file)
|
||||||
|
{
|
||||||
|
@@ -505,6 +507,7 @@ vfs_writef_t vfs_writef(struct file *fil
|
||||||
|
return new_sync_write;
|
||||||
|
return ERR_PTR(-ENOSYS);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(vfs_writef);
|
||||||
|
|
||||||
|
ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
|
||||||
|
{
|
||||||
|
@@ -574,6 +577,7 @@ ssize_t vfs_write(struct file *file, con
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(vfs_write);
|
||||||
|
|
||||||
|
static inline loff_t file_pos_read(struct file *file)
|
||||||
|
{
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/splice.c linux-4.14.14-aufs.mod/fs/splice.c
|
||||||
|
--- linux-4.14.14-aufs/fs/splice.c 2018-01-17 11:17:42.201975534 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/splice.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -850,6 +850,7 @@ long do_splice_from(struct pipe_inode_in
|
||||||
|
|
||||||
|
return splice_write(pipe, out, ppos, len, flags);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(do_splice_from);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to initiate a splice from a file to a pipe.
|
||||||
|
@@ -879,6 +880,7 @@ long do_splice_to(struct file *in, loff_
|
||||||
|
|
||||||
|
return splice_read(in, ppos, pipe, len, flags);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(do_splice_to);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* splice_direct_to_actor - splices data directly between two non-pipes
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/sync.c linux-4.14.14-aufs.mod/fs/sync.c
|
||||||
|
--- linux-4.14.14-aufs/fs/sync.c 2018-01-17 11:17:42.201975534 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/sync.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block
|
||||||
|
sb->s_op->sync_fs(sb, wait);
|
||||||
|
return __sync_blockdev(sb->s_bdev, wait);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(__sync_filesystem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write out and wait upon all dirty data associated with this
|
||||||
|
diff -Nurp linux-4.14.14-aufs/fs/xattr.c linux-4.14.14-aufs.mod/fs/xattr.c
|
||||||
|
--- linux-4.14.14-aufs/fs/xattr.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/fs/xattr.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -297,6 +297,7 @@ vfs_getxattr_alloc(struct dentry *dentry
|
||||||
|
*xattr_value = value;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
|
||||||
|
diff -Nurp linux-4.14.14-aufs/kernel/task_work.c linux-4.14.14-aufs.mod/kernel/task_work.c
|
||||||
|
--- linux-4.14.14-aufs/kernel/task_work.c 2018-01-17 11:08:18.979908919 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/kernel/task_work.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -116,3 +116,4 @@ void task_work_run(void)
|
||||||
|
} while (work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(task_work_run);
|
||||||
|
diff -Nurp linux-4.14.14-aufs/security/commoncap.c linux-4.14.14-aufs.mod/security/commoncap.c
|
||||||
|
--- linux-4.14.14-aufs/security/commoncap.c 2018-01-17 11:08:18.999909204 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/security/commoncap.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -1267,12 +1267,14 @@ int cap_mmap_addr(unsigned long addr)
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(cap_mmap_addr);
|
||||||
|
|
||||||
|
int cap_mmap_file(struct file *file, unsigned long reqprot,
|
||||||
|
unsigned long prot, unsigned long flags)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(cap_mmap_file);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY
|
||||||
|
|
||||||
|
diff -Nurp linux-4.14.14-aufs/security/device_cgroup.c linux-4.14.14-aufs.mod/security/device_cgroup.c
|
||||||
|
--- linux-4.14.14-aufs/security/device_cgroup.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/security/device_cgroup.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
#include <linux/device_cgroup.h>
|
||||||
|
#include <linux/cgroup.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
+#include <linux/export.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
@@ -850,6 +851,7 @@ int __devcgroup_inode_permission(struct
|
||||||
|
return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
|
||||||
|
access);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);
|
||||||
|
|
||||||
|
int devcgroup_inode_mknod(int mode, dev_t dev)
|
||||||
|
{
|
||||||
|
diff -Nurp linux-4.14.14-aufs/security/security.c linux-4.14.14-aufs.mod/security/security.c
|
||||||
|
--- linux-4.14.14-aufs/security/security.c 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux-4.14.14-aufs.mod/security/security.c 2018-01-17 11:18:22.791556855 +0200
|
||||||
|
@@ -530,6 +530,7 @@ int security_path_rmdir(const struct pat
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_rmdir, 0, dir, dentry);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_rmdir);
|
||||||
|
|
||||||
|
int security_path_unlink(const struct path *dir, struct dentry *dentry)
|
||||||
|
{
|
||||||
|
@@ -546,6 +547,7 @@ int security_path_symlink(const struct p
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_symlink, 0, dir, dentry, old_name);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_symlink);
|
||||||
|
|
||||||
|
int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
|
||||||
|
struct dentry *new_dentry)
|
||||||
|
@@ -554,6 +556,7 @@ int security_path_link(struct dentry *ol
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_link);
|
||||||
|
|
||||||
|
int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
|
||||||
|
const struct path *new_dir, struct dentry *new_dentry,
|
||||||
|
@@ -581,6 +584,7 @@ int security_path_truncate(const struct
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_truncate, 0, path);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_truncate);
|
||||||
|
|
||||||
|
int security_path_chmod(const struct path *path, umode_t mode)
|
||||||
|
{
|
||||||
|
@@ -588,6 +592,7 @@ int security_path_chmod(const struct pat
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_chmod, 0, path, mode);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_chmod);
|
||||||
|
|
||||||
|
int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
|
||||||
|
{
|
||||||
|
@@ -595,6 +600,7 @@ int security_path_chown(const struct pat
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(path_chown, 0, path, uid, gid);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_path_chown);
|
||||||
|
|
||||||
|
int security_path_chroot(const struct path *path)
|
||||||
|
{
|
||||||
|
@@ -680,6 +686,7 @@ int security_inode_readlink(struct dentr
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(inode_readlink, 0, dentry);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_inode_readlink);
|
||||||
|
|
||||||
|
int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
|
||||||
|
bool rcu)
|
||||||
|
@@ -695,6 +702,7 @@ int security_inode_permission(struct ino
|
||||||
|
return 0;
|
||||||
|
return call_int_hook(inode_permission, 0, inode, mask);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_inode_permission);
|
||||||
|
|
||||||
|
int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
|
{
|
||||||
|
@@ -866,6 +874,7 @@ int security_file_permission(struct file
|
||||||
|
|
||||||
|
return fsnotify_perm(file, mask);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_file_permission);
|
||||||
|
|
||||||
|
int security_file_alloc(struct file *file)
|
||||||
|
{
|
||||||
|
@@ -925,6 +934,7 @@ int security_mmap_file(struct file *file
|
||||||
|
return ret;
|
||||||
|
return ima_file_mmap(file, prot);
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(security_mmap_file);
|
||||||
|
|
||||||
|
int security_mmap_addr(unsigned long addr)
|
||||||
|
{
|
||||||
+3648
-1504
File diff suppressed because it is too large
Load Diff
@@ -1,402 +0,0 @@
|
|||||||
|
|
||||||
fs/aufs/Kconfig | 2 +-
|
|
||||||
fs/dcache.c | 2 ++
|
|
||||||
fs/exec.c | 1 +
|
|
||||||
fs/fcntl.c | 1 +
|
|
||||||
fs/file_table.c | 4 ++++
|
|
||||||
fs/inode.c | 1 +
|
|
||||||
fs/namespace.c | 2 ++
|
|
||||||
fs/notify/group.c | 4 ++++
|
|
||||||
fs/notify/mark.c | 4 ++++
|
|
||||||
fs/open.c | 2 ++
|
|
||||||
fs/read_write.c | 2 ++
|
|
||||||
fs/splice.c | 2 ++
|
|
||||||
fs/xattr.c | 1 +
|
|
||||||
kernel/task_work.c | 1 +
|
|
||||||
security/commoncap.c | 2 ++
|
|
||||||
security/device_cgroup.c | 2 ++
|
|
||||||
security/security.c | 10 ++++++++++
|
|
||||||
17 files changed, 42 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/aufs/Kconfig linux-4.9-aufs-mod/fs/aufs/Kconfig
|
|
||||||
--- linux-4.9-aufs/fs/aufs/Kconfig 2016-12-31 00:31:52.367789380 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/aufs/Kconfig 2016-12-31 00:32:35.153785422 +0200
|
|
||||||
@@ -1,5 +1,5 @@
|
|
||||||
config AUFS_FS
|
|
||||||
- bool "Aufs (Advanced multi layered unification filesystem) support"
|
|
||||||
+ tristate "Aufs (Advanced multi layered unification filesystem) support"
|
|
||||||
help
|
|
||||||
Aufs is a stackable unification filesystem such as Unionfs,
|
|
||||||
which unifies several directories and provides a merged single
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/dcache.c linux-4.9-aufs-mod/fs/dcache.c
|
|
||||||
--- linux-4.9-aufs/fs/dcache.c 2016-12-31 00:31:52.379789379 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/dcache.c 2016-12-31 01:49:12.324360147 +0200
|
|
||||||
@@ -1272,6 +1272,7 @@ rename_retry:
|
|
||||||
seq = 1;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(d_walk);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search for at least 1 mount point in the dentry's subdirs.
|
|
||||||
@@ -2855,6 +2856,7 @@ void d_exchange(struct dentry *dentry1,
|
|
||||||
|
|
||||||
write_sequnlock(&rename_lock);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(d_exchange);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* d_ancestor - search for an ancestor
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/exec.c linux-4.9-aufs-mod/fs/exec.c
|
|
||||||
--- linux-4.9-aufs/fs/exec.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/exec.c 2016-12-31 00:32:35.153785422 +0200
|
|
||||||
@@ -104,6 +104,7 @@ bool path_noexec(const struct path *path
|
|
||||||
return (path->mnt->mnt_flags & MNT_NOEXEC) ||
|
|
||||||
(path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(path_noexec);
|
|
||||||
|
|
||||||
#ifdef CONFIG_USELIB
|
|
||||||
/*
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/fcntl.c linux-4.9-aufs-mod/fs/fcntl.c
|
|
||||||
--- linux-4.9-aufs/fs/fcntl.c 2016-12-31 00:31:52.379789379 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/fcntl.c 2016-12-31 00:32:35.154785422 +0200
|
|
||||||
@@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, un
|
|
||||||
out:
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(setfl);
|
|
||||||
|
|
||||||
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
|
|
||||||
int force)
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/file_table.c linux-4.9-aufs-mod/fs/file_table.c
|
|
||||||
--- linux-4.9-aufs/fs/file_table.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/file_table.c 2016-12-31 00:32:35.154785422 +0200
|
|
||||||
@@ -147,6 +147,7 @@ over:
|
|
||||||
}
|
|
||||||
return ERR_PTR(-ENFILE);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(get_empty_filp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* alloc_file - allocate and initialize a 'struct file'
|
|
||||||
@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
|
|
||||||
{
|
|
||||||
delayed_fput(NULL);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(flush_delayed_fput);
|
|
||||||
|
|
||||||
static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
|
|
||||||
|
|
||||||
@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(fput);
|
|
||||||
+EXPORT_SYMBOL_GPL(__fput_sync);
|
|
||||||
|
|
||||||
void put_filp(struct file *file)
|
|
||||||
{
|
|
||||||
@@ -308,6 +311,7 @@ void put_filp(struct file *file)
|
|
||||||
file_free(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(put_filp);
|
|
||||||
|
|
||||||
void __init files_init(void)
|
|
||||||
{
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/inode.c linux-4.9-aufs-mod/fs/inode.c
|
|
||||||
--- linux-4.9-aufs/fs/inode.c 2016-12-31 00:31:52.379789379 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/inode.c 2016-12-31 00:32:35.154785422 +0200
|
|
||||||
@@ -1651,6 +1651,7 @@ int update_time(struct inode *inode, str
|
|
||||||
|
|
||||||
return update_time(inode, time, flags);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(update_time);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* touch_atime - update the access time
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/namespace.c linux-4.9-aufs-mod/fs/namespace.c
|
|
||||||
--- linux-4.9-aufs/fs/namespace.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/namespace.c 2016-12-31 00:32:35.154785422 +0200
|
|
||||||
@@ -466,6 +466,7 @@ void __mnt_drop_write(struct vfsmount *m
|
|
||||||
mnt_dec_writers(real_mount(mnt));
|
|
||||||
preempt_enable();
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(__mnt_drop_write);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mnt_drop_write - give up write access to a mount
|
|
||||||
@@ -1823,6 +1824,7 @@ int iterate_mounts(int (*f)(struct vfsmo
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(iterate_mounts);
|
|
||||||
|
|
||||||
static void cleanup_group_ids(struct mount *mnt, struct mount *end)
|
|
||||||
{
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/notify/group.c linux-4.9-aufs-mod/fs/notify/group.c
|
|
||||||
--- linux-4.9-aufs/fs/notify/group.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/notify/group.c 2016-12-31 00:32:35.155785422 +0200
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include <linux/srcu.h>
|
|
||||||
#include <linux/rculist.h>
|
|
||||||
#include <linux/wait.h>
|
|
||||||
+#include <linux/module.h>
|
|
||||||
|
|
||||||
#include <linux/fsnotify_backend.h>
|
|
||||||
#include "fsnotify.h"
|
|
||||||
@@ -100,6 +101,7 @@ void fsnotify_get_group(struct fsnotify_
|
|
||||||
{
|
|
||||||
atomic_inc(&group->refcnt);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_get_group);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Drop a reference to a group. Free it if it's through.
|
|
||||||
@@ -109,6 +111,7 @@ void fsnotify_put_group(struct fsnotify_
|
|
||||||
if (atomic_dec_and_test(&group->refcnt))
|
|
||||||
fsnotify_final_destroy_group(group);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_put_group);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new fsnotify_group and hold a reference for the group returned.
|
|
||||||
@@ -137,6 +140,7 @@ struct fsnotify_group *fsnotify_alloc_gr
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
|
|
||||||
|
|
||||||
int fsnotify_fasync(int fd, struct file *file, int on)
|
|
||||||
{
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/notify/mark.c linux-4.9-aufs-mod/fs/notify/mark.c
|
|
||||||
--- linux-4.9-aufs/fs/notify/mark.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/notify/mark.c 2016-12-31 00:32:35.155785422 +0200
|
|
||||||
@@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_m
|
|
||||||
mark->free_mark(mark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
|
|
||||||
|
|
||||||
/* Calculate mask of events for a list of marks */
|
|
||||||
u32 fsnotify_recalc_mask(struct hlist_head *head)
|
|
||||||
@@ -230,6 +231,7 @@ void fsnotify_destroy_mark(struct fsnoti
|
|
||||||
mutex_unlock(&group->mark_mutex);
|
|
||||||
fsnotify_free_mark(mark);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
|
|
||||||
|
|
||||||
void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
|
|
||||||
{
|
|
||||||
@@ -415,6 +417,7 @@ err:
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
|
|
||||||
|
|
||||||
int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
|
|
||||||
struct inode *inode, struct vfsmount *mnt, int allow_dups)
|
|
||||||
@@ -521,6 +524,7 @@ void fsnotify_duplicate_mark(struct fsno
|
|
||||||
new->mask = old->mask;
|
|
||||||
new->free_mark = old->free_mark;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nothing fancy, just initialize lists and locks and counters.
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/open.c linux-4.9-aufs-mod/fs/open.c
|
|
||||||
--- linux-4.9-aufs/fs/open.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/open.c 2016-12-31 00:32:35.155785422 +0200
|
|
||||||
@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l
|
|
||||||
inode_unlock(dentry->d_inode);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(do_truncate);
|
|
||||||
|
|
||||||
long vfs_truncate(const struct path *path, loff_t length)
|
|
||||||
{
|
|
||||||
@@ -695,6 +696,7 @@ int open_check_o_direct(struct file *f)
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(open_check_o_direct);
|
|
||||||
|
|
||||||
static int do_dentry_open(struct file *f,
|
|
||||||
struct inode *inode,
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/read_write.c linux-4.9-aufs-mod/fs/read_write.c
|
|
||||||
--- linux-4.9-aufs/fs/read_write.c 2016-12-31 00:31:52.380789379 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/read_write.c 2016-12-31 00:32:35.155785422 +0200
|
|
||||||
@@ -525,6 +525,7 @@ vfs_readf_t vfs_readf(struct file *file)
|
|
||||||
return new_sync_read;
|
|
||||||
return ERR_PTR(-ENOSYS);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(vfs_readf);
|
|
||||||
|
|
||||||
vfs_writef_t vfs_writef(struct file *file)
|
|
||||||
{
|
|
||||||
@@ -536,6 +537,7 @@ vfs_writef_t vfs_writef(struct file *fil
|
|
||||||
return new_sync_write;
|
|
||||||
return ERR_PTR(-ENOSYS);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(vfs_writef);
|
|
||||||
|
|
||||||
ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
|
|
||||||
{
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/splice.c linux-4.9-aufs-mod/fs/splice.c
|
|
||||||
--- linux-4.9-aufs/fs/splice.c 2016-12-31 00:31:52.380789379 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/splice.c 2016-12-31 00:32:35.156785422 +0200
|
|
||||||
@@ -868,6 +868,7 @@ long do_splice_from(struct pipe_inode_in
|
|
||||||
|
|
||||||
return splice_write(pipe, out, ppos, len, flags);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(do_splice_from);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Attempt to initiate a splice from a file to a pipe.
|
|
||||||
@@ -897,6 +898,7 @@ long do_splice_to(struct file *in, loff_
|
|
||||||
|
|
||||||
return splice_read(in, ppos, pipe, len, flags);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(do_splice_to);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* splice_direct_to_actor - splices data directly between two non-pipes
|
|
||||||
diff -Nurp linux-4.9-aufs/fs/xattr.c linux-4.9-aufs-mod/fs/xattr.c
|
|
||||||
--- linux-4.9-aufs/fs/xattr.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/fs/xattr.c 2016-12-31 00:32:35.156785422 +0200
|
|
||||||
@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry
|
|
||||||
*xattr_value = value;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
|
|
||||||
diff -Nurp linux-4.9-aufs/kernel/task_work.c linux-4.9-aufs-mod/kernel/task_work.c
|
|
||||||
--- linux-4.9-aufs/kernel/task_work.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/kernel/task_work.c 2016-12-31 00:32:35.156785422 +0200
|
|
||||||
@@ -119,3 +119,4 @@ void task_work_run(void)
|
|
||||||
} while (work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(task_work_run);
|
|
||||||
diff -Nurp linux-4.9-aufs/security/commoncap.c linux-4.9-aufs-mod/security/commoncap.c
|
|
||||||
--- linux-4.9-aufs/security/commoncap.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/security/commoncap.c 2016-12-31 00:32:35.156785422 +0200
|
|
||||||
@@ -1061,12 +1061,14 @@ int cap_mmap_addr(unsigned long addr)
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(cap_mmap_addr);
|
|
||||||
|
|
||||||
int cap_mmap_file(struct file *file, unsigned long reqprot,
|
|
||||||
unsigned long prot, unsigned long flags)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(cap_mmap_file);
|
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY
|
|
||||||
|
|
||||||
diff -Nurp linux-4.9-aufs/security/device_cgroup.c linux-4.9-aufs-mod/security/device_cgroup.c
|
|
||||||
--- linux-4.9-aufs/security/device_cgroup.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/security/device_cgroup.c 2016-12-31 00:32:35.156785422 +0200
|
|
||||||
@@ -7,6 +7,7 @@
|
|
||||||
#include <linux/device_cgroup.h>
|
|
||||||
#include <linux/cgroup.h>
|
|
||||||
#include <linux/ctype.h>
|
|
||||||
+#include <linux/export.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <linux/seq_file.h>
|
|
||||||
@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct
|
|
||||||
return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
|
|
||||||
access);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);
|
|
||||||
|
|
||||||
int devcgroup_inode_mknod(int mode, dev_t dev)
|
|
||||||
{
|
|
||||||
diff -Nurp linux-4.9-aufs/security/security.c linux-4.9-aufs-mod/security/security.c
|
|
||||||
--- linux-4.9-aufs/security/security.c 2016-12-11 21:17:54.000000000 +0200
|
|
||||||
+++ linux-4.9-aufs-mod/security/security.c 2016-12-31 00:32:35.157785422 +0200
|
|
||||||
@@ -443,6 +443,7 @@ int security_path_rmdir(const struct pat
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_rmdir, 0, dir, dentry);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_rmdir);
|
|
||||||
|
|
||||||
int security_path_unlink(const struct path *dir, struct dentry *dentry)
|
|
||||||
{
|
|
||||||
@@ -459,6 +460,7 @@ int security_path_symlink(const struct p
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_symlink, 0, dir, dentry, old_name);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_symlink);
|
|
||||||
|
|
||||||
int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
|
|
||||||
struct dentry *new_dentry)
|
|
||||||
@@ -467,6 +469,7 @@ int security_path_link(struct dentry *ol
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_link);
|
|
||||||
|
|
||||||
int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
|
|
||||||
const struct path *new_dir, struct dentry *new_dentry,
|
|
||||||
@@ -494,6 +497,7 @@ int security_path_truncate(const struct
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_truncate, 0, path);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_truncate);
|
|
||||||
|
|
||||||
int security_path_chmod(const struct path *path, umode_t mode)
|
|
||||||
{
|
|
||||||
@@ -501,6 +505,7 @@ int security_path_chmod(const struct pat
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_chmod, 0, path, mode);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_chmod);
|
|
||||||
|
|
||||||
int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
|
|
||||||
{
|
|
||||||
@@ -508,6 +513,7 @@ int security_path_chown(const struct pat
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(path_chown, 0, path, uid, gid);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_path_chown);
|
|
||||||
|
|
||||||
int security_path_chroot(const struct path *path)
|
|
||||||
{
|
|
||||||
@@ -593,6 +599,7 @@ int security_inode_readlink(struct dentr
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(inode_readlink, 0, dentry);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_inode_readlink);
|
|
||||||
|
|
||||||
int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
|
|
||||||
bool rcu)
|
|
||||||
@@ -608,6 +615,7 @@ int security_inode_permission(struct ino
|
|
||||||
return 0;
|
|
||||||
return call_int_hook(inode_permission, 0, inode, mask);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_inode_permission);
|
|
||||||
|
|
||||||
int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
|
|
||||||
{
|
|
||||||
@@ -779,6 +787,7 @@ int security_file_permission(struct file
|
|
||||||
|
|
||||||
return fsnotify_perm(file, mask);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_file_permission);
|
|
||||||
|
|
||||||
int security_file_alloc(struct file *file)
|
|
||||||
{
|
|
||||||
@@ -838,6 +847,7 @@ int security_mmap_file(struct file *file
|
|
||||||
return ret;
|
|
||||||
return ima_file_mmap(file, prot);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(security_mmap_file);
|
|
||||||
|
|
||||||
int security_mmap_addr(unsigned long addr)
|
|
||||||
{
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
arm build fails with:
|
||||||
|
|
||||||
|
n file included from fs/aufs/aufs.h:31:0,
|
||||||
|
from fs/aufs/module.c:11:
|
||||||
|
fs/aufs/file.h: In function 'au_do_vm_file_reset':
|
||||||
|
fs/aufs/file.h:273:9: error: dereferencing pointer to incomplete type 'struct vm_area_struct'
|
||||||
|
f = vma->vm_file;
|
||||||
|
^
|
||||||
|
|
||||||
|
on x86(64) we seem to get covered by implict inclusion.
|
||||||
|
|
||||||
|
So explicitly include it to avoid subtle breakage
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- ./fs/aufs/file.h.orig
|
||||||
|
+++ ./fs/aufs/file.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/mm_types.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
#include "rwsem.h"
|
||||||
|
|
||||||
|
struct au_branch;
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
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
|
|
||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
From e522751d605d99a81508e58390a8f51ee96fb662 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
|
|
||||||
Date: Tue, 29 Nov 2016 15:18:20 +0100
|
|
||||||
Subject: [PATCH] seq_file: reset iterator to first record for zero offset
|
|
||||||
|
|
||||||
If kernfs file is empty on a first read, successive read operations
|
|
||||||
using the same file descriptor will return no data, even when data is
|
|
||||||
available. Default kernfs 'seq_next' implementation advances iterator
|
|
||||||
position even when next object is not there. Kernfs 'seq_start' for
|
|
||||||
following requests will not return iterator as position is already on
|
|
||||||
the second object.
|
|
||||||
|
|
||||||
This defect doesn't allow to monitor badblocks sysfs files from MD raid.
|
|
||||||
They are initially empty but if data appears at some stage, userspace is
|
|
||||||
not able to read it.
|
|
||||||
|
|
||||||
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
|
|
||||||
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
|
|
||||||
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
||||||
---
|
|
||||||
fs/seq_file.c | 7 +++++++
|
|
||||||
1 file changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/fs/seq_file.c b/fs/seq_file.c
|
|
||||||
index 368bfb9..a11f271 100644
|
|
||||||
--- a/fs/seq_file.c
|
|
||||||
+++ b/fs/seq_file.c
|
|
||||||
@@ -190,6 +190,13 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
|
|
||||||
*/
|
|
||||||
m->version = file->f_version;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * if request is to read from zero offset, reset iterator to first
|
|
||||||
+ * record as it might have been already advanced by previous requests
|
|
||||||
+ */
|
|
||||||
+ if (*ppos == 0)
|
|
||||||
+ m->index = 0;
|
|
||||||
+
|
|
||||||
/* Don't assume *ppos is where we left it */
|
|
||||||
if (unlikely(*ppos != m->read_pos)) {
|
|
||||||
while ((err = traverse(m, *ppos)) == -EAGAIN)
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -1,469 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
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
@@ -1,32 +0,0 @@
|
|||||||
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
@@ -1,81 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
From 5643205c6340b565a3be0fe0e7305dc4aa551c74 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Imre Deak <imre.deak@intel.com>
|
||||||
|
Date: Wed, 29 Nov 2017 19:51:37 +0200
|
||||||
|
Subject: drm/i915: Avoid PPS HW/SW state mismatch due to rounding
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
We store a SW state of the t11_t12 timing in 100usec units but have to
|
||||||
|
program it in 100msec as required by HW. The rounding used during
|
||||||
|
programming means there will be a mismatch between the SW and HW states
|
||||||
|
of this value triggering a "PPS state mismatch" error. Avoid this by
|
||||||
|
storing the already rounded-up value in the SW state.
|
||||||
|
|
||||||
|
Note that we still calculate panel_power_cycle_delay with the finer
|
||||||
|
100usec granularity to avoid any needless waits using that version of
|
||||||
|
the delay.
|
||||||
|
|
||||||
|
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103903
|
||||||
|
Cc: joks <joks@linux.pl>
|
||||||
|
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||||
|
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||||
|
Link: https://patchwork.freedesktop.org/patch/msgid/20171129175137.2889-1-imre.deak@intel.com
|
||||||
|
---
|
||||||
|
drivers/gpu/drm/i915/intel_dp.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
(limited to 'drivers/gpu/drm/i915/intel_dp.c')
|
||||||
|
|
||||||
|
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
|
||||||
|
index dd0b3a0..c603d4c 100644
|
||||||
|
--- a/drivers/gpu/drm/i915/intel_dp.c
|
||||||
|
+++ b/drivers/gpu/drm/i915/intel_dp.c
|
||||||
|
@@ -5355,6 +5355,12 @@ intel_dp_init_panel_power_sequencer(struct intel_dp *intel_dp)
|
||||||
|
*/
|
||||||
|
final->t8 = 1;
|
||||||
|
final->t9 = 1;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * HW has only a 100msec granularity for t11_t12 so round it up
|
||||||
|
+ * accordingly.
|
||||||
|
+ */
|
||||||
|
+ final->t11_t12 = roundup(final->t11_t12, 100 * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
--
|
||||||
|
cgit v1.1
|
||||||
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
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) &&
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
From 9af0a9aecdb945cd5513941ffdcbcc031009b402 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
Date: Mon, 4 Sep 2017 18:33:53 -0700
|
||||||
|
Subject: hwmon: (k10temp) Add support for family 17h
|
||||||
|
|
||||||
|
Add support for temperature sensors on Family 17h (Ryzen) processors.
|
||||||
|
|
||||||
|
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
---
|
||||||
|
drivers/hwmon/k10temp.c | 16 ++++++++++++++++
|
||||||
|
1 file changed, 16 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
|
||||||
|
index fc8076c..c4dac53 100644
|
||||||
|
--- a/drivers/hwmon/k10temp.c
|
||||||
|
+++ b/drivers/hwmon/k10temp.c
|
||||||
|
@@ -36,6 +36,10 @@ MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
|
||||||
|
/* Provide lock for writing to NB_SMU_IND_ADDR */
|
||||||
|
static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||||
|
|
||||||
|
+#ifndef PCI_DEVICE_ID_AMD_17H_DF_F3
|
||||||
|
+#define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* CPUID function 0x80000001, ebx */
|
||||||
|
#define CPUID_PKGTYPE_MASK 0xf0000000
|
||||||
|
#define CPUID_PKGTYPE_F 0x00000000
|
||||||
|
@@ -61,6 +65,9 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||||
|
*/
|
||||||
|
#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
|
||||||
|
|
||||||
|
+/* F17h M01h Access througn SMN */
|
||||||
|
+#define F17H_M01H_REPORTED_TEMP_CTRL_OFFSET 0x00059800
|
||||||
|
+
|
||||||
|
struct k10temp_data {
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
|
||||||
|
@@ -88,6 +95,12 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
|
||||||
|
F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
|
||||||
|
+{
|
||||||
|
+ amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60,
|
||||||
|
+ F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static ssize_t temp1_input_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
@@ -224,6 +237,8 @@ static int k10temp_probe(struct pci_dev *pdev,
|
||||||
|
if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
|
||||||
|
boot_cpu_data.x86_model == 0x70))
|
||||||
|
data->read_tempreg = read_tempreg_nb_f15;
|
||||||
|
+ else if (boot_cpu_data.x86 == 0x17)
|
||||||
|
+ data->read_tempreg = read_tempreg_nb_f17;
|
||||||
|
else
|
||||||
|
data->read_tempreg = read_tempreg_pci;
|
||||||
|
|
||||||
|
@@ -242,6 +257,7 @@ static const struct pci_device_id k10temp_id_table[] = {
|
||||||
|
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
|
||||||
|
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
|
||||||
|
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
|
||||||
|
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(pci, k10temp_id_table);
|
||||||
|
--
|
||||||
|
cgit v1.1
|
||||||
|
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
From 1b50b776355fa6c6d7b3281a63c275d5c18d629d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
Date: Mon, 4 Sep 2017 18:33:53 -0700
|
||||||
|
Subject: hwmon: (k10temp) Add support for temperature offsets
|
||||||
|
|
||||||
|
Add support for handling temperature offset values for various AMD CPUs,
|
||||||
|
similar to the code used in the coretemp driver for Intel CPUs. This is
|
||||||
|
primarily for Ryzen CPUs (which has documented temperature offsets),
|
||||||
|
but the code is kept generic to simplify adding additional CPUs.
|
||||||
|
|
||||||
|
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
---
|
||||||
|
drivers/hwmon/k10temp.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 30 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
|
||||||
|
index c4dac53..46a54ed 100644
|
||||||
|
--- a/drivers/hwmon/k10temp.c
|
||||||
|
+++ b/drivers/hwmon/k10temp.c
|
||||||
|
@@ -71,6 +71,24 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||||
|
struct k10temp_data {
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
|
||||||
|
+ int temp_offset;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct tctl_offset {
|
||||||
|
+ u8 model;
|
||||||
|
+ char const *id;
|
||||||
|
+ int offset;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct tctl_offset tctl_offset_table[] = {
|
||||||
|
+ { 0x17, "AMD Ryzen 7 1600X", 20000 },
|
||||||
|
+ { 0x17, "AMD Ryzen 7 1700X", 20000 },
|
||||||
|
+ { 0x17, "AMD Ryzen 7 1800X", 20000 },
|
||||||
|
+ { 0x17, "AMD Ryzen Threadripper 1950X", 27000 },
|
||||||
|
+ { 0x17, "AMD Ryzen Threadripper 1920X", 27000 },
|
||||||
|
+ { 0x17, "AMD Ryzen Threadripper 1950", 10000 },
|
||||||
|
+ { 0x17, "AMD Ryzen Threadripper 1920", 10000 },
|
||||||
|
+ { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
|
||||||
|
@@ -110,6 +128,7 @@ static ssize_t temp1_input_show(struct device *dev,
|
||||||
|
|
||||||
|
data->read_tempreg(data->pdev, ®val);
|
||||||
|
temp = (regval >> 21) * 125;
|
||||||
|
+ temp -= data->temp_offset;
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", temp);
|
||||||
|
}
|
||||||
|
@@ -217,6 +236,7 @@ static int k10temp_probe(struct pci_dev *pdev,
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct k10temp_data *data;
|
||||||
|
struct device *hwmon_dev;
|
||||||
|
+ int i;
|
||||||
|
|
||||||
|
if (unreliable) {
|
||||||
|
if (!force) {
|
||||||
|
@@ -242,6 +262,16 @@ static int k10temp_probe(struct pci_dev *pdev,
|
||||||
|
else
|
||||||
|
data->read_tempreg = read_tempreg_pci;
|
||||||
|
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
|
||||||
|
+ const struct tctl_offset *entry = &tctl_offset_table[i];
|
||||||
|
+
|
||||||
|
+ if (boot_cpu_data.x86 == entry->model &&
|
||||||
|
+ strstr(boot_cpu_data.x86_model_id, entry->id)) {
|
||||||
|
+ data->temp_offset = entry->offset;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
|
||||||
|
k10temp_groups);
|
||||||
|
return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||||
|
--
|
||||||
|
cgit v1.1
|
||||||
|
|
||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
From 68546abf7a3a63f199e53d6dcaa7375df37a6aaa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
Date: Mon, 4 Sep 2017 18:33:53 -0700
|
||||||
|
Subject: hwmon: (k10temp) Move chip specific code into probe function
|
||||||
|
|
||||||
|
Introduce a local data structure and determine the temperature read
|
||||||
|
function at probe time to reduce runtime complexity.
|
||||||
|
|
||||||
|
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
---
|
||||||
|
drivers/hwmon/k10temp.c | 62 +++++++++++++++++++++++++++++++++++--------------
|
||||||
|
1 file changed, 45 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
|
||||||
|
index ce3b91f..fc8076c 100644
|
||||||
|
--- a/drivers/hwmon/k10temp.c
|
||||||
|
+++ b/drivers/hwmon/k10temp.c
|
||||||
|
@@ -61,31 +61,44 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||||
|
*/
|
||||||
|
#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
|
||||||
|
|
||||||
|
-static void amd_nb_smu_index_read(struct pci_dev *pdev, unsigned int devfn,
|
||||||
|
- int offset, u32 *val)
|
||||||
|
+struct k10temp_data {
|
||||||
|
+ struct pci_dev *pdev;
|
||||||
|
+ void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
|
||||||
|
+{
|
||||||
|
+ pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
|
||||||
|
+ unsigned int base, int offset, u32 *val)
|
||||||
|
{
|
||||||
|
mutex_lock(&nb_smu_ind_mutex);
|
||||||
|
pci_bus_write_config_dword(pdev->bus, devfn,
|
||||||
|
- 0xb8, offset);
|
||||||
|
+ base, offset);
|
||||||
|
pci_bus_read_config_dword(pdev->bus, devfn,
|
||||||
|
- 0xbc, val);
|
||||||
|
+ base + 4, val);
|
||||||
|
mutex_unlock(&nb_smu_ind_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
|
||||||
|
+{
|
||||||
|
+ amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
|
||||||
|
+ F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static ssize_t temp1_input_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
+ struct k10temp_data *data = dev_get_drvdata(dev);
|
||||||
|
u32 regval;
|
||||||
|
- struct pci_dev *pdev = dev_get_drvdata(dev);
|
||||||
|
-
|
||||||
|
- if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model == 0x60) {
|
||||||
|
- amd_nb_smu_index_read(pdev, PCI_DEVFN(0, 0),
|
||||||
|
- F15H_M60H_REPORTED_TEMP_CTRL_OFFSET,
|
||||||
|
- ®val);
|
||||||
|
- } else {
|
||||||
|
- pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, ®val);
|
||||||
|
- }
|
||||||
|
- return sprintf(buf, "%u\n", (regval >> 21) * 125);
|
||||||
|
+ unsigned int temp;
|
||||||
|
+
|
||||||
|
+ data->read_tempreg(data->pdev, ®val);
|
||||||
|
+ temp = (regval >> 21) * 125;
|
||||||
|
+
|
||||||
|
+ return sprintf(buf, "%u\n", temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t temp1_max_show(struct device *dev,
|
||||||
|
@@ -98,11 +111,12 @@ static ssize_t show_temp_crit(struct device *dev,
|
||||||
|
struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||||
|
+ struct k10temp_data *data = dev_get_drvdata(dev);
|
||||||
|
int show_hyst = attr->index;
|
||||||
|
u32 regval;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
- pci_read_config_dword(dev_get_drvdata(dev),
|
||||||
|
+ pci_read_config_dword(data->pdev,
|
||||||
|
REG_HARDWARE_THERMAL_CONTROL, ®val);
|
||||||
|
value = ((regval >> 16) & 0x7f) * 500 + 52000;
|
||||||
|
if (show_hyst)
|
||||||
|
@@ -119,7 +133,8 @@ static umode_t k10temp_is_visible(struct kobject *kobj,
|
||||||
|
struct attribute *attr, int index)
|
||||||
|
{
|
||||||
|
struct device *dev = container_of(kobj, struct device, kobj);
|
||||||
|
- struct pci_dev *pdev = dev_get_drvdata(dev);
|
||||||
|
+ struct k10temp_data *data = dev_get_drvdata(dev);
|
||||||
|
+ struct pci_dev *pdev = data->pdev;
|
||||||
|
|
||||||
|
if (index >= 2) {
|
||||||
|
u32 reg_caps, reg_htc;
|
||||||
|
@@ -187,6 +202,7 @@ static int k10temp_probe(struct pci_dev *pdev,
|
||||||
|
{
|
||||||
|
int unreliable = has_erratum_319(pdev);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
+ struct k10temp_data *data;
|
||||||
|
struct device *hwmon_dev;
|
||||||
|
|
||||||
|
if (unreliable) {
|
||||||
|
@@ -199,7 +215,19 @@ static int k10temp_probe(struct pci_dev *pdev,
|
||||||
|
"unreliable CPU thermal sensor; check erratum 319\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
- hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", pdev,
|
||||||
|
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||||
|
+ if (!data)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ data->pdev = pdev;
|
||||||
|
+
|
||||||
|
+ if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
|
||||||
|
+ boot_cpu_data.x86_model == 0x70))
|
||||||
|
+ data->read_tempreg = read_tempreg_nb_f15;
|
||||||
|
+ else
|
||||||
|
+ data->read_tempreg = read_tempreg_pci;
|
||||||
|
+
|
||||||
|
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
|
||||||
|
k10temp_groups);
|
||||||
|
return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
cgit v1.1
|
||||||
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
From Thierry Vignaud <tvignaud@mandriva.com> (Mandriva)
|
|
||||||
|
|
||||||
We now lacks /usr/include/linux/pci_ids.h which break ldetect build...
|
|
||||||
Can you readd it please?
|
|
||||||
Thanks
|
|
||||||
---
|
|
||||||
include/linux/Kbuild | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
--- linux/include/uapi/linux/Kbuild.include-kbuild-export-pci_ids.orig
|
|
||||||
+++ linux/include/uapi/linux/Kbuild
|
|
||||||
@@ -277,6 +277,7 @@ header-y += param.h
|
|
||||||
header-y += parport.h
|
|
||||||
header-y += patchkey.h
|
|
||||||
header-y += pci.h
|
|
||||||
+header-y += pci_ids.h
|
|
||||||
header-y += pci_regs.h
|
|
||||||
header-y += perf_event.h
|
|
||||||
header-y += personality.h
|
|
||||||
-102
@@ -1,102 +0,0 @@
|
|||||||
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() */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
From 7222708e823afc98dfb769d36bf2f26b6420b7ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
|
||||||
|
Date: Mon, 22 Jan 2018 12:22:30 +0300
|
||||||
|
Subject: [PATCH] mm, page_vma_mapped: Introduce pfn_in_hpage()
|
||||||
|
|
||||||
|
The new helper would check if the pfn belongs to the page. For huge
|
||||||
|
pages it checks if the PFN is within range covered by the huge page.
|
||||||
|
|
||||||
|
The helper is used in check_pte(). The original code the helper replaces
|
||||||
|
had two call to page_to_pfn(). page_to_pfn() is relatively costly.
|
||||||
|
|
||||||
|
Although current GCC is able to optimize code to have one call, it's
|
||||||
|
better to do this explicitly.
|
||||||
|
|
||||||
|
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
|
||||||
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||||
|
---
|
||||||
|
mm/page_vma_mapped.c | 17 +++++++++--------
|
||||||
|
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
|
||||||
|
index 956015614395..ae3c2a35d61b 100644
|
||||||
|
--- a/mm/page_vma_mapped.c
|
||||||
|
+++ b/mm/page_vma_mapped.c
|
||||||
|
@@ -30,6 +30,14 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline bool pfn_in_hpage(struct page *hpage, unsigned long pfn)
|
||||||
|
+{
|
||||||
|
+ unsigned long hpage_pfn = page_to_pfn(hpage);
|
||||||
|
+
|
||||||
|
+ /* THP can be referenced by any subpage */
|
||||||
|
+ return pfn >= hpage_pfn && pfn - hpage_pfn < hpage_nr_pages(hpage);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* check_pte - check if @pvmw->page is mapped at the @pvmw->pte
|
||||||
|
*
|
||||||
|
@@ -78,14 +86,7 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw)
|
||||||
|
pfn = pte_pfn(*pvmw->pte);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (pfn < page_to_pfn(pvmw->page))
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- /* THP can be referenced by any subpage */
|
||||||
|
- if (pfn - page_to_pfn(pvmw->page) >= hpage_nr_pages(pvmw->page))
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
+ return pfn_in_hpage(pvmw->page, pfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
+42
@@ -0,0 +1,42 @@
|
|||||||
|
From 69c64866ce072dea1d1e59a0d61e0f66c0dffb76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mohamed Ghannam <simo.ghannam@gmail.com>
|
||||||
|
Date: Tue, 5 Dec 2017 20:58:35 +0000
|
||||||
|
Subject: [PATCH] dccp: CVE-2017-8824: use-after-free in DCCP code
|
||||||
|
|
||||||
|
Whenever the sock object is in DCCP_CLOSED state,
|
||||||
|
dccp_disconnect() must free dccps_hc_tx_ccid and
|
||||||
|
dccps_hc_rx_ccid and set to NULL.
|
||||||
|
|
||||||
|
Signed-off-by: Mohamed Ghannam <simo.ghannam@gmail.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
net/dccp/proto.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
|
||||||
|
index b68168fcc06a..9d43c1f40274 100644
|
||||||
|
--- a/net/dccp/proto.c
|
||||||
|
+++ b/net/dccp/proto.c
|
||||||
|
@@ -259,6 +259,7 @@ int dccp_disconnect(struct sock *sk, int flags)
|
||||||
|
{
|
||||||
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||||
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
+ struct dccp_sock *dp = dccp_sk(sk);
|
||||||
|
int err = 0;
|
||||||
|
const int old_state = sk->sk_state;
|
||||||
|
|
||||||
|
@@ -278,6 +279,10 @@ int dccp_disconnect(struct sock *sk, int flags)
|
||||||
|
sk->sk_err = ECONNRESET;
|
||||||
|
|
||||||
|
dccp_clear_xmit_timers(sk);
|
||||||
|
+ ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
|
||||||
|
+ ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
|
||||||
|
+ dp->dccps_hc_rx_ccid = NULL;
|
||||||
|
+ dp->dccps_hc_tx_ccid = NULL;
|
||||||
|
|
||||||
|
__skb_queue_purge(&sk->sk_receive_queue);
|
||||||
|
__skb_queue_purge(&sk->sk_write_queue);
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
@@ -8,16 +8,16 @@ and Luiz Fernando N. Capitulino.
|
|||||||
|
|
||||||
Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
|
Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
|
||||||
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
|
[moved header to uapi for kernel-4.12.4 / tmb]
|
||||||
|
Signed-off-by Thomas Backlund <tmb@mageia.org>
|
||||||
---
|
---
|
||||||
include/linux/netfilter_ipv4/Kbuild | 1
|
|
||||||
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 23 +++++-
|
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 23 +++++-
|
||||||
net/ipv4/netfilter/ipt_IFWLOG.c | 108 +++++++++++++++---------------
|
net/ipv4/netfilter/ipt_IFWLOG.c | 108 +++++++++++++++---------------
|
||||||
3 files changed, 77 insertions(+), 55 deletions(-)
|
2 files changed, 77 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
diff -p -up linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h
|
diff -p -up linux/include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h.orig linux/include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h
|
||||||
--- linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig 2008-12-12 10:55:07.000000000 -0500
|
--- linux-2.6.28/include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h.orig
|
||||||
+++ linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h 2008-12-12 10:56:30.000000000 -0500
|
+++ linux-2.6.28/include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h
|
||||||
@@ -1,10 +1,25 @@
|
@@ -1,10 +1,25 @@
|
||||||
-#ifndef _IPT_IFWLOG_H
|
-#ifndef _IPT_IFWLOG_H
|
||||||
-#define _IPT_IFWLOG_H
|
-#define _IPT_IFWLOG_H
|
||||||
@@ -252,13 +252,3 @@ diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig linux-2.6.28/net/i
|
|||||||
+MODULE_AUTHOR("Luiz Capitulino <lcapitulino@mandriva.com.br>");
|
+MODULE_AUTHOR("Luiz Capitulino <lcapitulino@mandriva.com.br>");
|
||||||
+MODULE_DESCRIPTION("Interactive firewall logging and module");
|
+MODULE_DESCRIPTION("Interactive firewall logging and module");
|
||||||
+MODULE_VERSION("v1.1");
|
+MODULE_VERSION("v1.1");
|
||||||
--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.net-netfilter-IFWLOG-mdv.orig
|
|
||||||
+++ linux/include/uapi/linux/netfilter_ipv4/Kbuild
|
|
||||||
@@ -2,6 +2,7 @@ header-y += ip_queue.h
|
|
||||||
header-y += ip_tables.h
|
|
||||||
header-y += ipt_CLUSTERIP.h
|
|
||||||
header-y += ipt_ECN.h
|
|
||||||
+header-y += ipt_IFWLOG.h
|
|
||||||
header-y += ipt_LOG.h
|
|
||||||
header-y += ipt_REJECT.h
|
|
||||||
header-y += ipt_TTL.h
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
|
||||||
|
[moved header to uapi for kernel-4.12.4 / tmb]
|
||||||
|
Signed-off-by Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
---
|
---
|
||||||
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 26 +++
|
include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h | 26 +++
|
||||||
net/ipv4/netfilter/Kconfig | 11 +
|
net/ipv4/netfilter/Kconfig | 11 +
|
||||||
net/ipv4/netfilter/Makefile | 1
|
net/ipv4/netfilter/Makefile | 1
|
||||||
net/ipv4/netfilter/ipt_IFWLOG.c | 200 ++++++++++++++++++++++++++++++
|
net/ipv4/netfilter/ipt_IFWLOG.c | 200 ++++++++++++++++++++++++++++++
|
||||||
@@ -229,7 +233,7 @@
|
|||||||
config IP_NF_RAW
|
config IP_NF_RAW
|
||||||
tristate 'raw table support (required for NOTRACK/TRACE)'
|
tristate 'raw table support (required for NOTRACK/TRACE)'
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/include/linux/netfilter_ipv4/ipt_IFWLOG.h
|
+++ b/include/uapi/linux/netfilter_ipv4/ipt_IFWLOG.h
|
||||||
@@ -0,0 +1,26 @@
|
@@ -0,0 +1,26 @@
|
||||||
+#ifndef _IPT_IFWLOG_H
|
+#ifndef _IPT_IFWLOG_H
|
||||||
+#define _IPT_IFWLOG_H
|
+#define _IPT_IFWLOG_H
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Adjust for kernel changes.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- linux/net/ipv4/netfilter/ipt_IFWLOG.c.orig
|
||||||
|
+++ linux/net/ipv4/netfilter/ipt_IFWLOG.c
|
||||||
|
@@ -138,7 +138,7 @@ static unsigned int ipt_IFWLOG_target(st
|
||||||
|
{
|
||||||
|
const struct ipt_IFWLOG_info *info = target_param->targinfo;
|
||||||
|
|
||||||
|
- ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info);
|
||||||
|
+ ipt_IFWLOG_packet(skb, xt_in(target_param), xt_out(target_param), info);
|
||||||
|
|
||||||
|
return XT_CONTINUE;
|
||||||
|
}
|
||||||
@@ -2,16 +2,17 @@
|
|||||||
Make defines psd specific so they dont redefine in-kernel defines like
|
Make defines psd specific so they dont redefine in-kernel defines like
|
||||||
HASH_SIZE.
|
HASH_SIZE.
|
||||||
|
|
||||||
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
[moved header to uapi for kernel-4.12.4 / tmb]
|
||||||
|
Signed-off-by Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
---
|
||||||
include/linux/netfilter_ipv4/ipt_psd.h | 14 +++++++-------
|
include/uapi/linux/netfilter_ipv4/ipt_psd.h | 14 +++++++-------
|
||||||
net/ipv4/netfilter/ipt_psd.c | 14 +++++++-------
|
net/ipv4/netfilter/ipt_psd.c | 14 +++++++-------
|
||||||
2 files changed, 14 insertions(+), 14 deletions(-)
|
2 files changed, 14 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
diff -Nurp linux-4.9.5-psd/include/linux/netfilter_ipv4/ipt_psd.h linux-4.9.5-psd-fix/include/linux/netfilter_ipv4/ipt_psd.h
|
diff -Nurp linux-psd/include/uapi/linux/netfilter_ipv4/ipt_psd.h linux-psd-fix/include/uapi/linux/netfilter_ipv4/ipt_psd.h
|
||||||
--- linux-4.9.5-psd/include/linux/netfilter_ipv4/ipt_psd.h 2017-01-20 21:47:19.788931403 +0200
|
--- linux-psd/include/uapi/linux/netfilter_ipv4/ipt_psd.h
|
||||||
+++ linux-4.9.5-psd-fix/include/linux/netfilter_ipv4/ipt_psd.h 2017-01-20 21:58:09.995871253 +0200
|
+++ linux-psd-fix/include/uapi/linux/netfilter_ipv4/ipt_psd.h
|
||||||
@@ -21,14 +21,14 @@
|
@@ -21,14 +21,14 @@
|
||||||
#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
|
#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
|
|||||||
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
|
|
||||||
---
|
---
|
||||||
include/linux/netfilter_ipv4/Kbuild | 1
|
|
||||||
net/ipv4/netfilter/Kconfig | 8 ++
|
net/ipv4/netfilter/Kconfig | 8 ++
|
||||||
net/ipv4/netfilter/ipt_psd.c | 113 ++++++++++++++----------------------
|
net/ipv4/netfilter/ipt_psd.c | 113 ++++++++++++++----------------------
|
||||||
3 files changed, 55 insertions(+), 67 deletions(-)
|
2 files changed, 55 insertions(+), 67 deletions(-)
|
||||||
|
|
||||||
diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_psd.c
|
diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_psd.c
|
||||||
--- linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig 2008-12-12 11:03:05.000000000 -0500
|
--- linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig 2008-12-12 11:03:05.000000000 -0500
|
||||||
@@ -223,11 +222,3 @@ diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4
|
|||||||
config IP_NF_MATCH_RPFILTER
|
config IP_NF_MATCH_RPFILTER
|
||||||
tristate '"rpfilter" reverse path filter match support'
|
tristate '"rpfilter" reverse path filter match support'
|
||||||
depends on NETFILTER_ADVANCED
|
depends on NETFILTER_ADVANCED
|
||||||
--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.orig
|
|
||||||
+++ linux/include/uapi/linux/netfilter_ipv4/Kbuild
|
|
||||||
@@ -8,4 +8,5 @@ header-y += ipt_REJECT.h
|
|
||||||
header-y += ipt_TTL.h
|
|
||||||
header-y += ipt_ah.h
|
|
||||||
header-y += ipt_ecn.h
|
|
||||||
+header-y += ipt_psd.h
|
|
||||||
header-y += ipt_ttl.h
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
|
||||||
|
[moved header to uapi for kernel-4.12.4 / tmb]
|
||||||
|
Signed-off-by Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
---
|
---
|
||||||
include/linux/netfilter_ipv4/ipt_psd.h | 40 +++
|
include/uapi/linux/netfilter_ipv4/ipt_psd.h | 40 +++
|
||||||
net/ipv4/netfilter/Makefile | 1
|
net/ipv4/netfilter/Makefile | 1
|
||||||
net/ipv4/netfilter/ipt_psd.c | 358 +++++++++++++++++++++++++++++++++
|
net/ipv4/netfilter/ipt_psd.c | 358 +++++++++++++++++++++++++++++++++
|
||||||
3 files changed, 399 insertions(+)
|
3 files changed, 399 insertions(+)
|
||||||
@@ -366,7 +370,7 @@
|
|||||||
+module_init(init);
|
+module_init(init);
|
||||||
+module_exit(fini);
|
+module_exit(fini);
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/include/linux/netfilter_ipv4/ipt_psd.h
|
+++ b/include/uapi/linux/netfilter_ipv4/ipt_psd.h
|
||||||
@@ -0,0 +1,40 @@
|
@@ -0,0 +1,40 @@
|
||||||
+#ifndef _IPT_PSD_H
|
+#ifndef _IPT_PSD_H
|
||||||
+#define _IPT_PSD_H
|
+#define _IPT_PSD_H
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
This message causes numerous useless "bug reports", so silence it by default.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- linux/net/netfilter/xt_addrtype.c.orig 2017-11-12 20:46:13.000000000 +0200
|
||||||
|
+++ linux/net/netfilter/xt_addrtype.c 2018-02-06 20:26:49.854596642 +0200
|
||||||
|
@@ -203,7 +203,7 @@ static int addrtype_mt_checkentry_v1(con
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) {
|
||||||
|
- pr_err("ipv6 does not support BROADCAST matching\n");
|
||||||
|
+ /* pr_err("ipv6 does not support BROADCAST matching\n"); */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
From 7a8c4dd9be91a7e8f8f0e0419a560663adc694a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dave Watson <davejwatson@fb.com>
|
||||||
|
Date: Fri, 19 Jan 2018 12:30:13 -0800
|
||||||
|
Subject: [PATCH] tls: Correct length of scatterlist in tls_sw_sendpage
|
||||||
|
|
||||||
|
The scatterlist is reused by both sendmsg and sendfile.
|
||||||
|
If a sendmsg of smaller number of pages is followed by a sendfile
|
||||||
|
of larger number of pages, the scatterlist may be too short, resulting
|
||||||
|
in a crash in gcm_encrypt.
|
||||||
|
|
||||||
|
Add sg_unmark_end to make the list the correct length.
|
||||||
|
|
||||||
|
tls_sw_sendmsg already calls sg_unmark_end correctly when it allocates
|
||||||
|
memory in alloc_sg, or in zerocopy_from_iter.
|
||||||
|
|
||||||
|
Signed-off-by: Dave Watson <davejwatson@fb.com>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
net/tls/tls_sw.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
|
||||||
|
index 61f394d369bf..0a9b72fbd761 100644
|
||||||
|
--- a/net/tls/tls_sw.c
|
||||||
|
+++ b/net/tls/tls_sw.c
|
||||||
|
@@ -577,6 +577,8 @@ int tls_sw_sendpage(struct sock *sk, struct page *page,
|
||||||
|
get_page(page);
|
||||||
|
sg = ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem;
|
||||||
|
sg_set_page(sg, page, copy, offset);
|
||||||
|
+ sg_unmark_end(sg);
|
||||||
|
+
|
||||||
|
ctx->sg_plaintext_num_elem++;
|
||||||
|
|
||||||
|
sk_mem_charge(sk, copy);
|
||||||
|
--
|
||||||
|
2.16.1
|
||||||
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
From 22b68b93ae2506bd56ee3bf232a51bc8ab955b56 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
|
||||||
Date: Mon, 19 Dec 2016 20:38:12 -0600
|
|
||||||
Subject: [PATCH] rtlwifi: Fix kernel oops introduced with commit e49656147359
|
|
||||||
|
|
||||||
With commit e49656147359 {"rtlwifi: Use dev_kfree_skb_irq instead of
|
|
||||||
kfree_skb"), the method used to free an skb was changed because the
|
|
||||||
kfree_skb() was inside a spinlock. What was forgotten is that kfree_skb()
|
|
||||||
guards against a NULL value for the argument. Routine dev_kfree_skb_irq()
|
|
||||||
does not, and a test is needed to prevent kernel panics.
|
|
||||||
|
|
||||||
Fixes: e49656147359 ("rtlwifi: Use dev_kfree_skb_irq instead of kfree_skb")
|
|
||||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
|
||||||
Cc: Stable <stable@vger.kernel.org> # 4.9+
|
|
||||||
Cc: Wei Yongjun <weiyongjun1@huawei.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/realtek/rtlwifi/core.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
index 2caa4ad..ded1493 100644
|
|
||||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
@@ -1829,7 +1829,8 @@ bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
||||||
|
|
||||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
|
||||||
pskb = __skb_dequeue(&ring->queue);
|
|
||||||
- dev_kfree_skb_irq(pskb);
|
|
||||||
+ if (pskb)
|
|
||||||
+ dev_kfree_skb_irq(pskb);
|
|
||||||
|
|
||||||
/*this is wrong, fill_tx_cmddesc needs update*/
|
|
||||||
pdesc = &ring->desc[0];
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
From e49656147359411fb7529a211e852e587e5970dd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Wei Yongjun <weiyongjun1@huawei.com>
|
|
||||||
Date: Tue, 1 Nov 2016 14:48:40 +0000
|
|
||||||
Subject: [PATCH] rtlwifi: Use dev_kfree_skb_irq instead of kfree_skb
|
|
||||||
|
|
||||||
It is not allowed to call kfree_skb() from hardware interrupt
|
|
||||||
context or with interrupts being disabled, spin_lock_irqsave()
|
|
||||||
make sure always in irq disable context. So the kfree_skb()
|
|
||||||
should be replaced with dev_kfree_skb_irq().
|
|
||||||
|
|
||||||
This is detected by Coccinelle semantic patch.
|
|
||||||
|
|
||||||
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/realtek/rtlwifi/core.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
index f95760c..a11e8f5 100644
|
|
||||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
||||||
@@ -1832,7 +1832,7 @@ bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
||||||
|
|
||||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
|
||||||
pskb = __skb_dequeue(&ring->queue);
|
|
||||||
- kfree_skb(pskb);
|
|
||||||
+ dev_kfree_skb_irq(pskb);
|
|
||||||
|
|
||||||
/*this is wrong, fill_tx_cmddesc needs update*/
|
|
||||||
pdesc = &ring->desc[0];
|
|
||||||
--
|
|
||||||
2.10.2
|
|
||||||
|
|
||||||
@@ -0,0 +1,804 @@
|
|||||||
|
diff --git a/.gitignore b/.gitignore
|
||||||
|
index 0c39aa20b6ba..f6050b88e95b 100644
|
||||||
|
--- a/.gitignore
|
||||||
|
+++ b/.gitignore
|
||||||
|
@@ -7,38 +7,40 @@
|
||||||
|
# command after changing this file, to see if there are
|
||||||
|
# any tracked files which get ignored after the change.
|
||||||
|
#
|
||||||
|
-# Normal rules
|
||||||
|
+# Normal rules (sorted alphabetically)
|
||||||
|
#
|
||||||
|
.*
|
||||||
|
+*.a
|
||||||
|
+*.bin
|
||||||
|
+*.bz2
|
||||||
|
+*.c.[012]*.*
|
||||||
|
+*.dtb
|
||||||
|
+*.dtb.S
|
||||||
|
+*.dwo
|
||||||
|
+*.elf
|
||||||
|
+*.gcno
|
||||||
|
+*.gz
|
||||||
|
+*.i
|
||||||
|
+*.ko
|
||||||
|
+*.ll
|
||||||
|
+*.lst
|
||||||
|
+*.lz4
|
||||||
|
+*.lzma
|
||||||
|
+*.lzo
|
||||||
|
+*.mod.c
|
||||||
|
*.o
|
||||||
|
*.o.*
|
||||||
|
-*.a
|
||||||
|
+*.order
|
||||||
|
+*.patch
|
||||||
|
*.s
|
||||||
|
-*.ko
|
||||||
|
*.so
|
||||||
|
*.so.dbg
|
||||||
|
-*.mod.c
|
||||||
|
-*.i
|
||||||
|
-*.lst
|
||||||
|
+*.su
|
||||||
|
*.symtypes
|
||||||
|
-*.order
|
||||||
|
-*.elf
|
||||||
|
-*.bin
|
||||||
|
*.tar
|
||||||
|
-*.gz
|
||||||
|
-*.bz2
|
||||||
|
-*.lzma
|
||||||
|
*.xz
|
||||||
|
-*.lz4
|
||||||
|
-*.lzo
|
||||||
|
-*.patch
|
||||||
|
-*.gcno
|
||||||
|
-*.ll
|
||||||
|
-modules.builtin
|
||||||
|
Module.symvers
|
||||||
|
-*.dwo
|
||||||
|
-*.su
|
||||||
|
-*.c.[012]*.*
|
||||||
|
+modules.builtin
|
||||||
|
|
||||||
|
#
|
||||||
|
# Top-level generic files
|
||||||
|
@@ -53,6 +55,11 @@ Module.symvers
|
||||||
|
/System.map
|
||||||
|
/Module.markers
|
||||||
|
|
||||||
|
+#
|
||||||
|
+# RPM spec file (make rpm-pkg)
|
||||||
|
+#
|
||||||
|
+/*.spec
|
||||||
|
+
|
||||||
|
#
|
||||||
|
# Debian directory (make deb-pkg)
|
||||||
|
#
|
||||||
|
diff --git a/arch/arc/boot/.gitignore b/arch/arc/boot/.gitignore
|
||||||
|
index 5246969a20c5..c4c5fd529c25 100644
|
||||||
|
--- a/arch/arc/boot/.gitignore
|
||||||
|
+++ b/arch/arc/boot/.gitignore
|
||||||
|
@@ -1,2 +1 @@
|
||||||
|
-*.dtb*
|
||||||
|
uImage
|
||||||
|
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
|
||||||
|
index 3c79f85975aa..ce1c5ff746e7 100644
|
||||||
|
--- a/arch/arm/boot/.gitignore
|
||||||
|
+++ b/arch/arm/boot/.gitignore
|
||||||
|
@@ -3,4 +3,3 @@ zImage
|
||||||
|
xipImage
|
||||||
|
bootpImage
|
||||||
|
uImage
|
||||||
|
-*.dtb
|
||||||
|
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
|
||||||
|
index 0fcd82f01388..b8dc3b516f93 100644
|
||||||
|
--- a/arch/arm/kernel/traps.c
|
||||||
|
+++ b/arch/arm/kernel/traps.c
|
||||||
|
@@ -790,7 +790,6 @@ void abort(void)
|
||||||
|
/* if that doesn't kill us, halt */
|
||||||
|
panic("Oops failed to kill thread");
|
||||||
|
}
|
||||||
|
-EXPORT_SYMBOL(abort);
|
||||||
|
|
||||||
|
void __init trap_init(void)
|
||||||
|
{
|
||||||
|
diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore
|
||||||
|
deleted file mode 100644
|
||||||
|
index b60ed208c779..000000000000
|
||||||
|
--- a/arch/arm64/boot/dts/.gitignore
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-*.dtb
|
||||||
|
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
|
||||||
|
index cb79fba79d43..b88a8dd14933 100644
|
||||||
|
--- a/arch/m32r/kernel/traps.c
|
||||||
|
+++ b/arch/m32r/kernel/traps.c
|
||||||
|
@@ -122,7 +122,6 @@ void abort(void)
|
||||||
|
/* if that doesn't kill us, halt */
|
||||||
|
panic("Oops failed to kill thread");
|
||||||
|
}
|
||||||
|
-EXPORT_SYMBOL(abort);
|
||||||
|
|
||||||
|
void __init trap_init(void)
|
||||||
|
{
|
||||||
|
diff --git a/arch/metag/boot/.gitignore b/arch/metag/boot/.gitignore
|
||||||
|
index 2d6c0c160884..6c662ddb909a 100644
|
||||||
|
--- a/arch/metag/boot/.gitignore
|
||||||
|
+++ b/arch/metag/boot/.gitignore
|
||||||
|
@@ -1,4 +1,3 @@
|
||||||
|
vmlinux*
|
||||||
|
uImage*
|
||||||
|
ramdisk.*
|
||||||
|
-*.dtb*
|
||||||
|
diff --git a/arch/microblaze/boot/.gitignore b/arch/microblaze/boot/.gitignore
|
||||||
|
index bf0459186027..679502d64a97 100644
|
||||||
|
--- a/arch/microblaze/boot/.gitignore
|
||||||
|
+++ b/arch/microblaze/boot/.gitignore
|
||||||
|
@@ -1,3 +1,2 @@
|
||||||
|
-*.dtb
|
||||||
|
linux.bin*
|
||||||
|
simpleImage.*
|
||||||
|
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
|
||||||
|
index d3962cd5ce0c..a73d6e2c4f64 100644
|
||||||
|
--- a/arch/mips/boot/.gitignore
|
||||||
|
+++ b/arch/mips/boot/.gitignore
|
||||||
|
@@ -5,4 +5,3 @@ zImage
|
||||||
|
zImage.tmp
|
||||||
|
calc_vmlinuz_load_addr
|
||||||
|
uImage
|
||||||
|
-*.dtb
|
||||||
|
diff --git a/arch/nios2/boot/.gitignore b/arch/nios2/boot/.gitignore
|
||||||
|
index 109279ca5a4d..64386a8dedd8 100644
|
||||||
|
--- a/arch/nios2/boot/.gitignore
|
||||||
|
+++ b/arch/nios2/boot/.gitignore
|
||||||
|
@@ -1,2 +1 @@
|
||||||
|
-*.dtb
|
||||||
|
vmImage
|
||||||
|
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
|
||||||
|
index 84774ccba1c2..f92d0530ceb1 100644
|
||||||
|
--- a/arch/powerpc/boot/.gitignore
|
||||||
|
+++ b/arch/powerpc/boot/.gitignore
|
||||||
|
@@ -18,7 +18,6 @@ otheros.bld
|
||||||
|
uImage
|
||||||
|
cuImage.*
|
||||||
|
dtbImage.*
|
||||||
|
-*.dtb
|
||||||
|
treeImage.*
|
||||||
|
vmlinux.strip
|
||||||
|
zImage
|
||||||
|
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c
|
||||||
|
index 5f25b39f04d4..c4ac6043ebb0 100644
|
||||||
|
--- a/arch/unicore32/kernel/traps.c
|
||||||
|
+++ b/arch/unicore32/kernel/traps.c
|
||||||
|
@@ -298,7 +298,6 @@ void abort(void)
|
||||||
|
/* if that doesn't kill us, halt */
|
||||||
|
panic("Oops failed to kill thread");
|
||||||
|
}
|
||||||
|
-EXPORT_SYMBOL(abort);
|
||||||
|
|
||||||
|
void __init trap_init(void)
|
||||||
|
{
|
||||||
|
diff --git a/arch/xtensa/boot/.gitignore b/arch/xtensa/boot/.gitignore
|
||||||
|
index be7655998b26..38177c7ebcab 100644
|
||||||
|
--- a/arch/xtensa/boot/.gitignore
|
||||||
|
+++ b/arch/xtensa/boot/.gitignore
|
||||||
|
@@ -1,3 +1,2 @@
|
||||||
|
uImage
|
||||||
|
zImage.redboot
|
||||||
|
-*.dtb
|
||||||
|
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
|
||||||
|
index f5f58a6eee5d..e339960dcac7 100644
|
||||||
|
--- a/crypto/tcrypt.c
|
||||||
|
+++ b/crypto/tcrypt.c
|
||||||
|
@@ -221,11 +221,13 @@ static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE],
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_init_table(sg, np + 1);
|
||||||
|
- np--;
|
||||||
|
+ if (rem)
|
||||||
|
+ np--;
|
||||||
|
for (k = 0; k < np; k++)
|
||||||
|
sg_set_buf(&sg[k + 1], xbuf[k], PAGE_SIZE);
|
||||||
|
|
||||||
|
- sg_set_buf(&sg[k + 1], xbuf[k], rem);
|
||||||
|
+ if (rem)
|
||||||
|
+ sg_set_buf(&sg[k + 1], xbuf[k], rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_aead_speed(const char *algo, int enc, unsigned int secs,
|
||||||
|
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
|
||||||
|
index 46768c056193..0c28d0b995cc 100644
|
||||||
|
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
|
||||||
|
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
|
||||||
|
@@ -115,3 +115,6 @@ struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+MODULE_DESCRIPTION("Mediatek video codec driver");
|
||||||
|
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
|
||||||
|
index 0116097c0c0f..092c73f24589 100644
|
||||||
|
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
|
||||||
|
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
|
||||||
|
@@ -419,3 +419,7 @@ void soc_camera_calc_client_output(struct soc_camera_device *icd,
|
||||||
|
mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(soc_camera_calc_client_output);
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION("soc-camera scaling-cropping functions");
|
||||||
|
+MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
|
||||||
|
index f7080d0ab874..46b0372dd032 100644
|
||||||
|
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
|
||||||
|
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
|
||||||
|
@@ -3891,7 +3891,7 @@ static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
|
||||||
|
struct list_head *head = &mbx->cmd_q;
|
||||||
|
struct qlcnic_cmd_args *cmd = NULL;
|
||||||
|
|
||||||
|
- spin_lock(&mbx->queue_lock);
|
||||||
|
+ spin_lock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
while (!list_empty(head)) {
|
||||||
|
cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
|
||||||
|
@@ -3902,7 +3902,7 @@ static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
|
||||||
|
qlcnic_83xx_notify_cmd_completion(adapter, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
- spin_unlock(&mbx->queue_lock);
|
||||||
|
+ spin_unlock_bh(&mbx->queue_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
|
||||||
|
@@ -3938,12 +3938,12 @@ static void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
|
||||||
|
{
|
||||||
|
struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
|
||||||
|
|
||||||
|
- spin_lock(&mbx->queue_lock);
|
||||||
|
+ spin_lock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
list_del(&cmd->list);
|
||||||
|
mbx->num_cmds--;
|
||||||
|
|
||||||
|
- spin_unlock(&mbx->queue_lock);
|
||||||
|
+ spin_unlock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
qlcnic_83xx_notify_cmd_completion(adapter, cmd);
|
||||||
|
}
|
||||||
|
@@ -4008,7 +4008,7 @@ static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
|
||||||
|
init_completion(&cmd->completion);
|
||||||
|
cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
|
||||||
|
|
||||||
|
- spin_lock(&mbx->queue_lock);
|
||||||
|
+ spin_lock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
list_add_tail(&cmd->list, &mbx->cmd_q);
|
||||||
|
mbx->num_cmds++;
|
||||||
|
@@ -4016,7 +4016,7 @@ static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
|
||||||
|
*timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
|
||||||
|
queue_work(mbx->work_q, &mbx->work);
|
||||||
|
|
||||||
|
- spin_unlock(&mbx->queue_lock);
|
||||||
|
+ spin_unlock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -4112,15 +4112,15 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
|
||||||
|
mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
|
||||||
|
spin_unlock_irqrestore(&mbx->aen_lock, flags);
|
||||||
|
|
||||||
|
- spin_lock(&mbx->queue_lock);
|
||||||
|
+ spin_lock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
if (list_empty(head)) {
|
||||||
|
- spin_unlock(&mbx->queue_lock);
|
||||||
|
+ spin_unlock_bh(&mbx->queue_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
|
||||||
|
|
||||||
|
- spin_unlock(&mbx->queue_lock);
|
||||||
|
+ spin_unlock_bh(&mbx->queue_lock);
|
||||||
|
|
||||||
|
mbx_ops->encode_cmd(adapter, cmd);
|
||||||
|
mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
|
||||||
|
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
|
||||||
|
index 958ff931e790..619a1b7281a0 100644
|
||||||
|
--- a/drivers/net/ethernet/realtek/r8169.c
|
||||||
|
+++ b/drivers/net/ethernet/realtek/r8169.c
|
||||||
|
@@ -1388,7 +1388,7 @@ DECLARE_RTL_COND(rtl_ocp_tx_cond)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
|
||||||
|
- return RTL_R8(IBISR0) & 0x02;
|
||||||
|
+ return RTL_R8(IBISR0) & 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
|
||||||
|
@@ -1396,7 +1396,7 @@ static void rtl8168ep_stop_cmac(struct rtl8169_private *tp)
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
|
||||||
|
RTL_W8(IBCR2, RTL_R8(IBCR2) & ~0x01);
|
||||||
|
- rtl_msleep_loop_wait_low(tp, &rtl_ocp_tx_cond, 50, 2000);
|
||||||
|
+ rtl_msleep_loop_wait_high(tp, &rtl_ocp_tx_cond, 50, 2000);
|
||||||
|
RTL_W8(IBISR0, RTL_R8(IBISR0) | 0x20);
|
||||||
|
RTL_W8(IBCR0, RTL_R8(IBCR0) & ~0x01);
|
||||||
|
}
|
||||||
|
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
|
||||||
|
index fc8f8bdf6579..056cb6093630 100644
|
||||||
|
--- a/drivers/net/ethernet/rocker/rocker_main.c
|
||||||
|
+++ b/drivers/net/ethernet/rocker/rocker_main.c
|
||||||
|
@@ -2902,6 +2902,12 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
|
goto err_alloc_ordered_workqueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ err = rocker_probe_ports(rocker);
|
||||||
|
+ if (err) {
|
||||||
|
+ dev_err(&pdev->dev, "failed to probe ports\n");
|
||||||
|
+ goto err_probe_ports;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Only FIBs pointing to our own netdevs are programmed into
|
||||||
|
* the device, so no need to pass a callback.
|
||||||
|
*/
|
||||||
|
@@ -2918,22 +2924,16 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
|
|
||||||
|
rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
|
||||||
|
|
||||||
|
- err = rocker_probe_ports(rocker);
|
||||||
|
- if (err) {
|
||||||
|
- dev_err(&pdev->dev, "failed to probe ports\n");
|
||||||
|
- goto err_probe_ports;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
dev_info(&pdev->dev, "Rocker switch with id %*phN\n",
|
||||||
|
(int)sizeof(rocker->hw.id), &rocker->hw.id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
-err_probe_ports:
|
||||||
|
- unregister_switchdev_notifier(&rocker_switchdev_notifier);
|
||||||
|
err_register_switchdev_notifier:
|
||||||
|
unregister_fib_notifier(&rocker->fib_nb);
|
||||||
|
err_register_fib_notifier:
|
||||||
|
+ rocker_remove_ports(rocker);
|
||||||
|
+err_probe_ports:
|
||||||
|
destroy_workqueue(rocker->rocker_owq);
|
||||||
|
err_alloc_ordered_workqueue:
|
||||||
|
free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
|
||||||
|
@@ -2961,9 +2961,9 @@ static void rocker_remove(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct rocker *rocker = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
- rocker_remove_ports(rocker);
|
||||||
|
unregister_switchdev_notifier(&rocker_switchdev_notifier);
|
||||||
|
unregister_fib_notifier(&rocker->fib_nb);
|
||||||
|
+ rocker_remove_ports(rocker);
|
||||||
|
rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
|
||||||
|
destroy_workqueue(rocker->rocker_owq);
|
||||||
|
free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
|
||||||
|
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
||||||
|
index 2092febfcb42..8d9f02b7a71f 100644
|
||||||
|
--- a/drivers/net/usb/qmi_wwan.c
|
||||||
|
+++ b/drivers/net/usb/qmi_wwan.c
|
||||||
|
@@ -1243,6 +1243,7 @@ static const struct usb_device_id products[] = {
|
||||||
|
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
|
||||||
|
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */
|
||||||
|
{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */
|
||||||
|
+ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0306, 4)}, /* Quectel EP06 Mini PCIe */
|
||||||
|
|
||||||
|
/* 4. Gobi 1000 devices */
|
||||||
|
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
|
||||||
|
diff --git a/drivers/of/unittest-data/.gitignore b/drivers/of/unittest-data/.gitignore
|
||||||
|
deleted file mode 100644
|
||||||
|
index 4b3cf8b16de2..000000000000
|
||||||
|
--- a/drivers/of/unittest-data/.gitignore
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-testcases.dtb
|
||||||
|
-testcases.dtb.S
|
||||||
|
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
|
||||||
|
index 5e7200f05873..c17ccb913fde 100644
|
||||||
|
--- a/drivers/scsi/storvsc_drv.c
|
||||||
|
+++ b/drivers/scsi/storvsc_drv.c
|
||||||
|
@@ -1826,8 +1826,10 @@ static int storvsc_probe(struct hv_device *device,
|
||||||
|
fc_host_node_name(host) = stor_device->node_name;
|
||||||
|
fc_host_port_name(host) = stor_device->port_name;
|
||||||
|
stor_device->rport = fc_remote_port_add(host, 0, &ids);
|
||||||
|
- if (!stor_device->rport)
|
||||||
|
+ if (!stor_device->rport) {
|
||||||
|
+ ret = -ENOMEM;
|
||||||
|
goto err_out3;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
|
||||||
|
index bd15309ac5f1..082891dffd9d 100644
|
||||||
|
--- a/drivers/vhost/net.c
|
||||||
|
+++ b/drivers/vhost/net.c
|
||||||
|
@@ -1212,6 +1212,7 @@ static long vhost_net_reset_owner(struct vhost_net *n)
|
||||||
|
}
|
||||||
|
vhost_net_stop(n, &tx_sock, &rx_sock);
|
||||||
|
vhost_net_flush(n);
|
||||||
|
+ vhost_dev_stop(&n->dev);
|
||||||
|
vhost_dev_reset_owner(&n->dev, umem);
|
||||||
|
vhost_net_vq_reset(n);
|
||||||
|
done:
|
||||||
|
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||||
|
index f6cad39f35df..e3a08761eb40 100644
|
||||||
|
--- a/kernel/exit.c
|
||||||
|
+++ b/kernel/exit.c
|
||||||
|
@@ -1755,3 +1755,12 @@ COMPAT_SYSCALL_DEFINE5(waitid,
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+__weak void abort(void)
|
||||||
|
+{
|
||||||
|
+ BUG();
|
||||||
|
+
|
||||||
|
+ /* if that doesn't kill us, halt */
|
||||||
|
+ panic("Oops failed to kill thread");
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(abort);
|
||||||
|
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||||
|
index 53f7c919b916..66e7efabf0a1 100644
|
||||||
|
--- a/mm/memcontrol.c
|
||||||
|
+++ b/mm/memcontrol.c
|
||||||
|
@@ -5828,6 +5828,20 @@ void mem_cgroup_sk_alloc(struct sock *sk)
|
||||||
|
if (!mem_cgroup_sockets_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Socket cloning can throw us here with sk_memcg already
|
||||||
|
+ * filled. It won't however, necessarily happen from
|
||||||
|
+ * process context. So the test for root memcg given
|
||||||
|
+ * the current task's memcg won't help us in this case.
|
||||||
|
+ *
|
||||||
|
+ * Respecting the original socket's memcg is a better
|
||||||
|
+ * decision in this case.
|
||||||
|
+ */
|
||||||
|
+ if (sk->sk_memcg) {
|
||||||
|
+ css_get(&sk->sk_memcg->css);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
rcu_read_lock();
|
||||||
|
memcg = mem_cgroup_from_task(current);
|
||||||
|
if (memcg == root_mem_cgroup)
|
||||||
|
diff --git a/net/core/sock.c b/net/core/sock.c
|
||||||
|
index 415f441c63b9..beb1e299fed3 100644
|
||||||
|
--- a/net/core/sock.c
|
||||||
|
+++ b/net/core/sock.c
|
||||||
|
@@ -1677,16 +1677,13 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||||
|
newsk->sk_dst_pending_confirm = 0;
|
||||||
|
newsk->sk_wmem_queued = 0;
|
||||||
|
newsk->sk_forward_alloc = 0;
|
||||||
|
-
|
||||||
|
- /* sk->sk_memcg will be populated at accept() time */
|
||||||
|
- newsk->sk_memcg = NULL;
|
||||||
|
-
|
||||||
|
atomic_set(&newsk->sk_drops, 0);
|
||||||
|
newsk->sk_send_head = NULL;
|
||||||
|
newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;
|
||||||
|
atomic_set(&newsk->sk_zckey, 0);
|
||||||
|
|
||||||
|
sock_reset_flag(newsk, SOCK_DONE);
|
||||||
|
+ mem_cgroup_sk_alloc(newsk);
|
||||||
|
cgroup_sk_alloc(&newsk->sk_cgrp_data);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
|
||||||
|
index 5eeb1d20cc38..676092d7bd81 100644
|
||||||
|
--- a/net/core/sock_reuseport.c
|
||||||
|
+++ b/net/core/sock_reuseport.c
|
||||||
|
@@ -94,6 +94,16 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
|
||||||
|
return more_reuse;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void reuseport_free_rcu(struct rcu_head *head)
|
||||||
|
+{
|
||||||
|
+ struct sock_reuseport *reuse;
|
||||||
|
+
|
||||||
|
+ reuse = container_of(head, struct sock_reuseport, rcu);
|
||||||
|
+ if (reuse->prog)
|
||||||
|
+ bpf_prog_destroy(reuse->prog);
|
||||||
|
+ kfree(reuse);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* reuseport_add_sock - Add a socket to the reuseport group of another.
|
||||||
|
* @sk: New socket to add to the group.
|
||||||
|
@@ -102,7 +112,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
|
||||||
|
*/
|
||||||
|
int reuseport_add_sock(struct sock *sk, struct sock *sk2)
|
||||||
|
{
|
||||||
|
- struct sock_reuseport *reuse;
|
||||||
|
+ struct sock_reuseport *old_reuse, *reuse;
|
||||||
|
|
||||||
|
if (!rcu_access_pointer(sk2->sk_reuseport_cb)) {
|
||||||
|
int err = reuseport_alloc(sk2);
|
||||||
|
@@ -113,10 +123,13 @@ int reuseport_add_sock(struct sock *sk, struct sock *sk2)
|
||||||
|
|
||||||
|
spin_lock_bh(&reuseport_lock);
|
||||||
|
reuse = rcu_dereference_protected(sk2->sk_reuseport_cb,
|
||||||
|
- lockdep_is_held(&reuseport_lock)),
|
||||||
|
- WARN_ONCE(rcu_dereference_protected(sk->sk_reuseport_cb,
|
||||||
|
- lockdep_is_held(&reuseport_lock)),
|
||||||
|
- "socket already in reuseport group");
|
||||||
|
+ lockdep_is_held(&reuseport_lock));
|
||||||
|
+ old_reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
|
||||||
|
+ lockdep_is_held(&reuseport_lock));
|
||||||
|
+ if (old_reuse && old_reuse->num_socks != 1) {
|
||||||
|
+ spin_unlock_bh(&reuseport_lock);
|
||||||
|
+ return -EBUSY;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (reuse->num_socks == reuse->max_socks) {
|
||||||
|
reuse = reuseport_grow(reuse);
|
||||||
|
@@ -134,19 +147,11 @@ int reuseport_add_sock(struct sock *sk, struct sock *sk2)
|
||||||
|
|
||||||
|
spin_unlock_bh(&reuseport_lock);
|
||||||
|
|
||||||
|
+ if (old_reuse)
|
||||||
|
+ call_rcu(&old_reuse->rcu, reuseport_free_rcu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void reuseport_free_rcu(struct rcu_head *head)
|
||||||
|
-{
|
||||||
|
- struct sock_reuseport *reuse;
|
||||||
|
-
|
||||||
|
- reuse = container_of(head, struct sock_reuseport, rcu);
|
||||||
|
- if (reuse->prog)
|
||||||
|
- bpf_prog_destroy(reuse->prog);
|
||||||
|
- kfree(reuse);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void reuseport_detach_sock(struct sock *sk)
|
||||||
|
{
|
||||||
|
struct sock_reuseport *reuse;
|
||||||
|
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
|
||||||
|
index 013fed55b610..fbeb35ad804b 100644
|
||||||
|
--- a/net/ipv4/igmp.c
|
||||||
|
+++ b/net/ipv4/igmp.c
|
||||||
|
@@ -386,7 +386,11 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
|
||||||
|
pip->frag_off = htons(IP_DF);
|
||||||
|
pip->ttl = 1;
|
||||||
|
pip->daddr = fl4.daddr;
|
||||||
|
+
|
||||||
|
+ rcu_read_lock();
|
||||||
|
pip->saddr = igmpv3_get_srcaddr(dev, &fl4);
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+
|
||||||
|
pip->protocol = IPPROTO_IGMP;
|
||||||
|
pip->tot_len = 0; /* filled in later */
|
||||||
|
ip_select_ident(net, skb, NULL);
|
||||||
|
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
|
||||||
|
index b47a59cb3573..0cc08c512202 100644
|
||||||
|
--- a/net/ipv4/inet_connection_sock.c
|
||||||
|
+++ b/net/ipv4/inet_connection_sock.c
|
||||||
|
@@ -475,7 +475,6 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&queue->fastopenq.lock);
|
||||||
|
}
|
||||||
|
- mem_cgroup_sk_alloc(newsk);
|
||||||
|
out:
|
||||||
|
release_sock(sk);
|
||||||
|
if (req)
|
||||||
|
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
||||||
|
index 2a65d806b562..fe11128d7df4 100644
|
||||||
|
--- a/net/ipv4/tcp.c
|
||||||
|
+++ b/net/ipv4/tcp.c
|
||||||
|
@@ -2379,6 +2379,12 @@ int tcp_disconnect(struct sock *sk, int flags)
|
||||||
|
|
||||||
|
WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
|
||||||
|
|
||||||
|
+ if (sk->sk_frag.page) {
|
||||||
|
+ put_page(sk->sk_frag.page);
|
||||||
|
+ sk->sk_frag.page = NULL;
|
||||||
|
+ sk->sk_frag.offset = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
sk->sk_error_report(sk);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
|
||||||
|
index 8322f26e770e..25c5a0b60cfc 100644
|
||||||
|
--- a/net/ipv4/tcp_bbr.c
|
||||||
|
+++ b/net/ipv4/tcp_bbr.c
|
||||||
|
@@ -481,7 +481,8 @@ static void bbr_advance_cycle_phase(struct sock *sk)
|
||||||
|
|
||||||
|
bbr->cycle_idx = (bbr->cycle_idx + 1) & (CYCLE_LEN - 1);
|
||||||
|
bbr->cycle_mstamp = tp->delivered_mstamp;
|
||||||
|
- bbr->pacing_gain = bbr_pacing_gain[bbr->cycle_idx];
|
||||||
|
+ bbr->pacing_gain = bbr->lt_use_bw ? BBR_UNIT :
|
||||||
|
+ bbr_pacing_gain[bbr->cycle_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gain cycling: cycle pacing gain to converge to fair share of available bw. */
|
||||||
|
@@ -490,8 +491,7 @@ static void bbr_update_cycle_phase(struct sock *sk,
|
||||||
|
{
|
||||||
|
struct bbr *bbr = inet_csk_ca(sk);
|
||||||
|
|
||||||
|
- if ((bbr->mode == BBR_PROBE_BW) && !bbr->lt_use_bw &&
|
||||||
|
- bbr_is_next_cycle_phase(sk, rs))
|
||||||
|
+ if (bbr->mode == BBR_PROBE_BW && bbr_is_next_cycle_phase(sk, rs))
|
||||||
|
bbr_advance_cycle_phase(sk);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
||||||
|
index c5318f5f6a14..6a76e41e6d51 100644
|
||||||
|
--- a/net/ipv6/addrconf.c
|
||||||
|
+++ b/net/ipv6/addrconf.c
|
||||||
|
@@ -184,7 +184,8 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
|
||||||
|
|
||||||
|
static void addrconf_dad_start(struct inet6_ifaddr *ifp);
|
||||||
|
static void addrconf_dad_work(struct work_struct *w);
|
||||||
|
-static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id);
|
||||||
|
+static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id,
|
||||||
|
+ bool send_na);
|
||||||
|
static void addrconf_dad_run(struct inet6_dev *idev);
|
||||||
|
static void addrconf_rs_timer(unsigned long data);
|
||||||
|
static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
|
||||||
|
@@ -3825,12 +3826,17 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
|
||||||
|
idev->cnf.accept_dad < 1) ||
|
||||||
|
!(ifp->flags&IFA_F_TENTATIVE) ||
|
||||||
|
ifp->flags & IFA_F_NODAD) {
|
||||||
|
+ bool send_na = false;
|
||||||
|
+
|
||||||
|
+ if (ifp->flags & IFA_F_TENTATIVE &&
|
||||||
|
+ !(ifp->flags & IFA_F_OPTIMISTIC))
|
||||||
|
+ send_na = true;
|
||||||
|
bump_id = ifp->flags & IFA_F_TENTATIVE;
|
||||||
|
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
|
||||||
|
spin_unlock(&ifp->lock);
|
||||||
|
read_unlock_bh(&idev->lock);
|
||||||
|
|
||||||
|
- addrconf_dad_completed(ifp, bump_id);
|
||||||
|
+ addrconf_dad_completed(ifp, bump_id, send_na);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3959,16 +3965,21 @@ static void addrconf_dad_work(struct work_struct *w)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ifp->dad_probes == 0) {
|
||||||
|
+ bool send_na = false;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* DAD was successful
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ if (ifp->flags & IFA_F_TENTATIVE &&
|
||||||
|
+ !(ifp->flags & IFA_F_OPTIMISTIC))
|
||||||
|
+ send_na = true;
|
||||||
|
bump_id = ifp->flags & IFA_F_TENTATIVE;
|
||||||
|
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
|
||||||
|
spin_unlock(&ifp->lock);
|
||||||
|
write_unlock_bh(&idev->lock);
|
||||||
|
|
||||||
|
- addrconf_dad_completed(ifp, bump_id);
|
||||||
|
+ addrconf_dad_completed(ifp, bump_id, send_na);
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -4006,7 +4017,8 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id)
|
||||||
|
+static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id,
|
||||||
|
+ bool send_na)
|
||||||
|
{
|
||||||
|
struct net_device *dev = ifp->idev->dev;
|
||||||
|
struct in6_addr lladdr;
|
||||||
|
@@ -4038,6 +4050,16 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id)
|
||||||
|
if (send_mld)
|
||||||
|
ipv6_mc_dad_complete(ifp->idev);
|
||||||
|
|
||||||
|
+ /* send unsolicited NA if enabled */
|
||||||
|
+ if (send_na &&
|
||||||
|
+ (ifp->idev->cnf.ndisc_notify ||
|
||||||
|
+ dev_net(dev)->ipv6.devconf_all->ndisc_notify)) {
|
||||||
|
+ ndisc_send_na(dev, &in6addr_linklocal_allnodes, &ifp->addr,
|
||||||
|
+ /*router=*/ !!ifp->idev->cnf.forwarding,
|
||||||
|
+ /*solicited=*/ false, /*override=*/ true,
|
||||||
|
+ /*inc_opt=*/ true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (send_rs) {
|
||||||
|
/*
|
||||||
|
* If a host as already performed a random delay
|
||||||
|
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
|
||||||
|
index bcbd5f3bf8bd..9ccbf74deb99 100644
|
||||||
|
--- a/net/ipv6/af_inet6.c
|
||||||
|
+++ b/net/ipv6/af_inet6.c
|
||||||
|
@@ -284,6 +284,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||||
|
struct net *net = sock_net(sk);
|
||||||
|
__be32 v4addr = 0;
|
||||||
|
unsigned short snum;
|
||||||
|
+ bool saved_ipv6only;
|
||||||
|
int addr_type = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
@@ -389,19 +390,21 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||||
|
if (!(addr_type & IPV6_ADDR_MULTICAST))
|
||||||
|
np->saddr = addr->sin6_addr;
|
||||||
|
|
||||||
|
+ saved_ipv6only = sk->sk_ipv6only;
|
||||||
|
+ if (addr_type != IPV6_ADDR_ANY && addr_type != IPV6_ADDR_MAPPED)
|
||||||
|
+ sk->sk_ipv6only = 1;
|
||||||
|
+
|
||||||
|
/* Make sure we are allowed to bind here. */
|
||||||
|
if ((snum || !inet->bind_address_no_port) &&
|
||||||
|
sk->sk_prot->get_port(sk, snum)) {
|
||||||
|
+ sk->sk_ipv6only = saved_ipv6only;
|
||||||
|
inet_reset_saddr(sk);
|
||||||
|
err = -EADDRINUSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (addr_type != IPV6_ADDR_ANY) {
|
||||||
|
+ if (addr_type != IPV6_ADDR_ANY)
|
||||||
|
sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
|
||||||
|
- if (addr_type != IPV6_ADDR_MAPPED)
|
||||||
|
- sk->sk_ipv6only = 1;
|
||||||
|
- }
|
||||||
|
if (snum)
|
||||||
|
sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
|
||||||
|
inet->inet_sport = htons(inet->inet_num);
|
||||||
|
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
|
||||||
|
index f5500f5444e9..e1060f28410d 100644
|
||||||
|
--- a/net/ipv6/ip6mr.c
|
||||||
|
+++ b/net/ipv6/ip6mr.c
|
||||||
|
@@ -496,6 +496,7 @@ static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
|
|
||||||
|
it->mrt = mrt;
|
||||||
|
+ it->cache = NULL;
|
||||||
|
return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
|
||||||
|
: SEQ_START_TOKEN;
|
||||||
|
}
|
||||||
|
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
|
||||||
|
index 266a530414d7..2a937c8d19e9 100644
|
||||||
|
--- a/net/ipv6/ndisc.c
|
||||||
|
+++ b/net/ipv6/ndisc.c
|
||||||
|
@@ -558,6 +558,11 @@ static void ndisc_send_unsol_na(struct net_device *dev)
|
||||||
|
|
||||||
|
read_lock_bh(&idev->lock);
|
||||||
|
list_for_each_entry(ifa, &idev->addr_list, if_list) {
|
||||||
|
+ /* skip tentative addresses until dad completes */
|
||||||
|
+ if (ifa->flags & IFA_F_TENTATIVE &&
|
||||||
|
+ !(ifa->flags & IFA_F_OPTIMISTIC))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
ndisc_send_na(dev, &in6addr_linklocal_allnodes, &ifa->addr,
|
||||||
|
/*router=*/ !!idev->cnf.forwarding,
|
||||||
|
/*solicited=*/ false, /*override=*/ true,
|
||||||
|
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
|
||||||
|
index 34de8b953ecf..348af5b20618 100644
|
||||||
|
--- a/scripts/package/Makefile
|
||||||
|
+++ b/scripts/package/Makefile
|
||||||
|
@@ -50,7 +50,6 @@ rpm-pkg rpm: FORCE
|
||||||
|
$(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
|
||||||
|
$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
|
||||||
|
+rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
|
||||||
|
- rm $(KERNELPATH).tar.gz kernel.spec
|
||||||
|
|
||||||
|
# binrpm-pkg
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
@@ -59,7 +58,8 @@ binrpm-pkg: FORCE
|
||||||
|
$(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec
|
||||||
|
+rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
|
||||||
|
$(UTS_MACHINE) -bb $(objtree)/binkernel.spec
|
||||||
|
- rm binkernel.spec
|
||||||
|
+
|
||||||
|
+clean-files += $(objtree)/*.spec
|
||||||
|
|
||||||
|
# Deb target
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
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
@@ -1,179 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1419,12 +1419,12 @@ diff -Nurp linux-3.14.2/drivers/platform/x86/shuttle-wmi.c linux-3.14.2-shuttle/
|
|||||||
+
|
+
|
||||||
+module_init(shuttle_wmi_init);
|
+module_init(shuttle_wmi_init);
|
||||||
+module_exit(shuttle_wmi_exit);
|
+module_exit(shuttle_wmi_exit);
|
||||||
diff -Nurp linux-4.6/MAINTAINERS linux-4.6-shuttle/MAINTAINERS
|
diff -Nurp linux-4.13/MAINTAINERS linux-4.13-shuttle/MAINTAINERS
|
||||||
--- linux-4.6/MAINTAINERS
|
--- linux-4.13/MAINTAINERS
|
||||||
+++ linux-4.6-shuttle/MAINTAINERS
|
+++ linux-4.13-shuttle/MAINTAINERS
|
||||||
@@ -10130,6 +10130,12 @@ S: Orphan
|
@@ -11861,6 +11861,12 @@
|
||||||
F: drivers/media/platform/sh_vou.c
|
F: drivers/tty/serial/ioc?_serial.c
|
||||||
F: include/media/drv-intf/sh_vou.h
|
F: include/linux/ioc?.h
|
||||||
|
|
||||||
+SHUTTLE WMI EXTRAS DRIVER
|
+SHUTTLE WMI EXTRAS DRIVER
|
||||||
+M: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
+M: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
@@ -1432,6 +1432,6 @@ diff -Nurp linux-4.6/MAINTAINERS linux-4.6-shuttle/MAINTAINERS
|
|||||||
+S: Maintained
|
+S: Maintained
|
||||||
+F: drivers/platform/x86/shuttle-wmi.c
|
+F: drivers/platform/x86/shuttle-wmi.c
|
||||||
+
|
+
|
||||||
SIMPLE FIRMWARE INTERFACE (SFI)
|
SGI XP/XPC/XPNET DRIVER
|
||||||
M: Len Brown <lenb@kernel.org>
|
M: Cliff Whickman <cpw@sgi.com>
|
||||||
L: sfi-devel@simplefirmware.org
|
M: Robin Holt <robinmholt@gmail.com>
|
||||||
|
|||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
From f35823619db8bbaa2afea8705f239c3cecb9d22f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Santeri Toivonen <santeri.toivonen@vatsul.com>
|
|
||||||
Date: Tue, 4 Apr 2017 21:09:00 +0300
|
|
||||||
Subject: [PATCH] platform/x86: asus-nb-wmi: Add wapf4 quirk for the X302UA
|
|
||||||
|
|
||||||
Asus laptop X302UA starts up with Wi-Fi disabled,
|
|
||||||
without a way to enable it. Set wapf=4 to fix the problem.
|
|
||||||
|
|
||||||
Signed-off-by: Santeri Toivonen <santeri.toivonen@vatsul.com>
|
|
||||||
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
|
|
||||||
---
|
|
||||||
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
|
|
||||||
1 file changed, 9 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
|
|
||||||
index dea98ffb6f60..1ae58d906536 100644
|
|
||||||
--- a/drivers/platform/x86/asus-nb-wmi.c
|
|
||||||
+++ b/drivers/platform/x86/asus-nb-wmi.c
|
|
||||||
@@ -144,6 +144,15 @@ static const struct dmi_system_id asus_quirks[] = {
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.callback = dmi_matched,
|
|
||||||
+ .ident = "ASUSTeK COMPUTER INC. X302UA",
|
|
||||||
+ .matches = {
|
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
||||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"),
|
|
||||||
+ },
|
|
||||||
+ .driver_data = &quirk_asus_wapf4,
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ .callback = dmi_matched,
|
|
||||||
.ident = "ASUSTeK COMPUTER INC. X401U",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
||||||
--
|
|
||||||
2.13.2
|
|
||||||
|
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
Add Lenovo Ideapad 320-15IKB to no_hw_rfkill_list
|
||||||
|
|
||||||
|
https://bugs.mageia.org/show_bug.cgi?id=21728
|
||||||
|
|
||||||
|
Reported-by: Jean-Christophe Cardot <mageia@cardot.net>
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- a/drivers/platform/x86/ideapad-laptop.c
|
||||||
|
+++ b/drivers/platform/x86/ideapad-laptop.c
|
||||||
|
@@ -956,6 +956,13 @@ static const struct dmi_system_id no_hw_
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .ident = "Lenovo ideapad 320-15IKB",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 320-15IKB"),
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.ident = "Lenovo ideapad Y700-14ISK",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
sparse_keymap_free() is now obsolete.
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mageia.org>
|
||||||
|
|
||||||
|
--- linux/drivers/platform/x86/shuttle-wmi.c.orig 2017-10-15 00:39:53.041395980 +0300
|
||||||
|
+++ linux/drivers/platform/x86/shuttle-wmi.c 2017-10-15 01:05:37.008662881 +0300
|
||||||
|
@@ -763,14 +763,9 @@ static int shuttle_wmi_input_init(struct
|
||||||
|
goto err_free_dev;
|
||||||
|
|
||||||
|
rc = input_register_device(input);
|
||||||
|
- if (rc)
|
||||||
|
- goto err_free_keymap;
|
||||||
|
|
||||||
|
priv->inputdev = input;
|
||||||
|
return 0;
|
||||||
|
-
|
||||||
|
-err_free_keymap:
|
||||||
|
- sparse_keymap_free(input);
|
||||||
|
err_free_dev:
|
||||||
|
input_free_device(input);
|
||||||
|
return rc;
|
||||||
|
@@ -780,7 +775,6 @@ static void shuttle_wmi_input_remove(str
|
||||||
|
{
|
||||||
|
struct input_dev *input = priv->inputdev;
|
||||||
|
|
||||||
|
- sparse_keymap_free(input);
|
||||||
|
input_unregister_device(input);
|
||||||
|
}
|
||||||
|
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
From 3b7711fd3adb7d6b812a33da4a4639ddce6522b6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Fri, 19 Jan 2018 13:46:20 +0100
|
||||||
|
Subject: [PATCH 01/31] x86/asm-offsets: Move TSS_sp0 and TSS_sp1 to
|
||||||
|
asm-offsets.c
|
||||||
|
|
||||||
|
These offsets will be used in 32 bit assembly code as well,
|
||||||
|
so make them available for all of x86 code.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/kernel/asm-offsets.c | 4 ++++
|
||||||
|
arch/x86/kernel/asm-offsets_64.c | 2 --
|
||||||
|
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
|
||||||
|
index 76417a9aab73..232152ccb301 100644
|
||||||
|
--- a/arch/x86/kernel/asm-offsets.c
|
||||||
|
+++ b/arch/x86/kernel/asm-offsets.c
|
||||||
|
@@ -103,4 +103,8 @@ void common(void) {
|
||||||
|
OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline);
|
||||||
|
OFFSET(CPU_ENTRY_AREA_entry_stack, cpu_entry_area, entry_stack_page);
|
||||||
|
DEFINE(SIZEOF_entry_stack, sizeof(struct entry_stack));
|
||||||
|
+
|
||||||
|
+ /* Offset for sp0 and sp1 into the tss_struct */
|
||||||
|
+ OFFSET(TSS_sp0, tss_struct, x86_tss.sp0);
|
||||||
|
+ OFFSET(TSS_sp1, tss_struct, x86_tss.sp1);
|
||||||
|
}
|
||||||
|
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
|
||||||
|
index bf51e51d808d..d2eba73a5f8a 100644
|
||||||
|
--- a/arch/x86/kernel/asm-offsets_64.c
|
||||||
|
+++ b/arch/x86/kernel/asm-offsets_64.c
|
||||||
|
@@ -65,8 +65,6 @@ int main(void)
|
||||||
|
#undef ENTRY
|
||||||
|
|
||||||
|
OFFSET(TSS_ist, tss_struct, x86_tss.ist);
|
||||||
|
- OFFSET(TSS_sp0, tss_struct, x86_tss.sp0);
|
||||||
|
- OFFSET(TSS_sp1, tss_struct, x86_tss.sp1);
|
||||||
|
BLANK();
|
||||||
|
|
||||||
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
From 52806123bdb0b558a5b4fbfa132bae32e53b008a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Mon, 15 Jan 2018 18:20:15 +0100
|
||||||
|
Subject: [PATCH 02/31] x86/entry/32: Rename TSS_sysenter_sp0 to
|
||||||
|
TSS_entry_stack
|
||||||
|
|
||||||
|
The stack address doesn't need to be stored in tss.sp0 if
|
||||||
|
we switch manually like on sysenter. Rename the offset so
|
||||||
|
that it still makes sense when we change its location.
|
||||||
|
|
||||||
|
We will also use this stack for all kernel-entry points, not
|
||||||
|
just sysenter. Reflect that in the name as well.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 2 +-
|
||||||
|
arch/x86/kernel/asm-offsets_32.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index 2a35b1e0fb90..e65977615616 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -413,7 +413,7 @@ ENTRY(xen_sysenter_target)
|
||||||
|
* 0(%ebp) arg6
|
||||||
|
*/
|
||||||
|
ENTRY(entry_SYSENTER_32)
|
||||||
|
- movl TSS_sysenter_sp0(%esp), %esp
|
||||||
|
+ movl TSS_entry_stack(%esp), %esp
|
||||||
|
.Lsysenter_past_esp:
|
||||||
|
pushl $__USER_DS /* pt_regs->ss */
|
||||||
|
pushl %ebp /* pt_regs->sp (stashed in bp) */
|
||||||
|
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
index fa1261eefa16..f452bfdc485a 100644
|
||||||
|
--- a/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
+++ b/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
@@ -47,7 +47,7 @@ void foo(void)
|
||||||
|
BLANK();
|
||||||
|
|
||||||
|
/* Offset from the sysenter stack to tss.sp0 */
|
||||||
|
- DEFINE(TSS_sysenter_sp0, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) -
|
||||||
|
+ DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) -
|
||||||
|
offsetofend(struct cpu_entry_area, entry_stack_page.stack));
|
||||||
|
|
||||||
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
From b696a2c46d9b9937b816b11ff2ec72aa0b65f204 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Fri, 19 Jan 2018 13:33:37 +0100
|
||||||
|
Subject: [PATCH 03/31] x86/entry/32: Load task stack from x86_tss.sp1 in
|
||||||
|
SYSENTER handler
|
||||||
|
|
||||||
|
We want x86_tss.sp0 point to the entry stack later to use
|
||||||
|
it as a trampoline stack for other kernel entry points
|
||||||
|
besides SYSENTER.
|
||||||
|
|
||||||
|
So store the task stack pointer in x86_tss.sp1, which is
|
||||||
|
otherwise unused by the hardware, as Linux doesn't make use
|
||||||
|
of Ring 1.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/kernel/asm-offsets_32.c | 2 +-
|
||||||
|
arch/x86/kernel/process_32.c | 2 ++
|
||||||
|
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
index f452bfdc485a..b97e48c87e80 100644
|
||||||
|
--- a/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
+++ b/arch/x86/kernel/asm-offsets_32.c
|
||||||
|
@@ -47,7 +47,7 @@ void foo(void)
|
||||||
|
BLANK();
|
||||||
|
|
||||||
|
/* Offset from the sysenter stack to tss.sp0 */
|
||||||
|
- DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) -
|
||||||
|
+ DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, tss.x86_tss.sp1) -
|
||||||
|
offsetofend(struct cpu_entry_area, entry_stack_page.stack));
|
||||||
|
|
||||||
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||||
|
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
|
||||||
|
index 5224c6099184..097d36a64889 100644
|
||||||
|
--- a/arch/x86/kernel/process_32.c
|
||||||
|
+++ b/arch/x86/kernel/process_32.c
|
||||||
|
@@ -292,6 +292,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||||
|
this_cpu_write(cpu_current_top_of_stack,
|
||||||
|
(unsigned long)task_stack_page(next_p) +
|
||||||
|
THREAD_SIZE);
|
||||||
|
+ /* SYSENTER reads the task-stack from tss.sp1 */
|
||||||
|
+ this_cpu_write(cpu_tss_rw.x86_tss.sp1, next_p->thread.sp0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore %gs if needed (which is common)
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
From 7c97243c7694dc1c0e0ad73bc17bdc2c553225ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 10:50:02 +0100
|
||||||
|
Subject: [PATCH 04/31] x86/entry/32: Put ESPFIX code into a macro
|
||||||
|
|
||||||
|
This makes it easier to split up the shared iret code path.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 97 ++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 49 insertions(+), 48 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index e65977615616..0289bde37a08 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -221,6 +221,54 @@
|
||||||
|
POP_GS_EX
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+.macro CHECK_AND_APPLY_ESPFIX
|
||||||
|
+#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
+#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
|
||||||
|
+
|
||||||
|
+ ALTERNATIVE "jmp .Lend_\@", "", X86_BUG_ESPFIX
|
||||||
|
+
|
||||||
|
+ movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
|
||||||
|
+ /*
|
||||||
|
+ * Warning: PT_OLDSS(%esp) contains the wrong/random values if we
|
||||||
|
+ * are returning to the kernel.
|
||||||
|
+ * See comments in process.c:copy_thread() for details.
|
||||||
|
+ */
|
||||||
|
+ movb PT_OLDSS(%esp), %ah
|
||||||
|
+ movb PT_CS(%esp), %al
|
||||||
|
+ andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
|
||||||
|
+ cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
|
||||||
|
+ jne .Lend_\@ # returning to user-space with LDT SS
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Setup and switch to ESPFIX stack
|
||||||
|
+ *
|
||||||
|
+ * We're returning to userspace with a 16 bit stack. The CPU will not
|
||||||
|
+ * restore the high word of ESP for us on executing iret... This is an
|
||||||
|
+ * "official" bug of all the x86-compatible CPUs, which we can work
|
||||||
|
+ * around to make dosemu and wine happy. We do this by preloading the
|
||||||
|
+ * high word of ESP with the high word of the userspace ESP while
|
||||||
|
+ * compensating for the offset by changing to the ESPFIX segment with
|
||||||
|
+ * a base address that matches for the difference.
|
||||||
|
+ */
|
||||||
|
+ mov %esp, %edx /* load kernel esp */
|
||||||
|
+ mov PT_OLDESP(%esp), %eax /* load userspace esp */
|
||||||
|
+ mov %dx, %ax /* eax: new kernel esp */
|
||||||
|
+ sub %eax, %edx /* offset (low word is 0) */
|
||||||
|
+ shr $16, %edx
|
||||||
|
+ mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
|
||||||
|
+ mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
|
||||||
|
+ pushl $__ESPFIX_SS
|
||||||
|
+ pushl %eax /* new kernel esp */
|
||||||
|
+ /*
|
||||||
|
+ * Disable interrupts, but do not irqtrace this section: we
|
||||||
|
+ * will soon execute iret and the tracer was already set to
|
||||||
|
+ * the irqstate after the IRET:
|
||||||
|
+ */
|
||||||
|
+ DISABLE_INTERRUPTS(CLBR_ANY)
|
||||||
|
+ lss (%esp), %esp /* switch to espfix segment */
|
||||||
|
+.Lend_\@:
|
||||||
|
+#endif /* CONFIG_X86_ESPFIX32 */
|
||||||
|
+.endm
|
||||||
|
/*
|
||||||
|
* %eax: prev task
|
||||||
|
* %edx: next task
|
||||||
|
@@ -548,21 +596,7 @@ ENTRY(entry_INT80_32)
|
||||||
|
restore_all:
|
||||||
|
TRACE_IRQS_IRET
|
||||||
|
.Lrestore_all_notrace:
|
||||||
|
-#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
- ALTERNATIVE "jmp .Lrestore_nocheck", "", X86_BUG_ESPFIX
|
||||||
|
-
|
||||||
|
- movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
|
||||||
|
- /*
|
||||||
|
- * Warning: PT_OLDSS(%esp) contains the wrong/random values if we
|
||||||
|
- * are returning to the kernel.
|
||||||
|
- * See comments in process.c:copy_thread() for details.
|
||||||
|
- */
|
||||||
|
- movb PT_OLDSS(%esp), %ah
|
||||||
|
- movb PT_CS(%esp), %al
|
||||||
|
- andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
|
||||||
|
- cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
|
||||||
|
- je .Lldt_ss # returning to user-space with LDT SS
|
||||||
|
-#endif
|
||||||
|
+ CHECK_AND_APPLY_ESPFIX
|
||||||
|
.Lrestore_nocheck:
|
||||||
|
RESTORE_REGS 4 # skip orig_eax/error_code
|
||||||
|
.Lirq_return:
|
||||||
|
@@ -575,39 +609,6 @@ ENTRY(iret_exc )
|
||||||
|
jmp common_exception
|
||||||
|
.previous
|
||||||
|
_ASM_EXTABLE(.Lirq_return, iret_exc)
|
||||||
|
-
|
||||||
|
-#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
-.Lldt_ss:
|
||||||
|
-/*
|
||||||
|
- * Setup and switch to ESPFIX stack
|
||||||
|
- *
|
||||||
|
- * We're returning to userspace with a 16 bit stack. The CPU will not
|
||||||
|
- * restore the high word of ESP for us on executing iret... This is an
|
||||||
|
- * "official" bug of all the x86-compatible CPUs, which we can work
|
||||||
|
- * around to make dosemu and wine happy. We do this by preloading the
|
||||||
|
- * high word of ESP with the high word of the userspace ESP while
|
||||||
|
- * compensating for the offset by changing to the ESPFIX segment with
|
||||||
|
- * a base address that matches for the difference.
|
||||||
|
- */
|
||||||
|
-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
|
||||||
|
- mov %esp, %edx /* load kernel esp */
|
||||||
|
- mov PT_OLDESP(%esp), %eax /* load userspace esp */
|
||||||
|
- mov %dx, %ax /* eax: new kernel esp */
|
||||||
|
- sub %eax, %edx /* offset (low word is 0) */
|
||||||
|
- shr $16, %edx
|
||||||
|
- mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
|
||||||
|
- mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
|
||||||
|
- pushl $__ESPFIX_SS
|
||||||
|
- pushl %eax /* new kernel esp */
|
||||||
|
- /*
|
||||||
|
- * Disable interrupts, but do not irqtrace this section: we
|
||||||
|
- * will soon execute iret and the tracer was already set to
|
||||||
|
- * the irqstate after the IRET:
|
||||||
|
- */
|
||||||
|
- DISABLE_INTERRUPTS(CLBR_ANY)
|
||||||
|
- lss (%esp), %esp /* switch to espfix segment */
|
||||||
|
- jmp .Lrestore_nocheck
|
||||||
|
-#endif
|
||||||
|
ENDPROC(entry_INT80_32)
|
||||||
|
|
||||||
|
.macro FIXUP_ESPFIX_STACK
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
From c66ec22d03296d1311197aaef753c1c320eed225 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 10:58:38 +0100
|
||||||
|
Subject: [PATCH 05/31] x86/entry/32: Unshare NMI return path
|
||||||
|
|
||||||
|
NMI will no longer use most of the shared return path,
|
||||||
|
because NMI needs special handling when the CR3 switches for
|
||||||
|
PTI are added. This patch prepares for that.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index 0289bde37a08..00ae759a7c44 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -1007,7 +1007,7 @@ ENTRY(nmi)
|
||||||
|
|
||||||
|
/* Not on SYSENTER stack. */
|
||||||
|
call do_nmi
|
||||||
|
- jmp .Lrestore_all_notrace
|
||||||
|
+ jmp .Lnmi_return
|
||||||
|
|
||||||
|
.Lnmi_from_sysenter_stack:
|
||||||
|
/*
|
||||||
|
@@ -1018,7 +1018,11 @@ ENTRY(nmi)
|
||||||
|
movl PER_CPU_VAR(cpu_current_top_of_stack), %esp
|
||||||
|
call do_nmi
|
||||||
|
movl %ebx, %esp
|
||||||
|
- jmp .Lrestore_all_notrace
|
||||||
|
+
|
||||||
|
+.Lnmi_return:
|
||||||
|
+ CHECK_AND_APPLY_ESPFIX
|
||||||
|
+ RESTORE_REGS 4
|
||||||
|
+ jmp .Lirq_return
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
.Lnmi_espfix_stack:
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
From 916e5e906873de859d8a87c1ffb0323e167d1a44 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 11:07:32 +0100
|
||||||
|
Subject: [PATCH 06/31] x86/entry/32: Split off return-to-kernel path
|
||||||
|
|
||||||
|
Use a separate return path when we know we are returning to
|
||||||
|
the kernel. This allows us to put the PTI cr3-switch and the
|
||||||
|
switch to the entry-stack into the return-to-user path
|
||||||
|
without further checking.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 11 ++++++++---
|
||||||
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index 00ae759a7c44..9bd77183965f 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -65,7 +65,7 @@
|
||||||
|
# define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF
|
||||||
|
#else
|
||||||
|
# define preempt_stop(clobbers)
|
||||||
|
-# define resume_kernel restore_all
|
||||||
|
+# define resume_kernel restore_all_kernel
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.macro TRACE_IRQS_IRET
|
||||||
|
@@ -400,9 +400,9 @@ ENTRY(resume_kernel)
|
||||||
|
DISABLE_INTERRUPTS(CLBR_ANY)
|
||||||
|
.Lneed_resched:
|
||||||
|
cmpl $0, PER_CPU_VAR(__preempt_count)
|
||||||
|
- jnz restore_all
|
||||||
|
+ jnz restore_all_kernel
|
||||||
|
testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ?
|
||||||
|
- jz restore_all
|
||||||
|
+ jz restore_all_kernel
|
||||||
|
call preempt_schedule_irq
|
||||||
|
jmp .Lneed_resched
|
||||||
|
END(resume_kernel)
|
||||||
|
@@ -602,6 +602,11 @@ restore_all:
|
||||||
|
.Lirq_return:
|
||||||
|
INTERRUPT_RETURN
|
||||||
|
|
||||||
|
+restore_all_kernel:
|
||||||
|
+ TRACE_IRQS_IRET
|
||||||
|
+ RESTORE_REGS 4
|
||||||
|
+ jmp .Lirq_return
|
||||||
|
+
|
||||||
|
.section .fixup, "ax"
|
||||||
|
ENTRY(iret_exc )
|
||||||
|
pushl $0 # no error code
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
From c19ad15b16ec8908794459f28b44eca889a925f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 11:29:59 +0100
|
||||||
|
Subject: [PATCH 07/31] x86/entry/32: Restore segments before int registers
|
||||||
|
|
||||||
|
Restoring the segments can cause exceptions that need to be
|
||||||
|
handled. With PTI enabled, we still need to be on kernel cr3
|
||||||
|
when the exception happens. For the cr3-switch we need
|
||||||
|
at least one integer scratch register, so we can't switch
|
||||||
|
with the user integer registers already loaded.
|
||||||
|
|
||||||
|
Avoid a push/pop cycle to free a register for the cr3 switch
|
||||||
|
by restoring the segments first. That way the integer
|
||||||
|
registers are not live yet and we can use them for the cr3
|
||||||
|
switch.
|
||||||
|
|
||||||
|
This also helps in the NMI path, where we need to leave with
|
||||||
|
the same cr3 as we entered. There we still have the
|
||||||
|
callee-saved registers live when switching cr3s.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 50 ++++++++++++++++++++---------------------------
|
||||||
|
1 file changed, 21 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index 9bd77183965f..b39c5e210b43 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -92,11 +92,6 @@
|
||||||
|
.macro PUSH_GS
|
||||||
|
pushl $0
|
||||||
|
.endm
|
||||||
|
-.macro POP_GS pop=0
|
||||||
|
- addl $(4 + \pop), %esp
|
||||||
|
-.endm
|
||||||
|
-.macro POP_GS_EX
|
||||||
|
-.endm
|
||||||
|
|
||||||
|
/* all the rest are no-op */
|
||||||
|
.macro PTGS_TO_GS
|
||||||
|
@@ -116,20 +111,6 @@
|
||||||
|
pushl %gs
|
||||||
|
.endm
|
||||||
|
|
||||||
|
-.macro POP_GS pop=0
|
||||||
|
-98: popl %gs
|
||||||
|
- .if \pop <> 0
|
||||||
|
- add $\pop, %esp
|
||||||
|
- .endif
|
||||||
|
-.endm
|
||||||
|
-.macro POP_GS_EX
|
||||||
|
-.pushsection .fixup, "ax"
|
||||||
|
-99: movl $0, (%esp)
|
||||||
|
- jmp 98b
|
||||||
|
-.popsection
|
||||||
|
- _ASM_EXTABLE(98b, 99b)
|
||||||
|
-.endm
|
||||||
|
-
|
||||||
|
.macro PTGS_TO_GS
|
||||||
|
98: mov PT_GS(%esp), %gs
|
||||||
|
.endm
|
||||||
|
@@ -201,24 +182,35 @@
|
||||||
|
popl %eax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
-.macro RESTORE_REGS pop=0
|
||||||
|
- RESTORE_INT_REGS
|
||||||
|
-1: popl %ds
|
||||||
|
-2: popl %es
|
||||||
|
-3: popl %fs
|
||||||
|
- POP_GS \pop
|
||||||
|
+.macro RESTORE_SEGMENTS
|
||||||
|
+1: mov PT_DS(%esp), %ds
|
||||||
|
+2: mov PT_ES(%esp), %es
|
||||||
|
+3: mov PT_FS(%esp), %fs
|
||||||
|
+ PTGS_TO_GS
|
||||||
|
.pushsection .fixup, "ax"
|
||||||
|
-4: movl $0, (%esp)
|
||||||
|
+4: movl $0, PT_DS(%esp)
|
||||||
|
jmp 1b
|
||||||
|
-5: movl $0, (%esp)
|
||||||
|
+5: movl $0, PT_ES(%esp)
|
||||||
|
jmp 2b
|
||||||
|
-6: movl $0, (%esp)
|
||||||
|
+6: movl $0, PT_FS(%esp)
|
||||||
|
jmp 3b
|
||||||
|
.popsection
|
||||||
|
_ASM_EXTABLE(1b, 4b)
|
||||||
|
_ASM_EXTABLE(2b, 5b)
|
||||||
|
_ASM_EXTABLE(3b, 6b)
|
||||||
|
- POP_GS_EX
|
||||||
|
+ PTGS_TO_GS_EX
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
+.macro RESTORE_SKIP_SEGMENTS pop=0
|
||||||
|
+ /* Jump over the segments stored on stack */
|
||||||
|
+ addl $((4 * 4) + \pop), %esp
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
+.macro RESTORE_REGS pop=0
|
||||||
|
+ RESTORE_SEGMENTS
|
||||||
|
+ RESTORE_INT_REGS
|
||||||
|
+ /* Skip over already restored segment registers */
|
||||||
|
+ RESTORE_SKIP_SEGMENTS \pop
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro CHECK_AND_APPLY_ESPFIX
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+355
@@ -0,0 +1,355 @@
|
|||||||
|
From d9dc2b83bdfc2a9265302cc90b32739ac579f8cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Tue, 16 Jan 2018 10:55:52 +0100
|
||||||
|
Subject: [PATCH 08/31] x86/entry/32: Enter the kernel via trampoline stack
|
||||||
|
|
||||||
|
Use the entry-stack as a trampoline to enter the kernel. The
|
||||||
|
entry-stack is already in the cpu_entry_area and will be
|
||||||
|
mapped to userspace when PTI is enabled.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 135 +++++++++++++++++++++++++++++++--------
|
||||||
|
arch/x86/include/asm/switch_to.h | 6 +-
|
||||||
|
arch/x86/kernel/asm-offsets.c | 1 +
|
||||||
|
arch/x86/kernel/cpu/common.c | 5 +-
|
||||||
|
arch/x86/kernel/process.c | 2 -
|
||||||
|
arch/x86/kernel/process_32.c | 10 +--
|
||||||
|
6 files changed, 120 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index b39c5e210b43..e714b53b1eaa 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -135,25 +135,36 @@
|
||||||
|
|
||||||
|
#endif /* CONFIG_X86_32_LAZY_GS */
|
||||||
|
|
||||||
|
-.macro SAVE_ALL pt_regs_ax=%eax
|
||||||
|
+.macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0
|
||||||
|
cld
|
||||||
|
+ /* Push segment registers and %eax */
|
||||||
|
PUSH_GS
|
||||||
|
pushl %fs
|
||||||
|
pushl %es
|
||||||
|
pushl %ds
|
||||||
|
pushl \pt_regs_ax
|
||||||
|
+
|
||||||
|
+ /* Load kernel segments */
|
||||||
|
+ movl $(__USER_DS), %eax
|
||||||
|
+ movl %eax, %ds
|
||||||
|
+ movl %eax, %es
|
||||||
|
+ movl $(__KERNEL_PERCPU), %eax
|
||||||
|
+ movl %eax, %fs
|
||||||
|
+ SET_KERNEL_GS %eax
|
||||||
|
+
|
||||||
|
+ /* Push integer registers and complete PT_REGS */
|
||||||
|
pushl %ebp
|
||||||
|
pushl %edi
|
||||||
|
pushl %esi
|
||||||
|
pushl %edx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %ebx
|
||||||
|
- movl $(__USER_DS), %edx
|
||||||
|
- movl %edx, %ds
|
||||||
|
- movl %edx, %es
|
||||||
|
- movl $(__KERNEL_PERCPU), %edx
|
||||||
|
- movl %edx, %fs
|
||||||
|
- SET_KERNEL_GS %edx
|
||||||
|
+
|
||||||
|
+ /* Switch to kernel stack if necessary */
|
||||||
|
+.if \switch_stacks > 0
|
||||||
|
+ SWITCH_TO_KERNEL_STACK
|
||||||
|
+.endif
|
||||||
|
+
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -261,6 +272,71 @@
|
||||||
|
.Lend_\@:
|
||||||
|
#endif /* CONFIG_X86_ESPFIX32 */
|
||||||
|
.endm
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Called with pt_regs fully populated and kernel segments loaded,
|
||||||
|
+ * so we can access PER_CPU and use the integer registers.
|
||||||
|
+ *
|
||||||
|
+ * We need to be very careful here with the %esp switch, because an NMI
|
||||||
|
+ * can happen everywhere. If the NMI handler finds itself on the
|
||||||
|
+ * entry-stack, it will overwrite the task-stack and everything we
|
||||||
|
+ * copied there. So allocate the stack-frame on the task-stack and
|
||||||
|
+ * switch to it before we do any copying.
|
||||||
|
+ */
|
||||||
|
+.macro SWITCH_TO_KERNEL_STACK
|
||||||
|
+
|
||||||
|
+ ALTERNATIVE "", "jmp .Lend_\@", X86_FEATURE_XENPV
|
||||||
|
+
|
||||||
|
+ /* Are we on the entry stack? Bail out if not! */
|
||||||
|
+ movl PER_CPU_VAR(cpu_entry_area), %edi
|
||||||
|
+ addl $CPU_ENTRY_AREA_entry_stack, %edi
|
||||||
|
+ cmpl %esp, %edi
|
||||||
|
+ jae .Lend_\@
|
||||||
|
+
|
||||||
|
+ /* Load stack pointer into %esi and %edi */
|
||||||
|
+ movl %esp, %esi
|
||||||
|
+ movl %esi, %edi
|
||||||
|
+
|
||||||
|
+ /* Move %edi to the top of the entry stack */
|
||||||
|
+ andl $(MASK_entry_stack), %edi
|
||||||
|
+ addl $(SIZEOF_entry_stack), %edi
|
||||||
|
+
|
||||||
|
+ /* Load top of task-stack into %edi */
|
||||||
|
+ movl TSS_entry_stack(%edi), %edi
|
||||||
|
+
|
||||||
|
+ /* Bytes to copy */
|
||||||
|
+ movl $PTREGS_SIZE, %ecx
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_VM86
|
||||||
|
+ testl $X86_EFLAGS_VM, PT_EFLAGS(%esi)
|
||||||
|
+ jz .Lcopy_pt_regs_\@
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Stack-frame contains 4 additional segment registers when
|
||||||
|
+ * coming from VM86 mode
|
||||||
|
+ */
|
||||||
|
+ addl $(4 * 4), %ecx
|
||||||
|
+
|
||||||
|
+.Lcopy_pt_regs_\@:
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Allocate frame on task-stack */
|
||||||
|
+ subl %ecx, %edi
|
||||||
|
+
|
||||||
|
+ /* Switch to task-stack */
|
||||||
|
+ movl %edi, %esp
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We are now on the task-stack and can safely copy over the
|
||||||
|
+ * stack-frame
|
||||||
|
+ */
|
||||||
|
+ cld
|
||||||
|
+ rep movsb
|
||||||
|
+
|
||||||
|
+.Lend_\@:
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* %eax: prev task
|
||||||
|
* %edx: next task
|
||||||
|
@@ -454,6 +530,7 @@ ENTRY(xen_sysenter_target)
|
||||||
|
*/
|
||||||
|
ENTRY(entry_SYSENTER_32)
|
||||||
|
movl TSS_entry_stack(%esp), %esp
|
||||||
|
+
|
||||||
|
.Lsysenter_past_esp:
|
||||||
|
pushl $__USER_DS /* pt_regs->ss */
|
||||||
|
pushl %ebp /* pt_regs->sp (stashed in bp) */
|
||||||
|
@@ -462,7 +539,7 @@ ENTRY(entry_SYSENTER_32)
|
||||||
|
pushl $__USER_CS /* pt_regs->cs */
|
||||||
|
pushl $0 /* pt_regs->ip = 0 (placeholder) */
|
||||||
|
pushl %eax /* pt_regs->orig_ax */
|
||||||
|
- SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
|
||||||
|
+ SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest, stack already switched */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SYSENTER doesn't filter flags, so we need to clear NT, AC
|
||||||
|
@@ -573,7 +650,8 @@ ENDPROC(entry_SYSENTER_32)
|
||||||
|
ENTRY(entry_INT80_32)
|
||||||
|
ASM_CLAC
|
||||||
|
pushl %eax /* pt_regs->orig_ax */
|
||||||
|
- SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
|
||||||
|
+
|
||||||
|
+ SAVE_ALL pt_regs_ax=$-ENOSYS switch_stacks=1 /* save rest */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User mode is traced as though IRQs are on, and the interrupt gate
|
||||||
|
@@ -665,7 +743,8 @@ END(irq_entries_start)
|
||||||
|
common_interrupt:
|
||||||
|
ASM_CLAC
|
||||||
|
addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */
|
||||||
|
- SAVE_ALL
|
||||||
|
+
|
||||||
|
+ SAVE_ALL switch_stacks=1
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
movl %esp, %eax
|
||||||
|
@@ -673,16 +752,16 @@ common_interrupt:
|
||||||
|
jmp ret_from_intr
|
||||||
|
ENDPROC(common_interrupt)
|
||||||
|
|
||||||
|
-#define BUILD_INTERRUPT3(name, nr, fn) \
|
||||||
|
-ENTRY(name) \
|
||||||
|
- ASM_CLAC; \
|
||||||
|
- pushl $~(nr); \
|
||||||
|
- SAVE_ALL; \
|
||||||
|
- ENCODE_FRAME_POINTER; \
|
||||||
|
- TRACE_IRQS_OFF \
|
||||||
|
- movl %esp, %eax; \
|
||||||
|
- call fn; \
|
||||||
|
- jmp ret_from_intr; \
|
||||||
|
+#define BUILD_INTERRUPT3(name, nr, fn) \
|
||||||
|
+ENTRY(name) \
|
||||||
|
+ ASM_CLAC; \
|
||||||
|
+ pushl $~(nr); \
|
||||||
|
+ SAVE_ALL switch_stacks=1; \
|
||||||
|
+ ENCODE_FRAME_POINTER; \
|
||||||
|
+ TRACE_IRQS_OFF \
|
||||||
|
+ movl %esp, %eax; \
|
||||||
|
+ call fn; \
|
||||||
|
+ jmp ret_from_intr; \
|
||||||
|
ENDPROC(name)
|
||||||
|
|
||||||
|
#define BUILD_INTERRUPT(name, nr) \
|
||||||
|
@@ -908,16 +987,20 @@ common_exception:
|
||||||
|
pushl %es
|
||||||
|
pushl %ds
|
||||||
|
pushl %eax
|
||||||
|
+ movl $(__USER_DS), %eax
|
||||||
|
+ movl %eax, %ds
|
||||||
|
+ movl %eax, %es
|
||||||
|
+ movl $(__KERNEL_PERCPU), %eax
|
||||||
|
+ movl %eax, %fs
|
||||||
|
pushl %ebp
|
||||||
|
pushl %edi
|
||||||
|
pushl %esi
|
||||||
|
pushl %edx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %ebx
|
||||||
|
+ SWITCH_TO_KERNEL_STACK
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
cld
|
||||||
|
- movl $(__KERNEL_PERCPU), %ecx
|
||||||
|
- movl %ecx, %fs
|
||||||
|
UNWIND_ESPFIX_STACK
|
||||||
|
GS_TO_REG %ecx
|
||||||
|
movl PT_GS(%esp), %edi # get the function address
|
||||||
|
@@ -925,9 +1008,6 @@ common_exception:
|
||||||
|
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
|
||||||
|
REG_TO_PTGS %ecx
|
||||||
|
SET_KERNEL_GS %ecx
|
||||||
|
- movl $(__USER_DS), %ecx
|
||||||
|
- movl %ecx, %ds
|
||||||
|
- movl %ecx, %es
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
movl %esp, %eax # pt_regs pointer
|
||||||
|
CALL_NOSPEC %edi
|
||||||
|
@@ -946,6 +1026,7 @@ ENTRY(debug)
|
||||||
|
*/
|
||||||
|
ASM_CLAC
|
||||||
|
pushl $-1 # mark this as an int
|
||||||
|
+
|
||||||
|
SAVE_ALL
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
xorl %edx, %edx # error code 0
|
||||||
|
@@ -981,6 +1062,7 @@ END(debug)
|
||||||
|
*/
|
||||||
|
ENTRY(nmi)
|
||||||
|
ASM_CLAC
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
pushl %eax
|
||||||
|
movl %ss, %eax
|
||||||
|
@@ -1048,7 +1130,8 @@ END(nmi)
|
||||||
|
ENTRY(int3)
|
||||||
|
ASM_CLAC
|
||||||
|
pushl $-1 # mark this as an int
|
||||||
|
- SAVE_ALL
|
||||||
|
+
|
||||||
|
+ SAVE_ALL switch_stacks=1
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
xorl %edx, %edx # zero error code
|
||||||
|
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
|
||||||
|
index eb5f7999a893..20e5f7ab8260 100644
|
||||||
|
--- a/arch/x86/include/asm/switch_to.h
|
||||||
|
+++ b/arch/x86/include/asm/switch_to.h
|
||||||
|
@@ -89,13 +89,9 @@ static inline void refresh_sysenter_cs(struct thread_struct *thread)
|
||||||
|
/* This is used when switching tasks or entering/exiting vm86 mode. */
|
||||||
|
static inline void update_sp0(struct task_struct *task)
|
||||||
|
{
|
||||||
|
- /* On x86_64, sp0 always points to the entry trampoline stack, which is constant: */
|
||||||
|
-#ifdef CONFIG_X86_32
|
||||||
|
- load_sp0(task->thread.sp0);
|
||||||
|
-#else
|
||||||
|
+ /* sp0 always points to the entry trampoline stack, which is constant: */
|
||||||
|
if (static_cpu_has(X86_FEATURE_XENPV))
|
||||||
|
load_sp0(task_top_of_stack(task));
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_SWITCH_TO_H */
|
||||||
|
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
|
||||||
|
index 232152ccb301..86f06e808d02 100644
|
||||||
|
--- a/arch/x86/kernel/asm-offsets.c
|
||||||
|
+++ b/arch/x86/kernel/asm-offsets.c
|
||||||
|
@@ -103,6 +103,7 @@ void common(void) {
|
||||||
|
OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline);
|
||||||
|
OFFSET(CPU_ENTRY_AREA_entry_stack, cpu_entry_area, entry_stack_page);
|
||||||
|
DEFINE(SIZEOF_entry_stack, sizeof(struct entry_stack));
|
||||||
|
+ DEFINE(MASK_entry_stack, (~(sizeof(struct entry_stack) - 1)));
|
||||||
|
|
||||||
|
/* Offset for sp0 and sp1 into the tss_struct */
|
||||||
|
OFFSET(TSS_sp0, tss_struct, x86_tss.sp0);
|
||||||
|
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
||||||
|
index d63f4b5706e4..a0ed3481f2eb 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/common.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/common.c
|
||||||
|
@@ -1709,11 +1709,12 @@ void cpu_init(void)
|
||||||
|
enter_lazy_tlb(&init_mm, curr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Initialize the TSS. Don't bother initializing sp0, as the initial
|
||||||
|
- * task never enters user mode.
|
||||||
|
+ * Initialize the TSS. sp0 points to the entry trampoline stack
|
||||||
|
+ * regardless of what task is running.
|
||||||
|
*/
|
||||||
|
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
|
||||||
|
load_TR_desc();
|
||||||
|
+ load_sp0((unsigned long)(cpu_entry_stack(cpu) + 1));
|
||||||
|
|
||||||
|
load_mm_ldt(&init_mm);
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
|
||||||
|
index cb368c2a22ab..7fab4fa7655d 100644
|
||||||
|
--- a/arch/x86/kernel/process.c
|
||||||
|
+++ b/arch/x86/kernel/process.c
|
||||||
|
@@ -57,14 +57,12 @@ __visible DEFINE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw) = {
|
||||||
|
*/
|
||||||
|
.sp0 = (1UL << (BITS_PER_LONG-1)) + 1,
|
||||||
|
|
||||||
|
-#ifdef CONFIG_X86_64
|
||||||
|
/*
|
||||||
|
* .sp1 is cpu_current_top_of_stack. The init task never
|
||||||
|
* runs user code, but cpu_current_top_of_stack should still
|
||||||
|
* be well defined before the first context switch.
|
||||||
|
*/
|
||||||
|
.sp1 = TOP_OF_INIT_STACK,
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
.ss0 = __KERNEL_DS,
|
||||||
|
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
|
||||||
|
index 097d36a64889..3f3a8c620c63 100644
|
||||||
|
--- a/arch/x86/kernel/process_32.c
|
||||||
|
+++ b/arch/x86/kernel/process_32.c
|
||||||
|
@@ -289,10 +289,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||||
|
*/
|
||||||
|
update_sp0(next_p);
|
||||||
|
refresh_sysenter_cs(next);
|
||||||
|
- this_cpu_write(cpu_current_top_of_stack,
|
||||||
|
- (unsigned long)task_stack_page(next_p) +
|
||||||
|
- THREAD_SIZE);
|
||||||
|
- /* SYSENTER reads the task-stack from tss.sp1 */
|
||||||
|
+ this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p));
|
||||||
|
+ /*
|
||||||
|
+ * TODO: Find a way to let cpu_current_top_of_stack point to
|
||||||
|
+ * cpu_tss_rw.x86_tss.sp1. Doing so now results in stack corruption with
|
||||||
|
+ * iret exceptions.
|
||||||
|
+ */
|
||||||
|
this_cpu_write(cpu_tss_rw.x86_tss.sp1, next_p->thread.sp0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
From 4a06e416cfe4d173f8ed65799e112f77ecb12be8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Tue, 16 Jan 2018 11:28:30 +0100
|
||||||
|
Subject: [PATCH 09/31] x86/entry/32: Leave the kernel via trampoline stack
|
||||||
|
|
||||||
|
Switch back to the trampoline stack before returning to
|
||||||
|
userspace.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 55 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 55 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index e714b53b1eaa..ba3d8c2886ed 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -338,6 +338,59 @@
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Switch back from the kernel stack to the entry stack.
|
||||||
|
+ *
|
||||||
|
+ * The %esp register must point to pt_regs on the task stack. It will
|
||||||
|
+ * first calculate the size of the stack-frame to copy, depending on
|
||||||
|
+ * whether we return to VM86 mode or not. With that it uses 'rep movsb'
|
||||||
|
+ * to copy the contents of the stack over to the entry stack.
|
||||||
|
+ *
|
||||||
|
+ * We must be very careful here, as we can't trust the contents of the
|
||||||
|
+ * task-stack once we switched to the entry-stack. When an NMI happens
|
||||||
|
+ * while on the entry-stack, the NMI handler will switch back to the top
|
||||||
|
+ * of the task stack, overwriting our stack-frame we are about to copy.
|
||||||
|
+ * Therefore we switch the stack only after everything is copied over.
|
||||||
|
+ */
|
||||||
|
+.macro SWITCH_TO_ENTRY_STACK
|
||||||
|
+
|
||||||
|
+ ALTERNATIVE "", "jmp .Lend_\@", X86_FEATURE_XENPV
|
||||||
|
+
|
||||||
|
+ /* Bytes to copy */
|
||||||
|
+ movl $PTREGS_SIZE, %ecx
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_VM86
|
||||||
|
+ testl $(X86_EFLAGS_VM), PT_EFLAGS(%esp)
|
||||||
|
+ jz .Lcopy_pt_regs_\@
|
||||||
|
+
|
||||||
|
+ /* Additional 4 registers to copy when returning to VM86 mode */
|
||||||
|
+ addl $(4 * 4), %ecx
|
||||||
|
+
|
||||||
|
+.Lcopy_pt_regs_\@:
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Initialize source and destination for movsb */
|
||||||
|
+ movl PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %edi
|
||||||
|
+ subl %ecx, %edi
|
||||||
|
+ movl %esp, %esi
|
||||||
|
+
|
||||||
|
+ /* Save future stack pointer in %ebx */
|
||||||
|
+ movl %edi, %ebx
|
||||||
|
+
|
||||||
|
+ /* Copy over the stack-frame */
|
||||||
|
+ cld
|
||||||
|
+ rep movsb
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Switch to entry-stack - needs to happen after everything is
|
||||||
|
+ * copied because the NMI handler will overwrite the task-stack
|
||||||
|
+ * when on entry-stack
|
||||||
|
+ */
|
||||||
|
+ movl %ebx, %esp
|
||||||
|
+
|
||||||
|
+.Lend_\@:
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* %eax: prev task
|
||||||
|
* %edx: next task
|
||||||
|
*/
|
||||||
|
@@ -578,6 +631,7 @@ ENTRY(entry_SYSENTER_32)
|
||||||
|
|
||||||
|
/* Opportunistic SYSEXIT */
|
||||||
|
TRACE_IRQS_ON /* User mode traces as IRQs on. */
|
||||||
|
+ SWITCH_TO_ENTRY_STACK /* Switch to per-cpu entry stack */
|
||||||
|
movl PT_EIP(%esp), %edx /* pt_regs->ip */
|
||||||
|
movl PT_OLDESP(%esp), %ecx /* pt_regs->sp */
|
||||||
|
1: mov PT_FS(%esp), %fs
|
||||||
|
@@ -665,6 +719,7 @@ ENTRY(entry_INT80_32)
|
||||||
|
|
||||||
|
restore_all:
|
||||||
|
TRACE_IRQS_IRET
|
||||||
|
+ SWITCH_TO_ENTRY_STACK
|
||||||
|
.Lrestore_all_notrace:
|
||||||
|
CHECK_AND_APPLY_ESPFIX
|
||||||
|
.Lrestore_nocheck:
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
From 26b38ec7dd2591f092eb359a5a59752d799ab60d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 16:35:42 +0100
|
||||||
|
Subject: [PATCH 10/31] x86/entry/32: Introduce SAVE_ALL_NMI and
|
||||||
|
RESTORE_ALL_NMI
|
||||||
|
|
||||||
|
These macros will be used in the NMI handler code and
|
||||||
|
replace plain SAVE_ALL and RESTORE_REGS there. We will add
|
||||||
|
the NMI-specific CR3-switch to these macros later.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 23 +++++++++++++++++++----
|
||||||
|
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index ba3d8c2886ed..be1d814bd056 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -167,6 +167,9 @@
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+.macro SAVE_ALL_NMI
|
||||||
|
+ SAVE_ALL
|
||||||
|
+.endm
|
||||||
|
/*
|
||||||
|
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
|
||||||
|
* frame pointer is replaced with an encoded pointer to pt_regs. The encoding
|
||||||
|
@@ -224,6 +227,18 @@
|
||||||
|
RESTORE_SKIP_SEGMENTS \pop
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+.macro RESTORE_ALL_NMI pop=0
|
||||||
|
+ /*
|
||||||
|
+ * Restore segments - might cause exceptions when loading
|
||||||
|
+ * user-space segments
|
||||||
|
+ */
|
||||||
|
+ RESTORE_SEGMENTS
|
||||||
|
+
|
||||||
|
+ /* Restore integer registers and unwind stack to iret frame */
|
||||||
|
+ RESTORE_INT_REGS
|
||||||
|
+ RESTORE_SKIP_SEGMENTS \pop
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
.macro CHECK_AND_APPLY_ESPFIX
|
||||||
|
#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
|
||||||
|
@@ -1127,7 +1142,7 @@ ENTRY(nmi)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pushl %eax # pt_regs->orig_ax
|
||||||
|
- SAVE_ALL
|
||||||
|
+ SAVE_ALL_NMI
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
xorl %edx, %edx # zero error code
|
||||||
|
movl %esp, %eax # pt_regs pointer
|
||||||
|
@@ -1155,7 +1170,7 @@ ENTRY(nmi)
|
||||||
|
|
||||||
|
.Lnmi_return:
|
||||||
|
CHECK_AND_APPLY_ESPFIX
|
||||||
|
- RESTORE_REGS 4
|
||||||
|
+ RESTORE_ALL_NMI pop=4
|
||||||
|
jmp .Lirq_return
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
@@ -1171,12 +1186,12 @@ ENTRY(nmi)
|
||||||
|
pushl 16(%esp)
|
||||||
|
.endr
|
||||||
|
pushl %eax
|
||||||
|
- SAVE_ALL
|
||||||
|
+ SAVE_ALL_NMI
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
FIXUP_ESPFIX_STACK # %eax == %esp
|
||||||
|
xorl %edx, %edx # zero error code
|
||||||
|
call do_nmi
|
||||||
|
- RESTORE_REGS
|
||||||
|
+ RESTORE_ALL_NMI
|
||||||
|
lss 12+4(%esp), %esp # back to espfix stack
|
||||||
|
jmp .Lirq_return
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
From d7f5719fe456d24dd01fdcc281aac44dacfa57b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 16:58:57 +0100
|
||||||
|
Subject: [PATCH 11/31] x86/entry/32: Add PTI cr3 switches to NMI handler code
|
||||||
|
|
||||||
|
The NMI handler is special, as it needs to leave with the
|
||||||
|
same cr3 as it was entered with. We need to do this because
|
||||||
|
we could enter the NMI handler from kernel code with
|
||||||
|
user-cr3 already loaded.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 52 +++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 46 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index be1d814bd056..9693485c901a 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -77,6 +77,8 @@
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+#define PTI_SWITCH_MASK (1 << PAGE_SHIFT)
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* User gs save/restore
|
||||||
|
*
|
||||||
|
@@ -167,8 +169,30 @@
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
-.macro SAVE_ALL_NMI
|
||||||
|
+.macro SAVE_ALL_NMI cr3_reg:req
|
||||||
|
SAVE_ALL
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Now switch the CR3 when PTI is enabled.
|
||||||
|
+ *
|
||||||
|
+ * We can enter with either user or kernel cr3, the code will
|
||||||
|
+ * store the old cr3 in \cr3_reg and switches to the kernel cr3
|
||||||
|
+ * if necessary.
|
||||||
|
+ */
|
||||||
|
+ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
|
||||||
|
+
|
||||||
|
+ movl %cr3, \cr3_reg
|
||||||
|
+ testl $PTI_SWITCH_MASK, \cr3_reg
|
||||||
|
+ jz .Lend_\@ /* Already on kernel cr3 */
|
||||||
|
+
|
||||||
|
+ /* On user cr3 - write new kernel cr3 */
|
||||||
|
+ andl $(~PTI_SWITCH_MASK), \cr3_reg
|
||||||
|
+ movl \cr3_reg, %cr3
|
||||||
|
+
|
||||||
|
+ /* Restore user cr3 value */
|
||||||
|
+ orl $PTI_SWITCH_MASK, \cr3_reg
|
||||||
|
+
|
||||||
|
+.Lend_\@:
|
||||||
|
.endm
|
||||||
|
/*
|
||||||
|
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
|
||||||
|
@@ -227,13 +251,29 @@
|
||||||
|
RESTORE_SKIP_SEGMENTS \pop
|
||||||
|
.endm
|
||||||
|
|
||||||
|
-.macro RESTORE_ALL_NMI pop=0
|
||||||
|
+.macro RESTORE_ALL_NMI cr3_reg:req pop=0
|
||||||
|
/*
|
||||||
|
* Restore segments - might cause exceptions when loading
|
||||||
|
* user-space segments
|
||||||
|
*/
|
||||||
|
RESTORE_SEGMENTS
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Now switch the CR3 when PTI is enabled.
|
||||||
|
+ *
|
||||||
|
+ * We enter with kernel cr3 and switch the cr3 to the value
|
||||||
|
+ * stored on \cr3_reg, which is either a user or a kernel cr3.
|
||||||
|
+ */
|
||||||
|
+ ALTERNATIVE "jmp .Lswitched_\@", "", X86_FEATURE_PTI
|
||||||
|
+
|
||||||
|
+ testl $PTI_SWITCH_MASK, \cr3_reg
|
||||||
|
+ jz .Lswitched_\@
|
||||||
|
+
|
||||||
|
+ /* User cr3 in \cr3_reg - write it to hardware cr3 */
|
||||||
|
+ movl \cr3_reg, %cr3
|
||||||
|
+
|
||||||
|
+.Lswitched_\@:
|
||||||
|
+
|
||||||
|
/* Restore integer registers and unwind stack to iret frame */
|
||||||
|
RESTORE_INT_REGS
|
||||||
|
RESTORE_SKIP_SEGMENTS \pop
|
||||||
|
@@ -1142,7 +1182,7 @@ ENTRY(nmi)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pushl %eax # pt_regs->orig_ax
|
||||||
|
- SAVE_ALL_NMI
|
||||||
|
+ SAVE_ALL_NMI cr3_reg=%edi
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
xorl %edx, %edx # zero error code
|
||||||
|
movl %esp, %eax # pt_regs pointer
|
||||||
|
@@ -1170,7 +1210,7 @@ ENTRY(nmi)
|
||||||
|
|
||||||
|
.Lnmi_return:
|
||||||
|
CHECK_AND_APPLY_ESPFIX
|
||||||
|
- RESTORE_ALL_NMI pop=4
|
||||||
|
+ RESTORE_ALL_NMI cr3_reg=%edi pop=4
|
||||||
|
jmp .Lirq_return
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_ESPFIX32
|
||||||
|
@@ -1186,12 +1226,12 @@ ENTRY(nmi)
|
||||||
|
pushl 16(%esp)
|
||||||
|
.endr
|
||||||
|
pushl %eax
|
||||||
|
- SAVE_ALL_NMI
|
||||||
|
+ SAVE_ALL_NMI cr3_reg=%edi
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
FIXUP_ESPFIX_STACK # %eax == %esp
|
||||||
|
xorl %edx, %edx # zero error code
|
||||||
|
call do_nmi
|
||||||
|
- RESTORE_ALL_NMI
|
||||||
|
+ RESTORE_ALL_NMI cr3_reg=%edi
|
||||||
|
lss 12+4(%esp), %esp # back to espfix stack
|
||||||
|
jmp .Lirq_return
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
From 883518e6e2b618c2ee49ac822057712090784eda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 17:22:10 +0100
|
||||||
|
Subject: [PATCH 12/31] x86/entry/32: Add PTI cr3 switch to non-NMI entry/exit
|
||||||
|
points
|
||||||
|
|
||||||
|
Add unconditional cr3 switches between user and kernel cr3
|
||||||
|
to all non-NMI entry and exit points.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 59 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 58 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index 9693485c901a..b5ef00302316 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -328,6 +328,25 @@
|
||||||
|
#endif /* CONFIG_X86_ESPFIX32 */
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+/* Unconditionally switch to user cr3 */
|
||||||
|
+.macro SWITCH_TO_USER_CR3 scratch_reg:req
|
||||||
|
+ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
|
||||||
|
+
|
||||||
|
+ movl %cr3, \scratch_reg
|
||||||
|
+ orl $PTI_SWITCH_MASK, \scratch_reg
|
||||||
|
+ movl \scratch_reg, %cr3
|
||||||
|
+.Lend_\@:
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
+/* Unconditionally switch to kernel cr3 */
|
||||||
|
+.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
|
||||||
|
+ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
|
||||||
|
+ movl %cr3, \scratch_reg
|
||||||
|
+ andl $(~PTI_SWITCH_MASK), \scratch_reg
|
||||||
|
+ movl \scratch_reg, %cr3
|
||||||
|
+.Lend_\@:
|
||||||
|
+.endm
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called with pt_regs fully populated and kernel segments loaded,
|
||||||
|
@@ -343,6 +362,8 @@
|
||||||
|
|
||||||
|
ALTERNATIVE "", "jmp .Lend_\@", X86_FEATURE_XENPV
|
||||||
|
|
||||||
|
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%eax
|
||||||
|
+
|
||||||
|
/* Are we on the entry stack? Bail out if not! */
|
||||||
|
movl PER_CPU_VAR(cpu_entry_area), %edi
|
||||||
|
addl $CPU_ENTRY_AREA_entry_stack, %edi
|
||||||
|
@@ -637,6 +658,18 @@ ENTRY(xen_sysenter_target)
|
||||||
|
* 0(%ebp) arg6
|
||||||
|
*/
|
||||||
|
ENTRY(entry_SYSENTER_32)
|
||||||
|
+ /*
|
||||||
|
+ * On entry-stack with all userspace-regs live - save and
|
||||||
|
+ * restore eflags and %eax to use it as scratch-reg for the cr3
|
||||||
|
+ * switch.
|
||||||
|
+ */
|
||||||
|
+ pushfl
|
||||||
|
+ pushl %eax
|
||||||
|
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%eax
|
||||||
|
+ popl %eax
|
||||||
|
+ popfl
|
||||||
|
+
|
||||||
|
+ /* Stack empty again, switch to task stack */
|
||||||
|
movl TSS_entry_stack(%esp), %esp
|
||||||
|
|
||||||
|
.Lsysenter_past_esp:
|
||||||
|
@@ -691,6 +724,10 @@ ENTRY(entry_SYSENTER_32)
|
||||||
|
movl PT_OLDESP(%esp), %ecx /* pt_regs->sp */
|
||||||
|
1: mov PT_FS(%esp), %fs
|
||||||
|
PTGS_TO_GS
|
||||||
|
+
|
||||||
|
+ /* Segments are restored - switch to user cr3 */
|
||||||
|
+ SWITCH_TO_USER_CR3 scratch_reg=%eax
|
||||||
|
+
|
||||||
|
popl %ebx /* pt_regs->bx */
|
||||||
|
addl $2*4, %esp /* skip pt_regs->cx and pt_regs->dx */
|
||||||
|
popl %esi /* pt_regs->si */
|
||||||
|
@@ -778,7 +815,23 @@ restore_all:
|
||||||
|
.Lrestore_all_notrace:
|
||||||
|
CHECK_AND_APPLY_ESPFIX
|
||||||
|
.Lrestore_nocheck:
|
||||||
|
- RESTORE_REGS 4 # skip orig_eax/error_code
|
||||||
|
+ /*
|
||||||
|
+ * First restore user segments. This can cause exceptions, so we
|
||||||
|
+ * run it with kernel cr3.
|
||||||
|
+ */
|
||||||
|
+ RESTORE_SEGMENTS
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Segments are restored - no more exceptions from here on except on
|
||||||
|
+ * iret, but that handled safely.
|
||||||
|
+ */
|
||||||
|
+ SWITCH_TO_USER_CR3 scratch_reg=%eax
|
||||||
|
+
|
||||||
|
+ /* Restore rest */
|
||||||
|
+ RESTORE_INT_REGS
|
||||||
|
+
|
||||||
|
+ /* Unwind stack to the iret frame */
|
||||||
|
+ RESTORE_SKIP_SEGMENTS 4 # skip orig_eax/error_code
|
||||||
|
.Lirq_return:
|
||||||
|
INTERRUPT_RETURN
|
||||||
|
|
||||||
|
@@ -1139,6 +1192,10 @@ ENTRY(debug)
|
||||||
|
|
||||||
|
SAVE_ALL
|
||||||
|
ENCODE_FRAME_POINTER
|
||||||
|
+
|
||||||
|
+ /* Make sure we are running on kernel cr3 */
|
||||||
|
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%eax
|
||||||
|
+
|
||||||
|
xorl %edx, %edx # error code 0
|
||||||
|
movl %esp, %eax # pt_regs pointer
|
||||||
|
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+197
@@ -0,0 +1,197 @@
|
|||||||
|
From a98c3fa3166e37c6f66f5b7e221b9c0cf1455806 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Wed, 31 Jan 2018 20:48:02 +0100
|
||||||
|
Subject: [PATCH 13/31] x86/entry/32: Handle Entry from Kernel-Mode on
|
||||||
|
Entry-Stack
|
||||||
|
|
||||||
|
It can happen that we enter the kernel from kernel-mode and
|
||||||
|
on the entry-stack. The most common way this happens is when
|
||||||
|
we get an exception while loading the user-space segment
|
||||||
|
registers on the kernel-to-userspace exit path.
|
||||||
|
|
||||||
|
The segment loading needs to be done after the entry-stack
|
||||||
|
switch, because the stack-switch needs kernel %fs for
|
||||||
|
per_cpu access.
|
||||||
|
|
||||||
|
When this happens, we need to make sure that we leave the
|
||||||
|
kernel with the entry-stack again, so that the interrupted
|
||||||
|
code-path runs on the right stack when switching to the
|
||||||
|
user-cr3.
|
||||||
|
|
||||||
|
We do this by detecting this condition on kernel-entry by
|
||||||
|
checking CS.RPL and %esp, and if it happens, we copy over
|
||||||
|
the complete content of the entry stack to the task-stack.
|
||||||
|
This needs to be done because once we enter the exception
|
||||||
|
handlers we might be scheduled out or even migrated to a
|
||||||
|
different CPU, so that we can't rely on the entry-stack
|
||||||
|
contents. We also leave a marker in the stack-frame to
|
||||||
|
detect this condition on the exit path.
|
||||||
|
|
||||||
|
On the exit path the copy is reversed, we copy all of the
|
||||||
|
remaining task-stack back to the entry-stack and switch
|
||||||
|
to it.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/entry/entry_32.S | 109 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 108 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
|
||||||
|
index b5ef00302316..d94dab68b526 100644
|
||||||
|
--- a/arch/x86/entry/entry_32.S
|
||||||
|
+++ b/arch/x86/entry/entry_32.S
|
||||||
|
@@ -358,6 +358,9 @@
|
||||||
|
* copied there. So allocate the stack-frame on the task-stack and
|
||||||
|
* switch to it before we do any copying.
|
||||||
|
*/
|
||||||
|
+
|
||||||
|
+#define CS_FROM_ENTRY_STACK (1 << 31)
|
||||||
|
+
|
||||||
|
.macro SWITCH_TO_KERNEL_STACK
|
||||||
|
|
||||||
|
ALTERNATIVE "", "jmp .Lend_\@", X86_FEATURE_XENPV
|
||||||
|
@@ -381,6 +384,10 @@
|
||||||
|
/* Load top of task-stack into %edi */
|
||||||
|
movl TSS_entry_stack(%edi), %edi
|
||||||
|
|
||||||
|
+ /* Special case - entry from kernel mode via entry stack */
|
||||||
|
+ testl $SEGMENT_RPL_MASK, PT_CS(%esp)
|
||||||
|
+ jz .Lentry_from_kernel_\@
|
||||||
|
+
|
||||||
|
/* Bytes to copy */
|
||||||
|
movl $PTREGS_SIZE, %ecx
|
||||||
|
|
||||||
|
@@ -394,8 +401,8 @@
|
||||||
|
*/
|
||||||
|
addl $(4 * 4), %ecx
|
||||||
|
|
||||||
|
-.Lcopy_pt_regs_\@:
|
||||||
|
#endif
|
||||||
|
+.Lcopy_pt_regs_\@:
|
||||||
|
|
||||||
|
/* Allocate frame on task-stack */
|
||||||
|
subl %ecx, %edi
|
||||||
|
@@ -410,6 +417,56 @@
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
+ jmp .Lend_\@
|
||||||
|
+
|
||||||
|
+.Lentry_from_kernel_\@:
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * This handles the case when we enter the kernel from
|
||||||
|
+ * kernel-mode and %esp points to the entry-stack. When this
|
||||||
|
+ * happens we need to switch to the task-stack to run C code,
|
||||||
|
+ * but switch back to the entry-stack again when we approach
|
||||||
|
+ * iret and return to the interrupted code-path. This usually
|
||||||
|
+ * happens when we hit an exception while restoring user-space
|
||||||
|
+ * segment registers on the way back to user-space.
|
||||||
|
+ *
|
||||||
|
+ * When we switch to the task-stack here, we can't trust the
|
||||||
|
+ * contents of the entry-stack anymore, as the exception handler
|
||||||
|
+ * might be scheduled out or moved to another CPU. Therefore we
|
||||||
|
+ * copy the complete entry-stack to the task-stack and set a
|
||||||
|
+ * marker in the iret-frame (bit 31 of the CS dword) to detect
|
||||||
|
+ * what we've done on the iret path.
|
||||||
|
+ *
|
||||||
|
+ * On the iret path we copy everything back and switch to the
|
||||||
|
+ * entry-stack, so that the interrupted kernel code-path
|
||||||
|
+ * continues on the same stack it was interrupted with.
|
||||||
|
+ *
|
||||||
|
+ * Be aware that an NMI can happen anytime in this code.
|
||||||
|
+ *
|
||||||
|
+ * %esi: Entry-Stack pointer (same as %esp)
|
||||||
|
+ * %edi: Top of the task stack
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ /* Calculate number of bytes on the entry stack in %ecx */
|
||||||
|
+ movl %esi, %ecx
|
||||||
|
+
|
||||||
|
+ /* %ecx to the top of entry-stack */
|
||||||
|
+ andl $(MASK_entry_stack), %ecx
|
||||||
|
+ addl $(SIZEOF_entry_stack), %ecx
|
||||||
|
+
|
||||||
|
+ /* Number of bytes on the entry stack to %ecx */
|
||||||
|
+ sub %esi, %ecx
|
||||||
|
+
|
||||||
|
+ /* Mark stackframe as coming from entry stack */
|
||||||
|
+ orl $CS_FROM_ENTRY_STACK, PT_CS(%esp)
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * %esi and %edi are unchanged, %ecx contains the number of
|
||||||
|
+ * bytes to copy. The code at .Lcopy_pt_regs_\@ will allocate
|
||||||
|
+ * the stack-frame on task-stack and copy everything over
|
||||||
|
+ */
|
||||||
|
+ jmp .Lcopy_pt_regs_\@
|
||||||
|
+
|
||||||
|
.Lend_\@:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
@@ -467,6 +524,55 @@
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * This macro handles the case when we return to kernel-mode on the iret
|
||||||
|
+ * path and have to switch back to the entry stack.
|
||||||
|
+ *
|
||||||
|
+ * See the comments below the .Lentry_from_kernel_\@ label in the
|
||||||
|
+ * SWITCH_TO_KERNEL_STACK macro for more details.
|
||||||
|
+ */
|
||||||
|
+.macro PARANOID_EXIT_TO_KERNEL_MODE
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Test if we entered the kernel with the entry-stack. Most
|
||||||
|
+ * likely we did not, because this code only runs on the
|
||||||
|
+ * return-to-kernel path.
|
||||||
|
+ */
|
||||||
|
+ testl $CS_FROM_ENTRY_STACK, PT_CS(%esp)
|
||||||
|
+ jz .Lend_\@
|
||||||
|
+
|
||||||
|
+ /* Unlikely slow-path */
|
||||||
|
+
|
||||||
|
+ /* Clear marker from stack-frame */
|
||||||
|
+ andl $(~CS_FROM_ENTRY_STACK), PT_CS(%esp)
|
||||||
|
+
|
||||||
|
+ /* Copy the remaining task-stack contents to entry-stack */
|
||||||
|
+ movl %esp, %esi
|
||||||
|
+ movl PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %edi
|
||||||
|
+
|
||||||
|
+ /* Bytes on the task-stack to ecx */
|
||||||
|
+ movl PER_CPU_VAR(cpu_current_top_of_stack), %ecx
|
||||||
|
+ subl %esi, %ecx
|
||||||
|
+
|
||||||
|
+ /* Allocate stack-frame on entry-stack */
|
||||||
|
+ subl %ecx, %edi
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Save future stack-pointer, we must not switch until the
|
||||||
|
+ * copy is done, otherwise the NMI handler could destroy the
|
||||||
|
+ * contents of the task-stack we are about to copy.
|
||||||
|
+ */
|
||||||
|
+ movl %edi, %ebx
|
||||||
|
+
|
||||||
|
+ /* Do the copy */
|
||||||
|
+ cld
|
||||||
|
+ rep movsb
|
||||||
|
+
|
||||||
|
+ /* Safe to switch to entry-stack now */
|
||||||
|
+ movl %ebx, %esp
|
||||||
|
+
|
||||||
|
+.Lend_\@:
|
||||||
|
+.endm
|
||||||
|
+/*
|
||||||
|
* %eax: prev task
|
||||||
|
* %edx: next task
|
||||||
|
*/
|
||||||
|
@@ -837,6 +943,7 @@ restore_all:
|
||||||
|
|
||||||
|
restore_all_kernel:
|
||||||
|
TRACE_IRQS_IRET
|
||||||
|
+ PARANOID_EXIT_TO_KERNEL_MODE
|
||||||
|
RESTORE_REGS 4
|
||||||
|
jmp .Lirq_return
|
||||||
|
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
From cc4fcd3fae72f6a72d9f275366b7165fa4ac3f71 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Fri, 2 Feb 2018 10:41:36 +0100
|
||||||
|
Subject: [PATCH 14/31] x86/pgtable/pae: Unshare kernel PMDs when PTI is
|
||||||
|
enabled
|
||||||
|
|
||||||
|
With PTI we need to map the per-process LDT into the kernel
|
||||||
|
address-space for each process, so we need separate kernel
|
||||||
|
PMDs per PGD.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/include/asm/pgtable-3level_types.h | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h
|
||||||
|
index 876b4c77d983..ed8a200ecdaf 100644
|
||||||
|
--- a/arch/x86/include/asm/pgtable-3level_types.h
|
||||||
|
+++ b/arch/x86/include/asm/pgtable-3level_types.h
|
||||||
|
@@ -21,9 +21,10 @@ typedef union {
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PARAVIRT
|
||||||
|
-#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd)
|
||||||
|
+#define SHARED_KERNEL_PMD ((!static_cpu_has(X86_FEATURE_PTI) && \
|
||||||
|
+ (pv_info.shared_kernel_pmd)))
|
||||||
|
#else
|
||||||
|
-#define SHARED_KERNEL_PMD 1
|
||||||
|
+#define SHARED_KERNEL_PMD (!static_cpu_has(X86_FEATURE_PTI))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
From 5ea0338f46add135a70678a6eba2e402310e7b26 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joerg Roedel <jroedel@suse.de>
|
||||||
|
Date: Tue, 16 Jan 2018 13:10:57 +0100
|
||||||
|
Subject: [PATCH 15/31] x86/pgtable/32: Allocate 8k page-tables when PTI is
|
||||||
|
enabled
|
||||||
|
|
||||||
|
Allocate a kernel and a user page-table root when PTI is
|
||||||
|
enabled. Also allocate a full page per root for PAE because
|
||||||
|
otherwise the bit to flip in cr3 to switch between them
|
||||||
|
would be non-constant, which creates a lot of hassle.
|
||||||
|
Keep that for a later optimization.
|
||||||
|
|
||||||
|
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
||||||
|
---
|
||||||
|
arch/x86/kernel/head_32.S | 20 +++++++++++++++-----
|
||||||
|
arch/x86/mm/pgtable.c | 5 +++--
|
||||||
|
2 files changed, 18 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
|
||||||
|
index c29020907886..1f35d600b69f 100644
|
||||||
|
--- a/arch/x86/kernel/head_32.S
|
||||||
|
+++ b/arch/x86/kernel/head_32.S
|
||||||
|
@@ -512,11 +512,18 @@ ENTRY(initial_code)
|
||||||
|
ENTRY(setup_once_ref)
|
||||||
|
.long setup_once
|
||||||
|
|
||||||
|
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||||
|
+#define PGD_ALIGN (2 * PAGE_SIZE)
|
||||||
|
+#define PTI_USER_PGD_FILL 1024
|
||||||
|
+#else
|
||||||
|
+#define PGD_ALIGN (PAGE_SIZE)
|
||||||
|
+#define PTI_USER_PGD_FILL 0
|
||||||
|
+#endif
|
||||||
|
/*
|
||||||
|
* BSS section
|
||||||
|
*/
|
||||||
|
__PAGE_ALIGNED_BSS
|
||||||
|
- .align PAGE_SIZE
|
||||||
|
+ .align PGD_ALIGN
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
|
.globl initial_pg_pmd
|
||||||
|
initial_pg_pmd:
|
||||||
|
@@ -526,14 +533,17 @@ initial_pg_pmd:
|
||||||
|
initial_page_table:
|
||||||
|
.fill 1024,4,0
|
||||||
|
#endif
|
||||||
|
+ .align PGD_ALIGN
|
||||||
|
initial_pg_fixmap:
|
||||||
|
.fill 1024,4,0
|
||||||
|
-.globl empty_zero_page
|
||||||
|
-empty_zero_page:
|
||||||
|
- .fill 4096,1,0
|
||||||
|
.globl swapper_pg_dir
|
||||||
|
+ .align PGD_ALIGN
|
||||||
|
swapper_pg_dir:
|
||||||
|
.fill 1024,4,0
|
||||||
|
+ .fill PTI_USER_PGD_FILL,4,0
|
||||||
|
+.globl empty_zero_page
|
||||||
|
+empty_zero_page:
|
||||||
|
+ .fill 4096,1,0
|
||||||
|
EXPORT_SYMBOL(empty_zero_page)
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -542,7 +552,7 @@ EXPORT_SYMBOL(empty_zero_page)
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
|
__PAGE_ALIGNED_DATA
|
||||||
|
/* Page-aligned for the benefit of paravirt? */
|
||||||
|
- .align PAGE_SIZE
|
||||||
|
+ .align PGD_ALIGN
|
||||||
|
ENTRY(initial_page_table)
|
||||||
|
.long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
|
||||||
|
# if KPMDS == 3
|
||||||
|
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
|
||||||
|
index 004abf9ebf12..a81d42e48922 100644
|
||||||
|
--- a/arch/x86/mm/pgtable.c
|
||||||
|
+++ b/arch/x86/mm/pgtable.c
|
||||||
|
@@ -338,7 +338,8 @@ static inline pgd_t *_pgd_alloc(void)
|
||||||
|
* We allocate one page for pgd.
|
||||||
|
*/
|
||||||
|
if (!SHARED_KERNEL_PMD)
|
||||||
|
- return (pgd_t *)__get_free_page(PGALLOC_GFP);
|
||||||
|
+ return (pgd_t *)__get_free_pages(PGALLOC_GFP,
|
||||||
|
+ PGD_ALLOCATION_ORDER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now PAE kernel is not running as a Xen domain. We can allocate
|
||||||
|
@@ -350,7 +351,7 @@ static inline pgd_t *_pgd_alloc(void)
|
||||||
|
static inline void _pgd_free(pgd_t *pgd)
|
||||||
|
{
|
||||||
|
if (!SHARED_KERNEL_PMD)
|
||||||
|
- free_page((unsigned long)pgd);
|
||||||
|
+ free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER);
|
||||||
|
else
|
||||||
|
kmem_cache_free(pgd_cache, pgd);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.13.6
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user