diff options
author | Alexandre Oliva <lxoliva@fsfla.org> | 2012-06-28 10:01:14 +0000 |
---|---|---|
committer | Alexandre Oliva <lxoliva@fsfla.org> | 2012-06-28 10:01:14 +0000 |
commit | 364c8ba7dd2629de4fdb77431c204882010ea158 (patch) | |
tree | 18d4b556983abe3e6c6cf5c5f207e3a9c7b10efa /freed-ora/current/f16 | |
parent | a69ee8715bdc91cd2342dcb12882c315f455b693 (diff) | |
download | linux-libre-raptor-364c8ba7dd2629de4fdb77431c204882010ea158.tar.gz linux-libre-raptor-364c8ba7dd2629de4fdb77431c204882010ea158.zip |
3.4.4-3.fc16.gnu
Diffstat (limited to 'freed-ora/current/f16')
5 files changed, 602 insertions, 1 deletions
diff --git a/freed-ora/current/f16/ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch b/freed-ora/current/f16/ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch new file mode 100644 index 000000000..51dc6e211 --- /dev/null +++ b/freed-ora/current/f16/ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch @@ -0,0 +1,44 @@ +commit 931cb03afed7b541392295f3afc4638da32f08a0 +Author: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> +Date: Wed Jun 20 16:29:20 2012 +0530 + + ath9k_htc: configure bssid on ASSOC/IBSS change + + After the change "mac80211: remove spurious BSSID change flag", + BSS_CHANGED_BSSID will not be passed on association or IBSS + status changes. So it could be better to program bssid on ASSOC + or IBSS change notification. Not doing so, is affecting the + packet transmission. + + Cc: stable@vger.kernel.org [3.4+] + Reported-by: Michael Leun <lkml20120218@newton.leun.net> + Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> + Signed-off-by: John W. Linville <linville@tuxdriver.com> + +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +index 2b8f61c..abbd6ef 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, + priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; + + if (priv->ah->opmode == NL80211_IFTYPE_STATION) { ++ ath9k_htc_choose_set_bssid(priv); + if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) + ath9k_htc_start_ani(priv); + else if (priv->num_sta_assoc_vif == 0) +@@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, + } + } + +- if (changed & BSS_CHANGED_BSSID) { ++ if (changed & BSS_CHANGED_IBSS) { + if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { + common->curaid = bss_conf->aid; + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + ath9k_htc_set_bssid(priv); +- } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { +- ath9k_htc_choose_set_bssid(priv); + } + } + diff --git a/freed-ora/current/f16/block-fix-infinite-loop-in-__getblk_slow.patch b/freed-ora/current/f16/block-fix-infinite-loop-in-__getblk_slow.patch new file mode 100644 index 000000000..f075a7133 --- /dev/null +++ b/freed-ora/current/f16/block-fix-infinite-loop-in-__getblk_slow.patch @@ -0,0 +1,153 @@ + +Delivered-To: jwboyer@gmail.com
+Received: by 10.229.191.66 with SMTP id dl2csp36421qcb;
+ Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
+Received: by 10.68.228.136 with SMTP id si8mr53042278pbc.159.1340722548310;
+ Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
+Return-Path: <stable-owner@vger.kernel.org>
+Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67])
+ by mx.google.com with ESMTP id qg1si15735731pbc.300.2012.06.26.07.55.47;
+ Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
+Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67;
+Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mail=stable-owner@vger.kernel.org
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1757370Ab2FZOzp (ORCPT <rfc822;aaditya.kumar.30@gmail.com>
+ + 23 others); Tue, 26 Jun 2012 10:55:45 -0400
+Received: from mx1.redhat.com ([209.132.183.28]:64097 "EHLO mx1.redhat.com"
+ rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
+ id S1757325Ab2FZOzo (ORCPT <rfc822;stable@vger.kernel.org>);
+ Tue, 26 Jun 2012 10:55:44 -0400
+Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])
+ by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5QEtbK2017450
+ (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK);
+ Tue, 26 Jun 2012 10:55:38 -0400
+Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.16.60.26])
+ by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q5QEtZV9023431;
+ Tue, 26 Jun 2012 10:55:35 -0400
+From: Jeff Moyer <jmoyer@redhat.com>
+To: Jens Axboe <jaxboe@fusionio.com>, Nick Piggin <npiggin@kernel.dk>
+Cc: LKML List <linux-kernel@vger.kernel.org>,
+ torsten.hilbrich@secunet.com, Richard Jones <rjones@redhat.com>,
+ stable@vger.kernel.org, Marcos Mello <marcosfrm@gmail.com>
+Subject: [patch] block: fix infinite loop in __getblk_slow
+X-PGP-KeyID: 1F78E1B4
+X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4
+X-PCLoadLetter: What the f**k does that mean?
+Date: Tue, 26 Jun 2012 10:55:34 -0400
+Message-ID: <x49r4t2rul5.fsf@segfault.boston.devel.redhat.com>
+User-Agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.1 (gnu/linux)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11
+Sender: stable-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <stable.vger.kernel.org>
+X-Mailing-List: stable@vger.kernel.org
+
+Hi,
+
+This commit:
+
+commit 080399aaaf3531f5b8761ec0ac30ff98891e8686
+Author: Jeff Moyer <jmoyer@redhat.com>
+Date: Fri May 11 16:34:10 2012 +0200
+
+ block: don't mark buffers beyond end of disk as mapped
+
+exposed a bug in __getblk_slow that causes mount to hang as it loops
+infinitely waiting for a buffer that lies beyond the end of the disk to
+become uptodate. The problem was initially reported by Torsten Hilbrich
+here: https://lkml.org/lkml/2012/6/18/54, and also reported
+independently here:
+http://www.sysresccd.org/forums/viewtopic.php?f=13&t=4511, and then
+Richard W.M. Jones and Marcos Mello noted a few separate bugzillas also
+associated with the same issue.
+
+The main problem is here, in __getblk_slow:
+
+ for (;;) {
+ struct buffer_head * bh;
+ int ret;
+
+ bh = __find_get_block(bdev, block, size);
+ if (bh)
+ return bh;
+
+ ret = grow_buffers(bdev, block, size);
+ if (ret < 0)
+ return NULL;
+ if (ret == 0)
+ free_more_memory();
+ }
+
+__find_get_block does not find the block, since it will not be marked as
+mapped, and so grow_buffers is called to fill in the buffers for the
+associated page. I believe the for (;;) loop is there primarily to
+retry in the case of memory pressure keeping grow_buffers from
+succeeding. However, we also continue to loop for other cases, like the
+block lying beond the end of the disk. So, the fix I came up with is to
+only loop when grow_buffers fails due to memory allocation issues
+(return value of 0).
+
+The attached patch was tested by myself, Torsten, and Rich, and was
+found to resolve the problem in call cases.
+
+Comments, as always, are appreciated.
+
+Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
+Reported-and-Tested-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
+Tested-by: Richard W.M. Jones <rjones@redhat.com>
+Cc: Stable <stable@vger.kernel.org>
+
+--
+Stable Notes: this patch requires backport to 3.0, 3.2 and 3.3.
+
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 838a9cf..c7062c8 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -1036,6 +1036,9 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
+ static struct buffer_head *
+ __getblk_slow(struct block_device *bdev, sector_t block, int size)
+ {
++ int ret;
++ struct buffer_head *bh;
++
+ /* Size must be multiple of hard sectorsize */
+ if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
+ (size < 512 || size > PAGE_SIZE))) {
+@@ -1048,20 +1051,21 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
+ return NULL;
+ }
+
+- for (;;) {
+- struct buffer_head * bh;
+- int ret;
++retry:
++ bh = __find_get_block(bdev, block, size);
++ if (bh)
++ return bh;
+
++ ret = grow_buffers(bdev, block, size);
++ if (ret == 0) {
++ free_more_memory();
++ goto retry;
++ } else if (ret > 0) {
+ bh = __find_get_block(bdev, block, size);
+ if (bh)
+ return bh;
+-
+- ret = grow_buffers(bdev, block, size);
+- if (ret < 0)
+- return NULL;
+- if (ret == 0)
+- free_more_memory();
+ }
++ return NULL;
+ }
+
+ /*
+--
+To unsubscribe from this list: send the line "unsubscribe stable" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/freed-ora/current/f16/kernel.spec b/freed-ora/current/f16/kernel.spec index 93cf7c0c4..fb1232f87 100644 --- a/freed-ora/current/f16/kernel.spec +++ b/freed-ora/current/f16/kernel.spec @@ -54,7 +54,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 1 +%global baserelease 3 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -778,6 +778,7 @@ Patch19000: ips-noirq.patch # Uprobes (rhbz 832083) Patch20000: uprobes-3.4-backport.patch Patch20001: uprobes-3.4-tip.patch +Patch20002: uprobes-task_work_add-generic-process-context-callbacks.patch # Flattened devicetree support Patch21000: arm-omap-dt-compat.patch @@ -828,6 +829,15 @@ Patch22032: cifs-fix-parsing-of-password-mount-option.patch #rhbz 831807 Patch22034: usb-storage-try-read_capacity-10-first.patch +#rhbz 828731 +Patch22035: ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch + +#rhbz 835019 +Patch22036: block-fix-infinite-loop-in-__getblk_slow.patch + +#rhbz 832867 +Patch22040: mm-correctly-synchronize-rss-counters-at-exit-exec.patch + # END OF PATCH DEFINITIONS %endif @@ -1491,6 +1501,7 @@ ApplyPatch ips-noirq.patch # Uprobes (rhbz 832083) ApplyPatch uprobes-3.4-backport.patch ApplyPatch uprobes-3.4-tip.patch +ApplyPatch uprobes-task_work_add-generic-process-context-callbacks.patch #rhbz 754518 #ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch @@ -1528,6 +1539,15 @@ ApplyPatch cifs-fix-parsing-of-password-mount-option.patch #rhbz 831807 ApplyPatch usb-storage-try-read_capacity-10-first.patch +#rhbz 828731 +ApplyPatch ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch + +#rhbz 835019 +ApplyPatch block-fix-infinite-loop-in-__getblk_slow.patch + +#rhbz 832867 +ApplyPatch mm-correctly-synchronize-rss-counters-at-exit-exec.patch + # END OF PATCH APPLICATIONS %endif @@ -2266,6 +2286,16 @@ fi # and build. %changelog +* Tue Jun 26 2012 Dave Jones <davej@redhat.com> 3.4.4-3 +- Add mm-correctly-synchronize-rss-counters-at-exit-exec.patch (rhbz 832867) + +* Tue Jun 26 2012 Josh Boyer <jwboyer@redhat.com> +- Add task_work_add backport from Anton Arapov +- Add patch to fix mount hangs (rhbz 835019) + +* Tue Jun 26 2012 John W. Linville <linville@redhat.com> +- ath9k_htc: configure bssid on ASSOC/IBSS change (rhbz 828731) + * Sat Jun 23 2012 Alexandre Oliva <lxoliva@fsfla.org> -libre - GNU Linux-libre 3.4.4-gnu. Switched to -gnu patch. diff --git a/freed-ora/current/f16/mm-correctly-synchronize-rss-counters-at-exit-exec.patch b/freed-ora/current/f16/mm-correctly-synchronize-rss-counters-at-exit-exec.patch new file mode 100644 index 000000000..0ef36b311 --- /dev/null +++ b/freed-ora/current/f16/mm-correctly-synchronize-rss-counters-at-exit-exec.patch @@ -0,0 +1,125 @@ +From davej Wed Jun 20 11:37:32 2012 +Return-Path: oleg@redhat.com +X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on + gelk.kernelslacker.org +X-Spam-Level: +X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD, + UNPARSEABLE_RELAY autolearn=ham version=3.3.2 +Received: from mail.corp.redhat.com [10.4.128.1] + by gelk.kernelslacker.org with IMAP (fetchmail-6.3.21) + for <davej@localhost> (single-drop); Wed, 20 Jun 2012 11:37:32 -0400 (EDT) +Received: from zmta05.collab.prod.int.phx2.redhat.com (LHLO + zmta05.collab.prod.int.phx2.redhat.com) (10.5.81.12) by + zmail11.collab.prod.int.phx2.redhat.com with LMTP; Wed, 20 Jun 2012 + 11:37:18 -0400 (EDT) +Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) + by zmta05.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 539B1F2080 + for <davej@mail.corp.redhat.com>; Wed, 20 Jun 2012 11:37:18 -0400 (EDT) +Received: from tranklukator.englab.brq.redhat.com (dhcp-1-232.brq.redhat.com [10.34.1.232]) + by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id q5KFbGde008148; + Wed, 20 Jun 2012 11:37:17 -0400 +Received: by tranklukator.englab.brq.redhat.com (nbSMTP-1.00) for uid 500 + oleg@redhat.com; Wed, 20 Jun 2012 17:35:20 +0200 (CEST) +Date: Wed, 20 Jun 2012 17:35:19 +0200 +From: Oleg Nesterov <oleg@redhat.com> +To: Dave Jones <davej@redhat.com> +Cc: Fedora Kernel Team <kernel-team@fedoraproject.org> +Subject: Re: [Bug 832867] BUG: Bad rss-counter state mm:xxxxxxxx idx:1 + val:-2 output in console +Message-ID: <20120620153519.GA17642@redhat.com> +References: <bug-832867-176318@bugzilla.redhat.com> <bug-832867-176318-mTgNUmpuHi@bugzilla.redhat.com> <20120619172633.GG26103@redhat.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +In-Reply-To: <20120619172633.GG26103@redhat.com> +User-Agent: Mutt/1.5.18 (2008-05-17) +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 +Status: RO +Content-Length: 2687 +Lines: 84 + +Hi Dave, + +sorry for delay + +On 06/19, Dave Jones wrote: +> +> > https://bugzilla.redhat.com/show_bug.cgi?id=832867 +> > +> > --- Comment #11 from Bojan Smojver <bojan@rexursive.com> --- +> > Patches for this: +> > +> > http://comments.gmane.org/gmane.linux.kernel/1306252 +> +> Oleg, +> +> are these patches final ? Are they headed for stable ? + +No. And 1/2 was wrong actually, see +http://marc.info/?l=linux-kernel&m=133911852215275 + +Konstantin sent the minimal fix, +mm-correctly-synchronize-rss-counters-at-exit-exec.patch in -mm tree, +attached below. + +Oleg. + +------------------------------------------------------ +From: Konstantin Khlebnikov <khlebnikov@openvz.org> +Subject: mm: correctly synchronize rss-counters at exit/exec + +do_exit() and exec_mmap() call sync_mm_rss() before mm_release() does +put_user(clear_child_tid) which can update task->rss_stat and thus make +mm->rss_stat inconsistent. This triggers the "BUG:" printk in check_mm(). + +Let's fix this bug in the safest way, and optimize/cleanup this later. + +Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de> +Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org> +Cc: Oleg Nesterov <oleg@redhat.com> +Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> +Cc: Hugh Dickins <hughd@google.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +--- + + fs/exec.c | 2 +- + kernel/exit.c | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff -puN fs/exec.c~mm-correctly-synchronize-rss-counters-at-exit-exec fs/exec.c +--- a/fs/exec.c~mm-correctly-synchronize-rss-counters-at-exit-exec ++++ a/fs/exec.c +@@ -819,10 +819,10 @@ static int exec_mmap(struct mm_struct *m + /* Notify parent that we're no longer interested in the old VM */ + tsk = current; + old_mm = current->mm; +- sync_mm_rss(old_mm); + mm_release(tsk, old_mm); + + if (old_mm) { ++ sync_mm_rss(old_mm); + /* + * Make sure that if there is a core dump in progress + * for the old mm, we get out and die instead of going +diff -puN kernel/exit.c~mm-correctly-synchronize-rss-counters-at-exit-exec kernel/exit.c +--- a/kernel/exit.c~mm-correctly-synchronize-rss-counters-at-exit-exec ++++ a/kernel/exit.c +@@ -643,6 +643,7 @@ static void exit_mm(struct task_struct * + mm_release(tsk, mm); + if (!mm) + return; ++ sync_mm_rss(mm); + /* + * Serialize with any possible pending coredump. + * We must hold mmap_sem around checking core_state +_ +Subject: From: Konstantin Khlebnikov <khlebnikov@openvz.org> + +Patches currently in -mm which might be from khlebnikov@openvz.org are + +linux-next.patch +memcg-fix-use_hierarchy-css_is_ancestor-oops-regression.patch +mm-correctly-synchronize-rss-counters-at-exit-exec.patch + + diff --git a/freed-ora/current/f16/uprobes-task_work_add-generic-process-context-callbacks.patch b/freed-ora/current/f16/uprobes-task_work_add-generic-process-context-callbacks.patch new file mode 100644 index 000000000..6f56b4261 --- /dev/null +++ b/freed-ora/current/f16/uprobes-task_work_add-generic-process-context-callbacks.patch @@ -0,0 +1,249 @@ +FYI. This patch is upstream since linux-3.5. Backported in order to +bring SystemTap functionality back after the switch to linux-3.4 that +doesn't have utrace. :) + +The split-out series is available in the git repository at: + + git://fedorapeople.org/home/fedora/aarapov/public_git/kernel-uprobes.git + +Oleg Nesterov (1): + task_work_add: generic process-context callbacks + +Signed-off-by: Anton Arapov <anton@redhat.com> +--- + include/linux/sched.h | 2 ++ + include/linux/task_work.h | 33 ++++++++++++++++++ + include/linux/tracehook.h | 11 ++++++ + kernel/Makefile | 2 +- + kernel/exit.c | 5 ++- + kernel/fork.c | 1 + + kernel/task_work.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ + 7 files changed, 136 insertions(+), 2 deletions(-) + create mode 100644 include/linux/task_work.h + create mode 100644 kernel/task_work.c + +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 6869c60..e011a11 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1445,6 +1445,8 @@ struct task_struct { + int (*notifier)(void *priv); + void *notifier_data; + sigset_t *notifier_mask; ++ struct hlist_head task_works; ++ + struct audit_context *audit_context; + #ifdef CONFIG_AUDITSYSCALL + uid_t loginuid; +diff --git a/include/linux/task_work.h b/include/linux/task_work.h +new file mode 100644 +index 0000000..294d5d5 +--- /dev/null ++++ b/include/linux/task_work.h +@@ -0,0 +1,33 @@ ++#ifndef _LINUX_TASK_WORK_H ++#define _LINUX_TASK_WORK_H ++ ++#include <linux/list.h> ++#include <linux/sched.h> ++ ++struct task_work; ++typedef void (*task_work_func_t)(struct task_work *); ++ ++struct task_work { ++ struct hlist_node hlist; ++ task_work_func_t func; ++ void *data; ++}; ++ ++static inline void ++init_task_work(struct task_work *twork, task_work_func_t func, void *data) ++{ ++ twork->func = func; ++ twork->data = data; ++} ++ ++int task_work_add(struct task_struct *task, struct task_work *twork, bool); ++struct task_work *task_work_cancel(struct task_struct *, task_work_func_t); ++void task_work_run(void); ++ ++static inline void exit_task_work(struct task_struct *task) ++{ ++ if (unlikely(!hlist_empty(&task->task_works))) ++ task_work_run(); ++} ++ ++#endif /* _LINUX_TASK_WORK_H */ +diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h +index 51bd91d..48c597d 100644 +--- a/include/linux/tracehook.h ++++ b/include/linux/tracehook.h +@@ -49,6 +49,7 @@ + #include <linux/sched.h> + #include <linux/ptrace.h> + #include <linux/security.h> ++#include <linux/task_work.h> + struct linux_binprm; + + /* +@@ -165,8 +166,10 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, + */ + static inline void set_notify_resume(struct task_struct *task) + { ++#ifdef TIF_NOTIFY_RESUME + if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) + kick_process(task); ++#endif + } + + /** +@@ -184,6 +187,14 @@ static inline void set_notify_resume(struct task_struct *task) + */ + static inline void tracehook_notify_resume(struct pt_regs *regs) + { ++ /* ++ * The caller just cleared TIF_NOTIFY_RESUME. This barrier ++ * pairs with task_work_add()->set_notify_resume() after ++ * hlist_add_head(task->task_works); ++ */ ++ smp_mb__after_clear_bit(); ++ if (unlikely(!hlist_empty(¤t->task_works))) ++ task_work_run(); + } + #endif /* TIF_NOTIFY_RESUME */ + +diff --git a/kernel/Makefile b/kernel/Makefile +index cb41b95..2479528 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -5,7 +5,7 @@ + obj-y = fork.o exec_domain.o panic.o printk.o \ + cpu.o exit.o itimer.o time.o softirq.o resource.o \ + sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \ +- signal.o sys.o kmod.o workqueue.o pid.o \ ++ signal.o sys.o kmod.o workqueue.o pid.o task_work.o \ + rcupdate.o extable.o params.o posix-timers.o \ + kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ + hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ +diff --git a/kernel/exit.c b/kernel/exit.c +index d8bd3b42..b82c38e 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -946,11 +946,14 @@ void do_exit(long code) + exit_signals(tsk); /* sets PF_EXITING */ + /* + * tsk->flags are checked in the futex code to protect against +- * an exiting task cleaning up the robust pi futexes. ++ * an exiting task cleaning up the robust pi futexes, and in ++ * task_work_add() to avoid the race with exit_task_work(). + */ + smp_mb(); + raw_spin_unlock_wait(&tsk->pi_lock); + ++ exit_task_work(tsk); ++ + exit_irq_thread(); + + if (unlikely(in_atomic())) +diff --git a/kernel/fork.c b/kernel/fork.c +index 5b87e9f..76a961d 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1391,6 +1391,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, + */ + p->group_leader = p; + INIT_LIST_HEAD(&p->thread_group); ++ INIT_HLIST_HEAD(&p->task_works); + + /* Now that the task is set up, run cgroup callbacks if + * necessary. We need to run them before the task is visible +diff --git a/kernel/task_work.c b/kernel/task_work.c +new file mode 100644 +index 0000000..82d1c79 +--- /dev/null ++++ b/kernel/task_work.c +@@ -0,0 +1,84 @@ ++#include <linux/spinlock.h> ++#include <linux/task_work.h> ++#include <linux/tracehook.h> ++ ++int ++task_work_add(struct task_struct *task, struct task_work *twork, bool notify) ++{ ++ unsigned long flags; ++ int err = -ESRCH; ++ ++#ifndef TIF_NOTIFY_RESUME ++ if (notify) ++ return -ENOTSUPP; ++#endif ++ /* ++ * We must not insert the new work if the task has already passed ++ * exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait() ++ * and check PF_EXITING under pi_lock. ++ */ ++ raw_spin_lock_irqsave(&task->pi_lock, flags); ++ if (likely(!(task->flags & PF_EXITING))) { ++ hlist_add_head(&twork->hlist, &task->task_works); ++ err = 0; ++ } ++ raw_spin_unlock_irqrestore(&task->pi_lock, flags); ++ ++ /* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */ ++ if (likely(!err) && notify) ++ set_notify_resume(task); ++ return err; ++} ++ ++struct task_work * ++task_work_cancel(struct task_struct *task, task_work_func_t func) ++{ ++ unsigned long flags; ++ struct task_work *twork; ++ struct hlist_node *pos; ++ ++ raw_spin_lock_irqsave(&task->pi_lock, flags); ++ hlist_for_each_entry(twork, pos, &task->task_works, hlist) { ++ if (twork->func == func) { ++ hlist_del(&twork->hlist); ++ goto found; ++ } ++ } ++ twork = NULL; ++ found: ++ raw_spin_unlock_irqrestore(&task->pi_lock, flags); ++ ++ return twork; ++} ++ ++void task_work_run(void) ++{ ++ struct task_struct *task = current; ++ struct hlist_head task_works; ++ struct hlist_node *pos; ++ ++ raw_spin_lock_irq(&task->pi_lock); ++ hlist_move_list(&task->task_works, &task_works); ++ raw_spin_unlock_irq(&task->pi_lock); ++ ++ if (unlikely(hlist_empty(&task_works))) ++ return; ++ /* ++ * We use hlist to save the space in task_struct, but we want fifo. ++ * Find the last entry, the list should be short, then process them ++ * in reverse order. ++ */ ++ for (pos = task_works.first; pos->next; pos = pos->next) ++ ; ++ ++ for (;;) { ++ struct hlist_node **pprev = pos->pprev; ++ struct task_work *twork = container_of(pos, struct task_work, ++ hlist); ++ twork->func(twork); ++ ++ if (pprev == &task_works.first) ++ break; ++ pos = container_of(pprev, struct hlist_node, next); ++ } ++} |