From: Greg Kroah-Hartman Date: Thu, 10 Oct 2013 23:57:20 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.100~6^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ce8656b4fad15e235c186c2221ff2f1d3144e33;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: acpi-ipmi-fix-atomic-context-requirement-of-ipmi_msg_handler.patch btrfs-change-how-we-queue-blocks-for-backref-checking.patch ext4-avoid-hang-when-mounting-non-journal-filesystems-with-orphan-list.patch mm-show_mem-suppress-page-counts-in-non-blockable-contexts.patch tile-use-a-more-conservative-__my_cpu_offset-in-config_preempt.patch --- diff --git a/queue-3.4/acpi-ipmi-fix-atomic-context-requirement-of-ipmi_msg_handler.patch b/queue-3.4/acpi-ipmi-fix-atomic-context-requirement-of-ipmi_msg_handler.patch new file mode 100644 index 00000000000..325d2f38900 --- /dev/null +++ b/queue-3.4/acpi-ipmi-fix-atomic-context-requirement-of-ipmi_msg_handler.patch @@ -0,0 +1,181 @@ +From 06a8566bcf5cf7db9843a82cde7a33c7bf3947d9 Mon Sep 17 00:00:00 2001 +From: Lv Zheng +Date: Fri, 13 Sep 2013 13:13:23 +0800 +Subject: ACPI / IPMI: Fix atomic context requirement of ipmi_msg_handler() + +From: Lv Zheng + +commit 06a8566bcf5cf7db9843a82cde7a33c7bf3947d9 upstream. + +This patch fixes the issues indicated by the test results that +ipmi_msg_handler() is invoked in atomic context. + +BUG: scheduling while atomic: kipmi0/18933/0x10000100 +Modules linked in: ipmi_si acpi_ipmi ... +CPU: 3 PID: 18933 Comm: kipmi0 Tainted: G AW 3.10.0-rc7+ #2 +Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.0027.070120100606 07/01/2010 + ffff8838245eea00 ffff88103fc63c98 ffffffff814c4a1e ffff88103fc63ca8 + ffffffff814bfbab ffff88103fc63d28 ffffffff814c73e0 ffff88103933cbd4 + 0000000000000096 ffff88103fc63ce8 ffff88102f618000 ffff881035c01fd8 +Call Trace: + [] dump_stack+0x19/0x1b + [] __schedule_bug+0x46/0x54 + [] __schedule+0x83/0x59c + [] __cond_resched+0x22/0x2d + [] _cond_resched+0x14/0x1d + [] mutex_lock+0x11/0x32 + [] ? __default_send_IPI_dest_field.constprop.0+0x53/0x58 + [] ipmi_msg_handler+0x23/0x166 [ipmi_si] + [] deliver_response+0x55/0x5a + [] handle_new_recv_msgs+0xb67/0xc65 + [] ? read_tsc+0x9/0x19 + [] ? _raw_spin_lock_irq+0xa/0xc + [] ipmi_thread+0x5c/0x146 [ipmi_si] + ... + +Also Tony Camuso says: + + We were getting occasional "Scheduling while atomic" call traces + during boot on some systems. Problem was first seen on a Cisco C210 + but we were able to reproduce it on a Cisco c220m3. Setting + CONFIG_LOCKDEP and LOCKDEP_SUPPORT to 'y' exposed a lockdep around + tx_msg_lock in acpi_ipmi.c struct acpi_ipmi_device. + + ================================= + [ INFO: inconsistent lock state ] + 2.6.32-415.el6.x86_64-debug-splck #1 + --------------------------------- + inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. + ksoftirqd/3/17 [HC0[0]:SC1[1]:HE1:SE0] takes: + (&ipmi_device->tx_msg_lock){+.?...}, at: [] ipmi_msg_handler+0x71/0x126 + {SOFTIRQ-ON-W} state was registered at: + [] __lock_acquire+0x63c/0x1570 + [] lock_acquire+0xa4/0x120 + [] __mutex_lock_common+0x4c/0x400 + [] mutex_lock_nested+0x4a/0x60 + [] acpi_ipmi_space_handler+0x11b/0x234 + [] acpi_ev_address_space_dispatch+0x170/0x1be + +The fix implemented by this change has been tested by Tony: + + Tested the patch in a boot loop with lockdep debug enabled and never + saw the problem in over 400 reboots. + +Reported-and-tested-by: Tony Camuso +Signed-off-by: Lv Zheng +Reviewed-by: Huang Ying +Signed-off-by: Rafael J. Wysocki +Cc: Jonghwan Choi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/acpi_ipmi.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/drivers/acpi/acpi_ipmi.c ++++ b/drivers/acpi/acpi_ipmi.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + MODULE_AUTHOR("Zhao Yakui"); + MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); +@@ -57,7 +58,7 @@ struct acpi_ipmi_device { + struct list_head head; + /* the IPMI request message list */ + struct list_head tx_msg_list; +- struct mutex tx_msg_lock; ++ spinlock_t tx_msg_lock; + acpi_handle handle; + struct pnp_dev *pnp_dev; + ipmi_user_t user_interface; +@@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct + struct kernel_ipmi_msg *msg; + struct acpi_ipmi_buffer *buffer; + struct acpi_ipmi_device *device; ++ unsigned long flags; + + msg = &tx_msg->tx_message; + /* +@@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct + + /* Get the msgid */ + device = tx_msg->device; +- mutex_lock(&device->tx_msg_lock); ++ spin_lock_irqsave(&device->tx_msg_lock, flags); + device->curr_msgid++; + tx_msg->tx_msgid = device->curr_msgid; +- mutex_unlock(&device->tx_msg_lock); ++ spin_unlock_irqrestore(&device->tx_msg_lock, flags); + } + + static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, +@@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi + int msg_found = 0; + struct acpi_ipmi_msg *tx_msg; + struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; ++ unsigned long flags; + + if (msg->user != ipmi_device->user_interface) { + dev_warn(&pnp_dev->dev, "Unexpected response is returned. " +@@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi + ipmi_free_recv_msg(msg); + return; + } +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { + if (msg->msgid == tx_msg->tx_msgid) { + msg_found = 1; +@@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi + } + } + +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + if (!msg_found) { + dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " + "returned.\n", msg->msgid); +@@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, ac + struct acpi_ipmi_device *ipmi_device = handler_context; + int err, rem_time; + acpi_status status; ++ unsigned long flags; + /* + * IPMI opregion message. + * IPMI message is firstly written to the BMC and system software +@@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, ac + return AE_NO_MEMORY; + + acpi_format_ipmi_msg(tx_msg, address, value); +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + err = ipmi_request_settime(ipmi_device->user_interface, + &tx_msg->addr, + tx_msg->tx_msgid, +@@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, ac + status = AE_OK; + + end_label: +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_del(&tx_msg->head); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + kfree(tx_msg); + return status; + } +@@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct + + INIT_LIST_HEAD(&ipmi_device->head); + +- mutex_init(&ipmi_device->tx_msg_lock); ++ spin_lock_init(&ipmi_device->tx_msg_lock); + INIT_LIST_HEAD(&ipmi_device->tx_msg_list); + ipmi_install_space_handler(ipmi_device); + diff --git a/queue-3.4/btrfs-change-how-we-queue-blocks-for-backref-checking.patch b/queue-3.4/btrfs-change-how-we-queue-blocks-for-backref-checking.patch new file mode 100644 index 00000000000..1146ba3ee8d --- /dev/null +++ b/queue-3.4/btrfs-change-how-we-queue-blocks-for-backref-checking.patch @@ -0,0 +1,68 @@ +From b6c60c8018c4e9beb2f83fc82c09f9d033766571 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Tue, 30 Jul 2013 16:30:30 -0400 +Subject: Btrfs: change how we queue blocks for backref checking + +From: Josef Bacik + +commit b6c60c8018c4e9beb2f83fc82c09f9d033766571 upstream. + +Previously we only added blocks to the list to have their backrefs checked if +the level of the block is right above the one we are searching for. This is +because we want to make sure we don't add the entire path up to the root to the +lists to make sure we process things one at a time. This assumes that if any +blocks in the path to the root are going to be not checked (shared in other +words) then they will be in the level right above the current block on up. This +isn't quite right though since we can have blocks higher up the list that are +shared because they are attached to a reloc root. But we won't add this block +to be checked and then later on we will BUG_ON(!upper->checked). So instead +keep track of wether or not we've queued a block to be checked in this current +search, and if we haven't go ahead and queue it to be checked. This patch fixed +the panic I was seeing where we BUG_ON(!upper->checked). Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/relocation.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -684,6 +684,7 @@ struct backref_node *build_backref_tree( + int cowonly; + int ret; + int err = 0; ++ bool need_check = true; + + path1 = btrfs_alloc_path(); + path2 = btrfs_alloc_path(); +@@ -906,6 +907,7 @@ again: + cur->bytenr); + + lower = cur; ++ need_check = true; + for (; level < BTRFS_MAX_LEVEL; level++) { + if (!path2->nodes[level]) { + BUG_ON(btrfs_root_bytenr(&root->root_item) != +@@ -949,14 +951,12 @@ again: + + /* + * add the block to pending list if we +- * need check its backrefs. only block +- * at 'cur->level + 1' is added to the +- * tail of pending list. this guarantees +- * we check backrefs from lower level +- * blocks to upper level blocks. ++ * need check its backrefs, we only do this once ++ * while walking up a tree as we will catch ++ * anything else later on. + */ +- if (!upper->checked && +- level == cur->level + 1) { ++ if (!upper->checked && need_check) { ++ need_check = false; + list_add_tail(&edge->list[UPPER], + &list); + } else diff --git a/queue-3.4/ext4-avoid-hang-when-mounting-non-journal-filesystems-with-orphan-list.patch b/queue-3.4/ext4-avoid-hang-when-mounting-non-journal-filesystems-with-orphan-list.patch new file mode 100644 index 00000000000..35f58f54bca --- /dev/null +++ b/queue-3.4/ext4-avoid-hang-when-mounting-non-journal-filesystems-with-orphan-list.patch @@ -0,0 +1,48 @@ +From 0e9a9a1ad619e7e987815d20262d36a2f95717ca Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Thu, 27 Dec 2012 01:42:50 -0500 +Subject: ext4: avoid hang when mounting non-journal filesystems with orphan list + +From: Theodore Ts'o + +commit 0e9a9a1ad619e7e987815d20262d36a2f95717ca upstream. + +When trying to mount a file system which does not contain a journal, +but which does have a orphan list containing an inode which needs to +be truncated, the mount call with hang forever in +ext4_orphan_cleanup() because ext4_orphan_del() will return +immediately without removing the inode from the orphan list, leading +to an uninterruptible loop in kernel code which will busy out one of +the CPU's on the system. + +This can be trivially reproduced by trying to mount the file system +found in tests/f_orphan_extents_inode/image.gz from the e2fsprogs +source tree. If a malicious user were to put this on a USB stick, and +mount it on a Linux desktop which has automatic mounts enabled, this +could be considered a potential denial of service attack. (Not a big +deal in practice, but professional paranoids worry about such things, +and have even been known to allocate CVE numbers for such problems.) + +-js: This is a fix for CVE-2013-2015. + +Signed-off-by: "Theodore Ts'o" +Reviewed-by: Zheng Liu +Acked-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/namei.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2054,7 +2054,8 @@ int ext4_orphan_del(handle_t *handle, st + int err = 0; + + /* ext4_handle_valid() assumes a valid handle_t pointer */ +- if (handle && !ext4_handle_valid(handle)) ++ if (handle && !ext4_handle_valid(handle) && ++ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) + return 0; + + mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); diff --git a/queue-3.4/mm-show_mem-suppress-page-counts-in-non-blockable-contexts.patch b/queue-3.4/mm-show_mem-suppress-page-counts-in-non-blockable-contexts.patch new file mode 100644 index 00000000000..a1498f9cf7f --- /dev/null +++ b/queue-3.4/mm-show_mem-suppress-page-counts-in-non-blockable-contexts.patch @@ -0,0 +1,137 @@ +From 4b59e6c4730978679b414a8da61514a2518da512 Mon Sep 17 00:00:00 2001 +From: David Rientjes +Date: Mon, 29 Apr 2013 15:06:11 -0700 +Subject: mm, show_mem: suppress page counts in non-blockable contexts + +From: David Rientjes + +commit 4b59e6c4730978679b414a8da61514a2518da512 upstream. + +On large systems with a lot of memory, walking all RAM to determine page +types may take a half second or even more. + +In non-blockable contexts, the page allocator will emit a page allocation +failure warning unless __GFP_NOWARN is specified. In such contexts, irqs +are typically disabled and such a lengthy delay may even result in NMI +watchdog timeouts. + +To fix this, suppress the page walk in such contexts when printing the +page allocation failure warning. + +Signed-off-by: David Rientjes +Cc: Mel Gorman +Acked-by: Michal Hocko +Cc: Dave Hansen +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Xishi Qiu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mm/init.c | 3 +++ + arch/ia64/mm/contig.c | 2 ++ + arch/ia64/mm/discontig.c | 2 ++ + arch/parisc/mm/init.c | 2 ++ + arch/unicore32/mm/init.c | 3 +++ + include/linux/mm.h | 3 ++- + lib/show_mem.c | 3 +++ + mm/page_alloc.c | 7 +++++++ + 8 files changed, 24 insertions(+), 1 deletion(-) + +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -98,6 +98,9 @@ void show_mem(unsigned int filter) + printk("Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank (i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +--- a/arch/ia64/mm/contig.c ++++ b/arch/ia64/mm/contig.c +@@ -47,6 +47,8 @@ void show_mem(unsigned int filter) + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); + printk(KERN_INFO "Node memory in pages:\n"); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + for_each_online_pgdat(pgdat) { + unsigned long present; + unsigned long flags; +--- a/arch/ia64/mm/discontig.c ++++ b/arch/ia64/mm/discontig.c +@@ -623,6 +623,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + printk(KERN_INFO "Node memory in pages:\n"); + for_each_online_pgdat(pgdat) { + unsigned long present; +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -685,6 +685,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + #ifndef CONFIG_DISCONTIGMEM + i = max_mapnr; + while (i-- > 0) { +--- a/arch/unicore32/mm/init.c ++++ b/arch/unicore32/mm/init.c +@@ -66,6 +66,9 @@ void show_mem(unsigned int filter) + printk(KERN_DEFAULT "Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank(i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -866,7 +866,8 @@ extern void pagefault_out_of_memory(void + * Flags passed to show_mem() and show_free_areas() to suppress output in + * various contexts. + */ +-#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ ++#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ ++#define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */ + + extern void show_free_areas(unsigned int flags); + extern bool skip_free_areas_node(unsigned int flags, int nid); +--- a/lib/show_mem.c ++++ b/lib/show_mem.c +@@ -18,6 +18,9 @@ void show_mem(unsigned int filter) + printk("Mem-Info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1885,6 +1885,13 @@ void warn_alloc_failed(gfp_t gfp_mask, i + return; + + /* ++ * Walking all memory to count page types is very expensive and should ++ * be inhibited in non-blockable contexts. ++ */ ++ if (!(gfp_mask & __GFP_WAIT)) ++ filter |= SHOW_MEM_FILTER_PAGE_COUNT; ++ ++ /* + * This documents exceptions given to allocations in certain + * contexts that are allowed to allocate outside current's set + * of allowed nodes. diff --git a/queue-3.4/series b/queue-3.4/series index 3037f5ced7e..0b157bd659b 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -37,3 +37,8 @@ dmaengine-imx-dma-fix-lockdep-issue-between-irqhandler-and-tasklet.patch dmaengine-imx-dma-fix-callback-path-in-tasklet.patch dmaengine-imx-dma-fix-slow-path-issue-in-prep_dma_cyclic.patch staging-comedi-ni_65xx-bug-fix-confine-insn_bits-to-one-subdevice.patch +mm-show_mem-suppress-page-counts-in-non-blockable-contexts.patch +acpi-ipmi-fix-atomic-context-requirement-of-ipmi_msg_handler.patch +tile-use-a-more-conservative-__my_cpu_offset-in-config_preempt.patch +btrfs-change-how-we-queue-blocks-for-backref-checking.patch +ext4-avoid-hang-when-mounting-non-journal-filesystems-with-orphan-list.patch diff --git a/queue-3.4/tile-use-a-more-conservative-__my_cpu_offset-in-config_preempt.patch b/queue-3.4/tile-use-a-more-conservative-__my_cpu_offset-in-config_preempt.patch new file mode 100644 index 00000000000..64a75e1002a --- /dev/null +++ b/queue-3.4/tile-use-a-more-conservative-__my_cpu_offset-in-config_preempt.patch @@ -0,0 +1,71 @@ +From f862eefec0b68e099a9fa58d3761ffb10bad97e1 Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Thu, 26 Sep 2013 13:24:53 -0400 +Subject: tile: use a more conservative __my_cpu_offset in CONFIG_PREEMPT + +From: Chris Metcalf + +commit f862eefec0b68e099a9fa58d3761ffb10bad97e1 upstream. + +It turns out the kernel relies on barrier() to force a reload of the +percpu offset value. Since we can't easily modify the definition of +barrier() to include "tp" as an output register, we instead provide a +definition of __my_cpu_offset as extended assembly that includes a fake +stack read to hazard against barrier(), forcing gcc to know that it +must reread "tp" and recompute anything based on "tp" after a barrier. + +This fixes observed hangs in the slub allocator when we are looping +on a percpu cmpxchg_double. + +A similar fix for ARMv7 was made in June in change 509eb76ebf97. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + arch/tile/include/asm/percpu.h | 34 +++++++++++++++++++++++++++++++--- + 1 file changed, 31 insertions(+), 3 deletions(-) + +--- a/arch/tile/include/asm/percpu.h ++++ b/arch/tile/include/asm/percpu.h +@@ -15,9 +15,37 @@ + #ifndef _ASM_TILE_PERCPU_H + #define _ASM_TILE_PERCPU_H + +-register unsigned long __my_cpu_offset __asm__("tp"); +-#define __my_cpu_offset __my_cpu_offset +-#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp)) ++register unsigned long my_cpu_offset_reg asm("tp"); ++ ++#ifdef CONFIG_PREEMPT ++/* ++ * For full preemption, we can't just use the register variable ++ * directly, since we need barrier() to hazard against it, causing the ++ * compiler to reload anything computed from a previous "tp" value. ++ * But we also don't want to use volatile asm, since we'd like the ++ * compiler to be able to cache the value across multiple percpu reads. ++ * So we use a fake stack read as a hazard against barrier(). ++ * The 'U' constraint is like 'm' but disallows postincrement. ++ */ ++static inline unsigned long __my_cpu_offset(void) ++{ ++ unsigned long tp; ++ register unsigned long *sp asm("sp"); ++ asm("move %0, tp" : "=r" (tp) : "U" (*sp)); ++ return tp; ++} ++#define __my_cpu_offset __my_cpu_offset() ++#else ++/* ++ * We don't need to hazard against barrier() since "tp" doesn't ever ++ * change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only ++ * changes at function call points, at which we are already re-reading ++ * the value of "tp" due to "my_cpu_offset_reg" being a global variable. ++ */ ++#define __my_cpu_offset my_cpu_offset_reg ++#endif ++ ++#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp)) + + #include +