summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2011-12-20 10:13:16 +0100
committerNatanael Copa <ncopa@alpinelinux.org>2012-01-03 09:54:39 +0000
commitcbd9bedc12f1dc5bd7fc6fba352347d08bef26fd (patch)
treef1af037a77c60b37960464f5da87c588e8427d19
parentde933abf8f03ddac543a8fbc7219ff17c9c667ea (diff)
downloadaports-cbd9bedc12f1dc5bd7fc6fba352347d08bef26fd.tar.bz2
aports-cbd9bedc12f1dc5bd7fc6fba352347d08bef26fd.tar.xz
main/linux-grsec: fix "sleeping while atomic" oops under memory pressure
fixes "sleeping while atomic" kernel oops under memory pressure (cherry picked from commit a83c9124464c304d0d52bdadb7b89f94525cf54e)
-rw-r--r--main/linux-grsec/APKBUILD4
-rw-r--r--main/linux-grsec/net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch85
2 files changed, 88 insertions, 1 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD
index 2044d6e1e..3bb5a31c0 100644
--- a/main/linux-grsec/APKBUILD
+++ b/main/linux-grsec/APKBUILD
@@ -4,7 +4,7 @@ _flavor=grsec
pkgname=linux-${_flavor}
pkgver=3.0.13
_kernver=3.0
-pkgrel=0
+pkgrel=1
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs linux-firmware"
@@ -22,6 +22,7 @@ source="ftp://ftp.kernel.org/pub/linux/kernel/v3.0/linux-$_kernver.tar.bz2
x86-centaur-enable-cx8-for-via-eden-too.patch
linux-3.0.x-regression-with-ipv4-routes-having-mtu.patch
+ net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch
kernelconfig.x86
kernelconfig.x86_64
@@ -149,5 +150,6 @@ ebb99ef6ad8cd2d9fd8f49d5c5849057 0001-ip_gre-dont-increase-dev-needed_headroom-
776adeeb5272093574f8836c5037dd7d 0004-arp-flush-arp-cache-on-device-change.patch
f3eda7112ef074a4121ec6de943c63ee x86-centaur-enable-cx8-for-via-eden-too.patch
62cc7d7b5ba7ef05b72ff91c0411c189 linux-3.0.x-regression-with-ipv4-routes-having-mtu.patch
+b25335e8fcbf8c969230d55ac4e75cf8 net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch
587b1fb2f6a5c9ba714900b856f57f09 kernelconfig.x86
99836ffe918bbdef7da1a56a3d075c7a kernelconfig.x86_64"
diff --git a/main/linux-grsec/net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch b/main/linux-grsec/net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch
new file mode 100644
index 000000000..8eaadf942
--- /dev/null
+++ b/main/linux-grsec/net-flow-remove-sleeping-and-deferral-mechanism-from-flow_cache_flush.patch
@@ -0,0 +1,85 @@
+Based on http://patchwork.ozlabs.org/patch/132353/
+
+diff --git a/net/core/flow.c b/net/core/flow.c
+index 8ae42de..e318c7e 100644
+--- a/net/core/flow.c
++++ b/net/core/flow.c
+@@ -358,6 +358,18 @@ void flow_cache_flush(void)
+ put_online_cpus();
+ }
+
++static void flow_cache_flush_task(struct work_struct *work)
++{
++ flow_cache_flush();
++}
++
++static DECLARE_WORK(flow_cache_flush_work, flow_cache_flush_task);
++
++void flow_cache_flush_deferred(void)
++{
++ schedule_work(&flow_cache_flush_work);
++}
++
+ static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu)
+ {
+ struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu);
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 2118d64..9049a5c 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -2276,8 +2276,6 @@ static void __xfrm_garbage_collect(struct net *net)
+ {
+ struct dst_entry *head, *next;
+
+- flow_cache_flush();
+-
+ spin_lock_bh(&xfrm_policy_sk_bundle_lock);
+ head = xfrm_policy_sk_bundles;
+ xfrm_policy_sk_bundles = NULL;
+@@ -2290,6 +2288,18 @@ static void __xfrm_garbage_collect(struct net *net)
+ }
+ }
+
++static void xfrm_garbage_collect(struct net *net)
++{
++ flow_cache_flush();
++ __xfrm_garbage_collect(net);
++}
++
++static void xfrm_garbage_collect_deferred(struct net *net)
++{
++ flow_cache_flush_deferred();
++ __xfrm_garbage_collect(net);
++}
++
+ static void xfrm_init_pmtu(struct dst_entry *dst)
+ {
+ do {
+@@ -2422,7 +2432,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
+ if (likely(dst_ops->neigh_lookup == NULL))
+ dst_ops->neigh_lookup = xfrm_neigh_lookup;
+ if (likely(afinfo->garbage_collect == NULL))
+- afinfo->garbage_collect = __xfrm_garbage_collect;
++ afinfo->garbage_collect = xfrm_garbage_collect_deferred;
+ xfrm_policy_afinfo[afinfo->family] = afinfo;
+ }
+ write_unlock_bh(&xfrm_policy_afinfo_lock);
+@@ -2516,7 +2526,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
+
+ switch (event) {
+ case NETDEV_DOWN:
+- __xfrm_garbage_collect(dev_net(dev));
++ xfrm_garbage_collect(dev_net(dev));
+ }
+ return NOTIFY_DONE;
+ }
+--- ./include/net/flow.h.orig
++++ ./include/net/flow.h
+@@ -207,6 +207,7 @@
+ u8 dir, flow_resolve_t resolver, void *ctx);
+
+ extern void flow_cache_flush(void);
++extern void flow_cache_flush_deferred(void);
+ extern atomic_unchecked_t flow_cache_genid;
+
+ #endif