summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f16
diff options
context:
space:
mode:
authorAlexandre Oliva <lxoliva@fsfla.org>2012-06-28 10:01:14 +0000
committerAlexandre Oliva <lxoliva@fsfla.org>2012-06-28 10:01:14 +0000
commit364c8ba7dd2629de4fdb77431c204882010ea158 (patch)
tree18d4b556983abe3e6c6cf5c5f207e3a9c7b10efa /freed-ora/current/f16
parenta69ee8715bdc91cd2342dcb12882c315f455b693 (diff)
downloadlinux-libre-raptor-364c8ba7dd2629de4fdb77431c204882010ea158.tar.gz
linux-libre-raptor-364c8ba7dd2629de4fdb77431c204882010ea158.zip
3.4.4-3.fc16.gnu
Diffstat (limited to 'freed-ora/current/f16')
-rw-r--r--freed-ora/current/f16/ath9k_htc-configure-bssid-on-ASSOC-IBSS-change.patch44
-rw-r--r--freed-ora/current/f16/block-fix-infinite-loop-in-__getblk_slow.patch153
-rw-r--r--freed-ora/current/f16/kernel.spec32
-rw-r--r--freed-ora/current/f16/mm-correctly-synchronize-rss-counters-at-exit-exec.patch125
-rw-r--r--freed-ora/current/f16/uprobes-task_work_add-generic-process-context-callbacks.patch249
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(&current->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);
++ }
++}
OpenPOWER on IntegriCloud