Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, 2014-02-01 at 17:06 -0800, Suresh Siddha wrote: > Meanwhile I have the patch removing the delayed dynamic allocation for > non-eager fpu. will post it after some testing. Appended the patch for this. Tested for last 4-5 hours on my laptop. The real fix for Nate's problem will be coming from Linus, with a slightly modified option-b that Linus proposed. Linus, please let me know if you want me to spin it. I can do it sunday night. thanks, suresh --- From: Suresh Siddha Subject: x86, fpu: remove the logic of non-eager fpu mem allocation at the first usage For non-eager fpu mode, thread's fpu state is allocated during the first fpu usage (in the context of device not available exception). This can be a blocking call and hence we enable interrupts (which were originally disabled when the exception happened), allocate memory and disable interrupts etc. While this saves 512 bytes or so per-thread, there are some issues in general. a. Most of the future cases will be anyway using eager FPU (because of processor features like xsaveopt, LWP, MPX etc) and they do the allocation at the thread creation itself. Nice to have one common mechanism as all the state save/restore code is shared. Avoids the confusion and minimizes the subtle bugs in the core piece involved with context-switch. b. If a parent thread uses FPU, during fork() we allocate the FPU state in the child and copy the state etc. Shortly after this, during exec() we free it up, so that we can later allocate during the first usage of FPU. So this free/allocate might be slower for some workloads. c. math_state_restore() is called from multiple places and it is error pone if the caller expects interrupts to be disabled throughout the execution of math_state_restore(). Can lead to subtle bugs like Ubuntu bug #1265841. Memory savings will be small anyways and the code complexity introducing subtle bugs is not worth it. So remove the logic of non-eager fpu mem allocation at the first usage. Signed-off-by: Suresh Siddha --- arch/x86/kernel/i387.c| 14 +- arch/x86/kernel/process.c | 6 -- arch/x86/kernel/traps.c | 16 ++-- arch/x86/kernel/xsave.c | 2 -- 4 files changed, 7 insertions(+), 31 deletions(-) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index e8368c6..4e5f770 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -5,6 +5,7 @@ * General FPU state handling cleanups * Gareth Hughes , May 2000 */ +#include #include #include #include @@ -186,6 +187,10 @@ void fpu_init(void) if (xstate_size == 0) init_thread_xstate(); + if (!current->thread.fpu.state) + current->thread.fpu.state = + alloc_bootmem_align(xstate_size, __alignof__(struct xsave_struct)); + mxcsr_feature_mask_init(); xsave_init(); eager_fpu_init(); @@ -219,8 +224,6 @@ EXPORT_SYMBOL_GPL(fpu_finit); */ int init_fpu(struct task_struct *tsk) { - int ret; - if (tsk_used_math(tsk)) { if (cpu_has_fpu && tsk == current) unlazy_fpu(tsk); @@ -228,13 +231,6 @@ int init_fpu(struct task_struct *tsk) return 0; } - /* -* Memory allocation at the first usage of the FPU and other state. -*/ - ret = fpu_alloc(>thread.fpu); - if (ret) - return ret; - fpu_finit(>thread.fpu); set_stopped_child_used_math(tsk); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 3fb8d95..cd9c190 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -128,12 +128,6 @@ void flush_thread(void) flush_ptrace_hw_breakpoint(tsk); memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); drop_init_fpu(tsk); - /* -* Free the FPU state for non xsave platforms. They get reallocated -* lazily at the first use. -*/ - if (!use_eager_fpu()) - free_thread_xstate(tsk); } static void hard_disable_TSC(void) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 57409f6..3265429 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -623,20 +623,8 @@ void math_state_restore(void) { struct task_struct *tsk = current; - if (!tsk_used_math(tsk)) { - local_irq_enable(); - /* -* does a slab alloc which can sleep -*/ - if (init_fpu(tsk)) { - /* -* ran out of memory! -*/ - do_group_exit(SIGKILL); - return; - } - local_irq_disable(); - } + if (!tsk_used_math(tsk)) + init_fpu(tsk); __thread_fpu_begin(tsk); diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index a4b451c..46f6266 100644 ---
Re: [GIT PULL] Staging wireless driver for 3.14-rc1
On Sat, Feb 01, 2014 at 10:43:11AM -0800, Linus Torvalds wrote: > On Fri, Jan 31, 2014 at 6:32 AM, Greg KH wrote: > > > > Here's a single staging driver for a wireless chipset that has shown up > > in the SteamBox hardware. It is merged separately from the "main" > > staging pull request to sync up with the wireless api changes that came > > in from the networking tree. > > It causes an interesting warning for me: > > drivers/staging/rtl8821ae/rtl8821ae/dm.c: In function > ‘rtl8821ae_dm_clear_txpower_tracking_state’: > drivers/staging/rtl8821ae/rtl8821ae/dm.c:487:31: warning: iteration 2u > invokes undefined behavior [-Waggressive-loop-optimizations] >rtldm->bb_swing_idx_ofdm[p] = rtldm->default_ofdm_index; >^ > drivers/staging/rtl8821ae/rtl8821ae/dm.c:485:2: note: containing loop > for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) { > ^ > > and gcc is entirely correct: that loop iterates from 0 to 3, and does this: > > rtldm->bb_swing_idx_ofdm[p] = rtldm->default_ofdm_index; > > but the bb_swing_idx_ofdm[] array only has two members. So the last > two iterations will overwrite bb_swing_idx_ofdm_current and the first > entry in bb_swing_idx_ofdm_base[]. > > Now, the bug does seem to be benign: bb_swing_idx_ofdm_current isn't > actually ever *used* as far as I can tell, and the first entry of > bb_swing_idx_ofdm_base[] will have been written with that same > "rtldm->default_ofdm_index" value. > > But gcc is absolutely correct, and that driver needs fixing. > > I've pulled it and will let it be because it doesn't seem to be an > issue in practice, but please fix it. The obvious fix would seem to > change the size of "2" to be "MAX_RF_PATH", but I'll abstain from > doing those kinds of changes in the merge when it doesn't seem to > affect the build or functionality). Ok, thanks, someone's already sent me that patch to fix this up, I'll queue it up for the post-rc1 set of staging tree fixes. greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Documentation cleanup, update 00-INDEX files in Documentation/
On 01/31/14 16:24, Andrew Morton wrote: On Wed, 29 Jan 2014 22:24:11 -0600 Rob Landley wrote: On 01/29/14 18:27, Henrik Austad wrote: Some of the 00-INDEX files are somewhat outdated and some folders does not contain 00-INDEX at all. Only outdated (with the notably exception of spi) indexes are touched here, the 169 folders without 00-INDEX has not been touched. This applies to Linus' tip (0e47c969). Looks like an improvement. Acked-by: Rob Landley Are these 00-INDEX files actually useful? I've never opened one of them in my life. Back before kernel.org did its epic barn door locking after the horses escaped, I used to use them to generate HTML indexes for kernel.org/doc/Documentation, but sometime after they took away my ability to rsync updates to that they replaced that directory with a raw git checkout. I'm still waiting for them to replace the HTML versions of the menuconfig help text and the htmldocs output with raw git checkouts too. I periodically poke them about it, ala https://bugzilla.kernel.org/show_bug.cgi?id=52721#c7 but the answer is always crickets chirping or "you should upload web pages with git just like you browse the web with git, watch video with git, play skyrim with git, edit code with git, compile code with git... there is no other software tool." At which point I wander off for another 6 months. So I used to have a use for it, but since kernel.org got all paranoid I can't use it that way anymore. (That's why I haven't been updating these files when the patches themselves don't. It's on my todo list, but it's really hard to _care_ when they so obviously don't.) Insufficiently gruntled, Rob -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 13/16] drm/nouveau/ibus: add GK20A support
Some very trivial comments below: On Fri, Jan 31, 2014 at 10:16 PM, Alexandre Courbot wrote: > Add support for initializing the priv ring of GK20A. This is done by the > BIOS on desktop GPUs, but needs to be done by hand on Tegra. > > Signed-off-by: Alexandre Courbot > --- > drivers/gpu/drm/nouveau/Makefile | 1 + > drivers/gpu/drm/nouveau/core/include/subdev/ibus.h | 1 + > drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c| 108 > + > 3 files changed, 110 insertions(+) > create mode 100644 drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c > > diff --git a/drivers/gpu/drm/nouveau/Makefile > b/drivers/gpu/drm/nouveau/Makefile > index 6c4b76d..3548fcd 100644 > --- a/drivers/gpu/drm/nouveau/Makefile > +++ b/drivers/gpu/drm/nouveau/Makefile > @@ -132,6 +132,7 @@ nouveau-y += core/subdev/i2c/nv94.o > nouveau-y += core/subdev/i2c/nvd0.o > nouveau-y += core/subdev/ibus/nvc0.o > nouveau-y += core/subdev/ibus/nve0.o > +nouveau-y += core/subdev/ibus/nvea.o > nouveau-y += core/subdev/instmem/base.o > nouveau-y += core/subdev/instmem/nv04.o > nouveau-y += core/subdev/instmem/nv40.o > diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h > b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h > index 88814f1..056a42f 100644 > --- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h > +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h > @@ -30,5 +30,6 @@ nouveau_ibus(void *obj) > > extern struct nouveau_oclass nvc0_ibus_oclass; > extern struct nouveau_oclass nve0_ibus_oclass; > +extern struct nouveau_oclass nvea_ibus_oclass; > > #endif > diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c > b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c > new file mode 100644 > index 000..0bcd281 > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c > @@ -0,0 +1,108 @@ > +/* > + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + */ > + > +#include > + > +struct nvea_ibus_priv { > + struct nouveau_ibus base; > +}; > + > +static void > +nvea_ibus_init_priv_ring(struct nvea_ibus_priv *priv) > +{ > + u32 data; > + > + data = nv_rd32(priv, 0x137250); > + data &= (~0x3f); > + nv_wr32(priv, 0x137250, data); nv_mask(priv, 0x137250, 0x3f, 0) should do this, right? > + > + nv_mask(priv, 0x000200, 0x20, 0); > + udelay(20); > + nv_mask(priv, 0x000200, 0x20, 0x20); > + > + nv_wr32(priv, 0x12004c, 0x4); > + nv_wr32(priv, 0x122204, 0x2); > + nv_rd32(priv, 0x122204); > +} > + > +static void > +nvea_ibus_intr(struct nouveau_subdev *subdev) > +{ > + struct nvea_ibus_priv *priv = (void *)subdev; > + u32 status0 = nv_rd32(priv, 0x120058); > + s32 retry = 100; > + u32 command; > + > + if (status0 & 0x7) { > + nv_debug(priv, "resetting priv ring\n"); > + nvea_ibus_init_priv_ring(priv); > + } > + > + /* Acknowledge interrupt */ > + command = nv_rd32(priv, 0x0012004c); > + command |= 0x2; > + nv_wr32(priv, 0x0012004c, command); nv_mask(priv, 0x12004c, 0x2, 0x2) > + > + while (--retry >= 0) { > + command = nv_rd32(priv, 0x12004c) & 0x3f; > + if (command == 0) > + break; > + } > + > + if (retry < 0) > + nv_debug(priv, "timeout waiting for ringmaster ack\n"); this sounds kinda bad, no? perhaps a nv_warn? > +} > + > +static int > +nvea_ibus_init(struct nouveau_object *object) > +{ > + struct nvea_ibus_priv *priv = (void *)object; > + int ret; > + > + ret = _nouveau_ibus_init(object); > + if (ret) > + return ret; > + > + nvea_ibus_init_priv_ring(priv); > + > + return 0; > +} > + > +static int > +nvea_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, > + struct nouveau_oclass *oclass, void *data, u32 size, > + struct nouveau_object **pobject) > +{ > + struct nvea_ibus_priv *priv; > + int ret; > + > + ret = nouveau_ibus_create(parent, engine, oclass, ); > + *pobject = nv_object(priv); > + if (ret) > + return ret; > + > + nv_subdev(priv)->intr = nvea_ibus_intr; > + return 0; > +} > + > +struct nouveau_oclass > +nvea_ibus_oclass = { > + .handle = NV_SUBDEV(IBUS, 0xea), > + .ofuncs = &(struct nouveau_ofuncs) { > + .ctor = nvea_ibus_ctor, > +
[tip:x86/urgent] x86: Fix the initialization of physnode_map
Commit-ID: 85fc73a2cdf10cf42bc36fb3bca3896b2095a1c2 Gitweb: http://git.kernel.org/tip/85fc73a2cdf10cf42bc36fb3bca3896b2095a1c2 Author: Petr Tesarik AuthorDate: Sat, 1 Feb 2014 13:30:19 +0100 Committer: H. Peter Anvin CommitDate: Sat, 1 Feb 2014 22:15:51 -0800 x86: Fix the initialization of physnode_map With DISCONTIGMEM, the mapping between a pfn and its owning node is initialized using data provided by the BIOS. However, the initialization may fail if the extents are not aligned to section boundary (64M). The symptom of this bug is an early boot failure in pfn_to_page(), as it tries to access NODE_DATA(__nid) using index from an unitialized element of the physnode_map[] array. While the bug is always present, it is more likely to be hit in kdump kernels on large machines, because: 1. The memory map for a kdump kernel is specified as exactmap, and exactmap is more likely to be unaligned. 2. Large reservations are more likely to span across a 64M boundary. [ hpa: fixed incorrect use of "pfn" instead of "start" ] Signed-off-by: Petr Tesarik Link: http://lkml.kernel.org/r/20140201133019.32e56...@hananiah.suse.cz Acked-by: David Rientjes Signed-off-by: H. Peter Anvin --- arch/x86/mm/numa_32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c index 0342d27..47b6436 100644 --- a/arch/x86/mm/numa_32.c +++ b/arch/x86/mm/numa_32.c @@ -52,6 +52,8 @@ void memory_present(int nid, unsigned long start, unsigned long end) nid, start, end); printk(KERN_DEBUG " Setting physnode_map array to node %d for pfns:\n", nid); printk(KERN_DEBUG " "); + start = round_down(start, PAGES_PER_SECTION); + end = round_up(end, PAGES_PER_SECTION); for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { physnode_map[pfn / PAGES_PER_SECTION] = nid; printk(KERN_CONT "%lx ", pfn); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[tip:x86/urgent] x86: Fix the initialization of physnode_map
Commit-ID: 170750c108bb9382f32a2a99d097aa07d551a89e Gitweb: http://git.kernel.org/tip/170750c108bb9382f32a2a99d097aa07d551a89e Author: Petr Tesarik AuthorDate: Sat, 1 Feb 2014 13:30:19 +0100 Committer: H. Peter Anvin CommitDate: Sat, 1 Feb 2014 21:57:48 -0800 x86: Fix the initialization of physnode_map With DISCONTIGMEM, the mapping between a pfn and its owning node is initialized using data provided by the BIOS. However, the initialization may fail if the extents are not aligned to section boundary (64M). The symptom of this bug is an early boot failure in pfn_to_page(), as it tries to access NODE_DATA(__nid) using index from an unitialized element of the physnode_map[] array. While the bug is always present, it is more likely to be hit in kdump kernels on large machines, because: 1. The memory map for a kdump kernel is specified as exactmap, and exactmap is more likely to be unaligned. 2. Large reservations are more likely to span across a 64M boundary. Signed-off-by: Petr Tesarik Link: http://lkml.kernel.org/r/20140201133019.32e56...@hananiah.suse.cz Acked-by: David Rientjes Signed-off-by: H. Peter Anvin --- arch/x86/mm/numa_32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c index 0342d27..8c62ec6 100644 --- a/arch/x86/mm/numa_32.c +++ b/arch/x86/mm/numa_32.c @@ -52,6 +52,8 @@ void memory_present(int nid, unsigned long start, unsigned long end) nid, start, end); printk(KERN_DEBUG " Setting physnode_map array to node %d for pfns:\n", nid); printk(KERN_DEBUG " "); + pfn = round_down(pfn, PAGES_PER_SECTION); + end = round_up(end, PAGES_PER_SECTION); for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { physnode_map[pfn / PAGES_PER_SECTION] = nid; printk(KERN_CONT "%lx ", pfn); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 10/10] manpage: update FALLOC_FL_COLLAPSE_RANGE flag in fallocate
From: Namjae Jeon Update FALLOC_FL_COLLAPSE_RANGE flag in fallocate. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- man2/fallocate.2 | 21 + 1 file changed, 21 insertions(+) diff --git a/man2/fallocate.2 b/man2/fallocate.2 index ec9011c..69a4dbd 100644 --- a/man2/fallocate.2 +++ b/man2/fallocate.2 @@ -1,5 +1,6 @@ .\" Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved .\" Written by Dave Chinner +.\" Updated by Namjae Jeon .\" .\" %%%LICENSE_START(GPLv2_ONELINE) .\" May be distributed as per GNU General Public License version 2. @@ -7,6 +8,7 @@ .\" .\" 2011-09-19: Added FALLOC_FL_PUNCH_HOLE .\" 2011-09-19: Substantial restructuring of the page +.\" 2013-11-10: Added FALLOC_FL_COLLAPSE_RANGE .\" .TH FALLOCATE 2 2013-11-08 "Linux" "Linux Programmer's Manual" .SH NAME @@ -113,6 +115,25 @@ does not change. Not all filesystems support .BR FALLOC_FL_PUNCH_HOLE ; if a filesystem doesn't support the operation, an error is returned. +.SS Collapsing file space +Specifiying the +.BR FALLOC_FL_COLLAPSE_RANGE +flag in +.I mode +collpse space in the byte range starting at +.I offset +and continuing for +.I len +bytes. Within the specified range, it first de-allocates blocks and eliminates +the hole created in this process by shifting data blocks into the hole. + +Different filesystem may implement different limitatios on the granularity of +the operation. Most filesystem will limit operations to filesystem block size +boundaries, but this boundary may be larger or smaller depending +on the filesystem and/or the configuration of the filesystem or file. + +If filesystem has such limitation on granularity, It will return error(EINVAL). + .SH RETURN VALUE On success, .BR fallocate () -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 9/10] xfstest: shared/005: Test multiple fallocate collapse
From: Namjae Jeon We execute collapse range multiple times on same file. Each collapse range call collapses a single alternate block. After the test execution, file will be left with 80 blocks and as much number of extents. We also check for file system consistency after the completion. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- tests/shared/005 | 90 ++ tests/shared/005.out |4 +++ tests/shared/group |1 + 3 files changed, 95 insertions(+) create mode 100644 tests/shared/005 create mode 100644 tests/shared/005.out diff --git a/tests/shared/005 b/tests/shared/005 new file mode 100644 index 000..1347e7f --- /dev/null +++ b/tests/shared/005 @@ -0,0 +1,90 @@ +#! /bin/bash +# FS QA Test No. 5 +# +# Test multiple fallocate collapse range calls on same file. +# For different blocksizes, collapse a single alternate block multiple times +# until the file is left with 80 blocks and as much number of extents. +# Also check for file system consistency after completing this operation +# for each blocksize. +#--- +# Copyright (c) 2013 Samsung Electronics. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs xfs ext4 +_supported_os Linux + +_require_scratch +_require_xfs_io_fiemap +_require_xfs_io_falloc_collapse +_do_die_on_error=y +testfile=$SCRATCH_MNT/$seq.$$ +BLOCKS=10240 + +for (( BSIZE = 1024; BSIZE <= 4096; BSIZE *= 2 )); do + + length=$(($BLOCKS * $BSIZE)) + case $FSTYP in + xfs) + _scratch_mkfs -b size=$BSIZE >> $seqres.full 2>&1 + ;; + ext4) + _scratch_mkfs -b $BSIZE >> $seqres.full 2>&1 + ;; + esac + _scratch_mount >> $seqres.full 2>&1 + + # Write file + $XFS_IO_PROG -f -c "pwrite 0 $length" -c fsync $testfile > /dev/null + + # Collapse alternate blocks + for (( i = 1; i <= 7; i++ )); do + for (( j=0; j < $(($BLOCKS/(2**$i))); j++ )); do + offset=$(($j*$BSIZE)) + $XFS_IO_PROG -c "fcollapse $offset $BSIZE" $testfile > /dev/null + done + done + + # Check if 80 extents are present + $XFS_IO_PROG -c "fiemap -v" $testfile | grep "^ *[0-9]*:" |wc -l + + _check_scratch_fs + if [ $? -ne 0 ]; then + status=1 + exit + fi + + umount $SCRATCH_MNT +done + +# success, all done +status=0 +exit diff --git a/tests/shared/005.out b/tests/shared/005.out new file mode 100644 index 000..8d30b9d --- /dev/null +++ b/tests/shared/005.out @@ -0,0 +1,4 @@ +QA output created by 005 +80 +80 +80 diff --git a/tests/shared/group b/tests/shared/group index fb1d6d0..22f1d3a 100644 --- a/tests/shared/group +++ b/tests/shared/group @@ -7,6 +7,7 @@ 002 auto prealloc 003 auto prealloc 004 auto prealloc +005 auto prealloc 032 mkfs auto quick 051 acl udf auto quick 218 auto fsr quick -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 6/10] xfstest: shared/002: Delayed allocation collapse range
From: Namjae Jeon This testcase(002) tries to test various corner cases with delayed extents for fcollapse range functionality over different type of extents. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- tests/shared/002 | 65 ++ tests/shared/002.out | 53 tests/shared/group |1 + 3 files changed, 119 insertions(+) create mode 100755 tests/shared/002 create mode 100644 tests/shared/002.out diff --git a/tests/shared/002 b/tests/shared/002 new file mode 100755 index 000..54b957d --- /dev/null +++ b/tests/shared/002 @@ -0,0 +1,65 @@ +#! /bin/bash +# FS QA Test No. 2 +# +# Delayed allocation collapse range tests +# This testcase is one of the 4 testcases (shared 001 - 004) which tries to +# test various corner cases for fcollapse range functionality over different +# type of extents. These tests are based on generic/255 test case. +# For the type of tests, check the description of _test_generic_punch +# in common/rc. +#--- +# Copyright (c) 2013 Samsung Electronics. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ +rm -f $tmp.* +} + +trap "_cleanup ; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +# we need to include common/punch to get defination fo filter functions +. ./common/rc +. ./common/filter +. ./common/punch + +# real QA test starts here +_supported_fs xfs ext4 +_supported_os Linux + +_require_xfs_io_falloc_punch +_require_xfs_io_falloc +_require_xfs_io_fiemap +_require_xfs_io_falloc_collapse + +testfile=$TEST_DIR/$seq.$$ + +_test_generic_punch -d falloc fpunch fcollapse fiemap _filter_hole_fiemap $testfile +_check_test_fs + +status=0 +exit diff --git a/tests/shared/002.out b/tests/shared/002.out new file mode 100644 index 000..14c239c --- /dev/null +++ b/tests/shared/002.out @@ -0,0 +1,53 @@ +QA output created by 002 + 1. into a hole +f4f35d60b3cc18aaa6d8d92f0cd3708a + 2. into allocated space +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 + 3. into unwritten space +0: [0..95]: extent +f4f35d60b3cc18aaa6d8d92f0cd3708a + 4. hole -> data +0: [0..31]: hole +1: [32..63]: extent +2: [64..95]: hole +d8f51c20223dbce5c7c90db87bc221b0 + 5. hole -> unwritten +0: [0..31]: hole +1: [32..63]: extent +2: [64..95]: hole +f4f35d60b3cc18aaa6d8d92f0cd3708a + 6. data -> hole +0: [0..31]: extent +1: [32..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 7. data -> unwritten +0: [0..63]: extent +1: [64..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 8. unwritten -> hole +0: [0..31]: extent +1: [32..95]: hole +f4f35d60b3cc18aaa6d8d92f0cd3708a + 9. unwritten -> data +0: [0..63]: extent +1: [64..95]: hole +d8f51c20223dbce5c7c90db87bc221b0 + 10. hole -> data -> hole +bb7df04e1b0a2570657527a7e108ae23 + 11. data -> hole -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 12. unwritten -> data -> unwritten +0: [0..63]: extent +bb7df04e1b0a2570657527a7e108ae23 + 13. data -> unwritten -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 14. data -> hole @ EOF +fallocate: Invalid argument +0: [0..159]: extent +7670f4830c6724a25e7c22d9eb9a6f4f + 15. data -> hole @ 0 +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 diff --git a/tests/shared/group b/tests/shared/group index 5562f92..7230b28 100644 --- a/tests/shared/group +++ b/tests/shared/group @@ -4,6 +4,7 @@ # - comment line before each group is "new" description # 001 auto prealloc +002 auto prealloc 032 mkfs auto quick 051 acl udf auto quick 218 auto fsr quick -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[patch] mm, compaction: avoid isolating pinned pages
Page migration will fail for memory that is pinned in memory with, for example, get_user_pages(). In this case, it is unnecessary to take zone->lru_lock or isolating the page and passing it to page migration which will ultimately fail. This is a racy check, the page can still change from under us, but in that case we'll just fail later when attempting to move the page. This avoids very expensive memory compaction when faulting transparent hugepages after pinning a lot of memory with a Mellanox driver. On a 128GB machine and pinning ~120GB of memory, before this patch we see the enormous disparity in the number of page migration failures because of the pinning (from /proc/vmstat): compact_blocks_moved 7609 compact_pages_moved 3431 compact_pagemigrate_failed 133219 compact_stall 13 After the patch, it is much more efficient: compact_blocks_moved 7998 compact_pages_moved 6403 compact_pagemigrate_failed 3 compact_stall 15 Signed-off-by: David Rientjes --- mm/compaction.c | 8 1 file changed, 8 insertions(+) diff --git a/mm/compaction.c b/mm/compaction.c --- a/mm/compaction.c +++ b/mm/compaction.c @@ -578,6 +578,14 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, continue; } + /* +* Migration will fail if an anonymous page is pinned in memory, +* so avoid taking zone->lru_lock and isolating it unnecessarily +* in an admittedly racy check. +*/ + if (!page_mapping(page) && page_count(page)) + continue; + /* Check if it is ok to still hold the lock */ locked = compact_checklock_irqsave(>lru_lock, , locked, cc); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 8/10] xfstest: shared/004: Delayed allocation multi collapse
From: Namjae Jeon This testcase(004) tries to test various corner cases with delayed extents and pre-existing holes for fcollapse range functionality over different type of extents. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- tests/shared/004 | 65 ++ tests/shared/004.out | 53 tests/shared/group |1 + 3 files changed, 119 insertions(+) create mode 100755 tests/shared/004 create mode 100644 tests/shared/004.out diff --git a/tests/shared/004 b/tests/shared/004 new file mode 100755 index 000..5902b9f --- /dev/null +++ b/tests/shared/004 @@ -0,0 +1,65 @@ +#! /bin/bash +# FS QA Test No. 4 +# +# Delayed allocation multi collapse range tests +# This testcase is one of the 4 testcases (shared 001 - 004) which tries to +# test various corner cases for fcollapse range functionality over different +# type of extents. These tests are based on generic/255 test case. +# For the type of tests, check the description of _test_generic_punch +# in common/rc. +#--- +# Copyright (c) 2013 Samsung Electronics. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ +rm -f $tmp.* +} + +trap "_cleanup ; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +# we need to include common/punch to get defination fo filter functions +. ./common/rc +. ./common/filter +. ./common/punch + +# real QA test starts here +_supported_fs xfs ext4 +_supported_os Linux + +_require_xfs_io_falloc_punch +_require_xfs_io_falloc +_require_xfs_io_fiemap +_require_xfs_io_falloc_collapse + +testfile=$TEST_DIR/$seq.$$ + +_test_generic_punch -d -k falloc fpunch fcollapse fiemap _filter_hole_fiemap $testfile +_check_test_fs + +status=0 +exit diff --git a/tests/shared/004.out b/tests/shared/004.out new file mode 100644 index 000..a7d0f52 --- /dev/null +++ b/tests/shared/004.out @@ -0,0 +1,53 @@ +QA output created by 004 + 1. into a hole +f4f35d60b3cc18aaa6d8d92f0cd3708a + 2. into allocated space +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 + 3. into unwritten space +0: [0..95]: extent +f07217d5ac7ffa15dd8910c4aa912674 + 4. hole -> data +0: [0..63]: extent +1: [64..95]: hole +e5c94f6299822646f9f57aeacd8bdc01 + 5. hole -> unwritten +0: [0..63]: extent +1: [64..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 6. data -> hole +0: [0..31]: extent +1: [32..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 7. data -> unwritten +0: [0..63]: extent +1: [64..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 8. unwritten -> hole +0: [0..31]: extent +1: [32..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 9. unwritten -> data +0: [0..63]: extent +1: [64..95]: hole +e5c94f6299822646f9f57aeacd8bdc01 + 10. hole -> data -> hole +0: [0..31]: extent +1: [32..63]: hole +76cc863b386460b228a493933813a6a0 + 11. data -> hole -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 12. unwritten -> data -> unwritten +0: [0..63]: extent +76cc863b386460b228a493933813a6a0 + 13. data -> unwritten -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 14. data -> hole @ EOF +fallocate: Invalid argument +0: [0..159]: extent +7670f4830c6724a25e7c22d9eb9a6f4f + 15. data -> hole @ 0 +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 diff --git a/tests/shared/group b/tests/shared/group index 9226032..fb1d6d0 100644 --- a/tests/shared/group +++ b/tests/shared/group @@ -6,6 +6,7 @@ 001 auto prealloc 002 auto prealloc 003 auto prealloc +004 auto prealloc 032 mkfs auto quick 051 acl udf auto quick 218 auto fsr quick -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 7/10] xfstest: shared/003: Multi collapse range tests
From: Namjae Jeon This testcase(003) tries to test various corner cases with pre-existing holes for fcollapse range functionality over different type of extents. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- tests/shared/003 | 65 ++ tests/shared/003.out | 53 tests/shared/group |1 + 3 files changed, 119 insertions(+) create mode 100755 tests/shared/003 create mode 100644 tests/shared/003.out diff --git a/tests/shared/003 b/tests/shared/003 new file mode 100755 index 000..7b7f2df --- /dev/null +++ b/tests/shared/003 @@ -0,0 +1,65 @@ +#! /bin/bash +# FS QA Test No. 3 +# +# Multi collapse range tests +# This testcase is one of the 4 testcases (shared 001 - 004) which tries to +# test various corner cases for fcollapse range functionality over different +# type of extents. These tests are based on generic/255 test case. +# For the type of tests, check the description of _test_generic_punch +# in common/rc. +#--- +# Copyright (c) 2013 Samsung Electronics. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ +rm -f $tmp.* +} + +trap "_cleanup ; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +# we need to include common/punch to get defination fo filter functions +. ./common/rc +. ./common/filter +. ./common/punch + +# real QA test starts here +_supported_fs xfs ext4 +_supported_os Linux + +_require_xfs_io_falloc_punch +_require_xfs_io_falloc +_require_xfs_io_fiemap +_require_xfs_io_falloc_collapse + +testfile=$TEST_DIR/$seq.$$ + +_test_generic_punch -k falloc fpunch fcollapse fiemap _filter_hole_fiemap $testfile +_check_test_fs + +status=0 +exit diff --git a/tests/shared/003.out b/tests/shared/003.out new file mode 100644 index 000..545304e --- /dev/null +++ b/tests/shared/003.out @@ -0,0 +1,53 @@ +QA output created by 003 + 1. into a hole +f4f35d60b3cc18aaa6d8d92f0cd3708a + 2. into allocated space +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 + 3. into unwritten space +0: [0..95]: extent +f07217d5ac7ffa15dd8910c4aa912674 + 4. hole -> data +0: [0..63]: extent +1: [64..95]: hole +e5c94f6299822646f9f57aeacd8bdc01 + 5. hole -> unwritten +0: [0..63]: extent +1: [64..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 6. data -> hole +0: [0..31]: extent +1: [32..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 7. data -> unwritten +0: [0..63]: extent +1: [64..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 8. unwritten -> hole +0: [0..31]: extent +1: [32..95]: hole +f07217d5ac7ffa15dd8910c4aa912674 + 9. unwritten -> data +0: [0..63]: extent +1: [64..95]: hole +e5c94f6299822646f9f57aeacd8bdc01 + 10. hole -> data -> hole +0: [0..31]: extent +1: [32..63]: hole +76cc863b386460b228a493933813a6a0 + 11. data -> hole -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 12. unwritten -> data -> unwritten +0: [0..63]: extent +76cc863b386460b228a493933813a6a0 + 13. data -> unwritten -> data +0: [0..63]: extent +0f0151cbed83e4bf6e5bde26e82ab115 + 14. data -> hole @ EOF +fallocate: Invalid argument +0: [0..159]: extent +7670f4830c6724a25e7c22d9eb9a6f4f + 15. data -> hole @ 0 +0: [0..95]: extent +f1894a71ac539f6f90426d98a4990a47 diff --git a/tests/shared/group b/tests/shared/group index 7230b28..9226032 100644 --- a/tests/shared/group +++ b/tests/shared/group @@ -5,6 +5,7 @@ # 001 auto prealloc 002 auto prealloc +003 auto prealloc 032 mkfs auto quick 051 acl udf auto quick 218 auto fsr quick -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 4/10] xfsprog: xfsio: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate
From: Namjae Jeon Add support FALLOC_FL_COLLAPSE_RANGE for fallocate. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Reviewed-by: Dave Chinner --- io/prealloc.c | 41 +++-- man/man8/xfs_io.8 |6 ++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/io/prealloc.c b/io/prealloc.c index 8380646..d697f82 100644 --- a/io/prealloc.c +++ b/io/prealloc.c @@ -29,6 +29,10 @@ #define FALLOC_FL_PUNCH_HOLE 0x02 #endif +#ifndef FALLOC_FL_COLLAPSE_RANGE +#define FALLOC_FL_COLLAPSE_RANGE 0x08 +#endif + static cmdinfo_t allocsp_cmd; static cmdinfo_t freesp_cmd; static cmdinfo_t resvsp_cmd; @@ -37,6 +41,7 @@ static cmdinfo_t zero_cmd; #if defined(HAVE_FALLOCATE) static cmdinfo_t falloc_cmd; static cmdinfo_t fpunch_cmd; +static cmdinfo_t fcollapse_cmd; #endif static int @@ -159,8 +164,11 @@ fallocate_f( int mode = 0; int c; - while ((c = getopt(argc, argv, "kp")) != EOF) { + while ((c = getopt(argc, argv, "ckp")) != EOF) { switch (c) { + case 'c': + mode = FALLOC_FL_COLLAPSE_RANGE; + break; case 'k': mode = FALLOC_FL_KEEP_SIZE; break; @@ -203,6 +211,25 @@ fpunch_f( } return 0; } + +static int +fcollapse_f( + int argc, + char**argv) +{ + xfs_flock64_t segment; + int mode = FALLOC_FL_COLLAPSE_RANGE; + + if (!offset_length(argv[1], argv[2], )) + return 0; + + if (fallocate(file->fd, mode, + segment.l_start, segment.l_len)) { + perror("fallocate"); + return 0; + } + return 0; +} #endif /* HAVE_FALLOCATE */ void @@ -263,7 +290,7 @@ prealloc_init(void) falloc_cmd.argmin = 2; falloc_cmd.argmax = -1; falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - falloc_cmd.args = _("[-k] [-p] off len"); + falloc_cmd.args = _("[-c] [-k] [-p] off len"); falloc_cmd.oneline = _("allocates space associated with part of a file via fallocate"); add_command(_cmd); @@ -277,5 +304,15 @@ prealloc_init(void) fpunch_cmd.oneline = _("de-allocates space assocated with part of a file via fallocate"); add_command(_cmd); + + fcollapse_cmd.name = "fcollapse"; + fcollapse_cmd.cfunc = fcollapse_f; + fcollapse_cmd.argmin = 2; + fcollapse_cmd.argmax = 2; + fcollapse_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + fcollapse_cmd.args = _("off len"); + fcollapse_cmd.oneline = + _("de-allocates space and eliminates the hole by shifting extents"); + add_command(_cmd); #endif /* HAVE_FALLOCATE */ } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 767b50e..9543b20 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -380,6 +380,12 @@ will set the FALLOC_FL_KEEP_SIZE flag as described in .PD .RE .TP +.BI fcollapse " offset length" +Call fallocate with FALLOC_FL_COLLAPSE_RANGE flag as described in the +.BR fallocate (2) +manual page to de-allocates blocks and eliminates the hole created in this process +by shifting data blocks into the hole. +.TP .BI fpunch " offset length" Punches (de-allocates) blocks in the file by calling fallocate with the FALLOC_FL_PUNCH_HOLE flag as described in the -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 5/10] xfstest: shared/001: Standard collapse range tests
From: Namjae Jeon This testcase(001) tries to test various corner cases for fcollapse range functionality over different type of extents. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- common/punch | 133 -- common/rc| 14 ++ tests/shared/001 | 65 tests/shared/001.out | 53 tests/shared/group |1 + 5 files changed, 209 insertions(+), 57 deletions(-) create mode 100644 tests/shared/001 create mode 100644 tests/shared/001.out diff --git a/common/punch b/common/punch index a49638c..f401455 100644 --- a/common/punch +++ b/common/punch @@ -317,13 +317,23 @@ _test_generic_punch() map_cmd=$4 filter_cmd=$5 testfile=$6 + multiple=1 + + # + # If we are testing collapse range, we increare all the offsets of this + # test by a factor of 4. We do this because unlike punch, collapse + # range also decreases the size of file hence require bigger offsets. + # + if [ "$zero_cmd" == "fcollapse" ]; then + multiple=4 + fi echo " 1. into a hole" if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -332,9 +342,9 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "pwrite 0 20k" $sync_cmd \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "pwrite 0 $(($multiple * 20))k" $sync_cmd \ + -c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -344,9 +354,9 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "$alloc_cmd 0 20k" \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "$alloc_cmd 0 $(($multiple * 20))k" \ + -c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -356,9 +366,9 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "pwrite 8k 8k" $sync_cmd \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "pwrite $(($multiple * 8))k $(($multiple * 8))k" $sync_cmd \ + -c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -368,9 +378,9 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "$alloc_cmd 8k 8k" \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "$alloc_cmd $(($multiple * 8))k $(($multiple * 8))k" \ + -c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -380,9 +390,9 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "pwrite 0 8k" $sync_cmd \ - -c "$zero_cmd 4k 8k" \ + $XFS_IO_PROG -f -c "truncate $(($multiple * 20))k" \ + -c "pwrite 0 $(($multiple * 8))k" $sync_cmd \ +-c "$zero_cmd $(($multiple * 4))k $(($multiple * 8))k" \ -c "$map_cmd -v" $testfile | $filter_cmd [ $? -ne 0 ] && die_now _md5_checksum $testfile @@ -392,10 +402,10 @@ _test_generic_punch() if [ "$remove_testfile" ]; then rm -f $testfile fi - $XFS_IO_PROG -f -c "truncate 20k" \ - -c "pwrite 0 8k" $sync_cmd \ - -c "$alloc_cmd 8k 8k" \ -
[PATCH RESEND 2/10] xfs: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate
From: Namjae Jeon Add support FALLOC_FL_COLLAPSE_RANGE for fallocate. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- fs/xfs/xfs_bmap.c | 195 fs/xfs/xfs_bmap.h |5 ++ fs/xfs/xfs_bmap_util.c | 99 fs/xfs/xfs_bmap_util.h |2 + fs/xfs/xfs_file.c | 19 - fs/xfs/xfs_trace.h |1 + 6 files changed, 319 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 3ef11b2..aba3fc9 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -5358,3 +5358,198 @@ error0: } return error; } + +/* + * Shift extent records to the left to cover a hole. + * + * The maximum number of extents to be shifted in a single operation + * is @num_exts, and @current_ext keeps track of the current extent + * index we have shifted. @offset_shift_fsb is the length by which each + * extent is shifted. If there is no hole to shift the extents + * into, this will be considered invalid operation and we abort immediately. + */ +int +xfs_bmap_shift_extents( + struct xfs_trans*tp, + struct xfs_inode*ip, + int *done, + xfs_fileoff_t start_fsb, + xfs_fileoff_t offset_shift_fsb, + xfs_extnum_t*current_ext, + xfs_fsblock_t *firstblock, + struct xfs_bmap_free*flist, + int num_exts) +{ + struct xfs_btree_cur*cur; + struct xfs_bmbt_rec_host*gotp; + struct xfs_bmbt_irecgot; + struct xfs_bmbt_irecleft; + struct xfs_mount*mp = ip->i_mount; + struct xfs_ifork*ifp; + xfs_extnum_tnexts = 0; + xfs_fileoff_t startoff; + int error = 0; + int i; + int whichfork = XFS_DATA_FORK; + int logflags; + xfs_filblks_t blockcount = 0; + + if (unlikely(XFS_TEST_ERROR( + (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && +XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), +mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { + XFS_ERROR_REPORT("xfs_bmap_shift_extents", +XFS_ERRLEVEL_LOW, mp); + return XFS_ERROR(EFSCORRUPTED); + } + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + + ASSERT(current_ext != NULL); + + ifp = XFS_IFORK_PTR(ip, whichfork); + + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + /* Read in all the extents */ + error = xfs_iread_extents(tp, ip, whichfork); + if (error) + return error; + } + + /* +* If *current_ext is 0, we would need to lookup the extent +* from where we would start shifting and store it in gotp. +*/ + if (!*current_ext) { + gotp = xfs_iext_bno_to_ext(ifp, start_fsb, current_ext); + /* +* gotp can be null in 2 cases: 1) if there are no extents +* or 2) start_fsb lies in a hole beyond which there are +* no extents. Either way, we are done. +*/ + if (!gotp) { + *done = 1; + return 0; + } + } + + /* We are going to change core inode */ + logflags = XFS_ILOG_CORE; + + if (ifp->if_flags & XFS_IFBROOT) { + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); + cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.flist = flist; + cur->bc_private.b.flags = 0; + } else { + cur = NULL; + logflags |= XFS_ILOG_DEXT; + } + + while (nexts++ < num_exts && + *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) { + + gotp = xfs_iext_get_ext(ifp, *current_ext); + xfs_bmbt_get_all(gotp, ); + startoff = got.br_startoff - offset_shift_fsb; + + /* +* Before shifting extent into hole, make sure that the hole +* is large enough to accomodate the shift. +*/ + if (*current_ext) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, + *current_ext - 1), ); + + if (startoff < left.br_startoff + left.br_blockcount) + error = XFS_ERROR(EINVAL); + + } else if (startoff > xfs_bmbt_get_startoff(gotp)) { + /* Hole is at the start but not large enough */ + error =
[PATCH RESEND 3/10] ext4: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate
From: Namjae Jeon Add support FALLOC_FL_COLLAPSE_RANGE for fallocate Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- fs/ext4/ext4.h |3 + fs/ext4/extents.c | 297 ++- fs/ext4/move_extent.c |2 +- include/trace/events/ext4.h | 25 4 files changed, 325 insertions(+), 2 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e618503..5cc015a 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2745,6 +2745,7 @@ extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk); extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len); extern int ext4_ext_precache(struct inode *inode); +extern int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len); /* move_extent.c */ extern void ext4_double_down_write_data_sem(struct inode *first, @@ -2754,6 +2755,8 @@ extern void ext4_double_up_write_data_sem(struct inode *orig_inode, extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 start_orig, __u64 start_donor, __u64 len, __u64 *moved_len); +extern int mext_next_extent(struct inode *inode, struct ext4_ext_path *path, + struct ext4_extent **extent); /* page-io.c */ extern int __init ext4_init_pageio(void); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 267c9fb..12338c1 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4566,12 +4566,16 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) unsigned int credits, blkbits = inode->i_blkbits; /* Return error if mode is not supported */ - if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | +FALLOC_FL_COLLAPSE_RANGE)) return -EOPNOTSUPP; if (mode & FALLOC_FL_PUNCH_HOLE) return ext4_punch_hole(inode, offset, len); + if (mode & FALLOC_FL_COLLAPSE_RANGE) + return ext4_collapse_range(inode, offset, len); + ret = ext4_convert_inline_data(inode); if (ret) return ret; @@ -4870,3 +4874,294 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ext4_es_lru_add(inode); return error; } + +/* + * ext4_access_path: + * Function to access the path buffer for marking it dirty. + * It also checks if there are sufficient credits left in the journal handle + * to update path. + */ +static int +ext4_access_path(handle_t *handle, struct inode *inode, + struct ext4_ext_path *path) +{ + int credits, err; + + /* +* Check if need to extend journal credits +* 3 for leaf, sb, and inode plus 2 (bmap and group +* descriptor) for each block group; assume two block +* groups +*/ + if (handle->h_buffer_credits < 7) { + credits = ext4_writepage_trans_blocks(inode); + err = ext4_ext_truncate_extend_restart(handle, inode, credits); + /* EAGAIN is success */ + if (err && err != -EAGAIN) + return err; + } + + err = ext4_ext_get_access(handle, inode, path); + return err; +} + +/* + * ext4_ext_shift_path_extents: + * Shift the extents of a path structure lying between path[depth].p_ext + * and EXT_LAST_EXTENT(path[depth].p_hdr) downwards, by subtracting shift + * from starting block for each extent. + */ +static int +ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, + struct inode *inode, handle_t *handle, + ext4_lblk_t *start) +{ + int depth, err = 0; + struct ext4_extent *ex_start, *ex_last; + bool update = 0; + depth = path->p_depth; + + while (depth >= 0) { + if (depth == path->p_depth) { + ex_start = path[depth].p_ext; + if (!ex_start) + return -EIO; + + ex_last = EXT_LAST_EXTENT(path[depth].p_hdr); + if (!ex_last) + return -EIO; + + err = ext4_access_path(handle, inode, path + depth); + if (err) + goto out; + + if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) + update = 1; + + *start = ex_last->ee_block + + ext4_ext_get_actual_len(ex_last); + + while (ex_start <= ex_last) { + ex_start->ee_block -= shift; + if (ex_start > + EXT_FIRST_EXTENT(path[depth].p_hdr)) { +
[PATCH RESEND 1/10] fs: Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate
From: Namjae Jeon Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate. updated detailed semantics in comments. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan --- fs/open.c | 24 +--- include/uapi/linux/falloc.h | 21 + 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/fs/open.c b/fs/open.c index 4b3e1ed..4a923a5 100644 --- a/fs/open.c +++ b/fs/open.c @@ -231,7 +231,8 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) return -EINVAL; /* Return error if mode is not supported */ - if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | +FALLOC_FL_COLLAPSE_RANGE)) return -EOPNOTSUPP; /* Punch hole must have keep size set */ @@ -239,11 +240,20 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) !(mode & FALLOC_FL_KEEP_SIZE)) return -EOPNOTSUPP; + /* Collapse range should only be used exclusively. */ + if ((mode & FALLOC_FL_COLLAPSE_RANGE) && + (mode & ~FALLOC_FL_COLLAPSE_RANGE)) + return -EINVAL; + if (!(file->f_mode & FMODE_WRITE)) return -EBADF; - /* It's not possible punch hole on append only file */ - if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode)) + /* +* It's not possible to punch hole or perform collapse range +* on append only file +*/ + if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE) + && IS_APPEND(inode)) return -EPERM; if (IS_IMMUTABLE(inode)) @@ -271,6 +281,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG; + /* +* There is no need to overlap collapse range with EOF, in which case +* it is effectively a truncate operation +*/ + if ((mode & FALLOC_FL_COLLAPSE_RANGE) && + (offset + len >= i_size_read(inode))) + return -EINVAL; + if (!file->f_op->fallocate) return -EOPNOTSUPP; diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h index 990c4cc..5b214cc 100644 --- a/include/uapi/linux/falloc.h +++ b/include/uapi/linux/falloc.h @@ -5,5 +5,26 @@ #define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */ #define FALLOC_FL_NO_HIDE_STALE0x04 /* reserved codepoint */ +/* + * FALLOC_FL_COLLAPSE_RANGE is used to remove a range of a file + * without leaving a hole in the file. The contents of the file beyond + * the range being removed is appended to the start offset of the range + * being removed (i.e. the hole that was punched is "collapsed"), + * resulting in a file layout that looks like the range that was + * removed never existed. As such collapsing a range of a file changes + * the size of the file, reducing it by the same length of the range + * that has been removed by the operation. + * + * Different filesystems may implement different limitations on the + * granularity of the operation. Most will limit operations to + * filesystem block size boundaries, but this boundary may be larger or + * smaller depending on the filesystem and/or the configuration of the + * filesystem or file. + * + * Attempting to collapse a range that crosses the end of the file is + * considered an illegal operation - just use ftruncate(2) if you need + * to collapse a range that crosses EOF. + */ +#define FALLOC_FL_COLLAPSE_RANGE 0x08 #endif /* _UAPI_FALLOC_H_ */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RESEND 0/10] fs: Introduce new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate
From: Namjae Jeon This patch series is in response of the following post: http://lwn.net/Articles/556136/ "ext4: introduce two new ioctls" Dave chinner suggested that truncate_block_range (which was one of the ioctls name) should be an fallocate operation and not any fs specific ioctl, hence we add this functionality to fallocate. This patch series introduces new flag FALLOC_FL_COLLAPSE_RANGE for fallocate and implements it for XFS and Ext4. The semantics of this flag are following: 1) It collapses the range lying between offset and length by removing any data blocks which are present in this range and than updates all the logical offsets of extents beyond "offset + len" to nullify the hole created by removing blocks. In short, it does not leave a hole. 2) It should be used exclusively. No other fallocate flag in combination. 3) Offset and length supplied to fallocate should be fs block size aligned in case of xfs and ext4. 4) Collaspe range does not work beyond i_size. This new functionality of collapsing range could be used by media editing tools which does non linear editing to quickly purge and edit parts of a media file. This will immensely improve the performance of these operations. The limitation of fs block size aligned offsets can be easily handled by media codecs which are encapsulated in a conatiner as they have to just change the offset to next keyframe value to match the proper alignment. Change log v4: - vfs: Move block size aligned check from VFS layer to FS specific layer. - vfs: update comments for FALLOC_FL_COLLAPSE_RANGE in user visible header file. - xfs: update comments for xfs_bmap_shift_extents and change variable name to more reasonable name. - xfs: add ASSERTs for pointers in XFS patch. - xfs: drop all the xfs_bmbt_get*() wrappers. - xfs and ext4: change return errno from EFSCORRUPTED to EINVAL when hole is not large enough to shift. - xfs: remove extents from on-disk btree also in case of merge. - xfstest: separate shared/316 test to shared/001 ~ 004 in xfstest. - xfstest: update multi collapse test shared/005 for block size less than page size case. - manpage: update description. v3: Fix checkpatch.pl errors v2: Fix review points from Dave Chinner. Namjae Jeon (10): fs: Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate xfs: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate ext4: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate xfsprog: xfsio: Add support FALLOC_FL_COLLAPSE_RANGE for fallocate xfstest: shared/001: Standard collapse range tests xfstest: shared/002: Delayed allocation collapse range xfstest: shared/003: Multi collapse range tests xfstest: shared/004: Delayed allocation multi collapse xfstest: shared/005: Test multiple fallocate collapse manpage: update FALLOC_FL_COLLAPSE_RANGE flag in fallocate -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 04/11] HID: logitech-dj: remove hidinput_input_event
hid-logitech-dj uses its own ->hidinput_input_event() instead of the generic binding in hid-input. Moving the handling of LEDs towards logi_dj_output_hidraw_report() allows two things: - remove hidinput_input_event in struct hid_device - hidraw user space programs can also set the LEDs Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-logitech-dj.c | 99 +++ 1 file changed, 35 insertions(+), 64 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index f45279c..61d2bbf 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -44,14 +44,6 @@ static const char kbd_descriptor[] = { 0x19, 0xE0, /* USAGE_MINIMUM (Left Control) */ 0x29, 0xE7, /* USAGE_MAXIMUM (Right GUI) */ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ - 0x95, 0x05, /* REPORT COUNT (5) */ - 0x05, 0x08, /* USAGE PAGE (LED page) */ - 0x19, 0x01, /* USAGE MINIMUM (1) */ - 0x29, 0x05, /* USAGE MAXIMUM (5) */ - 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */ - 0x95, 0x01, /* REPORT COUNT (1) */ - 0x75, 0x03, /* REPORT SIZE (3)*/ - 0x91, 0x01, /* OUTPUT (Constant) */ 0x95, 0x06, /* REPORT_COUNT (6) */ 0x75, 0x08, /* REPORT_SIZE (8)*/ 0x15, 0x00, /* LOGICAL_MINIMUM (0)*/ @@ -60,6 +52,18 @@ static const char kbd_descriptor[] = { 0x19, 0x00, /* USAGE_MINIMUM (no event) */ 0x2A, 0xFF, 0x00, /* USAGE_MAXIMUM (reserved) */ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0x85, 0x0e, /* REPORT_ID (14) */ + 0x05, 0x08, /* USAGE PAGE (LED page) */ + 0x95, 0x05, /* REPORT COUNT (5) */ + 0x75, 0x01, /* REPORT SIZE (1)*/ + 0x15, 0x00, /* LOGICAL_MINIMUM (0)*/ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1)*/ + 0x19, 0x01, /* USAGE MINIMUM (1) */ + 0x29, 0x05, /* USAGE MAXIMUM (5) */ + 0x91, 0x02, /* OUTPUT (Data, Variable, Absolute) */ + 0x95, 0x01, /* REPORT COUNT (1) */ + 0x75, 0x03, /* REPORT SIZE (3)*/ + 0x91, 0x01, /* OUTPUT (Constant) */ 0xC0 }; @@ -544,10 +548,30 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, size_t count, unsigned char report_type) { - /* Called by hid raw to send data */ - dbg_hid("%s\n", __func__); + struct dj_device *djdev = hid->driver_data; + struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev; + u8 *out_buf; + int ret; - return 0; + if (buf[0] != REPORT_TYPE_LEDS) + return -EINVAL; + + out_buf = kzalloc(DJREPORT_SHORT_LENGTH, GFP_ATOMIC); + if (!out_buf) + return -ENOMEM; + + if (count < DJREPORT_SHORT_LENGTH - 2) + count = DJREPORT_SHORT_LENGTH - 2; + + out_buf[0] = REPORT_ID_DJ_SHORT; + out_buf[1] = djdev->device_index; + memcpy(out_buf + 2, buf, count); + + ret = djrcv_dev->hdev->hid_output_raw_report(djrcv_dev->hdev, out_buf, + DJREPORT_SHORT_LENGTH, report_type); + + kfree(out_buf); + return ret; } static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size) @@ -613,58 +637,6 @@ static int logi_dj_ll_parse(struct hid_device *hid) return retval; } -static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, - unsigned int code, int value) -{ - /* Sent by the input layer to handle leds and Force Feedback */ - struct hid_device *dj_hiddev = input_get_drvdata(dev); - struct dj_device *dj_dev = dj_hiddev->driver_data; - - struct dj_receiver_dev *djrcv_dev = - dev_get_drvdata(dj_hiddev->dev.parent); - struct hid_device *dj_rcv_hiddev = djrcv_dev->hdev; - struct hid_report_enum *output_report_enum; - - struct hid_field *field; - struct hid_report *report; - unsigned char *data; - int offset; - - dbg_hid("%s: %s, type:%d | code:%d | value:%d\n", - __func__, dev->phys, type, code, value); - - if (type != EV_LED) - return -1; - - offset = hidinput_find_field(dj_hiddev, type, code, ); - - if (offset == -1) { - dev_warn(>dev, "event field
[PATCH 02/11] HID: i2c-hid: implement ll_driver transport-layer callbacks
Add output_report and raw_request to i2c-hid. Hopefully, we will manage to have the same transport level between all the transport drivers. Signed-off-by: Benjamin Tissoires --- drivers/hid/i2c-hid/i2c-hid.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index ce68a12..5099f1f 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -574,6 +574,28 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, return ret; } +static int i2c_hid_output_report(struct hid_device *hid, __u8 *buf, + size_t count) +{ + return i2c_hid_output_raw_report(hid, buf, count, HID_OUTPUT_REPORT); +} + +static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum, + __u8 *buf, size_t len, unsigned char rtype, + int reqtype) +{ + switch (reqtype) { + case HID_REQ_GET_REPORT: + return i2c_hid_get_raw_report(hid, reportnum, buf, len, rtype); + case HID_REQ_SET_REPORT: + if (buf[0] != reportnum) + return -EINVAL; + return i2c_hid_output_raw_report(hid, buf, len, rtype); + default: + return -EIO; + } +} + static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype) { @@ -761,6 +783,8 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .close = i2c_hid_close, .power = i2c_hid_power, .request = i2c_hid_request, + .output_report = i2c_hid_output_report, + .raw_request = i2c_hid_raw_request, }; static int i2c_hid_init_irq(struct i2c_client *client) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/11] HID: add inliners for ll_driver transport-layer callbacks
Those callbacks are not mandatory, so it's better to add inliners to use them safely. Signed-off-by: Benjamin Tissoires --- include/linux/hid.h | 45 + 1 file changed, 45 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index 003cc8e..dddcad0 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -680,6 +680,8 @@ struct hid_driver { *shouldn't allocate anything to not leak memory * @request: send report request to device (e.g. feature report) * @wait: wait for buffered io to complete (send/recv reports) + * @raw_request: send raw report request to device (e.g. feature report) + * @output_report: send output report to device * @idle: send idle request to device */ struct hid_ll_driver { @@ -974,6 +976,49 @@ static inline void hid_hw_request(struct hid_device *hdev, } /** + * hid_hw_raw_request - send report request to device + * + * @hdev: hid device + * @reportnum: report ID + * @buf: in/out data to transfer + * @len: length of buf + * @rtype: HID report type + * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT + * + * @return: count of data transfered, negative if error + * + * Same behavior as hid_hw_request, but with raw buffers instead. + */ +static inline int hid_hw_raw_request(struct hid_device *hdev, + unsigned char reportnum, __u8 *buf, + size_t len, unsigned char rtype, int reqtype) +{ + if (hdev->ll_driver->raw_request) + return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, + rtype, reqtype); + + return -ENOSYS; +} + +/** + * hid_hw_output_report - send output report to device + * + * @hdev: hid device + * @buf: raw data to transfer + * @len: length of buf + * + * @return: count of data transfered, negative if error + */ +static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, + size_t len) +{ + if (hdev->ll_driver->output_report) + return hdev->ll_driver->output_report(hdev, buf, len); + + return -ENOSYS; +} + +/** * hid_hw_idle - send idle request to device * * @hdev: hid device -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/11] HID: HIDp: remove duplicated coded
- Move hidp_output_report() above - Removed duplicated code in hidp_output_raw_report() Signed-off-by: Benjamin Tissoires --- net/bluetooth/hidp/core.c | 68 --- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 469e61b..02670b3 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -373,62 +373,25 @@ err: return ret; } -static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, - unsigned char report_type) +static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count) { struct hidp_session *session = hid->driver_data; - int ret; + return hidp_send_intr_message(session, + HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT, + data, count); +} + +static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, + size_t count, unsigned char report_type) +{ if (report_type == HID_OUTPUT_REPORT) { - report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; - return hidp_send_intr_message(session, report_type, - data, count); + return hidp_output_report(hid, data, count); } else if (report_type != HID_FEATURE_REPORT) { return -EINVAL; } - if (mutex_lock_interruptible(>report_mutex)) - return -ERESTARTSYS; - - /* Set up our wait, and send the report request to the device. */ - set_bit(HIDP_WAITING_FOR_SEND_ACK, >flags); - report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; - ret = hidp_send_ctrl_message(session, report_type, data, count); - if (ret) - goto err; - - /* Wait for the ACK from the device. */ - while (test_bit(HIDP_WAITING_FOR_SEND_ACK, >flags) && - !atomic_read(>terminate)) { - int res; - - res = wait_event_interruptible_timeout(session->report_queue, - !test_bit(HIDP_WAITING_FOR_SEND_ACK, >flags) - || atomic_read(>terminate), - 10*HZ); - if (res == 0) { - /* timeout */ - ret = -EIO; - goto err; - } - if (res < 0) { - /* signal */ - ret = -ERESTARTSYS; - goto err; - } - } - - if (!session->output_report_success) { - ret = -EIO; - goto err; - } - - ret = count; - -err: - clear_bit(HIDP_WAITING_FOR_SEND_ACK, >flags); - mutex_unlock(>report_mutex); - return ret; + return hidp_set_raw_report(hid, data[0], data, count, report_type); } static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum, @@ -445,15 +408,6 @@ static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum, } } -static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count) -{ - struct hidp_session *session = hid->driver_data; - - return hidp_send_intr_message(session, - HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT, - data, count); -} - static void hidp_idle_timeout(unsigned long arg) { struct hidp_session *session = (struct hidp_session *) arg; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 00/11] HID: spring cleaning
Hi guys, This is an attempt to complete the branch for-3.15/ll-driver-new-callbacks: - try to implement as much as possible ll_driver callbacks (some are still missing, but I did not had the time to complete it) - add inliners hid_hw_* for all the ll_driver callbacks - remove transport dependant callbacks in struct hid_device - remove the so called "obsolete" hidinput_input_event handler which was used in 2/4 transport drivers Bonus point: 14 files changed, 213 insertions(+), 272 deletions(-) Yay! I made sure I kept the PS3 controller working and the LEDs (on logitech-dj and on bluetooth keyboard) working. The rest do not mostly need further testing, the code path did not changed. But still, a review (and some tests) would be a good idea :) Cheers, Benjamin PS: obviously, this goes on top on the branch for-3.15/ll-driver-new-callbacks Benjamin Tissoires (11): HID: uHID: implement .raw_request HID: i2c-hid: implement ll_driver transport-layer callbacks HID: add inliners for ll_driver transport-layer callbacks HID: logitech-dj: remove hidinput_input_event HID: HIDp: remove hidp_hidinput_event HID: remove hidinput_input_event handler HID: HIDp: remove duplicated coded HID: usbhid: remove duplicated code HID: remove hid_get_raw_report in struct hid_device HID: introduce helper to access hid_output_raw_report() HID: move hid_output_raw_report to hid_ll_driver drivers/hid/hid-input.c| 12 ++--- drivers/hid/hid-lg.c | 6 ++- drivers/hid/hid-logitech-dj.c | 101 +- drivers/hid/hid-magicmouse.c | 2 +- drivers/hid/hid-sony.c | 19 +-- drivers/hid/hid-thingm.c | 4 +- drivers/hid/hid-wacom.c| 16 +++--- drivers/hid/hid-wiimote-core.c | 4 +- drivers/hid/hidraw.c | 11 ++-- drivers/hid/i2c-hid/i2c-hid.c | 27 +- drivers/hid/uhid.c | 20 ++- drivers/hid/usbhid/hid-core.c | 67 +-- include/linux/hid.h| 77 ++ net/bluetooth/hidp/core.c | 119 + 14 files changed, 213 insertions(+), 272 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/11] HID: HIDp: remove hidp_hidinput_event
hidp uses its own ->hidinput_input_event() instead of the generic binding in hid-input. Moving the handling of LEDs towards hidp_hidinput_event() allows two things: - remove hidinput_input_event definitively from struct hid_device - hidraw user space programs can also set the LEDs Signed-off-by: Benjamin Tissoires --- net/bluetooth/hidp/core.c | 46 -- 1 file changed, 46 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index b062cee..469e61b 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -223,51 +223,6 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) input_sync(dev); } -static int hidp_send_report(struct hidp_session *session, struct hid_report *report) -{ - unsigned char hdr; - u8 *buf; - int rsize, ret; - - buf = hid_alloc_report_buf(report, GFP_ATOMIC); - if (!buf) - return -EIO; - - hid_output_report(report, buf); - hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; - - rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); - ret = hidp_send_intr_message(session, hdr, buf, rsize); - - kfree(buf); - return ret; -} - -static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, - unsigned int code, int value) -{ - struct hid_device *hid = input_get_drvdata(dev); - struct hidp_session *session = hid->driver_data; - struct hid_field *field; - int offset; - - BT_DBG("session %p type %d code %d value %d", - session, type, code, value); - - if (type != EV_LED) - return -1; - - offset = hidinput_find_field(hid, type, code, ); - if (offset == -1) { - hid_warn(dev, "event field not found\n"); - return -1; - } - - hid_set_field(field, offset, value); - - return hidp_send_report(session, field->report); -} - static int hidp_get_raw_report(struct hid_device *hid, unsigned char report_number, unsigned char *data, size_t count, @@ -817,7 +772,6 @@ static struct hid_ll_driver hidp_hid_driver = { .close = hidp_close, .raw_request = hidp_raw_request, .output_report = hidp_output_report, - .hidinput_input_event = hidp_hidinput_event, }; /* This function sets up the hid device. It does not add it -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 09/11] HID: remove hid_get_raw_report in struct hid_device
dev->hid_get_raw_report(X) and hid_hw_raw_request(X, HID_REQ_GET_REPORT) are strictly equivalent. Switch the hid subsystem to the hid_hw notation and remove the field .hid_get_raw_report in struct hid_device. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-input.c | 6 +++--- drivers/hid/hid-sony.c| 3 ++- drivers/hid/hidraw.c | 7 --- drivers/hid/i2c-hid/i2c-hid.c | 1 - drivers/hid/uhid.c| 1 - drivers/hid/usbhid/hid-core.c | 1 - include/linux/hid.h | 3 --- net/bluetooth/hidp/core.c | 1 - 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 594722d..1de5997 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -350,9 +350,9 @@ static int hidinput_get_battery_property(struct power_supply *psy, ret = -ENOMEM; break; } - ret = dev->hid_get_raw_report(dev, dev->battery_report_id, - buf, 2, - dev->battery_report_type); + ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2, +dev->battery_report_type, +HID_REQ_GET_REPORT); if (ret != 2) { ret = -ENODATA; diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 1235405..3930acb 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -706,7 +706,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) if (!buf) return -ENOMEM; - ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT); + ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, +HID_REQ_GET_REPORT); if (ret < 0) hid_err(hdev, "can't set operational mode\n"); diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index cb0137b..4b2dc95 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -189,7 +189,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t dev = hidraw_table[minor]->hid; - if (!dev->hid_get_raw_report) { + if (!dev->ll_driver->raw_request) { ret = -ENODEV; goto out; } @@ -216,14 +216,15 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t /* * Read the first byte from the user. This is the report number, -* which is passed to dev->hid_get_raw_report(). +* which is passed to hid_hw_raw_request(). */ if (copy_from_user(_number, buffer, 1)) { ret = -EFAULT; goto out_free; } - ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type); + ret = hid_hw_raw_request(dev, report_number, buf, count, report_type, +HID_REQ_GET_REPORT); if (ret < 0) goto out_free; diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 5099f1f..fe3b392 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1029,7 +1029,6 @@ static int i2c_hid_probe(struct i2c_client *client, hid->driver_data = client; hid->ll_driver = _hid_ll_driver; - hid->hid_get_raw_report = i2c_hid_get_raw_report; hid->hid_output_raw_report = i2c_hid_output_raw_report; hid->dev.parent = >dev; ACPI_COMPANION_SET(>dev, ACPI_COMPANION(>dev)); diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 438c9f1..7358346 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -421,7 +421,6 @@ static int uhid_dev_create(struct uhid_device *uhid, hid->uniq[63] = 0; hid->ll_driver = _hid_driver; - hid->hid_get_raw_report = uhid_hid_get_raw; hid->hid_output_raw_report = uhid_hid_output_raw; hid->bus = ev->u.create.bus; hid->vendor = ev->u.create.vendor; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 406497b..b9a770f 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1289,7 +1289,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * usb_set_intfdata(intf, hid); hid->ll_driver = _hid_driver; - hid->hid_get_raw_report = usbhid_get_raw_report; hid->hid_output_raw_report = usbhid_output_raw_report; hid->ff_init = hid_pidff_init; #ifdef CONFIG_USB_HIDDEV diff --git a/include/linux/hid.h b/include/linux/hid.h index 38c307b..c56681a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -508,9 +508,6 @@ struct hid_device { /* device report descriptor */ struct
[PATCH 06/11] HID: remove hidinput_input_event handler
All the different transport drivers use now the generic event handling in hid-input. We can remove the handler definitively now. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-input.c | 4 +--- include/linux/hid.h | 4 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a713e62..594722d 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1263,9 +1263,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) } input_set_drvdata(input_dev, hid); - if (hid->ll_driver->hidinput_input_event) - input_dev->event = hid->ll_driver->hidinput_input_event; - else if (hid->ll_driver->request || hid->hid_output_raw_report) + if (hid->ll_driver->request || hid->hid_output_raw_report) input_dev->event = hidinput_input_event; input_dev->open = hidinput_open; input_dev->close = hidinput_close; diff --git a/include/linux/hid.h b/include/linux/hid.h index dddcad0..38c307b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -675,7 +675,6 @@ struct hid_driver { * @stop: called on remove * @open: called by input layer on open * @close: called by input layer on close - * @hidinput_input_event: event input event (e.g. ff or leds) * @parse: this method is called only once to parse the device data, *shouldn't allocate anything to not leak memory * @request: send report request to device (e.g. feature report) @@ -693,9 +692,6 @@ struct hid_ll_driver { int (*power)(struct hid_device *hdev, int level); - int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, - unsigned int code, int value); - int (*parse)(struct hid_device *hdev); void (*request)(struct hid_device *hdev, -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 08/11] HID: usbhid: remove duplicated code
Well, no use to keep twice the same code. Signed-off-by: Benjamin Tissoires --- drivers/hid/usbhid/hid-core.c | 64 --- 1 file changed, 11 insertions(+), 53 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index f8ca312..406497b 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -915,59 +915,6 @@ static int usbhid_set_raw_report(struct hid_device *hid, unsigned int reportnum, return ret; } - -static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, - unsigned char report_type) -{ - struct usbhid_device *usbhid = hid->driver_data; - struct usb_device *dev = hid_to_usb_dev(hid); - struct usb_interface *intf = usbhid->intf; - struct usb_host_interface *interface = intf->cur_altsetting; - int ret; - - if (usbhid->urbout && report_type != HID_FEATURE_REPORT) { - int actual_length; - int skipped_report_id = 0; - - if (buf[0] == 0x0) { - /* Don't send the Report ID */ - buf++; - count--; - skipped_report_id = 1; - } - ret = usb_interrupt_msg(dev, usbhid->urbout->pipe, - buf, count, _length, - USB_CTRL_SET_TIMEOUT); - /* return the number of bytes transferred */ - if (ret == 0) { - ret = actual_length; - /* count also the report id */ - if (skipped_report_id) - ret++; - } - } else { - int skipped_report_id = 0; - int report_id = buf[0]; - if (buf[0] == 0x0) { - /* Don't send the Report ID */ - buf++; - count--; - skipped_report_id = 1; - } - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - HID_REQ_SET_REPORT, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ((report_type + 1) << 8) | report_id, - interface->desc.bInterfaceNumber, buf, count, - USB_CTRL_SET_TIMEOUT); - /* count also the report id, if this was a numbered report. */ - if (ret > 0 && skipped_report_id) - ret++; - } - - return ret; -} - static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) { struct usbhid_device *usbhid = hid->driver_data; @@ -998,6 +945,17 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) return ret; } +static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, + size_t count, unsigned char report_type) +{ + struct usbhid_device *usbhid = hid->driver_data; + + if (usbhid->urbout && report_type != HID_FEATURE_REPORT) + return usbhid_output_report(hid, buf, count); + + return usbhid_set_raw_report(hid, buf[0], buf, count, report_type); +} + static void usbhid_restart_queues(struct usbhid_device *usbhid) { if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, >iofl)) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 11/11] HID: move hid_output_raw_report to hid_ll_driver
struct hid_ll_driver is responsible for the transport communication. Move hid_output_raw_report from hid_device to the transport layer then. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-input.c| 2 +- drivers/hid/hid-logitech-dj.c | 2 +- drivers/hid/hid-sony.c | 11 ++- drivers/hid/hid-wiimote-core.c | 2 +- drivers/hid/hidraw.c | 2 +- drivers/hid/i2c-hid/i2c-hid.c | 2 +- drivers/hid/uhid.c | 2 +- drivers/hid/usbhid/hid-core.c | 2 +- include/linux/hid.h| 11 +++ net/bluetooth/hidp/core.c | 4 ++-- 10 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 78293c3..3125155 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1263,7 +1263,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) } input_set_drvdata(input_dev, hid); - if (hid->ll_driver->request || hid->hid_output_raw_report) + if (hid->ll_driver->request || hid->ll_driver->hid_output_raw_report) input_dev->event = hidinput_input_event; input_dev->open = hidinput_open; input_dev->close = hidinput_close; diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9347625..bdfa1db 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -262,7 +262,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, } dj_hiddev->ll_driver = _dj_ll_driver; - dj_hiddev->hid_output_raw_report = logi_dj_output_hidraw_report; dj_hiddev->dev.parent = _hdev->dev; dj_hiddev->bus = BUS_USB; @@ -655,6 +654,7 @@ static struct hid_ll_driver logi_dj_ll_driver = { .stop = logi_dj_ll_stop, .open = logi_dj_ll_open, .close = logi_dj_ll_close, + .hid_output_raw_report = logi_dj_output_hidraw_report, }; diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 8494b8c..9dd37ff 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -494,6 +494,8 @@ struct sony_sc { unsigned long quirks; struct work_struct state_worker; + struct hid_ll_driver *ll_driver; + #ifdef CONFIG_SONY_FF __u8 left; __u8 right; @@ -1077,7 +1079,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) } if (sc->quirks & SIXAXIS_CONTROLLER_USB) { - hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; + sc->ll_driver = devm_kzalloc(>dev, sizeof(*sc->ll_driver), +GFP_KERNEL); + if (sc->ll_driver == NULL) + return -ENOMEM; + *sc->ll_driver = *hdev->ll_driver; + hdev->ll_driver = sc->ll_driver; + sc->ll_driver->hid_output_raw_report = + sixaxis_usb_output_raw_report; ret = sixaxis_set_operational_usb(hdev); INIT_WORK(>state_worker, sixaxis_state_worker); } diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index d7dc6c5b..715a3ab 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -28,7 +28,7 @@ static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, __u8 *buf; int ret; - if (!hdev->hid_output_raw_report) + if (!hdev->ll_driver->hid_output_raw_report) return -ENODEV; buf = kmemdup(buffer, count, GFP_KERNEL); diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index f8708c9..c60c530 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -123,7 +123,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, dev = hidraw_table[minor]->hid; - if (!dev->hid_output_raw_report) { + if (!dev->ll_driver->hid_output_raw_report) { ret = -ENODEV; goto out; } diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index fe3b392..fabb388 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -785,6 +785,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .request = i2c_hid_request, .output_report = i2c_hid_output_report, .raw_request = i2c_hid_raw_request, + .hid_output_raw_report = i2c_hid_output_raw_report, }; static int i2c_hid_init_irq(struct i2c_client *client) @@ -1029,7 +1030,6 @@ static int i2c_hid_probe(struct i2c_client *client, hid->driver_data = client; hid->ll_driver = _hid_ll_driver; - hid->hid_output_raw_report = i2c_hid_output_raw_report; hid->dev.parent = >dev; ACPI_COMPANION_SET(>dev, ACPI_COMPANION(>dev)); hid->bus = BUS_I2C; diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 7358346..8e99a5a
[PATCH 10/11] HID: introduce helper to access hid_output_raw_report()
Add a helper to access hdev->hid_output_raw_report(). To convert the drivers, use the following snippets: for i in drivers/hid/*.c do sed -i.bak "s/[^ \t]*->hid_output_raw_report(/hid_output_raw_report(/g" $i done Then manually fix for checkpatch.pl Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-input.c| 2 +- drivers/hid/hid-lg.c | 6 -- drivers/hid/hid-logitech-dj.c | 2 +- drivers/hid/hid-magicmouse.c | 2 +- drivers/hid/hid-sony.c | 5 +++-- drivers/hid/hid-thingm.c | 4 ++-- drivers/hid/hid-wacom.c| 16 +++- drivers/hid/hid-wiimote-core.c | 2 +- drivers/hid/hidraw.c | 2 +- include/linux/hid.h| 16 10 files changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 1de5997..78293c3 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1184,7 +1184,7 @@ static void hidinput_led_worker(struct work_struct *work) hid_output_report(report, buf); /* synchronous output report */ - hid->hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT); + hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT); kfree(buf); } diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 9fe9d4a..76ed7e5 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -692,7 +692,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); + ret = hid_output_raw_report(hdev, buf, sizeof(buf), + HID_FEATURE_REPORT); if (ret >= 0) { /* insert a little delay of 10 jiffies ~ 40ms */ @@ -704,7 +705,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) buf[1] = 0xB2; get_random_bytes([2], 2); - ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); + ret = hid_output_raw_report(hdev, buf, sizeof(buf), + HID_FEATURE_REPORT); } } diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 61d2bbf..9347625 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -567,7 +567,7 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, out_buf[1] = djdev->device_index; memcpy(out_buf + 2, buf, count); - ret = djrcv_dev->hdev->hid_output_raw_report(djrcv_dev->hdev, out_buf, + ret = hid_output_raw_report(djrcv_dev->hdev, out_buf, DJREPORT_SHORT_LENGTH, report_type); kfree(out_buf); diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 3b43d1c..cb5db3a 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -538,7 +538,7 @@ static int magicmouse_probe(struct hid_device *hdev, * but there seems to be no other way of switching the mode. * Thus the super-ugly hacky success check below. */ - ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), + ret = hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); if (ret != -EIO && ret != sizeof(feature)) { hid_err(hdev, "unable to request touch data (%d)\n", ret); diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 3930acb..8494b8c 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -720,7 +720,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) static int sixaxis_set_operational_bt(struct hid_device *hdev) { unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; - return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); + return hid_output_raw_report(hdev, buf, sizeof(buf), +HID_FEATURE_REPORT); } static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) @@ -942,7 +943,7 @@ static void sixaxis_state_worker(struct work_struct *work) buf[10] |= sc->led_state[2] << 3; buf[10] |= sc->led_state[3] << 4; - sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf), + hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT); } diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 99342cf..7dd3197 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -48,8 +48,8 @@ static int blink1_send_command(struct blink1_data *data,
[PATCH 01/11] HID: uHID: implement .raw_request
It was missing, so adding it. Signed-off-by: Benjamin Tissoires --- drivers/hid/uhid.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index f5a2b19..438c9f1 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -270,6 +270,22 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, return count; } +static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum, + __u8 *buf, size_t len, unsigned char rtype, + int reqtype) +{ + switch (reqtype) { + case HID_REQ_GET_REPORT: + return uhid_hid_get_raw(hid, reportnum, buf, len, rtype); + case HID_REQ_SET_REPORT: + if (buf[0] != reportnum) + return -EINVAL; + return uhid_hid_output_raw(hid, buf, len, rtype); + default: + return -EIO; + } +} + static struct hid_ll_driver uhid_hid_driver = { .start = uhid_hid_start, .stop = uhid_hid_stop, @@ -277,6 +293,7 @@ static struct hid_ll_driver uhid_hid_driver = { .close = uhid_hid_close, .parse = uhid_hid_parse, .output_report = uhid_hid_output_report, + .raw_request = uhid_raw_request, }; #ifdef CONFIG_COMPAT -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] HID: fix buffer allocations
When using hid_output_report(), the buffer should be allocated by hid_alloc_report_buf(), not a custom malloc. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-input.c | 2 +- drivers/hid/i2c-hid/i2c-hid.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d50e731..a713e62 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1178,7 +1178,7 @@ static void hidinput_led_worker(struct work_struct *work) /* fall back to generic raw-output-report */ len = ((report->size - 1) >> 3) + 1 + (report->id > 0); - buf = kmalloc(len, GFP_KERNEL); + buf = hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) return; diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index e914f27..ce68a12 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -582,7 +582,7 @@ static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, int ret; int len = i2c_hid_get_report_length(rep) - 2; - buf = kzalloc(len, GFP_KERNEL); + buf = hid_alloc_report_buf(rep, GFP_KERNEL); if (!buf) return; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] irq_work: allow certain work in hard irq context
On Fri, 2014-01-31 at 15:34 +0100, Sebastian Andrzej Siewior wrote: > irq_work is processed in softirq context on -RT because we want to avoid > long latencies which might arise from processing lots of perf events. > The noHZ-full mode requires its callback to be called from real hardirq > context (commit 76c24fb ("nohz: New APIs to re-evaluate the tick on full > dynticks CPUs")). If it is called from a thread context we might get > wrong results for checks like "is_idle_task(current)". > This patch introduces a second list (hirq_work_list) which will be used > if irq_work_run() has been invoked from hardirq context and process only > work items marked with IRQ_WORK_HARD_IRQ. This patch (w. too noisy to live pr_err whacked) reliable kills my 64 core test box, but only in _virgin_ 3.12-rt11. Add my local patches, and it runs and runs, happy as a clam. Odd. But whatever, box with virgin source running says it's busted. Killing what was killable in this run before box had a chance to turn into a brick, the two tasks below were left, burning 100% CPU until 5 minute RCU deadline expired. All other cores were idle. [ 705.465667] INFO: rcu_preempt detected stalls on CPUs/tasks: [ 705.465674] 5: (714 GPs behind) idle=b03/1/0 softirq=1/1 [ 705.465681] (detected by 0, t=32 jiffies, g=14203, c=14202, q=0) [ 705.465681] sending NMI to all CPUs: [ 705.465685] NMI backtrace for cpu 0 [ 705.465688] CPU: 0 PID: 0 Comm: swapper/0 Tainted: GF3.12.9-rt11 #376 [ 705.465689] Hardware name: Hewlett-Packard ProLiant DL980 G7, BIOS P66 07/07/2010 [ 705.465691] task: 81a14460 ti: 81a0 task.ti: 81a0 [ 705.465701] RIP: 0010:[] [] native_write_msr_safe+0xa/0x10 [ 705.465702] RSP: :880276e03c48 EFLAGS: 0046 [ 705.465703] RAX: 0400 RBX: b084 RCX: 0830 [ 705.465704] RDX: 0002 RSI: 0400 RDI: 0830 [ 705.465705] RBP: 880276e03c48 R08: 0100 R09: 81ab74a0 [ 705.465705] R10: 0502 R11: 0028 R12: 81ab74a0 [ 705.465706] R13: 0008 R14: 0002 R15: 0002 [ 705.465708] FS: () GS:880276e0() knlGS: [ 705.465709] CS: 0010 DS: ES: CR0: 8005003b [ 705.465710] CR2: 7ff8086cbed0 CR3: 00026347c000 CR4: 07f0 [ 705.465710] Stack: [ 705.465712] 880276e03cb8 8103aab9 0001 0001 [ 705.465714] 880276e03cc8 815d1810 0092 [ 705.465715] 880276e03c98 81a42e00 81ab7480 [ 705.465716] Call Trace: [ 705.465718] [ 705.465722] [] __x2apic_send_IPI_mask+0xa9/0xe0 [ 705.465727] [] ? printk+0x54/0x78 [ 705.465729] [] x2apic_send_IPI_all+0x19/0x20 [ 705.465731] [] arch_trigger_all_cpu_backtrace+0x73/0xb0 [ 705.465734] [] print_other_cpu_stall+0x259/0x360 [ 705.465739] [] ? native_sched_clock+0x20/0xa0 [ 705.465740] [] __rcu_pending+0x88/0x1f0 [ 705.465742] [] rcu_check_callbacks+0x1f5/0x300 [ 705.465745] [] update_process_times+0x46/0x80 [ 705.465749] [] tick_sched_handle+0x32/0x70 [ 705.465751] [] tick_sched_timer+0x40/0x70 [ 705.465755] [] __run_hrtimer+0x14d/0x280 [ 705.465757] [] ? tick_nohz_handler+0xa0/0xa0 [ 705.465758] [] hrtimer_interrupt+0x12a/0x310 [ 705.465762] [] ? __atomic_notifier_call_chain+0x4f/0x70 [ 705.465764] [] local_apic_timer_interrupt+0x36/0x60 [ 705.465766] [] smp_apic_timer_interrupt+0x3e/0x60 [ 705.465768] [] apic_timer_interrupt+0x6d/0x80 [ 705.465770] [ 705.465771] [] ? native_safe_halt+0x6/0x10 [ 705.465774] [] default_idle+0x83/0x120 [ 705.465776] [] arch_cpu_idle+0x26/0x30 [ 705.465778] [] cpu_idle_loop+0x28d/0x2e0 [ 705.465779] [] cpu_startup_entry+0x4c/0x50 [ 705.465781] [] rest_init+0x83/0x90 [ 705.465785] [] start_kernel+0x3fc/0x4a3 [ 705.465787] [] ? repair_env_string+0x58/0x58 [ 705.465789] [] x86_64_start_reservations+0x1b/0x32 [ 705.465791] [] x86_64_start_kernel+0x16f/0x17e [ 705.465792] [] ? early_idt_handlers+0x120/0x120 [ 705.465805] Code: 00 55 89 f9 48 89 e5 0f 32 31 c9 89 c7 48 89 d0 89 0e 48 c1 e0 20 89 fa 48 09 d0 c9 c3 0f 1f 40 00 55 89 f9 89 f0 48 89 e5 0f 30 <31> c0 c9 c3 66 90 55 89 f9 48 89 e5 0f 33 89 c1 48 89 d0 48 c1 [ 705.466006] NMI backtrace for cpu 5 [ 705.466009] CPU: 5 PID: 21792 Comm: cc1 Tainted: GF3.12.9-rt11 #376 [ 705.466010] Hardware name: Hewlett-Packard ProLiant DL980 G7, BIOS P66 07/07/2010 [ 705.466011] task: 88026e9ebdb0 ti: 880037b62000 task.ti: 880037b62000 [ 705.466015] RIP: 0010:[] [] _raw_spin_unlock_irq+0x40/0x40 [ 705.466016] RSP: :880276ea3d00 EFLAGS: 0002 [ 705.466017] RAX: 880276eadcc0 RBX: RCX: 0086 [ 705.466018] RDX: 0002 RSI: 0086 RDI: 880276eadc40 [
[RFC PATCHv2] usb: move hub init and LED blink work to power efficient workqueue
From: Shaibal Dutta Allow the scheduler to select the best CPU to handle hub initalization and LED blinking work. This extends idle residency times on idle CPUs and conserves power. This functionality is enabled when CONFIG_WQ_POWER_EFFICIENT is selected. Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Sarah Sharp Cc: Xenia Ragiadakou Cc: Julius Werner Cc: Krzysztof Mazur Cc: Matthias Beyer Cc: Dan Williams Cc: Mathias Nyman Cc: Thomas Pugliese Signed-off-by: Shaibal Dutta [zoran.marko...@linaro.org: Rebased to latest kernel. Added commit message. Changed reference from system to power efficient workqueue for LEDs in check_highspeed() and hub_port_connect_change().] Signed-off-by: Zoran Markovic --- drivers/usb/core/hub.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index babba88..e11a7e9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -504,7 +504,8 @@ static void led_work (struct work_struct *work) changed++; } if (changed) - schedule_delayed_work(>leds, LED_CYCLE_PERIOD); + queue_delayed_work(system_power_efficient_wq, + >leds, LED_CYCLE_PERIOD); } /* use a short timeout for hub/port status fetches */ @@ -1046,7 +1047,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) if (type == HUB_INIT) { delay = hub_power_on(hub, false); PREPARE_DELAYED_WORK(>init_work, hub_init_func2); - schedule_delayed_work(>init_work, + queue_delayed_work(system_power_efficient_wq, + >init_work, msecs_to_jiffies(delay)); /* Suppress autosuspend until init is done */ @@ -1200,7 +1202,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Don't do a long sleep inside a workqueue routine */ if (type == HUB_INIT2) { PREPARE_DELAYED_WORK(>init_work, hub_init_func3); - schedule_delayed_work(>init_work, + queue_delayed_work(system_power_efficient_wq, + >init_work, msecs_to_jiffies(delay)); return; /* Continues at init3: below */ } else { @@ -1214,7 +1217,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) if (status < 0) dev_err(hub->intfdev, "activate --> %d\n", status); if (hub->has_indicators && blinkenlights) - schedule_delayed_work(>leds, LED_CYCLE_PERIOD); + queue_delayed_work(system_power_efficient_wq, + >leds, LED_CYCLE_PERIOD); /* Scan all ports that need attention */ kick_khubd(hub); @@ -4316,7 +4320,8 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) /* hub LEDs are probably harder to miss than syslog */ if (hub->has_indicators) { hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; - schedule_delayed_work (>leds, 0); + queue_delayed_work(system_power_efficient_wq, + >leds, 0); } } kfree(qual); @@ -4545,7 +4550,9 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (hub->has_indicators) { hub->indicator[port1-1] = INDICATOR_AMBER_BLINK; - schedule_delayed_work (>leds, 0); + queue_delayed_work( + system_power_efficient_wq, + >leds, 0); } status = -ENOTCONN; /* Don't retry */ goto loop_disable; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH RFC] compat: Get rid of (get|put)_compat_time(val|spec)
From: "H. Peter Anvin" We have two APIs for compatiblity timespec/val, with confusingly similar names. compat_(get|put)_time(val|spec) *do* handle the case where COMPAT_USE_64BIT_TIME is set, whereas (get|put)_compat_time(val|spec) do not. This is an accident waiting to happen. Clean it up by favoring the full-service version; the limited version is replaced with double-underscore versions static to kernel/compat.c. A common pattern is to convert a struct timeval/timespec to kernel format in an allocation on the user stack. Unfortunately it is open-coded in several places. Since this allocation isn't actually needed if COMPAT_USE_64BIT_TIME is true (since user format == kernel format) encapsulate that whole pattern into functions compat_convert_time(spec|val). Finally, get rid of compat_(get|put)_timeval_convert(): each was only used once, and the latter was not even doing what the function said (no conversion actually was being done.) Moving the conversion into compat_sys_settimeofday() itself makes the code much more similar to sys_settimeofday() itself. Cc: Mauro Carvalho Chehab Cc: Alexander Viro Cc: Hans Verkuil Cc: Andrew Morton Cc: Heiko Carstens Cc: Manfred Spraul Cc: Mateusz Guzik Cc: Rafael Aquini Cc: Davidlohr Bueso Cc: Stephen Rothwell Cc: Dan Carpenter Cc: Arnd Bergmann Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Linus Torvalds Cc: H.J. Lu Signed-off-by: H. Peter Anvin --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 2 +- fs/compat.c | 6 +- include/linux/compat.h| 23 ++--- ipc/compat.c | 12 +-- ipc/compat_mq.c | 19 +--- kernel/compat.c | 131 +++--- kernel/futex_compat.c | 2 +- 7 files changed, 98 insertions(+), 97 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 8f7a6a454a4c..6191968db8fa 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -733,7 +733,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u copy_to_user(>u, >u, sizeof(kp->u)) || put_user(kp->pending, >pending) || put_user(kp->sequence, >sequence) || - put_compat_timespec(>timestamp, >timestamp) || + compat_put_timespec(>timestamp, >timestamp) || put_user(kp->id, >id) || copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) return -EFAULT; diff --git a/fs/compat.c b/fs/compat.c index 6af20de2c1a3..62092f433759 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -92,8 +92,8 @@ asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filena struct timespec tv[2]; if (t) { - if (get_compat_timespec([0], [0]) || - get_compat_timespec([1], [1])) + if (compat_get_timespec([0], [0]) || + compat_get_timespec([1], [1])) return -EFAULT; if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) @@ -512,7 +512,7 @@ compat_sys_io_getevents(aio_context_t ctx_id, nr * sizeof(struct io_event goto out; if (timeout) { - if (get_compat_timespec(, timeout)) + if (compat_get_timespec(, timeout)) goto out; ut = compat_alloc_user_space(sizeof(*ut)); diff --git a/include/linux/compat.h b/include/linux/compat.h index 3f448c65511b..0d9678e15823 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -141,26 +141,23 @@ struct compat_sigaction { }; /* - * These functions operate strictly on struct compat_time* - */ -extern int get_compat_timespec(struct timespec *, - const struct compat_timespec __user *); -extern int put_compat_timespec(const struct timespec *, - struct compat_timespec __user *); -extern int get_compat_timeval(struct timeval *, - const struct compat_timeval __user *); -extern int put_compat_timeval(const struct timeval *, - struct compat_timeval __user *); -/* * These functions operate on 32- or 64-bit specs depending on - * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the - * naming as compat_get/put_ rather than get/put_compat_. + * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments. */ extern int compat_get_timespec(struct timespec *, const void __user *); extern int compat_put_timespec(const struct timespec *, void __user *); extern int compat_get_timeval(struct timeval *, const void __user *); extern int compat_put_timeval(const struct timeval *, void __user
Re: Why is syscall auditing on with no rules?
On Sat, Feb 1, 2014 at 6:32 PM, Andy Lutomirski wrote: > On a stock Fedora installation: > > $ sudo auditctl -l > No rules > > Nonetheless TIF_SYSCALL_AUDIT is set and the __audit_syscall_entry and > __audit_syscall_exit account for >20% of syscall overhead according to > perf. > > This sucks. Unless I'm missing something, syscall auditing is *off*. > > How hard would it be to arrange for TIF_SYSCALL_AUDIT to be cleared > when there are no syscall rules? > > (This is extra bad in kernels before 3.13, where the clear call for > TIF_SYSCALL_AUDIT was completely missing.) The current code seems to have really odd effects. For example, processes that are created before the very first auditctl -e 1 (or auditd) invocation will never be subject to syscall auditing. But auditctl -e 1; auditctl -e 0 will cause all subsequently started processes to have audit contexts allocated and therefore to be subject to syscall auditing. I doubt that this behavior is considered desirable. --Andy > > --Andy -- Andy Lutomirski AMA Capital Management, LLC -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] kernel/kprobes.c: move cleanup_rp_inst() to where CONFIG_KRETPROBES enabled
(2014/02/01 21:17), Chen Gang wrote: > When CONFIG_KRETPROBES disabled, cleanup_rp_inst() is useless too. It > is only called by unregister_kretprobes() which is in CONFIG_KRETPROBES > enabled area. > > The related warning (allmodconfig under avr32): > > kernel/kprobes.c:1181: warning: 'cleanup_rp_inst' defined but not used This patch itself looks good to me. And it seems that not only the cleanup_rp_inst, but also other kretprobe related functions should be moved (free_rp_inst,etc) Thank you, > > > Signed-off-by: Chen Gang > --- > kernel/kprobes.c | 40 > 1 file changed, 20 insertions(+), 20 deletions(-) > > diff --git a/kernel/kprobes.c b/kernel/kprobes.c > index ceeadfc..18a520d 100644 > --- a/kernel/kprobes.c > +++ b/kernel/kprobes.c > @@ -1178,26 +1178,6 @@ static inline void free_rp_inst(struct kretprobe *rp) > } > } > > -static void __kprobes cleanup_rp_inst(struct kretprobe *rp) > -{ > - unsigned long flags, hash; > - struct kretprobe_instance *ri; > - struct hlist_node *next; > - struct hlist_head *head; > - > - /* No race here */ > - for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) { > - kretprobe_table_lock(hash, ); > - head = _inst_table[hash]; > - hlist_for_each_entry_safe(ri, next, head, hlist) { > - if (ri->rp == rp) > - ri->rp = NULL; > - } > - kretprobe_table_unlock(hash, ); > - } > - free_rp_inst(rp); > -} > - > /* > * Add the new probe to ap->list. Fail if this is the > * second jprobe at the address - two jprobes can't coexist > @@ -1885,6 +1865,26 @@ void __kprobes unregister_kretprobe(struct kretprobe > *rp) > } > EXPORT_SYMBOL_GPL(unregister_kretprobe); > > +static void __kprobes cleanup_rp_inst(struct kretprobe *rp) > +{ > + unsigned long flags, hash; > + struct kretprobe_instance *ri; > + struct hlist_node *next; > + struct hlist_head *head; > + > + /* No race here */ > + for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) { > + kretprobe_table_lock(hash, ); > + head = _inst_table[hash]; > + hlist_for_each_entry_safe(ri, next, head, hlist) { > + if (ri->rp == rp) > + ri->rp = NULL; > + } > + kretprobe_table_unlock(hash, ); > + } > + free_rp_inst(rp); > +} > + > void __kprobes unregister_kretprobes(struct kretprobe **rps, int num) > { > int i; > -- Masami HIRAMATSU IT Management Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu...@hitachi.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] Btrfs
On Sun, 2 Feb 2014, Filipe David Manana wrote: > >> Btrfs: fix btrfs boot when compiled as built-in (+73/-9) > > > > This one, 14a958e678cd ("Btrfs: fix btrfs boot when compiled as > > built-in"), breaks the build if CONFIG_LIBCRC32C=m: > > > > fs/built-in.o: In function `btrfs_check_super_csum': > > disk-io.c:(.text+0x1a1c8b): undefined reference to `crc32c' > > fs/built-in.o: In function `write_dev_supers.isra.120': > > disk-io.c:(.text+0x1a2054): undefined reference to `crc32c' > > fs/built-in.o: In function `csum_tree_block.isra.122': > > disk-io.c:(.text+0x1a22c4): undefined reference to `crc32c' > > fs/built-in.o: In function `btrfs_csum_data': > > (.text+0x1a2a46): undefined reference to `crc32c' > > fs/built-in.o: In function `send_cmd': > > send.c:(.text+0x20fe4c): undefined reference to `crc32c' > > One of the kbuild test robots reported this a few days ago too. > The following patch, sent shortly after the robot's warning, fixes it: > > https://patchwork.kernel.org/patch/3554671/ > Acked-by: David Rientjes Fixes the build problem for me, thanks! This needs to get into 3.14 since the breakage is currently in Linus's tree. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Why is syscall auditing on with no rules?
On a stock Fedora installation: $ sudo auditctl -l No rules Nonetheless TIF_SYSCALL_AUDIT is set and the __audit_syscall_entry and __audit_syscall_exit account for >20% of syscall overhead according to perf. This sucks. Unless I'm missing something, syscall auditing is *off*. How hard would it be to arrange for TIF_SYSCALL_AUDIT to be cleared when there are no syscall rules? (This is extra bad in kernels before 3.13, where the clear call for TIF_SYSCALL_AUDIT was completely missing.) --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
Yes, that is exactly the "eageronly" features - currently LWP and MPX. On February 1, 2014 6:05:05 PM PST, Linus Torvalds wrote: >On Sat, Feb 1, 2014 at 5:57 PM, H. Peter Anvin wrote: >> >> Twiddling CR0.TS is pretty slow if we're not taking advantage of it. > >Immaterial. > >We *already* avoid twiddling TS if it's not needed. > >It is true that we used to twiddle it at every context switch (and >then twiddle it *again* if we decided that we'd want to pre-load the >FPU state anyway, and avoid the extra fault). > >But that was fixed, and if we switch from a task that had math state >to another task that has math state, we leave TS alone. > >But Suresh apparently hits on the real issue: > >> not all the state under xsave adhers to cr0.TS/DNA rules > >which if so is sad but yes, makes CR0.TS no longer sufficient. > > Linus -- Sent from my mobile phone. Please pardon brevity and lack of formatting. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/1] Drivers: hv: vmbus: Cleanup the packet send path
The current channel code is using scatterlist abstraction to pass data to the ringbuffer API on the send path. This causes unnecessary translations between virtual and physical addresses. Fix this. Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel.c | 42 +++--- drivers/hv/hyperv_vmbus.h |4 ++-- drivers/hv/ring_buffer.c | 17 +++-- include/linux/hyperv.h|2 +- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 69ea36f..602ca86 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "hyperv_vmbus.h" @@ -554,14 +555,14 @@ EXPORT_SYMBOL_GPL(vmbus_close); * * Mainly used by Hyper-V drivers. */ -int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, +int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, u32 bufferlen, u64 requestid, enum vmbus_packet_type type, u32 flags) { struct vmpacket_descriptor desc; u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen; u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64)); - struct scatterlist bufferlist[3]; + struct kvec bufferlist[3]; u64 aligned_data = 0; int ret; bool signal = false; @@ -575,11 +576,12 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, desc.len8 = (u16)(packetlen_aligned >> 3); desc.trans_id = requestid; - sg_init_table(bufferlist, 3); - sg_set_buf([0], , sizeof(struct vmpacket_descriptor)); - sg_set_buf([1], buffer, bufferlen); - sg_set_buf([2], _data, - packetlen_aligned - packetlen); + bufferlist[0].iov_base = + bufferlist[0].iov_len = sizeof(struct vmpacket_descriptor); + bufferlist[1].iov_base = buffer; + bufferlist[1].iov_len = bufferlen; + bufferlist[2].iov_base = _data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); ret = hv_ringbuffer_write(>outbound, bufferlist, 3, ); @@ -605,7 +607,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, u32 descsize; u32 packetlen; u32 packetlen_aligned; - struct scatterlist bufferlist[3]; + struct kvec bufferlist[3]; u64 aligned_data = 0; bool signal = false; @@ -637,11 +639,12 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, desc.range[i].pfn= pagebuffers[i].pfn; } - sg_init_table(bufferlist, 3); - sg_set_buf([0], , descsize); - sg_set_buf([1], buffer, bufferlen); - sg_set_buf([2], _data, - packetlen_aligned - packetlen); + bufferlist[0].iov_base = + bufferlist[0].iov_len = descsize; + bufferlist[1].iov_base = buffer; + bufferlist[1].iov_len = bufferlen; + bufferlist[2].iov_base = _data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); ret = hv_ringbuffer_write(>outbound, bufferlist, 3, ); @@ -665,7 +668,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, u32 descsize; u32 packetlen; u32 packetlen_aligned; - struct scatterlist bufferlist[3]; + struct kvec bufferlist[3]; u64 aligned_data = 0; bool signal = false; u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, @@ -700,11 +703,12 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array, pfncount * sizeof(u64)); - sg_init_table(bufferlist, 3); - sg_set_buf([0], , descsize); - sg_set_buf([1], buffer, bufferlen); - sg_set_buf([2], _data, - packetlen_aligned - packetlen); + bufferlist[0].iov_base = + bufferlist[0].iov_len = descsize; + bufferlist[1].iov_base = buffer; + bufferlist[1].iov_len = bufferlen; + bufferlist[2].iov_base = _data; + bufferlist[2].iov_len = (packetlen_aligned - packetlen); ret = hv_ringbuffer_write(>outbound, bufferlist, 3, ); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index e055176..1544609 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -559,8 +559,8 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, - struct scatterlist *sglist, - u32 sgcount, bool *signal); + struct kvec *kv_list, + u32 kv_count, bool *signal); int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen); diff --git
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:57 PM, H. Peter Anvin wrote: > > Twiddling CR0.TS is pretty slow if we're not taking advantage of it. Immaterial. We *already* avoid twiddling TS if it's not needed. It is true that we used to twiddle it at every context switch (and then twiddle it *again* if we decided that we'd want to pre-load the FPU state anyway, and avoid the extra fault). But that was fixed, and if we switch from a task that had math state to another task that has math state, we leave TS alone. But Suresh apparently hits on the real issue: > not all the state under xsave adhers to cr0.TS/DNA rules which if so is sad but yes, makes CR0.TS no longer sufficient. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On 02/01/2014 05:51 PM, Linus Torvalds wrote: > On Sat, Feb 1, 2014 at 5:47 PM, Suresh Siddha wrote: >> >> So if the restore failed, we should do something like drop_init_fpu(), >> which will restore init-state to the registers. >> >> for eager-fpu() paths we don't use clts() stts() etc. > > Uhhuh. Ok. > > Why do we do that, btw? I think it would make much more sense to just > do what I *thought* we did, and just make it a context-switch-time > optimization ("let's always switch FP state"), not make it a huge > semantic difference. > Twiddling CR0.TS is pretty slow if we're not taking advantage of it. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:51 PM, Linus Torvalds wrote: > On Sat, Feb 1, 2014 at 5:47 PM, Suresh Siddha wrote: >> >> So if the restore failed, we should do something like drop_init_fpu(), >> which will restore init-state to the registers. >> >> for eager-fpu() paths we don't use clts() stts() etc. > > Uhhuh. Ok. > > Why do we do that, btw? I think it would make much more sense to just > do what I *thought* we did, and just make it a context-switch-time > optimization ("let's always switch FP state"), not make it a huge > semantic difference. clts/stts is more costly and not all the state under xsave adhers to cr0.TS/DNA rules. did I answer your question? thanks, suresh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:47 PM, Suresh Siddha wrote: > > So if the restore failed, we should do something like drop_init_fpu(), > which will restore init-state to the registers. > > for eager-fpu() paths we don't use clts() stts() etc. Uhhuh. Ok. Why do we do that, btw? I think it would make much more sense to just do what I *thought* we did, and just make it a context-switch-time optimization ("let's always switch FP state"), not make it a huge semantic difference. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:38 PM, Linus Torvalds wrote: > It definitely does not want an else, I think. > > If tsk_used_math() is false, or if the FPU restore failed, we > *definitely* need that stts(). Otherwise we'd return to user mode with > random contents in the FP state, and let user mode muck around with > it. > > No? So if the restore failed, we should do something like drop_init_fpu(), which will restore init-state to the registers. for eager-fpu() paths we don't use clts() stts() etc. thanks, suresh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:43 PM, H. Peter Anvin wrote: > What does the inner if clause do? It looks like it returns either way... Suresh broke it with his suggested version. The inner if-statement is supposed to avoid the stts *if* we had used math *and* the FPU restore worked. But with the extra "else" that Suresh added, it now always avoids the stts for the eager-fpu case, which breaks the whole logic for "hey, if the process hadn't used math, we don't waste time restoring data that doesn't exist". And, as you say, making the inner if clause pointless. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
What does the inner if clause do? It looks like it returns either way... On February 1, 2014 5:35:13 PM PST, Suresh Siddha wrote: >On Sat, Feb 1, 2014 at 5:26 PM, H. Peter Anvin wrote: >> Even "b" does that, no? > >oh right. It needs an else. only for non-eager fpu case we should do >stts() > > void __kernel_fpu_end(void) > { > if (use_eager_fpu()) { > struct task_struct *me = current; > > if (tsk_used_math(me) && likely(!restore_fpu_checking( >me))) > return; > } else > stts(); > } > >thanks, >suresh > >> "a" should be fine as long as we don't ever use >> those features in the kernel, even under kernel_fpu_begin/end(). -- Sent from my mobile phone. Please pardon brevity and lack of formatting. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:35 PM, Suresh Siddha wrote: > On Sat, Feb 1, 2014 at 5:26 PM, H. Peter Anvin wrote: >> Even "b" does that, no? > > oh right. It needs an else. only for non-eager fpu case we should do stts() It definitely does not want an else, I think. If tsk_used_math() is false, or if the FPU restore failed, we *definitely* need that stts(). Otherwise we'd return to user mode with random contents in the FP state, and let user mode muck around with it. No? Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 5:26 PM, H. Peter Anvin wrote: > Even "b" does that, no? oh right. It needs an else. only for non-eager fpu case we should do stts() void __kernel_fpu_end(void) { if (use_eager_fpu()) { struct task_struct *me = current; if (tsk_used_math(me) && likely(!restore_fpu_checking( me))) return; } else stts(); } thanks, suresh > "a" should be fine as long as we don't ever use > those features in the kernel, even under kernel_fpu_begin/end(). -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] Btrfs
On Sun, Feb 2, 2014 at 12:15 AM, David Rientjes wrote: > On Thu, 30 Jan 2014, Chris Mason wrote: > >> >> Hi Linus >> >> Please pull my for-linus branch: >> >> git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git for-linus >> >> There are two conflicts right now, one with the ACL code (pick your >> version) and one with Kent's changes in the block layer pull. That one >> is pretty obvious too, just do both our cleanup and Kent's rework. >> >> This is a pretty big pull, and most of these changes have been floating >> in btrfs-next for a long time. Filipe's properties work is a cool >> building block for inheriting attributes like compression down on a >> per inode basis. >> >> Jeff Mahoney kicked in code to export filesystem info into sysfs. >> >> Otherwise, lots of performance improvements, cleanups and bug fixes. >> >> Looks like there are still a few other small pending incrementals, but I >> wanted to get the bulk of this in first. >> >> Filipe David Borba Manana (29) commits (+1856/-301): >> Btrfs: fix deadlock when iterating inode refs and running delayed inodes >> (+12/-7) >> Btrfs: fix send file hole detection leading to data corruption (+15/-0) >> Btrfs: remove field tree_mod_seq_elem from btrfs_fs_info struct (+0/-1) >> Btrfs: make send's file extent item search more efficient (+17/-10) >> Btrfs: fix infinite path build loops in incremental send (+518/-21) >> Btrfs: reduce btree node locking duration on item update (+14/-10) >> Btrfs: return immediately if tree log mod is not necessary (+1/-1) >> Btrfs: fix pass of transid with wrong endianness in send.c (+3/-3) >> Btrfs: fix btrfs_search_slot_for_read backwards iteration (+3/-1) >> Btrfs: fix send to not send non-aligned clone operations (+2/-1) >> Btrfs: faster and more efficient extent map insertion (+41/-31) >> Btrfs: fix extent boundary check in bio_readpage_error (+1/-1) >> Btrfs: faster file extent item search in clone ioctl (+14/-9) >> Btrfs: unlock inodes in correct order in clone ioctl (+11/-3) >> Btrfs: faster file extent item replace operations (+114/-46) >> Btrfs: avoid unnecessary ordered extent cache resets (+2/-1) >> Btrfs: fix very slow inode eviction and fs unmount (+84/-14) >> Btrfs: fix snprintf usage by send's gen_unique_name (+1/-1) >> Btrfs: fix ordered extent check in btrfs_punch_hole (+1/-1) >> Btrfs: fix btrfs boot when compiled as built-in (+73/-9) > > This one, 14a958e678cd ("Btrfs: fix btrfs boot when compiled as > built-in"), breaks the build if CONFIG_LIBCRC32C=m: > > fs/built-in.o: In function `btrfs_check_super_csum': > disk-io.c:(.text+0x1a1c8b): undefined reference to `crc32c' > fs/built-in.o: In function `write_dev_supers.isra.120': > disk-io.c:(.text+0x1a2054): undefined reference to `crc32c' > fs/built-in.o: In function `csum_tree_block.isra.122': > disk-io.c:(.text+0x1a22c4): undefined reference to `crc32c' > fs/built-in.o: In function `btrfs_csum_data': > (.text+0x1a2a46): undefined reference to `crc32c' > fs/built-in.o: In function `send_cmd': > send.c:(.text+0x20fe4c): undefined reference to `crc32c' One of the kbuild test robots reported this a few days ago too. The following patch, sent shortly after the robot's warning, fixes it: https://patchwork.kernel.org/patch/3554671/ thanks -- Filipe David Manana, "Reasonable men adapt themselves to the world. Unreasonable men adapt the world to themselves. That's why all progress depends on unreasonable men." -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On 02/01/2014 05:06 PM, Suresh Siddha wrote: > > so I will Ack for option "b", as option "a" breaks the features which > don't take into account cr0.TS. > Even "b" does that, no? "a" should be fine as long as we don't ever use those features in the kernel, even under kernel_fpu_begin/end(). > Meanwhile I have the patch removing the delayed dynamic allocation for > non-eager fpu. will post it after some testing. Thanks. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On 02/01/2014 05:19 PM, George Spelvin wrote: >> OK, let's circle back for a bit. We have an active bug, and we clearly >> have a lot of restructuring that could/should be done. We need to fix >> the bug first; if we're going to a bunch of restructuring then that >> ought to be separate. The first bit is how we fix the immediate bug. > > Well, that's what the [PATCH] that started this thread,s for which seems > to greatly reduce the incidence. > > The issue being discussed here is the fact that it's far from clear to > people that the result of applying that patch is actually bug-free. > > Given how long it's been in shipping kernels (2.6.26 or 3.10, depending > on what you think causes it to trigger) and how few complaints there > have been, I'm happy to take a while to think about it. > Yes, I would agree with that. I guess I should have said "how do we fix the immediate bug(s) properly." -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
> OK, let's circle back for a bit. We have an active bug, and we clearly > have a lot of restructuring that could/should be done. We need to fix > the bug first; if we're going to a bunch of restructuring then that > ought to be separate. The first bit is how we fix the immediate bug. Well, that's what the [PATCH] that started this thread,s for which seems to greatly reduce the incidence. The issue being discussed here is the fact that it's far from clear to people that the result of applying that patch is actually bug-free. Given how long it's been in shipping kernels (2.6.26 or 3.10, depending on what you think causes it to trigger) and how few complaints there have been, I'm happy to take a while to think about it. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 11:27 AM, Linus Torvalds wrote: > That said, regardless of the allocation issue, I do think that it's > stupid for kernel_fpu_{begin,end} to save the math state if > "used_math" was not set. So I do think__kernel_fpu_end() as-s is > buggy and stupid. For eager_fpu case, assumption was every task should always have 'used_math' set. But i think there is a race, where we drop the fpu explicitly by doing drop_fpu() and meanwhile if we get an interrupt etc that ends up using fpu? so I will Ack for option "b", as option "a" breaks the features which don't take into account cr0.TS. Meanwhile I have the patch removing the delayed dynamic allocation for non-eager fpu. will post it after some testing. thanks, suresh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/2] Drivers: net: hyperv: Cleanup the recive path
From: "K. Y. Srinivasan" Date: Fri, 31 Jan 2014 08:24:38 -0800 > Some minor cleanup of the receive path. Get rid of unnecessary > indirection as well as unnecessary re-establishment of state. It is not appropriate to submit cleanups at this time. Please wait until the net-next tree opens back up, and submit your changes against it at that time. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 0/4] OpenCores 10/100 MAC ethtool operations
From: Max Filippov Date: Fri, 31 Jan 2014 09:41:03 +0400 > Hello David, Ben, Florian and everybody, > > this series implements ethtool callbacks for the ethoc driver as was > requested by Florian. > > Changes v1->v2: > - fix {get,set}_settings return code in case there's no PHY; > - fix set_ringparam: check ring sizes, change ring sizes on the fly. Series applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/4] Add 32 bit VDSO time support for 32 bit kernel
On 02/01/2014 04:41 PM, H. Peter Anvin wrote: >> >> Right. But there's some obscure ABI reason for CONFIG_COMPAT_VDSO, >> and if this breaks it, then it's no good. From extremely vague >> memory, there's some version of SuSE that breaks if the 32-bit vdso >> moves. I have no idea what the bug is, but moving a "compat" address >> seems suspect. >> Sure enough: > config COMPAT_VDSO > def_bool y > prompt "Compat VDSO support" > depends on X86_32 || IA32_EMULATION > ---help--- > Map the 32-bit VDSO to the predictable old-style address too. > > Say N here if you are running a sufficiently recent glibc > version (2.3.3 or later), to remove the high-mapped > VDSO mapping and to exclusively use the randomized VDSO. > > If unsure, say Y. So we need this for 32-bit glibc < 2.3.3, and we effecively have the same problem as on 64 bits. Next question is if those old glibcs rely on the entry point alone or if they also expect the vdso header at that address. I looked at the glibc diffs from 2.3.2 to 2.3.3, but it isn't really obvious to me what assumptions the 2.3.2 glibc made. Perhaps Roland has any idea? The safest thing for that might be to have the compat vdso be a completely separate object from the real vdso, and let the former be an object as similar to the current one as possible. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 6/6] ACPI / hotplug / PCI: Hotplug notifications from acpi_bus_notify()
From: Rafael J. Wysocki Since acpi_bus_notify() is executed on all notifications for all devices anyway, rename acpi_hotplug_notify_cb() to acpi_system_notify() and call it directly from acpi_bus_notify() instead of installing notify handlers pointing to it for all hotplug devices. This change reduces both the size and complexity of ACPI-based device hotplug code. Moreover, since acpi_system_notify() only does significant things for devices that either have an ACPI scan handler, or have a hotplug context with .eject() defined, and those devices had notify handlers pointing to acpi_hotplug_notify_cb() installed before anyway, this modification shouldn't change functionality. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 42 --- drivers/acpi/internal.h|1 drivers/acpi/scan.c| 49 - drivers/pci/hotplug/acpiphp.h |1 drivers/pci/hotplug/acpiphp_glue.c | 16 +--- include/acpi/acpi_bus.h|2 - 6 files changed, 15 insertions(+), 96 deletions(-) Index: linux-pm/drivers/acpi/bus.c === --- linux-pm.orig/drivers/acpi/bus.c +++ linux-pm/drivers/acpi/bus.c @@ -346,47 +346,7 @@ static void acpi_bus_notify(acpi_handle ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", type, handle)); - switch (type) { - - case ACPI_NOTIFY_BUS_CHECK: - /* TBD */ - break; - - case ACPI_NOTIFY_DEVICE_CHECK: - /* TBD */ - break; - - case ACPI_NOTIFY_DEVICE_WAKE: - /* TBD */ - break; - - case ACPI_NOTIFY_EJECT_REQUEST: - /* TBD */ - break; - - case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: - /* TBD: Exactly what does 'light' mean? */ - break; - - case ACPI_NOTIFY_FREQUENCY_MISMATCH: - /* TBD */ - break; - - case ACPI_NOTIFY_BUS_MODE_MISMATCH: - /* TBD */ - break; - - case ACPI_NOTIFY_POWER_FAULT: - /* TBD */ - break; - - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received unknown/unsupported notification [%08x]\n", - type)); - break; - } - + acpi_system_notify(handle, type); acpi_bus_get_device(handle, ); if (device) { driver = device->driver; Index: linux-pm/drivers/acpi/internal.h === --- linux-pm.orig/drivers/acpi/internal.h +++ linux-pm/drivers/acpi/internal.h @@ -74,6 +74,7 @@ static inline void acpi_lpss_init(void) bool acpi_queue_hotplug_work(struct work_struct *work); bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent); +void acpi_system_notify(acpi_handle handle, u32 type); /* -- Device Node Initialization / Removal Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -522,7 +522,7 @@ static void acpi_device_hotplug(void *da unlock_device_hotplug(); } -static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) +void acpi_system_notify(acpi_handle handle, u32 type) { u32 ost_code = ACPI_OST_SC_SUCCESS; struct acpi_device *adev; @@ -537,6 +537,11 @@ static void acpi_hotplug_notify_cb(acpi_ acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); break; + case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: + acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT event\n"); + /* TBD: Exactly what does 'light' mean? */ + break; + case ACPI_NOTIFY_EJECT_REQUEST: acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); break; @@ -582,18 +587,6 @@ static void acpi_hotplug_notify_cb(acpi_ acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); } -void acpi_install_hotplug_notify_handler(acpi_handle handle) -{ - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - acpi_hotplug_notify_cb, NULL); -} - -void acpi_remove_hotplug_notify_handler(acpi_handle handle) -{ - acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - acpi_hotplug_notify_cb); -} - static ssize_t real_power_state_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2005,34 +1998,6 @@ void acpi_scan_hotplug_enabled(struct ac mutex_unlock(_scan_lock); }
[PATCH v2 3/6] ACPI / hotplug / PCI: Consolidate ACPIPHP with ACPI core hotplug
From: Rafael J. Wysocki The ACPI-based PCI hotplug (ACPIPHP) code currently attaches its hotplug context objects directly to ACPI namespace nodes representing hotplug devices. However, after recent changes causing struct acpi_device to be created for every namespace node representing a device (regardless of its status), that is not necessary any more. Moreover, it's vulnerable to a theoretical issue that the ACPI handle passed in the context between handle_hotplug_event() and hotplug_event_work() may become invalid in the meantime (as a result of a concurrent table unload). In principle, this issue might be addressed by adding a non-empty release handler for ACPIPHP hotplug context objects analogous to acpi_scan_drop_device(), but that would duplicate the code in that function and in acpi_device_del_work_fn(). For this reason, it's better to modify ACPIPHP to attach its device hotplug contexts to struct device objects representing hotplug devices and make it use acpi_hotplug_notify_cb() as its notify handler. At the same time, acpi_device_hotplug() can be modified to dispatch the new .hp.event() callback pointing to acpiphp_hotplug_event() from ACPI device objects associated with PCI devices and use the generic ACPI device hotplug code for device objects with scan handlers attached to them. This allows the existing code duplication between ACPIPHP and the ACPI core to be reduced too and makes further ACPI-based device hotplug consolidation possible. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c| 106 +--- drivers/pci/hotplug/acpiphp.h |9 +- drivers/pci/hotplug/acpiphp_glue.c | 136 +++-- include/acpi/acpi_bus.h| 22 + 4 files changed, 136 insertions(+), 137 deletions(-) Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -452,43 +452,61 @@ static int acpi_scan_bus_check(struct ac return 0; } +static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type) +{ + switch (type) { + case ACPI_NOTIFY_BUS_CHECK: + return acpi_scan_bus_check(adev); + case ACPI_NOTIFY_DEVICE_CHECK: + return acpi_scan_device_check(adev); + case ACPI_NOTIFY_EJECT_REQUEST: + case ACPI_OST_EC_OSPM_EJECT: + return acpi_scan_hot_remove(adev); + } + return -EINVAL; +} + static void acpi_device_hotplug(void *data, u32 src) { u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; struct acpi_device *adev = data; - int error; + int error = -ENODEV; lock_device_hotplug(); mutex_lock(_scan_lock); /* * The device object's ACPI handle cannot become invalid as long as we -* are holding acpi_scan_lock, but it may have become invalid before +* are holding acpi_scan_lock, but it might have become invalid before * that lock was acquired. */ if (adev->handle == INVALID_ACPI_HANDLE) - goto out; + goto err_out; - switch (src) { - case ACPI_NOTIFY_BUS_CHECK: - error = acpi_scan_bus_check(adev); - break; - case ACPI_NOTIFY_DEVICE_CHECK: - error = acpi_scan_device_check(adev); - break; - case ACPI_NOTIFY_EJECT_REQUEST: - case ACPI_OST_EC_OSPM_EJECT: - error = acpi_scan_hot_remove(adev); - break; - default: - error = -EINVAL; - break; + if (adev->handler) { + error = acpi_generic_hotplug_event(adev, src); + } else { + int (*event)(struct acpi_device *, u32); + + acpi_lock_hp_context(); + event = adev->hp ? adev->hp->event : NULL; + acpi_unlock_hp_context(); + /* +* There may be additional notify handlers for device objects +* without the .event() callback, so ignore them here. +*/ + if (event) + error = event(adev, src); + else + goto out; } if (!error) ost_code = ACPI_OST_SC_SUCCESS; - out: + err_out: acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); + + out: put_device(>dev); mutex_unlock(_scan_lock); unlock_device_hotplug(); @@ -496,8 +514,8 @@ static void acpi_device_hotplug(void *da static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) { - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; struct acpi_scan_handler *handler = data; + u32 ost_code = ACPI_OST_SC_SUCCESS; struct acpi_device *adev; acpi_status status; @@ -505,27 +523,50 @@ static void acpi_hotplug_notify_cb(acpi_
[PATCH v2 2/6] ACPI / hotplug / PCI: Define hotplug context lock in the core
From: Rafael J. Wysocki Subsequent changes will require the ACPI core to acquire the lock protecting the ACPIPHP hotplug contexts, so move the definition of the lock to the core and change its name to be more generic. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c| 11 + drivers/pci/hotplug/acpiphp_glue.c | 41 ++--- include/acpi/acpi_bus.h|2 + 3 files changed, 33 insertions(+), 21 deletions(-) Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -43,6 +43,7 @@ DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); static LIST_HEAD(acpi_device_del_list); static DEFINE_MUTEX(acpi_device_del_lock); +static DEFINE_MUTEX(acpi_hp_context_lock); struct acpi_device_bus_id{ char bus_id[15]; @@ -62,6 +63,16 @@ void acpi_scan_lock_release(void) } EXPORT_SYMBOL_GPL(acpi_scan_lock_release); +void acpi_lock_hp_context(void) +{ + mutex_lock(_hp_context_lock); +} + +void acpi_unlock_hp_context(void) +{ + mutex_unlock(_hp_context_lock); +} + int acpi_scan_add_handler(struct acpi_scan_handler *handler) { if (!handler || !handler->attach) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -58,7 +58,6 @@ static LIST_HEAD(bridge_list); static DEFINE_MUTEX(bridge_mutex); -static DEFINE_MUTEX(acpiphp_context_lock); static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); static void acpiphp_sanitize_bus(struct pci_bus *bus); @@ -75,7 +74,7 @@ static void acpiphp_context_handler(acpi * acpiphp_init_context - Create hotplug context and grab a reference to it. * @adev: ACPI device object to create the context for. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) { @@ -100,7 +99,7 @@ static struct acpiphp_context *acpiphp_i * acpiphp_get_context - Get hotplug context and grab a reference to it. * @handle: ACPI object handle to get the context for. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) { @@ -122,7 +121,7 @@ static struct acpiphp_context *acpiphp_g * * The context object is removed if there are no more references to it. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ static void acpiphp_put_context(struct acpiphp_context *context) { @@ -151,7 +150,7 @@ static void free_bridge(struct kref *kre struct acpiphp_slot *slot, *next; struct acpiphp_func *func, *tmp; - mutex_lock(_context_lock); + acpi_lock_hp_context(); bridge = container_of(kref, struct acpiphp_bridge, ref); @@ -175,7 +174,7 @@ static void free_bridge(struct kref *kre pci_dev_put(bridge->pci_dev); kfree(bridge); - mutex_unlock(_context_lock); + acpi_unlock_hp_context(); } /* @@ -291,17 +290,17 @@ static acpi_status register_slot(acpi_ha device = (adr >> 16) & 0x; function = adr & 0x; - mutex_lock(_context_lock); + acpi_lock_hp_context(); context = acpiphp_init_context(adev); if (!context) { - mutex_unlock(_context_lock); + acpi_unlock_hp_context(); acpi_handle_err(handle, "No hotplug context\n"); return AE_NOT_EXIST; } newfunc = >func; newfunc->function = function; newfunc->parent = bridge; - mutex_unlock(_context_lock); + acpi_unlock_hp_context(); if (acpi_has_method(handle, "_EJ0")) newfunc->flags = FUNC_HAS_EJ0; @@ -319,9 +318,9 @@ static acpi_status register_slot(acpi_ha slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { - mutex_lock(_context_lock); + acpi_lock_hp_context(); acpiphp_put_context(context); - mutex_unlock(_context_lock); + acpi_unlock_hp_context(); return AE_NO_MEMORY; } @@ -396,7 +395,7 @@ static struct acpiphp_bridge *acpiphp_ha struct acpiphp_context *context; struct acpiphp_bridge *bridge = NULL; - mutex_lock(_context_lock); + acpi_lock_hp_context(); context = acpiphp_get_context(handle); if (context) { bridge = context->bridge; @@ -405,7 +404,7 @@ static struct acpiphp_bridge *acpiphp_ha acpiphp_put_context(context); } - mutex_unlock(_context_lock); + acpi_unlock_hp_context(); return bridge; } @@ -796,12 +795,12 @@
[PATCH v2 1/6] ACPI / hotplug: Fix theoretical race in acpi_hotplug_notify_cb()
From: Rafael J. Wysocki There is a slight possibility for the ACPI device object pointed to by adev in acpi_hotplug_notify_cb() to become invalid between the acpi_bus_get_device() that it comes from and the subsequent get_device(). Namely, if acpi_scan_drop_device() runs concurrently with respect to acpi_hotplug_notify_cb() and acpi_device_del_list is not empty, acpi_device_del_work_fn() may delete the device object in question without waiting for the ACPI events workqueue to drain, which very well may happen right after a successful execution of acpi_bus_get_device() in acpi_hotplug_notify_cb(). To prevent that from happening, run acpi_bus_get_device() and the subsequent get_device() in acpi_hotplug_notify_cb() under acpi_device_del_lock, so that the deletion of the given device object cannot be queued up by acpi_scan_drop_device() between the two. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -41,6 +41,8 @@ static DEFINE_MUTEX(acpi_scan_lock); static LIST_HEAD(acpi_scan_handlers_list); DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); +static LIST_HEAD(acpi_device_del_list); +static DEFINE_MUTEX(acpi_device_del_lock); struct acpi_device_bus_id{ char bus_id[15]; @@ -488,9 +490,6 @@ static void acpi_hotplug_notify_cb(acpi_ struct acpi_device *adev; acpi_status status; - if (acpi_bus_get_device(handle, )) - goto err_out; - switch (type) { case ACPI_NOTIFY_BUS_CHECK: acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); @@ -512,7 +511,13 @@ static void acpi_hotplug_notify_cb(acpi_ /* non-hotplug event; possibly handled by other handler */ return; } + mutex_lock(_device_del_lock); + if (acpi_bus_get_device(handle, )) { + mutex_unlock(_device_del_lock); + goto err_out; + } get_device(>dev); + mutex_unlock(_device_del_lock); status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); if (ACPI_SUCCESS(status)) return; @@ -1042,9 +1047,6 @@ static void acpi_device_del(struct acpi_ device_del(>dev); } -static LIST_HEAD(acpi_device_del_list); -static DEFINE_MUTEX(acpi_device_del_lock); - static void acpi_device_del_work_fn(struct work_struct *work_not_used) { for (;;) { -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 5/6] ACPI / hotplug / PCI: Simplify acpi_install_hotplug_notify_handler()
From: Rafael J. Wysocki Since acpi_hotplug_notify_cb() does not use its data argument any more, the second argument of acpi_install_hotplug_notify_handler() can be dropped, so do that and update its callers accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c|6 +++--- drivers/pci/hotplug/acpiphp_glue.c |2 +- include/acpi/acpi_bus.h|2 +- 3 files changed, 5 insertions(+), 5 deletions(-) Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -582,10 +582,10 @@ static void acpi_hotplug_notify_cb(acpi_ acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); } -void acpi_install_hotplug_notify_handler(acpi_handle handle, void *data) +void acpi_install_hotplug_notify_handler(acpi_handle handle) { acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - acpi_hotplug_notify_cb, data); + acpi_hotplug_notify_cb, NULL); } void acpi_remove_hotplug_notify_handler(acpi_handle handle) @@ -2024,7 +2024,7 @@ static void acpi_scan_init_hotplug(acpi_ list_for_each_entry(hwid, , list) { handler = acpi_scan_match_handler(hwid->id, NULL); if (handler) { - acpi_install_hotplug_notify_handler(handle, handler); + acpi_install_hotplug_notify_handler(handle); break; } } Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -362,7 +362,7 @@ static acpi_status register_slot(acpi_ha /* install notify handler */ if (!(newfunc->flags & FUNC_HAS_DCK)) - acpi_install_hotplug_notify_handler(handle, NULL); + acpi_install_hotplug_notify_handler(handle); return AE_OK; } Index: linux-pm/include/acpi/acpi_bus.h === --- linux-pm.orig/include/acpi/acpi_bus.h +++ linux-pm/include/acpi/acpi_bus.h @@ -443,7 +443,7 @@ static inline bool acpi_device_enumerate typedef void (*acpi_hp_callback)(void *data, u32 src); acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src); -void acpi_install_hotplug_notify_handler(acpi_handle handle, void *data); +void acpi_install_hotplug_notify_handler(acpi_handle handle); void acpi_remove_hotplug_notify_handler(acpi_handle handle); /** -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 0/6] ACPI / hotplug / PCI: Consolidation of ACPIPHP with ACPI core device hotplug
On Wednesday, January 29, 2014 12:57:06 AM Rafael J. Wysocki wrote: > On Tuesday, January 28, 2014 11:10:30 PM Rafael J. Wysocki wrote: > > Hi All, > > > > It looks like there's time for more adventurous stuff. :-) > > > > The following series is on top of the one I sent on Sunday: > > > > https://lkml.org/lkml/2014/1/26/191 > > > > The final outcome of the patches below is that all ACPI hotplug > > notifications > > for PCI devices and for core system things like CPU, memory, PCI roots etc., > > will be dispatched from acpi_bus_notify() and it is not necessary to > > install a > > separate hotplug notify handler for each device any more. > > > > [1/5] Attach ACPIPHP hotplug contexts to struct acpi_device objects. > > [2/5] Introduce wrappers for installing and removing hotplug notify handlers > > (those wrappers go away later on, but they are useful for separating > >changes). > > [3/5] Consolidate ACPI hotplug signaling for PCI and ACPI core. > > [4/5] Simplify notify handle registration wrapper. > > [5/5] Dispatch ACPI hotplug notifications for "core" devices and PCI from > > acpi_bus_notify(). > > Unfortunately, I realized that patches [3-5/5] were buggy. The bugs were > kind of subtle and might not be easy to reproduce, but they were bugs anyway. > :-) > > A respin of the whole series follows. After the Mika's testing it turned out that they were more buggy than I had though. Oh well. The following patchset is a reworked version of the previous one. Functionality-wise the final result should be very similar, but not exactly the same. [1/6] Fix a theoretical race condition in acpi_hotplug_notify_cb(). [2/6] Move the hotplug context lock definition to the ACPI core (from ACPIPHP). [3/6] Consolidate ACPI hotplug signaling for PCI and ACPI core (this is a combination of patches [1-3/5] from the previous series). [4/6] Rework the handling of eject requests in the ACPI core. [5/6] Simplify a routine for installing hotplug notify handlers. [6/6] Dispatch ACPI hotplug notifications for "core" devices and PCI from acpi_bus_notify(). This is on top of https://lkml.org/lkml/2014/2/1/123 which in turn is on top of the current mainline. For the adventurous all this stuff is on the test-next branch of linux-pm.git. Thanks! -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 4/6] ACPI / hotplug / PCI: Rework the handling of eject requests
From: Rafael J. Wysocki To avoid the need to install a hotplug notify handler for each ACPI namespace node representing a device and having a matching scan handler, move the check whether or not the ejection of the given device is enabled through its scan handler from acpi_hotplug_notify_cb() to acpi_generic_hotplug_event(). Also, move the execution of ACPI_OST_SC_EJECT_IN_PROGRESS _OST to acpi_generic_hotplug_event(), because in acpi_hotplug_notify_cb() or in acpi_eject_store() we really don't know whether or not the eject is going to be in progress (for example, acpi_hotplug_execute() may still fail without queuing up the work item). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) Index: linux-pm/drivers/acpi/scan.c === --- linux-pm.orig/drivers/acpi/scan.c +++ linux-pm/drivers/acpi/scan.c @@ -461,6 +461,12 @@ static int acpi_generic_hotplug_event(st return acpi_scan_device_check(adev); case ACPI_NOTIFY_EJECT_REQUEST: case ACPI_OST_EC_OSPM_EJECT: + if (adev->handler && !adev->handler->hotplug.enabled) { + dev_info(>dev, "Eject disabled\n"); + return -EPERM; + } + acpi_evaluate_hotplug_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST, + ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); return acpi_scan_hot_remove(adev); } return -EINVAL; @@ -485,6 +491,10 @@ static void acpi_device_hotplug(void *da if (adev->handler) { error = acpi_generic_hotplug_event(adev, src); + if (error == -EPERM) { + ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; + goto err_out; + } } else { int (*event)(struct acpi_device *, u32); @@ -514,7 +524,6 @@ static void acpi_device_hotplug(void *da static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) { - struct acpi_scan_handler *handler = data; u32 ost_code = ACPI_OST_SC_SUCCESS; struct acpi_device *adev; acpi_status status; @@ -530,13 +539,6 @@ static void acpi_hotplug_notify_cb(acpi_ case ACPI_NOTIFY_EJECT_REQUEST: acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); - if (handler && !handler->hotplug.enabled) { - acpi_handle_err(handle, "Eject disabled\n"); - ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; - goto out; - } - acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, - ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); break; case ACPI_NOTIFY_DEVICE_WAKE: @@ -637,8 +639,6 @@ acpi_eject_store(struct device *d, struc if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) return -ENODEV; - acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, - ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); get_device(_device->dev); status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device, ACPI_OST_EC_OSPM_EJECT); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/4] Add 32 bit VDSO time support for 32 bit kernel
Yes, that we can move, of course. On February 1, 2014 4:30:17 PM PST, Andy Lutomirski wrote: >On Sat, Feb 1, 2014 at 4:26 PM, H. Peter Anvin wrote: >> On 02/01/2014 03:59 PM, Andy Lutomirski wrote: >>> >>> If it is, indeed, okay to use non-fixed maps on 32-bit, it might >>> also be okay on 64-bit. If so, it could be useful to implement >that, >>> which would remove a bit of a wart and allow PR_SET_TSC to work >>> usefully for 64-bit userspace. (This would remove the need for the >>> VVAR macro and would allow shorter rip-relative address modes.) >>> >> >> We can't really move the 64-bit legacy vsyscall area, though, as it >is >> an ABI. It can be disabled with vsyscall=none, but Linus has >vehemently >> vetoed removing them. > >VVAR != vsyscall. They've been different pages since I wrote the >vsyscall emulation stuff. Any userspace code that relies on any of >the contents of the VVAR page is totally screwed already, since the >layout changes semi-regularly and depends on whether lockdep is >enabled. > >> >>> (Note that those fixmaps are a security problem on native 32-bit if >>> NX is not available. We may not care.) >> >> Not only on native 32 bit... although the amount of 64-bit hardware >> without NX is quite small, the same is true for anywhere near modern >> 32-bit hardware. > >It can't be a problem for 32-bit compat mode, though, >since userspace can't address the fixmap anyway. > >> -#define VDSO_HIGH_BASE 0xe000U /* CONFIG_COMPAT_VDSO >address */ +#define VDSO_HIGH_BASE 0xc000U /* CONFIG_COMPAT_VDSO >address */ >>> >>> This is odd. Can you explain it? >>> >> >> He needs 3 pages instead of 1 after his changes. > >Right. But there's some obscure ABI reason for CONFIG_COMPAT_VDSO, >and if this breaks it, then it's no good. From extremely vague >memory, there's some version of SuSE that breaks if the 32-bit vdso >moves. I have no idea what the bug is, but moving a "compat" address >seems suspect. > >--Andy -- Sent from my mobile phone. Please pardon brevity and lack of formatting. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/4] Add 32 bit VDSO time support for 32 bit kernel
On Sat, Feb 1, 2014 at 4:26 PM, H. Peter Anvin wrote: > On 02/01/2014 03:59 PM, Andy Lutomirski wrote: >> >> If it is, indeed, okay to use non-fixed maps on 32-bit, it might >> also be okay on 64-bit. If so, it could be useful to implement that, >> which would remove a bit of a wart and allow PR_SET_TSC to work >> usefully for 64-bit userspace. (This would remove the need for the >> VVAR macro and would allow shorter rip-relative address modes.) >> > > We can't really move the 64-bit legacy vsyscall area, though, as it is > an ABI. It can be disabled with vsyscall=none, but Linus has vehemently > vetoed removing them. VVAR != vsyscall. They've been different pages since I wrote the vsyscall emulation stuff. Any userspace code that relies on any of the contents of the VVAR page is totally screwed already, since the layout changes semi-regularly and depends on whether lockdep is enabled. > >> (Note that those fixmaps are a security problem on native 32-bit if >> NX is not available. We may not care.) > > Not only on native 32 bit... although the amount of 64-bit hardware > without NX is quite small, the same is true for anywhere near modern > 32-bit hardware. It can't be a problem for 32-bit compat mode, though, since userspace can't address the fixmap anyway. > >>> >>> -#define VDSO_HIGH_BASE 0xe000U /* CONFIG_COMPAT_VDSO address */ >>> +#define VDSO_HIGH_BASE 0xc000U /* CONFIG_COMPAT_VDSO address */ >> >> This is odd. Can you explain it? >> > > He needs 3 pages instead of 1 after his changes. Right. But there's some obscure ABI reason for CONFIG_COMPAT_VDSO, and if this breaks it, then it's no good. From extremely vague memory, there's some version of SuSE that breaks if the 32-bit vdso moves. I have no idea what the bug is, but moving a "compat" address seems suspect. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/4] Add 32 bit VDSO time support for 32 bit kernel
On 02/01/2014 03:59 PM, Andy Lutomirski wrote: > > If it is, indeed, okay to use non-fixed maps on 32-bit, it might > also be okay on 64-bit. If so, it could be useful to implement that, > which would remove a bit of a wart and allow PR_SET_TSC to work > usefully for 64-bit userspace. (This would remove the need for the > VVAR macro and would allow shorter rip-relative address modes.) > We can't really move the 64-bit legacy vsyscall area, though, as it is an ABI. It can be disabled with vsyscall=none, but Linus has vehemently vetoed removing them. > (Note that those fixmaps are a security problem on native 32-bit if > NX is not available. We may not care.) Not only on native 32 bit... although the amount of 64-bit hardware without NX is quite small, the same is true for anywhere near modern 32-bit hardware. >> >> -#define VDSO_HIGH_BASE 0xe000U /* CONFIG_COMPAT_VDSO address */ >> +#define VDSO_HIGH_BASE 0xc000U /* CONFIG_COMPAT_VDSO address */ > > This is odd. Can you explain it? > He needs 3 pages instead of 1 after his changes. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Would devm_regulator_enable be useful ?
Hi all, while working with regulators, I noticed that there is no devm_regulator_enable() API. Seems to me it would be useful to have it, but then devm_clk_enable() doesn't exist either, so I wonder if there is a reason for not having it. I'll be happy to submit a patch if people think it is useful; on the other side, I would like to understand the reason for not having it if there is one. Thanks, Guenter -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 11/13] ACPI / hotplug / PCI: Simplify hotplug_event()
From: Rafael J. Wysocki A few lines of code can be cut from hotplug_event() by defining and initializing the slot variable at the top of the function, so do that. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 19 ++- 1 file changed, 6 insertions(+), 13 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -792,6 +792,7 @@ static void hotplug_event(acpi_handle ha { struct acpiphp_context *context = data; struct acpiphp_func *func = >func; + struct acpiphp_slot *slot = func->slot; struct acpiphp_bridge *bridge; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), @@ -813,14 +814,11 @@ static void hotplug_event(acpi_handle ha pr_debug("%s: Bus check notify on %s\n", __func__, objname); pr_debug("%s: re-enumerating slots under %s\n", __func__, objname); - if (bridge) { + if (bridge) acpiphp_check_bridge(bridge); - } else { - struct acpiphp_slot *slot = func->slot; + else if (!(slot->flags & SLOT_IS_GOING_AWAY)) + enable_slot(slot); - if (!(slot->flags & SLOT_IS_GOING_AWAY)) - enable_slot(slot); - } break; case ACPI_NOTIFY_DEVICE_CHECK: @@ -828,12 +826,7 @@ static void hotplug_event(acpi_handle ha pr_debug("%s: Device check notify on %s\n", __func__, objname); if (bridge) { acpiphp_check_bridge(bridge); - } else { - struct acpiphp_slot *slot = func->slot; - - if (slot->flags & SLOT_IS_GOING_AWAY) - break; - + } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) { /* * Check if anything has changed in the slot and rescan * from the parent if that's the case. @@ -846,7 +839,7 @@ static void hotplug_event(acpi_handle ha case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ pr_debug("%s: Device eject notify on %s\n", __func__, objname); - acpiphp_disable_and_eject_slot(func->slot); + acpiphp_disable_and_eject_slot(slot); break; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 9/13] ACPI / hotplug / PCI: Drop acpiphp_bus_add()
From: Rafael J. Wysocki acpiphp_bus_add() is only called from one place, so move the code out of it into that place and drop it. Also make that code use func_to_acpi_device() to get the struct acpi_device pointer it needs instead of calling acpi_bus_get_device() which may be costly. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 22 ++ 1 file changed, 6 insertions(+), 16 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -470,20 +470,6 @@ static unsigned char acpiphp_max_busnr(s return max; } -/** - * acpiphp_bus_add - Scan ACPI namespace subtree. - * @handle: ACPI object handle to start the scan from. - */ -static void acpiphp_bus_add(acpi_handle handle) -{ - struct acpi_device *adev = NULL; - - acpi_bus_scan(handle); - acpi_bus_get_device(handle, ); - if (acpi_device_enumerated(adev)) - acpi_device_set_power(adev, ACPI_STATE_D0); -} - static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) { struct acpiphp_func *func; @@ -523,9 +509,13 @@ static int acpiphp_rescan_slot(struct ac { struct acpiphp_func *func; - list_for_each_entry(func, >funcs, sibling) - acpiphp_bus_add(func_to_handle(func)); + list_for_each_entry(func, >funcs, sibling) { + struct acpi_device *adev = func_to_acpi_device(func); + acpi_bus_scan(adev->handle); + if (acpi_device_enumerated(adev)) + acpi_device_set_power(adev, ACPI_STATE_D0); + } return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0)); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 10/13] ACPI / hotplug / PCI: Drop crit_sect locking
From: Rafael J. Wysocki After recent PCI core changes related to the rescan/remove locking, the code sections under crit_sect mutexes from ACPIPHP slot objects are always executed under the general PCI rescan/remove lock. For this reason, the crit_sect mutexes are simply redundant, so drop them. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp.h |1 - drivers/pci/hotplug/acpiphp_glue.c | 23 +++ 2 files changed, 3 insertions(+), 21 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -328,7 +328,6 @@ static acpi_status register_slot(acpi_ha slot->bus = bridge->pci_bus; slot->device = device; INIT_LIST_HEAD(>funcs); - mutex_init(>crit_sect); list_add_tail(>node, >slots); @@ -723,7 +722,6 @@ static void acpiphp_check_bridge(struct struct pci_bus *bus = slot->bus; struct pci_dev *dev, *tmp; - mutex_lock(>crit_sect); if (slot_no_hotplug(slot)) { ; /* do nothing */ } else if (get_slot_status(slot) == ACPI_STA_ALL) { @@ -738,7 +736,6 @@ static void acpiphp_check_bridge(struct } else { disable_slot(slot); } - mutex_unlock(>crit_sect); } } @@ -821,12 +818,8 @@ static void hotplug_event(acpi_handle ha } else { struct acpiphp_slot *slot = func->slot; - if (slot->flags & SLOT_IS_GOING_AWAY) - break; - - mutex_lock(>crit_sect); - enable_slot(slot); - mutex_unlock(>crit_sect); + if (!(slot->flags & SLOT_IS_GOING_AWAY)) + enable_slot(slot); } break; @@ -837,7 +830,6 @@ static void hotplug_event(acpi_handle ha acpiphp_check_bridge(bridge); } else { struct acpiphp_slot *slot = func->slot; - int ret; if (slot->flags & SLOT_IS_GOING_AWAY) break; @@ -846,10 +838,7 @@ static void hotplug_event(acpi_handle ha * Check if anything has changed in the slot and rescan * from the parent if that's the case. */ - mutex_lock(>crit_sect); - ret = acpiphp_rescan_slot(slot); - mutex_unlock(>crit_sect); - if (ret) + if (acpiphp_rescan_slot(slot)) acpiphp_check_bridge(func->parent); } break; @@ -1055,13 +1044,10 @@ int acpiphp_enable_slot(struct acpiphp_s if (slot->flags & SLOT_IS_GOING_AWAY) return -ENODEV; - mutex_lock(>crit_sect); /* configure all functions */ if (!(slot->flags & SLOT_ENABLED)) enable_slot(slot); - mutex_unlock(>crit_sect); - pci_unlock_rescan_remove(); return 0; } @@ -1077,8 +1063,6 @@ static int acpiphp_disable_and_eject_slo if (slot->flags & SLOT_IS_GOING_AWAY) return -ENODEV; - mutex_lock(>crit_sect); - /* unconfigure all functions */ disable_slot(slot); @@ -1092,7 +1076,6 @@ static int acpiphp_disable_and_eject_slo break; } - mutex_unlock(>crit_sect); return 0; } Index: linux-pm/drivers/pci/hotplug/acpiphp.h === --- linux-pm.orig/drivers/pci/hotplug/acpiphp.h +++ linux-pm/drivers/pci/hotplug/acpiphp.h @@ -93,7 +93,6 @@ struct acpiphp_slot { struct list_head funcs; /* one slot may have different objects (i.e. for each function) */ struct slot *slot; - struct mutex crit_sect; u8 device; /* pci device# */ u32 flags; /* see below */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 7/13] ACPI / hotplug / PCI: Rework acpiphp_no_hotplug()
From: Rafael J. Wysocki If a struct acpi_device pointer is passed to acpiphp_no_hotplug() instead of an ACPI handle, the function won't need to call acpi_bus_get_device(), which may be costly, any more. Then, trim_stale_devices() can call acpiphp_no_hotplug() passing the struct acpi_device object it already has directly to that function. Make those changes and update slot_no_hotplug() accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -617,11 +617,8 @@ static void disable_slot(struct acpiphp_ slot->flags &= (~SLOT_ENABLED); } -static bool acpiphp_no_hotplug(acpi_handle handle) +static bool acpiphp_no_hotplug(struct acpi_device *adev) { - struct acpi_device *adev = NULL; - - acpi_bus_get_device(handle, ); return adev && adev->flags.no_hotplug; } @@ -629,10 +626,13 @@ static bool slot_no_hotplug(struct acpip { struct acpiphp_func *func; - list_for_each_entry(func, >funcs, sibling) - if (acpiphp_no_hotplug(func_to_handle(func))) - return true; + list_for_each_entry(func, >funcs, sibling) { + struct acpi_device *adev = NULL; + acpi_bus_get_device(func_to_handle(func), ); + if (acpiphp_no_hotplug(adev)) + return true; + } return false; } @@ -689,13 +689,12 @@ static void trim_stale_devices(struct pc bool alive = false; if (adev) { - acpi_handle handle = adev->handle; acpi_status status; unsigned long long sta; - status = acpi_evaluate_integer(handle, "_STA", NULL, ); + status = acpi_evaluate_integer(adev->handle, "_STA", NULL, ); alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL) - || acpiphp_no_hotplug(handle); + || acpiphp_no_hotplug(adev); } if (!alive) { u32 v; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 8/13] ACPI / hotplug / PCI: Store acpi_device pointer in acpiphp_context
From: Rafael J. Wysocki After recent modifications of the ACPI core making it create a struct acpi_device object for every namespace node representing a device regardless of the current status of that device the ACPIPHP code can store a struct acpi_device pointer instead of an ACPI handle in struct acpiphp_context. This immediately makes it possible to avoid making potentially costly calls to acpi_bus_get_device() in two places and allows some more simplifications to be made going forward. The reason why that is correct is because ACPIPHP only installs hotify handlers for namespace nodes that exist when acpiphp_enumerate_slots() is called for their parent bridge. That only happens if the parent bridge has an ACPI companion associated with it, which means that the ACPI namespace scope in question has been scanned already at that point. That, in turn, means that struct acpi_device objects have been created for all namespace nodes in that scope and pointers to those objects can be stored directly instead of their ACPI handles. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp.h |9 +-- drivers/pci/hotplug/acpiphp_glue.c | 44 + 2 files changed, 28 insertions(+), 25 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp.h === --- linux-pm.orig/drivers/pci/hotplug/acpiphp.h +++ linux-pm/drivers/pci/hotplug/acpiphp.h @@ -117,8 +117,8 @@ struct acpiphp_func { }; struct acpiphp_context { - acpi_handle handle; struct acpiphp_func func; + struct acpi_device *adev; struct acpiphp_bridge *bridge; unsigned int refcount; }; @@ -128,9 +128,14 @@ static inline struct acpiphp_context *fu return container_of(func, struct acpiphp_context, func); } +static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func) +{ + return func_to_context(func)->adev; +} + static inline acpi_handle func_to_handle(struct acpiphp_func *func) { - return func_to_context(func)->handle; + return func_to_acpi_device(func)->handle; } /* Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -73,11 +73,11 @@ static void acpiphp_context_handler(acpi /** * acpiphp_init_context - Create hotplug context and grab a reference to it. - * @handle: ACPI object handle to create the context for. + * @adev: ACPI device object to create the context for. * * Call under acpiphp_context_lock. */ -static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) +static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) { struct acpiphp_context *context; acpi_status status; @@ -86,9 +86,9 @@ static struct acpiphp_context *acpiphp_i if (!context) return NULL; - context->handle = handle; + context->adev = adev; context->refcount = 1; - status = acpi_attach_data(handle, acpiphp_context_handler, context); + status = acpi_attach_data(adev->handle, acpiphp_context_handler, context); if (ACPI_FAILURE(status)) { kfree(context); return NULL; @@ -118,7 +118,7 @@ static struct acpiphp_context *acpiphp_g /** * acpiphp_put_context - Drop a reference to ACPI hotplug context. - * @handle: ACPI object handle to put the context for. + * @context: ACPI hotplug context to drop a reference to. * * The context object is removed if there are no more references to it. * @@ -130,7 +130,7 @@ static void acpiphp_put_context(struct a return; WARN_ON(context->bridge); - acpi_detach_data(context->handle, acpiphp_context_handler); + acpi_detach_data(context->adev->handle, acpiphp_context_handler); kfree(context); } @@ -265,6 +265,7 @@ static acpi_status register_slot(acpi_ha { struct acpiphp_bridge *bridge = data; struct acpiphp_context *context; + struct acpi_device *adev; struct acpiphp_slot *slot; struct acpiphp_func *newfunc; acpi_status status = AE_OK; @@ -284,12 +285,14 @@ static acpi_status register_slot(acpi_ha "can't evaluate _ADR (%#x)\n", status); return AE_OK; } + if (acpi_bus_get_device(handle, )) + return AE_OK; device = (adr >> 16) & 0x; function = adr & 0x; mutex_lock(_context_lock); - context = acpiphp_init_context(handle); + context = acpiphp_init_context(adev); if (!context) { mutex_unlock(_context_lock); acpi_handle_err(handle, "No hotplug context\n"); @@ -607,12 +610,8 @@ static void disable_slot(struct acpiphp_ if (PCI_SLOT(dev->devfn) ==
[PATCH v2 6/13] ACPI / hotplug / PCI: Drop acpiphp_bus_trim()
From: Rafael J. Wysocki If trim_stale_devices() calls acpi_bus_trim() directly, we can save a potentially costly acpi_bus_get_device() invocation. After making that change acpiphp_bus_trim() would only be called from one place, so move the code from it to that place and drop it. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 30 +++--- 1 file changed, 11 insertions(+), 19 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -468,19 +468,6 @@ static unsigned char acpiphp_max_busnr(s } /** - * acpiphp_bus_trim - Trim device objects in an ACPI namespace subtree. - * @handle: ACPI device object handle to start from. - */ -static void acpiphp_bus_trim(acpi_handle handle) -{ - struct acpi_device *adev = NULL; - - acpi_bus_get_device(handle, ); - if (adev) - acpi_bus_trim(adev); -} - -/** * acpiphp_bus_add - Scan ACPI namespace subtree. * @handle: ACPI object handle to start the scan from. */ @@ -620,8 +607,12 @@ static void disable_slot(struct acpiphp_ if (PCI_SLOT(dev->devfn) == slot->device) pci_stop_and_remove_bus_device(dev); - list_for_each_entry(func, >funcs, sibling) - acpiphp_bus_trim(func_to_handle(func)); + list_for_each_entry(func, >funcs, sibling) { + struct acpi_device *adev; + + if (!acpi_bus_get_device(func_to_handle(func), )) + acpi_bus_trim(adev); + } slot->flags &= (~SLOT_ENABLED); } @@ -693,11 +684,12 @@ static unsigned int get_slot_status(stru */ static void trim_stale_devices(struct pci_dev *dev) { - acpi_handle handle = ACPI_HANDLE(>dev); + struct acpi_device *adev = ACPI_COMPANION(>dev); struct pci_bus *bus = dev->subordinate; bool alive = false; - if (handle) { + if (adev) { + acpi_handle handle = adev->handle; acpi_status status; unsigned long long sta; @@ -713,8 +705,8 @@ static void trim_stale_devices(struct pc } if (!alive) { pci_stop_and_remove_bus_device(dev); - if (handle) - acpiphp_bus_trim(handle); + if (adev) + acpi_bus_trim(adev); } else if (bus) { struct pci_dev *child, *tmp; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 12/13] ACPI / hotplug / PCI: Use acpi_handle_debug() in hotplug_event()
From: Rafael J. Wysocki Make hotplug_event() use acpi_handle_debug() instead of an open-coded debug message printing and clean up the messages printed by it. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -794,9 +794,6 @@ static void hotplug_event(acpi_handle ha struct acpiphp_func *func = >func; struct acpiphp_slot *slot = func->slot; struct acpiphp_bridge *bridge; - char objname[64]; - struct acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; mutex_lock(_context_lock); bridge = context->bridge; @@ -806,14 +803,11 @@ static void hotplug_event(acpi_handle ha mutex_unlock(_context_lock); pci_lock_rescan_remove(); - acpi_get_name(handle, ACPI_FULL_PATHNAME, ); switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ - pr_debug("%s: Bus check notify on %s\n", __func__, objname); - pr_debug("%s: re-enumerating slots under %s\n", -__func__, objname); + acpi_handle_debug(handle, "Bus check in %s()\n", __func__); if (bridge) acpiphp_check_bridge(bridge); else if (!(slot->flags & SLOT_IS_GOING_AWAY)) @@ -823,7 +817,7 @@ static void hotplug_event(acpi_handle ha case ACPI_NOTIFY_DEVICE_CHECK: /* device check */ - pr_debug("%s: Device check notify on %s\n", __func__, objname); + acpi_handle_debug(handle, "Device check in %s()\n", __func__); if (bridge) { acpiphp_check_bridge(bridge); } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) { @@ -838,7 +832,7 @@ static void hotplug_event(acpi_handle ha case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ - pr_debug("%s: Device eject notify on %s\n", __func__, objname); + acpi_handle_debug(handle, "Eject request in %s()\n", __func__); acpiphp_disable_and_eject_slot(slot); break; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 5/13] ACPI / hotplug / PCI: Simplify register_slot()
From: Rafael J. Wysocki The err label in register_slot() is only jumped to from one place, so move the code under the label to that place and drop the label. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -316,8 +316,10 @@ static acpi_status register_slot(acpi_ha slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { - status = AE_NO_MEMORY; - goto err; + mutex_lock(_context_lock); + acpiphp_put_context(context); + mutex_unlock(_context_lock); + return AE_NO_MEMORY; } slot->bus = bridge->pci_bus; @@ -385,12 +387,6 @@ static acpi_status register_slot(acpi_ha } return AE_OK; - - err: - mutex_lock(_context_lock); - acpiphp_put_context(context); - mutex_unlock(_context_lock); - return status; } static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 4/13] ACPI / hotplug / PCI: Proper kerneldoc comments for enumeration/removal
From: Rafael J. Wysocki Add proper kerneldoc comments describing acpiphp_enumerate_slots() and acpiphp_remove_slots(). Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -968,9 +968,12 @@ static void handle_hotplug_event(acpi_ha acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); } -/* - * Create hotplug slots for the PCI bus. - * It should always return 0 to avoid skipping following notifiers. +/** + * acpiphp_enumerate_slots - Enumerate PCI slots for a given bus. + * @bus: PCI bus to enumerate the slots for. + * + * A "slot" is an object associated with a PCI device number. All functions + * (PCI devices) with the same bus and device number belong to the same slot. */ void acpiphp_enumerate_slots(struct pci_bus *bus) { @@ -1043,7 +1046,10 @@ void acpiphp_enumerate_slots(struct pci_ } } -/* Destroy hotplug slots associated with the PCI bus */ +/** + * acpiphp_remove_slots - Remove slot objects associated with a given bus. + * @bus: PCI bus to remove the slot objects for. + */ void acpiphp_remove_slots(struct pci_bus *bus) { struct acpiphp_bridge *bridge; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/13] ACPI / hotplug / PCI: Remove entries from bus->devices in reverse order
From: Rafael J. Wysocki According to the changelog of commit 29ed1f29b68a (PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device) it is unsafe to walk the bus->devices list of a PCI bus and remove devices from it in direct order, because that may lead to NULL pointer dereferences related to virtual functions. For this reason, change all of the bus->devices list walks in acpiphp_glue.c during which devices may be removed to be carried out in reverse order. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c |8 1 file changed, 4 insertions(+), 4 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -742,7 +742,7 @@ static void trim_stale_devices(struct pc /* The device is a bridge. so check the bus below it. */ pm_runtime_get_sync(>dev); - list_for_each_entry_safe(child, tmp, >devices, bus_list) + list_for_each_entry_safe_reverse(child, tmp, >devices, bus_list) trim_stale_devices(child); pm_runtime_put(>dev); @@ -773,8 +773,8 @@ static void acpiphp_check_bridge(struct ; /* do nothing */ } else if (get_slot_status(slot) == ACPI_STA_ALL) { /* remove stale devices if any */ - list_for_each_entry_safe(dev, tmp, >devices, -bus_list) + list_for_each_entry_safe_reverse(dev, tmp, +>devices, bus_list) if (PCI_SLOT(dev->devfn) == slot->device) trim_stale_devices(dev); @@ -805,7 +805,7 @@ static void acpiphp_sanitize_bus(struct int i; unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; - list_for_each_entry_safe(dev, tmp, >devices, bus_list) { + list_for_each_entry_safe_reverse(dev, tmp, >devices, bus_list) { for (i=0; iresource[i]; if ((res->flags & type_mask) && !res->start && -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/13] ACPI / hotplug / PCI: Move PCI rescan-remove locking to hotplug_event()
From: Rafael J. Wysocki Commit 9217a984671e (ACPI / hotplug / PCI: Use global PCI rescan-remove locking) modified ACPIPHP to protect its PCI device removal and addition code paths from races against sysfs-driven rescan and remove operations with the help of PCI rescan-remove locking. However, it overlooked the fact that hotplug_event_work() is not the only caller of hotplug_event() which may also be called by dock_hotplug_event() and that code path is missing the PCI rescan-remove locking. This means that, although the PCI rescan-remove lock is held as appropriate during the handling of events originating from handle_hotplug_event(), the ACPIPHP's operations resulting from dock events may still suffer the race conditions that commit 9217a984671e was supposed to eliminate. To address that problem, move the PCI rescan-remove locking from hotplug_event_work() to hotplug_event() so that it is used regardless of the way that function is invoked. Revamps: 9217a984671e (ACPI / hotplug / PCI: Use global PCI rescan-remove locking) Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -852,6 +852,7 @@ static void hotplug_event(acpi_handle ha mutex_unlock(_context_lock); + pci_lock_rescan_remove(); acpi_get_name(handle, ACPI_FULL_PATHNAME, ); switch (type) { @@ -905,6 +906,7 @@ static void hotplug_event(acpi_handle ha break; } + pci_unlock_rescan_remove(); if (bridge) put_bridge(bridge); } @@ -915,11 +917,9 @@ static void hotplug_event_work(void *dat acpi_handle handle = context->handle; acpi_scan_lock_acquire(); - pci_lock_rescan_remove(); hotplug_event(handle, type, context); - pci_unlock_rescan_remove(); acpi_scan_lock_release(); acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); put_bridge(context->func.parent); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/13] ACPI / hotplug / PCI: Simplify disable_slot()
From: Rafael J. Wysocki After recent PCI core changes related to the rescan/remove locking, the ACPIPHP's disable_slot() function is only called under the general PCI rescan/remove lock, so it doesn't have to use dev_in_slot() any more to avoid race conditions. Make it simply walk the devices on the bus and drop the ones in the slot being disabled and drop dev_in_slot() which has no more users. Moreover, to avoid problems described in the changelog of commit 29ed1f29b68a (PCI: pciehp: Fix null pointer deref when hot-removing SR-IOV device), make disable_slot() carry out the list walk in reverse order. Signed-off-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 28 +--- 1 file changed, 5 insertions(+), 23 deletions(-) Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -604,32 +604,15 @@ static void __ref enable_slot(struct acp } } -/* return first device in slot, acquiring a reference on it */ -static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) -{ - struct pci_bus *bus = slot->bus; - struct pci_dev *dev; - struct pci_dev *ret = NULL; - - down_read(_bus_sem); - list_for_each_entry(dev, >devices, bus_list) - if (PCI_SLOT(dev->devfn) == slot->device) { - ret = pci_dev_get(dev); - break; - } - up_read(_bus_sem); - - return ret; -} - /** * disable_slot - disable a slot * @slot: ACPI PHP slot */ static void disable_slot(struct acpiphp_slot *slot) { + struct pci_bus *bus = slot->bus; + struct pci_dev *dev, *prev; struct acpiphp_func *func; - struct pci_dev *pdev; /* * enable_slot() enumerates all functions in this device via @@ -637,10 +620,9 @@ static void disable_slot(struct acpiphp_ * methods (_EJ0, etc.) or not. Therefore, we remove all functions * here. */ - while ((pdev = dev_in_slot(slot))) { - pci_stop_and_remove_bus_device(pdev); - pci_dev_put(pdev); - } + list_for_each_entry_safe_reverse(dev, prev, >devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->device) + pci_stop_and_remove_bus_device(dev); list_for_each_entry(func, >funcs, sibling) acpiphp_bus_trim(func_to_handle(func)); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 0/13] ACPI / hotplug / PCI: Updates on top of changes merged recently
On Monday, January 27, 2014 01:37:17 AM Rafael J. Wysocki wrote: > Hi All, > > ACPIPHP can be simplified a bit on top of some PCI and ACPI changes merged > recently and the following series of patches implements those simplifications: > > [1/11] Fix up two kerneldoc comments in acpiphp_glue.c. > [2/11] Get rid of an unnecessary label in register_slot(). > [3/11] Drop acpiphp_bus_trim() and use acpi_bus_trim() instead of it directly. > [4/11] Move the acpi_bus_get_device() call out of acpiphp_no_hotplug(). > [5/11] Store struct acpi_device pointers instead of ACPI handles in struct > acpiphp_context. > [6/11] Drop acpiphp_bus_add() (which has only one user). > [7/11] Drop crit_sect mutexes (that are redundant). > [8/11] Clean up the usage of the slot variable in hotplug_event(). > [9/11] Drop dev_in_slot() and rework disable_slot() to walk bus->devices > directly. > [10/11] Use acpi_handle_debug() in hotplug_event() instead of open-coded > stuff. > [11/11] Drop handle argument from the member functions of struct > acpi_dock_ops. > > All of that is relateively straightforward, but I have some more intrusive > changes > on top of it in the works. They will be posted separately later this week. I've learned a couple of things since I sent this patchset. First, all bus->devices list walks that may remove PCI devices should be done in reverse order or they can crash if virtual functions are involved. Second, hotplug_event() (in acpiphp_glue.c) has to acquire pci_rescan_remove_lock by itself, because it may be called from multiple places and all of them need that lock to be held. That is done by patches [1-2/13] which I'm planning to push as fixes for 3.14-rc2. The rest is pretty much the same as last time except that the old patch [9/11] became [3/13] in this series and it has been changed so that the list is walked in reverse order. Thanks! -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 13/13] ACPI / hotplug: Do not pass ACPI handles to ACPI dock operations
From: Rafael J. Wysocki None of the existing users of struct acpi_dock_ops actually needs the first argument of its member functions, so redefine those functions to take only two arguments, the event type and data pointer, and update the users of struct acpi_dock_ops accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c|4 ++-- drivers/ata/libata-acpi.c |8 drivers/pci/hotplug/acpiphp_glue.c | 13 +++-- include/acpi/acpi_drivers.h|6 +++--- 4 files changed, 16 insertions(+), 15 deletions(-) Index: linux-pm/include/acpi/acpi_drivers.h === --- linux-pm.orig/include/acpi/acpi_drivers.h +++ linux-pm/include/acpi/acpi_drivers.h @@ -110,9 +110,9 @@ void pci_acpi_crs_quirks(void); Dock Station -- */ struct acpi_dock_ops { - acpi_notify_handler fixup; - acpi_notify_handler handler; - acpi_notify_handler uevent; + void (*handler)(u32 event_type, void *data); + void (*fixup)(u32 event_type, void *data); + void (*uevent)(u32 event_type, void *data); }; #ifdef CONFIG_ACPI_DOCK Index: linux-pm/drivers/pci/hotplug/acpiphp_glue.c === --- linux-pm.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-pm/drivers/pci/hotplug/acpiphp_glue.c @@ -63,7 +63,7 @@ static DEFINE_MUTEX(acpiphp_context_lock static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); -static void hotplug_event(acpi_handle handle, u32 type, void *data); +static void hotplug_event(u32 type, void *data); static void free_bridge(struct kref *kref); static void acpiphp_context_handler(acpi_handle handle, void *context) @@ -185,7 +185,7 @@ static void free_bridge(struct kref *kre * TBD - figure out a way to only call fixups for * systems that require them. */ -static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) +static void post_dock_fixups(u32 event, void *data) { struct acpiphp_context *context = data; struct pci_bus *bus = context->func.slot->bus; @@ -788,11 +788,12 @@ void acpiphp_check_host_bridge(acpi_hand static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); -static void hotplug_event(acpi_handle handle, u32 type, void *data) +static void hotplug_event(u32 type, void *data) { struct acpiphp_context *context = data; struct acpiphp_func *func = >func; struct acpiphp_slot *slot = func->slot; + acpi_handle handle = context->adev->handle; struct acpiphp_bridge *bridge; mutex_lock(_context_lock); @@ -845,14 +846,14 @@ static void hotplug_event(acpi_handle ha static void hotplug_event_work(void *data, u32 type) { struct acpiphp_context *context = data; - acpi_handle handle = context->adev->handle; acpi_scan_lock_acquire(); - hotplug_event(handle, type, context); + hotplug_event(type, context); acpi_scan_lock_release(); - acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); + acpi_evaluate_hotplug_ost(context->adev->handle, type, + ACPI_OST_SC_SUCCESS, NULL); put_bridge(context->func.parent); } Index: linux-pm/drivers/acpi/dock.c === --- linux-pm.orig/drivers/acpi/dock.c +++ linux-pm/drivers/acpi/dock.c @@ -185,7 +185,7 @@ static void dock_release_hotplug(struct static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, enum dock_callback_type cb_type) { - acpi_notify_handler cb = NULL; + void (*cb)(u32, void *) = NULL; bool run = false; mutex_lock(_lock); @@ -213,7 +213,7 @@ static void dock_hotplug_event(struct do return; if (cb) - cb(dd->handle, event, dd->hp_context); + cb(event, dd->hp_context); dock_release_hotplug(dd); } Index: linux-pm/drivers/ata/libata-acpi.c === --- linux-pm.orig/drivers/ata/libata-acpi.c +++ linux-pm/drivers/ata/libata-acpi.c @@ -121,14 +121,14 @@ static void ata_acpi_handle_hotplug(stru ata_port_wait_eh(ap); } -static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) +static void ata_acpi_dev_notify_dock(u32 event, void *data) { struct ata_device *dev = data; ata_acpi_handle_hotplug(dev->link->ap, dev, event); } -static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) +static void ata_acpi_ap_notify_dock(u32 event, void *data) { struct ata_port *ap
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On Sat, Feb 1, 2014 at 3:40 PM, H. Peter Anvin wrote: > > OK, let's circle back for a bit. We have an active bug, and we clearly > have a lot of restructuring that could/should be done. We need to fix > the bug first; if we're going to a bunch of restructuring then that > ought to be separate. The first bit is how we fix the immediate bug. So either of my suggested changes to __kernel_fpu_end() _should_ fix the bug, with the caveat that if we do take the "check tsk-used-math" version, we had better verify that yes, we allocate the save storage before we set that flag. One of the reasons I tended to prefer simpler the "just do stts()" version is that it seemed safer. I am a bit worried about the whole interaction with synchronous task state and interrupts. Suresh's notion of just always allocating the FP state save area at process creation would fix it too. So many ways to fix it, so little knowledge about the actual usage patterns and performance issues.. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL] Btrfs
On Thu, 30 Jan 2014, Chris Mason wrote: > > Hi Linus > > Please pull my for-linus branch: > > git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git for-linus > > There are two conflicts right now, one with the ACL code (pick your > version) and one with Kent's changes in the block layer pull. That one > is pretty obvious too, just do both our cleanup and Kent's rework. > > This is a pretty big pull, and most of these changes have been floating > in btrfs-next for a long time. Filipe's properties work is a cool > building block for inheriting attributes like compression down on a > per inode basis. > > Jeff Mahoney kicked in code to export filesystem info into sysfs. > > Otherwise, lots of performance improvements, cleanups and bug fixes. > > Looks like there are still a few other small pending incrementals, but I > wanted to get the bulk of this in first. > > Filipe David Borba Manana (29) commits (+1856/-301): > Btrfs: fix deadlock when iterating inode refs and running delayed inodes > (+12/-7) > Btrfs: fix send file hole detection leading to data corruption (+15/-0) > Btrfs: remove field tree_mod_seq_elem from btrfs_fs_info struct (+0/-1) > Btrfs: make send's file extent item search more efficient (+17/-10) > Btrfs: fix infinite path build loops in incremental send (+518/-21) > Btrfs: reduce btree node locking duration on item update (+14/-10) > Btrfs: return immediately if tree log mod is not necessary (+1/-1) > Btrfs: fix pass of transid with wrong endianness in send.c (+3/-3) > Btrfs: fix btrfs_search_slot_for_read backwards iteration (+3/-1) > Btrfs: fix send to not send non-aligned clone operations (+2/-1) > Btrfs: faster and more efficient extent map insertion (+41/-31) > Btrfs: fix extent boundary check in bio_readpage_error (+1/-1) > Btrfs: faster file extent item search in clone ioctl (+14/-9) > Btrfs: unlock inodes in correct order in clone ioctl (+11/-3) > Btrfs: faster file extent item replace operations (+114/-46) > Btrfs: avoid unnecessary ordered extent cache resets (+2/-1) > Btrfs: fix very slow inode eviction and fs unmount (+84/-14) > Btrfs: fix snprintf usage by send's gen_unique_name (+1/-1) > Btrfs: fix ordered extent check in btrfs_punch_hole (+1/-1) > Btrfs: fix btrfs boot when compiled as built-in (+73/-9) This one, 14a958e678cd ("Btrfs: fix btrfs boot when compiled as built-in"), breaks the build if CONFIG_LIBCRC32C=m: fs/built-in.o: In function `btrfs_check_super_csum': disk-io.c:(.text+0x1a1c8b): undefined reference to `crc32c' fs/built-in.o: In function `write_dev_supers.isra.120': disk-io.c:(.text+0x1a2054): undefined reference to `crc32c' fs/built-in.o: In function `csum_tree_block.isra.122': disk-io.c:(.text+0x1a22c4): undefined reference to `crc32c' fs/built-in.o: In function `btrfs_csum_data': (.text+0x1a2a46): undefined reference to `crc32c' fs/built-in.o: In function `send_cmd': send.c:(.text+0x20fe4c): undefined reference to `crc32c' -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/4] Add 32 bit VDSO time support for 32 bit kernel
On Sat, Feb 1, 2014 at 7:32 AM, wrote: > From: Stefani Seibold > > This patch add the time support for 32 bit a VDSO to a 32 bit kernel. > > For 32 bit programs running on a 32 bit kernel, the same mechanism is > used as for 64 bit programs running on a 64 bit kernel. > > Signed-off-by: Stefani Seibold I have multiple issues with this patch. - It's very hard to review the vclock_gettime.c changes. You're doing at least three things in there: reworking the return types of all the helpers, moving code, and adding 32-bit code. Can you split the patch so that the resulting diff is readable? (e.g. one patch that purely reorders things, one patch that reworks the return types, and a third patch with the meat? if splitting into just two results in a comprehensible diff, that's fine, too.) - There are multiple vvar mappings. I still don't understand why. You've stuck the vvar page into the fixmap *and* into a special mapping. The former works on native 32 bit only, but you don't seem to *use* the mapping, which confuses me. The latter may or may not confuse things (criu?) that try to parse /proc/self/maps. If it is, indeed, okay to use non-fixed maps on 32-bit, it might also be okay on 64-bit. If so, it could be useful to implement that, which would remove a bit of a wart and allow PR_SET_TSC to work usefully for 64-bit userspace. (This would remove the need for the VVAR macro and would allow shorter rip-relative address modes.) (Note that those fixmaps are a security problem on native 32-bit if NX is not available. We may not care.) - The VVAR macro is all screwed up now. Please either continue to use it (and fix the definition) or stop using it everywhere and figure out a different way. The current approach is just going to fester if anyone ports the rest of the vdso to work in 32-bit environments. - You've hardcoded the address of the counter in the HPET page into the linker script. Please don't. If you really need to have the HPET mapping in the linker script, please just reference the base address and add the offset in C code using the appropriate macro. > --- > arch/x86/include/asm/elf.h| 2 +- > arch/x86/include/asm/vdso.h | 3 + > arch/x86/include/asm/vdso32.h | 10 +++ > arch/x86/vdso/Makefile| 7 ++ > arch/x86/vdso/vclock_gettime.c| 165 > ++ > arch/x86/vdso/vdso-layout.lds.S | 25 ++ > arch/x86/vdso/vdso32-setup.c | 47 -- > arch/x86/vdso/vdso32/vclock_gettime.c | 16 > arch/x86/vdso/vdso32/vdso32.lds.S | 11 ++- > 9 files changed, 218 insertions(+), 68 deletions(-) > create mode 100644 arch/x86/include/asm/vdso32.h > create mode 100644 arch/x86/vdso/vdso32/vclock_gettime.c > > diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h > index 9c999c1..21bae90 100644 > --- a/arch/x86/include/asm/elf.h > +++ b/arch/x86/include/asm/elf.h > @@ -289,7 +289,7 @@ do { > \ > > #else /* CONFIG_X86_32 */ > > -#define VDSO_HIGH_BASE 0xe000U /* CONFIG_COMPAT_VDSO address */ > +#define VDSO_HIGH_BASE 0xc000U /* CONFIG_COMPAT_VDSO address */ This is odd. Can you explain it? --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
Am Samstag, den 01.02.2014, 18:28 -0500 schrieb Ilia Mirkin: > On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach wrote: > > Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot: > >> Add a clumsy-but-working FB support for GK20A. This chip only uses system > >> memory, so we allocate a big chunk using CMA and let the existing memory > >> managers work on it. > >> > >> A better future design would be to allocate objects directly from system > >> memory without having to suffer from the limitations of a large, > >> contiguous pool. > >> > > I don't know if Tegra124 is similar to 114 in this regard [hint: get the > > TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it > > make sense to take a chunk of the MMIO overlaid memory for this when > > possible, rather than carving this out of CPU accessible mem? > > This is probably a stupid question... what do you need VRAM for > anyways? In _theory_ it's an abstraction to talk about memory that's > not accessible by the CPU. This is obviously not the case here, and > presumably the GPU can access all the memory in the system, so it can > be all treated as "GART" memory... AFAIK all accesses are behind the > in-GPU MMU, so contiguous physical memory isn't an issue either. In > practice, I suspect nouveau automatically sticks certain things into > vram (gpuobj's), but it should be feasible to make them optionally use > GART memory when VRAM is not available. I haven't really looked at the > details though, perhaps that's a major undertaking. > > -ilia > If it's similar to the Tegar114 there actually is memory that isn't accessible from the CPU. About 2GB of the address space is overlaid with MMIO for the devices, so in a 4GB system you potentially have 2GB of RAM that's only visible for the devices. But yes in general nouveau should just fall back to a GART placement if VRAM isn't available. > > > >> Signed-off-by: Alexandre Courbot > >> --- > >> drivers/gpu/drm/nouveau/Makefile | 2 + > >> drivers/gpu/drm/nouveau/core/include/subdev/fb.h | 1 + > >> drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c| 28 ++ > >> drivers/gpu/drm/nouveau/core/subdev/fb/priv.h| 1 + > >> drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c | 67 > >> > >> 5 files changed, 99 insertions(+) > >> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > >> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c > >> > >> diff --git a/drivers/gpu/drm/nouveau/Makefile > >> b/drivers/gpu/drm/nouveau/Makefile > >> index 3548fcd..d9fe3e6 100644 > >> --- a/drivers/gpu/drm/nouveau/Makefile > >> +++ b/drivers/gpu/drm/nouveau/Makefile > >> @@ -100,6 +100,7 @@ nouveau-y += core/subdev/fb/nvaa.o > >> nouveau-y += core/subdev/fb/nvaf.o > >> nouveau-y += core/subdev/fb/nvc0.o > >> nouveau-y += core/subdev/fb/nve0.o > >> +nouveau-y += core/subdev/fb/nvea.o > >> nouveau-y += core/subdev/fb/ramnv04.o > >> nouveau-y += core/subdev/fb/ramnv10.o > >> nouveau-y += core/subdev/fb/ramnv1a.o > >> @@ -114,6 +115,7 @@ nouveau-y += core/subdev/fb/ramnva3.o > >> nouveau-y += core/subdev/fb/ramnvaa.o > >> nouveau-y += core/subdev/fb/ramnvc0.o > >> nouveau-y += core/subdev/fb/ramnve0.o > >> +nouveau-y += core/subdev/fb/ramnvea.o > >> nouveau-y += core/subdev/fb/sddr3.o > >> nouveau-y += core/subdev/fb/gddr5.o > >> nouveau-y += core/subdev/gpio/base.o > >> diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > >> b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > >> index d7ecafb..3905816 100644 > >> --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > >> +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > >> @@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass; > >> extern struct nouveau_oclass *nvaf_fb_oclass; > >> extern struct nouveau_oclass *nvc0_fb_oclass; > >> extern struct nouveau_oclass *nve0_fb_oclass; > >> +extern struct nouveau_oclass *nvea_fb_oclass; > >> > >> #include > >> > >> diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > >> b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > >> new file mode 100644 > >> index 000..5ff6029 > >> --- /dev/null > >> +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > >> @@ -0,0 +1,28 @@ > >> +/* > >> + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. > >> + * > >> + * This program is free software; you can redistribute it and/or modify it > >> + * under the terms and conditions of the GNU General Public License, > >> + * version 2, as published by the Free Software Foundation. > >> + * > >> + * This program is distributed in the hope it will be useful, but WITHOUT > >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > >> for > >> + * more details. > >> + * > >> + */ > >> + > >> +#include "nvc0.h" > >> + > >> +struct nouveau_oclass * > >> +nvea_fb_oclass = &(struct
Re: [Update][PATCH 4/5][RFT] ACPI / hotplug / PCI: Simplify acpi_install_hotplug_notify_handler()
On Friday, January 31, 2014 06:34:22 PM Rafael J. Wysocki wrote: > On Friday, January 31, 2014 07:09:51 PM Mika Westerberg wrote: > > On Fri, Jan 31, 2014 at 05:16:03PM +0100, Rafael J. Wysocki wrote: [...] > > > > [ 64.914639] ACPI: \_SB_.PCI0.RP05: ACPI_NOTIFY_BUS_CHECK event > > [ 64.914640] ACPI: \_SB_.PCI0.RP05: BEFORE mutex_lock() > > > > Then running sysrq-w I get following task as blocked: > > > > [ 346.885950] SysRq : Show Blocked State > > [ 346.887733] taskPC stack pid father > > [ 346.889535] kworker/0:0 D 880100241ae0 5280 4 2 > > 0x > > [ 346.891355] Workqueue: kacpi_notify acpi_os_execute_deferred > > [ 346.893171] 8801003c7d30 0046 880100241710 > > 81e10460 > > [ 346.895011] 8801003c7fd8 000129c0 000129c0 > > 880100241710 > > [ 346.896849] 81e5db70 81e5db74 880100241710 > > > > [ 346.898702] Call Trace: > > [ 346.900518] [] schedule_preempt_disabled+0x24/0x70 > > [ 346.902338] [] __mutex_lock_slowpath+0x132/0x1b0 > > [ 346.904164] [] mutex_lock+0x1a/0x2a > > [ 346.905993] [] acpi_hotplug_notify_cb+0x70/0x227 > > [ 346.907820] [] acpi_ev_notify_dispatch+0x44/0x5c > > [ 346.909637] [] acpi_os_execute_deferred+0xf/0x1b > > [ 346.911455] [] process_one_work+0x17a/0x440 > > [ 346.913285] [] worker_thread+0x119/0x390 > > [ 346.915121] [] ? manage_workers.isra.25+0x2a0/0x2a0 > > [ 346.916970] [] kthread+0xcd/0xf0 > > [ 346.918809] [] ? kthread_create_on_node+0x180/0x180 > > [ 346.920653] [] ret_from_fork+0x7c/0xb0 > > [ 346.922501] [] ? kthread_create_on_node+0x180/0x180 > > [ 346.924351] kworker/u8:5D 88006ea55860 4696 945 2 > > 0x > > [ 346.926212] Workqueue: kacpi_hotplug acpi_hotplug_work_fn > > [ 346.928074] 88006de49a40 0046 88006ea55490 > > 880100245490 > > [ 346.929978] 88006de49fd8 000129c0 000129c0 > > 88006ea55490 > > [ 346.931872] 88006de49ba0 7fff 88006de49b98 > > 88006ea55490 > > [ 346.933753] Call Trace: > > [ 346.935626] [] schedule+0x24/0x70 > > [ 346.937516] [] schedule_timeout+0x1a9/0x2a0 > > [ 346.939415] [] ? __wake_up_common+0x58/0x90 > > [ 346.941312] [] wait_for_completion+0x98/0x100 > > [ 346.943222] [] ? wake_up_state+0x10/0x10 > > [ 346.945133] [] flush_workqueue+0x115/0x5a0 > > [ 346.947054] [] ? acpi_pci_find_companion+0x40/0x40 > > [ 346.948986] [] ? acpi_pci_find_companion+0x40/0x40 > > [ 346.950904] [] acpi_os_wait_events_complete+0x1c/0x1e > > [ 346.952829] [] acpi_remove_notify_handler+0x78/0x1ef > > [ 346.954748] [] ? acpi_pci_find_companion+0x40/0x40 > > [ 346.956669] [] acpi_remove_pm_notifier+0x39/0x5c > > [ 346.958592] [] pci_acpi_cleanup+0x25/0x50 > > [ 346.960508] [] acpi_platform_notify_remove+0x44/0x53 > > [ 346.962427] [] device_del+0x142/0x1b0 > > [ 346.964333] [] pci_remove_bus_device+0x7a/0x100 > > [ 346.966238] [] > > pci_stop_and_remove_bus_device+0x15/0x20 > > [ 346.968140] [] disable_slot+0x4e/0xa0 > > [ 346.970030] [] acpiphp_check_bridge.part.10+0xe8/0xf0 > > [ 346.971911] [] hotplug_event+0xf2/0x1a0 > > [ 346.973776] [] acpiphp_hotplug_event+0x61/0xe0 > > [ 346.975630] [] acpi_device_hotplug+0x37c/0x3c2 > > [ 346.977471] [] acpi_hotplug_work_fn+0x17/0x22 > > [ 346.979299] [] process_one_work+0x17a/0x440 > > [ 346.981122] [] worker_thread+0x119/0x390 > > [ 346.982956] [] ? manage_workers.isra.25+0x2a0/0x2a0 > > [ 346.984762] [] kthread+0xcd/0xf0 > > [ 346.986581] [] ? kthread_create_on_node+0x180/0x180 > > [ 346.988419] [] ret_from_fork+0x7c/0xb0 > > [ 346.990221] [] ? kthread_create_on_node+0x180/0x180 > > > > I have to leave now but I can continue debugging tomorrow if needed. > > No need for now, I think I know what's happening. I'll follow up later. acpi_remove_notify_handler() which is called from acpi_remove_pm_notifier() executes acpi_os_wait_events_complete() which does flush_workqueue(kacpi_notify_wq) and all that happens under acpi_scan_lock acquired by acpi_device_hotplug(). Now, acpi_hotplug_notify_cb() runs from kacpi_notify_wq, so effectively acpi_os_wait_events_complete() waits for it to return, so if it attempts to acquire acpi_scan_lock, it will deadlock. Which happens on the NUC. The good news is that we can use a different lock to eliminate the race I wanted to deal with using acpi_scan_lock, but that required me to rework the whole patchset. I'll send a new version shortly, but I need to update the ACPIPHP updates it is on top of. Thanks! -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at
Re: [PATCHv2] x86: fix the initialization of physnode_map
On Sat, 1 Feb 2014, Petr Tesarik wrote: > With DISCONTIGMEM, the mapping between a pfn and its owning node is > initialized using data provided by the BIOS. However, the initialization > may fail if the extents are not aligned to section boundary (64M). > > The symptom of this bug is an early boot failure in pfn_to_page(), > as it tries to access NODE_DATA(__nid) using index from an unitialized > element of the physnode_map[] array. > > While the bug is always present, it is more likely to be hit in kdump > kernels on large machines, because: > > 1. The memory map for a kdump kernel is specified as exactmap, and >exactmap is more likely to be unaligned. > > 2. Large reservations are more likely to span across a 64M boundary. > > Signed-off-by: Petr Tesarik Acked-by: David Rientjes -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
On 02/01/2014 01:17 PM, George Spelvin wrote: >> .. which *does* actually bring up something that might work, and might >> be a good idea: remove the "restore math state or set TS" from the >> normal kernel paths *entirely*, and move it to the "return to user >> space" phase. > > This definitely seems much more sensible. For processors without > optimized context save/restore, the decision whether to restore eagerly > is best made once the kernel has decided what it's returning *to*. > > From an interrupt handler, there are now three cases: > 1) FPU not in use, available for immediate use. > 2) FPU in use by user-space; save to before using. > 3) FPU in use by kernel code; may not be used (unless we want >to add nested FPU state save hair). > OK, let's circle back for a bit. We have an active bug, and we clearly have a lot of restructuring that could/should be done. We need to fix the bug first; if we're going to a bunch of restructuring then that ought to be separate. The first bit is how we fix the immediate bug. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/4] Make vsyscall_gtod_data handling x86 generic
On Sat, Feb 1, 2014 at 7:32 AM, wrote: > From: Stefani Seibold > > This patch move the vsyscall_gtod_data handling out of vsyscall_64.c > into an additonal file vsyscall_gtod.c to make the functionality > available for x86 32 bit kernel. > > It also adds a new vsyscall_32.c which setup the VVAR page. > > Signed-off-by: Stefani Seibold Acked-by: Andy Lutomirski ...with the caveat that it would be even better if you moved vgetcpu over and called this thing vvar.c instead of vsyscall_gtod.c. > --- > arch/x86/Kconfig | 4 +-- > arch/x86/include/asm/clocksource.h | 4 --- > arch/x86/include/asm/fixmap.h | 2 ++ > arch/x86/include/asm/vvar.h| 4 +++ > arch/x86/kernel/Makefile | 3 +- > arch/x86/kernel/hpet.c | 4 --- > arch/x86/kernel/setup.c| 2 -- > arch/x86/kernel/tsc.c | 2 -- > arch/x86/kernel/vmlinux.lds.S | 3 -- > arch/x86/kernel/vsyscall_32.c | 24 +++ > arch/x86/kernel/vsyscall_64.c | 44 > arch/x86/kernel/vsyscall_gtod.c| 60 > ++ > 12 files changed, 94 insertions(+), 62 deletions(-) > create mode 100644 arch/x86/kernel/vsyscall_32.c > create mode 100644 arch/x86/kernel/vsyscall_gtod.c > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 940e50e..b556f00 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -107,9 +107,9 @@ config X86 > select HAVE_ARCH_SOFT_DIRTY > select CLOCKSOURCE_WATCHDOG > select GENERIC_CLOCKEVENTS > - select ARCH_CLOCKSOURCE_DATA if X86_64 > + select ARCH_CLOCKSOURCE_DATA > select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && > X86_LOCAL_APIC) > - select GENERIC_TIME_VSYSCALL if X86_64 > + select GENERIC_TIME_VSYSCALL > select KTIME_SCALAR if X86_32 > select GENERIC_STRNCPY_FROM_USER > select GENERIC_STRNLEN_USER > diff --git a/arch/x86/include/asm/clocksource.h > b/arch/x86/include/asm/clocksource.h > index 16a57f4..eda81dc 100644 > --- a/arch/x86/include/asm/clocksource.h > +++ b/arch/x86/include/asm/clocksource.h > @@ -3,8 +3,6 @@ > #ifndef _ASM_X86_CLOCKSOURCE_H > #define _ASM_X86_CLOCKSOURCE_H > > -#ifdef CONFIG_X86_64 > - > #define VCLOCK_NONE 0 /* No vDSO clock available. */ > #define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */ > #define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */ > @@ -14,6 +12,4 @@ struct arch_clocksource_data { > int vclock_mode; > }; > > -#endif /* CONFIG_X86_64 */ > - > #endif /* _ASM_X86_CLOCKSOURCE_H */ > diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h > index 7252cd3..504c04a 100644 > --- a/arch/x86/include/asm/fixmap.h > +++ b/arch/x86/include/asm/fixmap.h > @@ -74,6 +74,8 @@ extern unsigned long __FIXADDR_TOP; > enum fixed_addresses { > #ifdef CONFIG_X86_32 > FIX_HOLE, > + VSYSCALL_HPET, > + VVAR_PAGE, > FIX_VDSO, > #else > VSYSCALL_LAST_PAGE, > diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h > index d76ac40..c442782 100644 > --- a/arch/x86/include/asm/vvar.h > +++ b/arch/x86/include/asm/vvar.h > @@ -17,7 +17,11 @@ > */ > > /* Base address of vvars. This is not ABI. */ > +#ifdef CONFIG_X86_64 > #define VVAR_ADDRESS (-10*1024*1024 - 4096) > +#else > +#define VVAR_ADDRESS 0xd000 > +#endif > > #if defined(__VVAR_KERNEL_LDS) > > diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile > index cb648c8..3282eda 100644 > --- a/arch/x86/kernel/Makefile > +++ b/arch/x86/kernel/Makefile > @@ -26,7 +26,8 @@ obj-$(CONFIG_IRQ_WORK) += irq_work.o > obj-y += probe_roms.o > obj-$(CONFIG_X86_32) += i386_ksyms_32.o > obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o > -obj-y += syscall_$(BITS).o > +obj-y += syscall_$(BITS).o vsyscall_gtod.o > +obj-$(CONFIG_X86_32) += vsyscall_32.o > obj-$(CONFIG_X86_64) += vsyscall_64.o > obj-$(CONFIG_X86_64) += vsyscall_emu_64.o > obj-$(CONFIG_SYSFS)+= ksysfs.o > diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c > index da85a8e..54263f0 100644 > --- a/arch/x86/kernel/hpet.c > +++ b/arch/x86/kernel/hpet.c > @@ -74,9 +74,7 @@ static inline void hpet_writel(unsigned int d, unsigned int > a) > static inline void hpet_set_mapping(void) > { > hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); > -#ifdef CONFIG_X86_64 > __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VVAR_NOCACHE); > -#endif > } > > static inline void hpet_clear_mapping(void) > @@ -752,9 +750,7 @@ static struct clocksource clocksource_hpet = { > .mask = HPET_MASK, > .flags = CLOCK_SOURCE_IS_CONTINUOUS, > .resume = hpet_resume_counter, > -#ifdef CONFIG_X86_64 > .archdata = { .vclock_mode = VCLOCK_HPET }, > -#endif > }; > > static int
Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach wrote: > Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot: >> Add a clumsy-but-working FB support for GK20A. This chip only uses system >> memory, so we allocate a big chunk using CMA and let the existing memory >> managers work on it. >> >> A better future design would be to allocate objects directly from system >> memory without having to suffer from the limitations of a large, >> contiguous pool. >> > I don't know if Tegra124 is similar to 114 in this regard [hint: get the > TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it > make sense to take a chunk of the MMIO overlaid memory for this when > possible, rather than carving this out of CPU accessible mem? This is probably a stupid question... what do you need VRAM for anyways? In _theory_ it's an abstraction to talk about memory that's not accessible by the CPU. This is obviously not the case here, and presumably the GPU can access all the memory in the system, so it can be all treated as "GART" memory... AFAIK all accesses are behind the in-GPU MMU, so contiguous physical memory isn't an issue either. In practice, I suspect nouveau automatically sticks certain things into vram (gpuobj's), but it should be feasible to make them optionally use GART memory when VRAM is not available. I haven't really looked at the details though, perhaps that's a major undertaking. -ilia > >> Signed-off-by: Alexandre Courbot >> --- >> drivers/gpu/drm/nouveau/Makefile | 2 + >> drivers/gpu/drm/nouveau/core/include/subdev/fb.h | 1 + >> drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c| 28 ++ >> drivers/gpu/drm/nouveau/core/subdev/fb/priv.h| 1 + >> drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c | 67 >> >> 5 files changed, 99 insertions(+) >> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c >> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c >> >> diff --git a/drivers/gpu/drm/nouveau/Makefile >> b/drivers/gpu/drm/nouveau/Makefile >> index 3548fcd..d9fe3e6 100644 >> --- a/drivers/gpu/drm/nouveau/Makefile >> +++ b/drivers/gpu/drm/nouveau/Makefile >> @@ -100,6 +100,7 @@ nouveau-y += core/subdev/fb/nvaa.o >> nouveau-y += core/subdev/fb/nvaf.o >> nouveau-y += core/subdev/fb/nvc0.o >> nouveau-y += core/subdev/fb/nve0.o >> +nouveau-y += core/subdev/fb/nvea.o >> nouveau-y += core/subdev/fb/ramnv04.o >> nouveau-y += core/subdev/fb/ramnv10.o >> nouveau-y += core/subdev/fb/ramnv1a.o >> @@ -114,6 +115,7 @@ nouveau-y += core/subdev/fb/ramnva3.o >> nouveau-y += core/subdev/fb/ramnvaa.o >> nouveau-y += core/subdev/fb/ramnvc0.o >> nouveau-y += core/subdev/fb/ramnve0.o >> +nouveau-y += core/subdev/fb/ramnvea.o >> nouveau-y += core/subdev/fb/sddr3.o >> nouveau-y += core/subdev/fb/gddr5.o >> nouveau-y += core/subdev/gpio/base.o >> diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h >> b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h >> index d7ecafb..3905816 100644 >> --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h >> +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h >> @@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass; >> extern struct nouveau_oclass *nvaf_fb_oclass; >> extern struct nouveau_oclass *nvc0_fb_oclass; >> extern struct nouveau_oclass *nve0_fb_oclass; >> +extern struct nouveau_oclass *nvea_fb_oclass; >> >> #include >> >> diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c >> b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c >> new file mode 100644 >> index 000..5ff6029 >> --- /dev/null >> +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c >> @@ -0,0 +1,28 @@ >> +/* >> + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. >> + * >> + * This program is free software; you can redistribute it and/or modify it >> + * under the terms and conditions of the GNU General Public License, >> + * version 2, as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> + * more details. >> + * >> + */ >> + >> +#include "nvc0.h" >> + >> +struct nouveau_oclass * >> +nvea_fb_oclass = &(struct nouveau_fb_impl) { >> + .base.handle = NV_SUBDEV(FB, 0xea), >> + .base.ofuncs = &(struct nouveau_ofuncs) { >> + .ctor = nvc0_fb_ctor, >> + .dtor = nvc0_fb_dtor, >> + .init = nvc0_fb_init, >> + .fini = _nouveau_fb_fini, >> + }, >> + .memtype = nvc0_fb_memtype_valid, >> + .ram = _ram_oclass, >> +}.base; >> diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h >> b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h >> index edaf95d..0b95a25 100644 >> --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h >> +++
Re: [PATCH v11 0/4] Introducing a queue read/write lock implementation
On Fri, Jan 31, 2014 at 11:17:29AM +0100, Peter Zijlstra wrote: > On Fri, Jan 31, 2014 at 05:03:48AM -0500, George Spelvin wrote: > > How about getting rid of that TICKET_MSB mess and doing something like: > > > > #define TICKET_MASK 0x > > > > static inline void ticket_spin_unlock(atomic_t *tickets) > > { > > u32 t = *tickets; > > > > smp_mb__before_atomic_inc(); > > > > /* Increment the low 16 bits without affecting the upper. */ > > if (unlikely((~t & TICKET_MASK) == 0)) > > atomic_add(-(atomic_t)TICKET_MASK, tickets); > > else > > atomic_inc(tickets); > > } > > > > That also allows up to 2^16 waiters, up from 2^15. > > (Minus one on both cases, if you want to be fussy.) > > Ah indeed. That'll work. That said, any arch that can single-copy > address shorts can probably do better than this generic atomic_t thing. > > My main point was that we should seriously look at a ticket lock instead > of the MCS one, because while the MCS has better contention behaviour, > we shouldn't optimize locks for the worst contention. We do need to articulate what we -are- optimizing for, or more generally, what we are trying to accomplish with these locking primitives. Here are some of the traditional goals: 1. Avoid performance collapse under heavy load. Here the goal is to have throughput level off rather than decreasing when load exceeds saturation levels. 2. Avoid starvation of requesters. Here the goal is a very minimal level of fairness. 3. Achieve some reasonable level of fairness if the underlying hardware provides fair access to memory. Here "reasonable" might mean that lock-grant probabilities not differ by more than (say) a factor of two. 4. Achieve some reasonable level of fairness even if the underlying hardware is unfair. Rumor has it that some of the very large systems in use today do not guarantee fair access to cache lines under heavy memory contention. 5. Achieve some minimal level of scalability, so that throughput increases monotonically with increasing load. Preferably without penalizing small-system performance. 6. Achieve some reasonable level of scalability, so that adding a given CPU provides at least some fraction (say, 80%) of one CPU's worth of incremental throughput. 7. Achieve linear scalability. Ticket locking has problems with #1 on some systems due to the thundering herd of reads following each invalidation. (Yes, it is not as bad as the atomic-operation thundering herd associated with test-and-set spinlocks, but it can neverthelless be a problem on larger systems.) Achieving #4 requires some sort of queued lock as far as I can see. Although you -might- get #5 with a very clever NUMA-aware lock, #6 and #7 will require some level of redesign. Fancy locks can help if the common code path is fully parallelized, but where some rare error path is not worth the effort. In this case, using a fancy lock on the error path can at least keep the system moving during the time that the error condition is in force, and hopefully permit returning to full throughput once the error condition is gone. So, what exactly are we trying to achieve with all this? ;-) Thanx, Paul -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot: > Add a clumsy-but-working FB support for GK20A. This chip only uses system > memory, so we allocate a big chunk using CMA and let the existing memory > managers work on it. > > A better future design would be to allocate objects directly from system > memory without having to suffer from the limitations of a large, > contiguous pool. > I don't know if Tegra124 is similar to 114 in this regard [hint: get the TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it make sense to take a chunk of the MMIO overlaid memory for this when possible, rather than carving this out of CPU accessible mem? > Signed-off-by: Alexandre Courbot > --- > drivers/gpu/drm/nouveau/Makefile | 2 + > drivers/gpu/drm/nouveau/core/include/subdev/fb.h | 1 + > drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c| 28 ++ > drivers/gpu/drm/nouveau/core/subdev/fb/priv.h| 1 + > drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c | 67 > > 5 files changed, 99 insertions(+) > create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c > > diff --git a/drivers/gpu/drm/nouveau/Makefile > b/drivers/gpu/drm/nouveau/Makefile > index 3548fcd..d9fe3e6 100644 > --- a/drivers/gpu/drm/nouveau/Makefile > +++ b/drivers/gpu/drm/nouveau/Makefile > @@ -100,6 +100,7 @@ nouveau-y += core/subdev/fb/nvaa.o > nouveau-y += core/subdev/fb/nvaf.o > nouveau-y += core/subdev/fb/nvc0.o > nouveau-y += core/subdev/fb/nve0.o > +nouveau-y += core/subdev/fb/nvea.o > nouveau-y += core/subdev/fb/ramnv04.o > nouveau-y += core/subdev/fb/ramnv10.o > nouveau-y += core/subdev/fb/ramnv1a.o > @@ -114,6 +115,7 @@ nouveau-y += core/subdev/fb/ramnva3.o > nouveau-y += core/subdev/fb/ramnvaa.o > nouveau-y += core/subdev/fb/ramnvc0.o > nouveau-y += core/subdev/fb/ramnve0.o > +nouveau-y += core/subdev/fb/ramnvea.o > nouveau-y += core/subdev/fb/sddr3.o > nouveau-y += core/subdev/fb/gddr5.o > nouveau-y += core/subdev/gpio/base.o > diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > index d7ecafb..3905816 100644 > --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h > @@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass; > extern struct nouveau_oclass *nvaf_fb_oclass; > extern struct nouveau_oclass *nvc0_fb_oclass; > extern struct nouveau_oclass *nve0_fb_oclass; > +extern struct nouveau_oclass *nvea_fb_oclass; > > #include > > diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > new file mode 100644 > index 000..5ff6029 > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c > @@ -0,0 +1,28 @@ > +/* > + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + */ > + > +#include "nvc0.h" > + > +struct nouveau_oclass * > +nvea_fb_oclass = &(struct nouveau_fb_impl) { > + .base.handle = NV_SUBDEV(FB, 0xea), > + .base.ofuncs = &(struct nouveau_ofuncs) { > + .ctor = nvc0_fb_ctor, > + .dtor = nvc0_fb_dtor, > + .init = nvc0_fb_init, > + .fini = _nouveau_fb_fini, > + }, > + .memtype = nvc0_fb_memtype_valid, > + .ram = _ram_oclass, > +}.base; > diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h > b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h > index edaf95d..0b95a25 100644 > --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h > +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h > @@ -32,6 +32,7 @@ extern struct nouveau_oclass nva3_ram_oclass; > extern struct nouveau_oclass nvaa_ram_oclass; > extern struct nouveau_oclass nvc0_ram_oclass; > extern struct nouveau_oclass nve0_ram_oclass; > +extern struct nouveau_oclass nvea_ram_oclass; > > int nouveau_sddr3_calc(struct nouveau_ram *ram); > int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts); > diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c > b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c > new file mode 100644 > index 000..3038e08 > --- /dev/null > +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c > @@ -0,0 +1,67 @@ > +/* > + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and
[PATCH] cpufreq: cpu0: make THERMAL_CPU support optional
From: Rob Herring The addition of THERMAL and THERMAL_CPU selections causes a kconfig warning on highbank platforms: warning: (ARM_HIGHBANK_CPUFREQ) selects GENERIC_CPUFREQ_CPU0 which has unmet direct dependencies (ARCH_HAS_CPUFREQ && CPU_FREQ && HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL) The cpufreq-cpu0 driver does not require thermal zone support, and it should be selectable independently. Add a new kconfig option to enable this feature. Reported-by: Olof Johansson Cc: "Rafael J. Wysocki" Cc: Viresh Kumar Cc: cpuf...@vger.kernel.org Signed-off-by: Rob Herring --- drivers/cpufreq/Kconfig | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4b029c0..a197a04a 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE config GENERIC_CPUFREQ_CPU0 tristate "Generic CPU0 cpufreq driver" - depends on HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL + depends on HAVE_CLK && REGULATOR && OF select PM_OPP help This adds a generic cpufreq driver for CPU0 frequency management. @@ -194,6 +194,14 @@ config GENERIC_CPUFREQ_CPU0 If in doubt, say N. +config GENERIC_CPUFREQ_CPU0_THERMAL + bool "Thermal zone support for Generic CPU0 cpufreq" + depends on GENERIC_CPUFREQ_CPU0 + select THERMAL + select THERMAL_CPU + help + This adds thermal support to the generic cpufreq driver for CPU0. + menu "x86 CPU frequency scaling drivers" depends on X86 source "drivers/cpufreq/Kconfig.x86" -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/3] power_supply: modelgauge_battery: Remove Maxim MAX17040 gauge
Remove Maxim MAX17040 gauge driver since it is superseded by full-functional Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips Signed-off-by: Vladimir Barinov --- drivers/power/Kconfig|8 - drivers/power/Makefile |1 drivers/power/max17040_battery.c | 297 --- include/linux/max17040_battery.h | 19 -- 4 files changed, 325 deletions(-) Index: linux-2.6.torvalds/drivers/power/Kconfig === --- linux-2.6.torvalds.orig/drivers/power/Kconfig 2014-02-02 01:37:35.374626307 +0400 +++ linux-2.6.torvalds/drivers/power/Kconfig2014-02-02 01:38:21.966627415 +0400 @@ -185,14 +185,6 @@ Say Y here to enable support for batteries charger integrated into DA9052 PMIC. -config BATTERY_MAX17040 - tristate "Maxim MAX17040 Fuel Gauge" - depends on I2C - help - MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries - in handheld and portable equipment. The MAX17040 is configured - to operate with a single lithium cell - config BATTERY_MAX17042 tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge" depends on I2C Index: linux-2.6.torvalds/drivers/power/Makefile === --- linux-2.6.torvalds.orig/drivers/power/Makefile 2014-02-02 01:37:35.0 +0400 +++ linux-2.6.torvalds/drivers/power/Makefile 2014-02-02 01:38:21.966627415 +0400 @@ -30,7 +30,6 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o -obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o obj-$(CONFIG_BATTERY_MODELGAUGE) += modelgauge_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o Index: linux-2.6.torvalds/drivers/power/max17040_battery.c === --- linux-2.6.torvalds.orig/drivers/power/max17040_battery.c2014-02-02 01:38:29.614627597 +0400 +++ /dev/null 1970-01-01 00:00:00.0 + @@ -1,297 +0,0 @@ -/* - * max17040_battery.c - * fuel-gauge systems for lithium-ion (Li+) batteries - * - * Copyright (C) 2009 Samsung Electronics - * Minkyu Kang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX17040_VCELL_MSB 0x02 -#define MAX17040_VCELL_LSB 0x03 -#define MAX17040_SOC_MSB 0x04 -#define MAX17040_SOC_LSB 0x05 -#define MAX17040_MODE_MSB 0x06 -#define MAX17040_MODE_LSB 0x07 -#define MAX17040_VER_MSB 0x08 -#define MAX17040_VER_LSB 0x09 -#define MAX17040_RCOMP_MSB 0x0C -#define MAX17040_RCOMP_LSB 0x0D -#define MAX17040_CMD_MSB 0xFE -#define MAX17040_CMD_LSB 0xFF - -#define MAX17040_DELAY 1000 -#define MAX17040_BATTERY_FULL 95 - -struct max17040_chip { - struct i2c_client *client; - struct delayed_work work; - struct power_supply battery; - struct max17040_platform_data *pdata; - - /* State Of Connect */ - int online; - /* battery voltage */ - int vcell; - /* battery capacity */ - int soc; - /* State Of Charge */ - int status; -}; - -static int max17040_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct max17040_chip *chip = container_of(psy, - struct max17040_chip, battery); - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = chip->status; - break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = chip->online; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = chip->vcell; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = chip->soc; - break; - default: - return -EINVAL; - } - return 0; -} - -static int max17040_write_reg(struct i2c_client *client, int reg, u8 value) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, value); - - if (ret < 0) - dev_err(>dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static int max17040_read_reg(struct i2c_client *client, int reg) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) - dev_err(>dev, "%s: err %d\n", __func__, ret);
[PATCH v2 0/3] power_supply: modelgauge_battery: Add Maxim ModelGauge ICs gauge
Hello. This adds the folowing: - Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips - Document DT bindings - Remove superseded Maxim MAX17040 gauge driver Vladimir Barinov (3): [1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge [2/3] dt: Document ModelGauge gauge bindings [3/3] power_supply: modelgauge_battery: Remove Maxim MAX17040 gauge --- This patchset is against the 'kernel/git/torvalds/linux.git' repo. Changes since v1: - switched to REGMAP API - replaced request_threaded_irq with devm_request_threaded_irq - replaced cancel_delayed_work with _sync version - moved "empty_alert_threshold, soc_change_alert, hibernate_threshold, active_threshold, undervoltage, overvoltage, resetvoltage" parameters out from platform_data and DT - removed unused parameters "empty_adjustment, empty_adjustment" - added return value checks for of_property_read_XX functions - removed irrelevant bindings - fixed dt properties naming in documentation - added binding size description in documentation - removed satelite include file include/linux/max17040_battery.h Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt | 61 drivers/power/Kconfig | 17 drivers/power/Makefile|2 drivers/power/max17040_battery.c | 297 --- drivers/power/modelgauge_battery.c| 838 ++ include/linux/max17040_battery.h | 19 include/linux/platform_data/battery-modelgauge.h | 31 7 files changed, 940 insertions(+), 325 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
Add Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips Signed-off-by: Vladimir Barinov --- drivers/power/Kconfig|9 drivers/power/Makefile |1 drivers/power/modelgauge_battery.c | 838 +++ include/linux/platform_data/battery-modelgauge.h | 31 4 files changed, 879 insertions(+) Index: battery-2.6/drivers/power/Kconfig === --- battery-2.6.orig/drivers/power/Kconfig 2014-02-02 01:29:07.434614235 +0400 +++ battery-2.6/drivers/power/Kconfig 2014-02-02 01:29:29.070614750 +0400 @@ -205,6 +205,15 @@ with MAX17042. This driver also supports max17047/50 chips which are improved version of max17042. +config BATTERY_MODELGAUGE + tristate "Maxim ModelGauge ICs fuel gauge" + depends on I2C + select REGMAP_I2C + help + ModelGauge(TM) is a Maxim algorithm incorporated in + MAX17040/41/43/44/48/49/58/59 fuel-gauges for lithium-ion (Li+) + batteries. + config BATTERY_Z2 tristate "Z2 battery driver" depends on I2C && MACH_ZIPIT2 Index: battery-2.6/drivers/power/Makefile === --- battery-2.6.orig/drivers/power/Makefile 2014-02-02 01:29:07.462614237 +0400 +++ battery-2.6/drivers/power/Makefile 2014-02-02 01:29:12.978614368 +0400 @@ -32,6 +32,7 @@ obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o +obj-$(CONFIG_BATTERY_MODELGAUGE) += modelgauge_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o Index: battery-2.6/drivers/power/modelgauge_battery.c === --- /dev/null 1970-01-01 00:00:00.0 + +++ battery-2.6/drivers/power/modelgauge_battery.c 2014-02-02 01:29:34.314614874 +0400 @@ -0,0 +1,838 @@ +/* + * Maxim ModelGauge ICs fuel gauge driver + * + * Author: Vladimir Barinov + * Copyright (C) 2013 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "modelgauge" + +/* Register offsets for ModelGauge ICs */ +#define MODELGAUGE_VCELL_REG 0x02 +#define MODELGAUGE_SOC_REG 0x04 +#define MODELGAUGE_MODE_REG0x06 +#define MODELGAUGE_VERSION_REG 0x08 +#define MODELGAUGE_HIBRT_REG 0x0A +#define MODELGAUGE_CONFIG_REG 0x0C +#define MODELGAUGE_OCV_REG 0x0E +#define MODELGAUGE_VALRT_REG 0x14 +#define MODELGAUGE_CRATE_REG 0x16 +#define MODELGAUGE_VRESETID_REG0x18 +#define MODELGAUGE_STATUS_REG 0x1A +#define MODELGAUGE_UNLOCK_REG 0x3E +#define MODELGAUGE_TABLE_REG 0x40 +#define MODELGAUGE_RCOMPSEG_REG0x80 +#define MODELGAUGE_CMD_REG 0xFE + +/* MODE register bits */ +#define MODELGAUGE_MODE_QUICKSTART (1 << 14) +#define MODELGAUGE_MODE_ENSLEEP(1 << 13) +#define MODELGAUGE_MODE_HIBSTAT(1 << 12) + +/* CONFIG register bits */ +#define MODELGAUGE_CONFIG_SLEEP(1 << 7) +#define MODELGAUGE_CONFIG_ALSC (1 << 6) +#define MODELGAUGE_CONFIG_ALRT (1 << 5) +#define MODELGAUGE_CONFIG_ATHD_MASK0x1f + +/* STATUS register bits */ +#define MODELGAUGE_STATUS_ENVR (1 << 14) +#define MODELGAUGE_STATUS_SC (1 << 13) +#define MODELGAUGE_STATUS_HD (1 << 12) +#define MODELGAUGE_STATUS_VR (1 << 11) +#define MODELGAUGE_STATUS_VL (1 << 10) +#define MODELGAUGE_STATUS_VH (1 << 9) +#define MODELGAUGE_STATUS_RI (1 << 8) + +/* VRESETID register bits */ +#define MODELGAUGE_VRESETID_DIS(1 << 8) + +#define MODELGAUGE_UNLOCK_VALUE0x4a57 +#define MODELGAUGE_RESET_VALUE 0x5400 + +#define MODELGAUGE_RCOMP_UPDATE_DELAY 6 + +/* Capacity threshold where an interrupt is generated on the ALRT pin */ +#define MODELGAUGE_EMPTY_ATHD 15 +/* Enable alert for 1% soc change */ +#define MODELGAUGE_SOC_CHANGE_ALERT1 +/* Hibernate threshold (crate), where IC enters hibernate mode */ +#define MODELGAUGE_HIBRT_THD 20 +/* Active threshold (mV), where IC exits hibernate mode */ +#define MODELGAUGE_ACTIVE_THD 60 +/* Voltage (mV), when IC alerts if battery voltage less then
[PATCH v2 2/3] dt: Document ModelGauge gauge bindings
These bindings can be used to register Maxim ModelGauge ICs fuel gauge (MAX17040/41/43/44/48/49/58/59) Signed-off-by: Vladimir Barinov --- Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt | 61 ++ 1 file changed, 61 insertions(+) Index: battery-2.6/Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt === --- /dev/null 1970-01-01 00:00:00.0 + +++ battery-2.6/Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt 2014-02-02 01:36:12.638624341 +0400 @@ -0,0 +1,61 @@ +modelgauge_battery +~~ + +Required properties: + - compatible : should contain one of the following: + - "maxim,max17040" for MAX17040 + - "maxim,max17041" for MAX17041 + - "maxim,max17043" for MAX17043 + - "maxim,max17044" for MAX17044 + - "maxim,max17048" for MAX17048 + - "maxim,max17049" for MAX17049 + - "maxim,max17058" for MAX17058 + - "maxim,max17059" for MAX17059 + +Optional properties: + - maxim,rcomp0: ModelGauge RCOMP parameter, used for + temperature compensation (u8); + - maxim,temp-co-up: ModelGauge TempCoUp parameter, used for + temperature compensation (signed); + - maxim,temp-co-down : ModelGauge TempCoDown parameter, used for + temperature compensation (signed); + - maxim,ocvtest : ModelGauge OCVTest parameter, used for + verification of Custom Model calibration data + loaded into IC RAM (u16); + - maxim,soc-check-a : ModelGauge SOCCheckA parameter, used for + verification of Custom Model calibration data + loaded into IC RAM (u8); + - maxim,soc-check-b : ModelGauge SOCCheckB parameter, used for + verification of Custom Model calibration data + loaded into IC RAM (u8); + - maxim,bits : ModelGauge Bits parameter, used as + scaling parameter in Custom Model algorithm (u8); + - maxim,model-data: ModelGauge ModelData data, + Custom Model calibration data (array_u8[64]). + +Example: + +modelgauge@36 { + compatible = "maxim,max17058"; + reg = <0x36>; + interrupt-parent = <>; + interrupts = <107 0x2>; + + maxim,rcomp0 = /bits/ 8 <175>; + maxim,temp-co-up = <(-1100)>; + maxim,temp-co-down = <(-4000)>; + maxim,ocvtest = /bits/ 16 <56144>; + maxim,soc-check-a = /bits/ 8 <241>; + maxim,soc-check-b = /bits/ 8 <243>; + maxim,bits = /bits/ 8 <19>; + + maxim,model-data = /bits/ 8 < + 0x9B 0x70 0xAB 0x30 0xB5 0xA0 0xB9 0xD0 + 0xBB 0xA0 0xBC 0x00 0xBC 0xB0 0xBD 0x00 + 0xBD 0x60 0xBE 0x40 0xBF 0x40 0xC1 0xF0 + 0xC5 0x60 0xC8 0xA0 0xCD 0x00 0xD1 0x50 + 0x00 0xE0 0x01 0x80 0x18 0x60 0x1C 0x20 + 0x54 0x00 0x6A 0xC0 0x79 0x20 0x65 0xC0 + 0x0B 0xE0 0x2A 0xC0 0x1D 0x00 0x17 0xE0 + 0x15 0xE0 0x11 0xE0 0x11 0x00 0x11 0x00>; +}; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v7 0/7] ARM: rockchip: add smp functionality
Hi Heiko, On Fri, Jan 31, 2014 at 11:03:03PM +0100, Heiko Stübner wrote: > On Monday, 20. January 2014 16:41:43 Heiko Stübner wrote: > > This series enables the use of the additional cores on Rockchip > > Cortex-A9 SoCs. > > So, two weeks without any general complaints, but I guess part of the more > general patches could use an ack. > > Going forward, what would be best way to merge them? > As one pull request to arm-soc, or for example splitting them into the first > three patches going through the misc tree and the rockchip specific stuff > going > through arm-soc? Or something else altogether? > > > > Heiko Stuebner (7): > > of: add functions to count number of elements in a property > > One of the intermediate versions of this patch got a > Reviewed-by: Mark Rutland . > Mark, is this still true for this variant addressing some additional wished > from Rob? > > And this final version got a "Looks good" from Rob Herring in the original > thread, but a more formal "ack" might be nice :-) . > > > > dt-bindings: sram: describe option to reserve parts of the memory > > misc: sram: implement mmio-sram-reserved option > > Philipp, you acked an intermediate version, and this v7 now should also > contain the two separate loops (1st gathering data and 2nd creating the pool > parts) you asked for. > > Could I persuade you to take a look again? Acked-by: Philipp Zabel regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
It would be good to know how often #3 happens on a real workload. On February 1, 2014 1:17:10 PM PST, George Spelvin wrote: >> .. which *does* actually bring up something that might work, and >might >> be a good idea: remove the "restore math state or set TS" from the >> normal kernel paths *entirely*, and move it to the "return to user >> space" phase. > >This definitely seems much more sensible. For processors without >optimized context save/restore, the decision whether to restore eagerly >is best made once the kernel has decided what it's returning *to*. > >From an interrupt handler, there are now three cases: >1) FPU not in use, available for immediate use. >2) FPU in use by user-space; save to before using. >3) FPU in use by kernel code; may not be used (unless we want > to add nested FPU state save hair). -- Sent from my mobile phone. Please pardon brevity and lack of formatting. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/