]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-3.9-cpuset' of git://git.kernel.org/pub/scm/linux/kernel/git/tj...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 17:18:31 +0000 (09:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 17:18:31 +0000 (09:18 -0800)
Pull cpuset changes from Tejun Heo:

 - Synchornization has seen a lot of changes with focus on decoupling
   cpuset synchronization from cgroup internal locking.

   After this change, there only remain a couple of mostly trivial
   dependencies on cgroup_lock outside cgroup core proper.  cgroup_lock
   is scheduled to be unexported in this devel cycle.

   This will finally remove the fragile locking order around cgroup
   (cgroup locking wants to / should be one of the outermost but yet has
   been acquired from deep inside individual controllers).

 - At this point, Li is most knowlegeable with cpuset and taking over
   the maintainership of cpuset.

* 'for-3.9-cpuset' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cpuset: drop spurious retval assignment in proc_cpuset_show()
  cpuset: fix RCU lockdep splat
  cpuset: update MAINTAINERS
  cpuset: remove cpuset->parent
  cpuset: replace cpuset->stack_list with cpuset_for_each_descendant_pre()
  cpuset: replace cgroup_mutex locking with cpuset internal locking
  cpuset: schedule hotplug propagation from cpuset_attach() if the cpuset is empty
  cpuset: pin down cpus and mems while a task is being attached
  cpuset: make CPU / memory hotplug propagation asynchronous
  cpuset: drop async_rebuild_sched_domains()
  cpuset: don't nest cgroup_mutex inside get_online_cpus()
  cpuset: reorganize CPU / memory hotplug handling
  cpuset: cleanup cpuset[_can]_attach()
  cpuset: introduce cpuset_for_each_child()
  cpuset: introduce CS_ONLINE
  cpuset: introduce ->css_on/offline()
  cpuset: remove fast exit path from remove_tasks_in_empty_cpuset()
  cpuset: remove unused cpuset_unlock()

1  2 
MAINTAINERS
kernel/cpuset.c

diff --combined MAINTAINERS
index 526fb85f2f7e3bffaa7ff62fcc1a57229912303d,d58bc1222b57fbc81bebd810434c0a9f74d2e92b..b7013e41b62348064eb1a9b0913382b34699aa25
@@@ -228,7 -228,7 +228,7 @@@ S: Maintaine
  F:    drivers/platform/x86/acerhdf.c
  
  ACER WMI LAPTOP EXTRAS
 -M:    Joey Lee <jlee@novell.com>
 +M:    "Lee, Chun-Yi" <jlee@suse.com>
  L:    platform-driver-x86@vger.kernel.org
  S:    Maintained
  F:    drivers/platform/x86/acer-wmi.c
@@@ -449,7 -449,6 +449,7 @@@ T: git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/char/agp/
  F:    include/linux/agp*
 +F:    include/uapi/linux/agp*
  
  AHA152X SCSI DRIVER
  M:    "Juergen E. Fischer" <fischer@norbit.de>
@@@ -590,7 -589,6 +590,7 @@@ M: Jiri Kosina <jkosina@suse.cz
  S:    Odd fixes
  F:    arch/x86/kernel/apm_32.c
  F:    include/linux/apm_bios.h
 +F:    include/uapi/linux/apm_bios.h
  F:    drivers/char/apm-emulation.c
  
  APPLE BCM5974 MULTITOUCH DRIVER
@@@ -648,7 -646,7 +648,7 @@@ F: arch/arm
  
  ARM SUB-ARCHITECTURES
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    MAINTAINED
 +S:    Maintained
  F:    arch/arm/mach-*/
  F:    arch/arm/plat-*/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
@@@ -1007,6 -1005,7 +1007,6 @@@ F:      drivers/mmc/host/msm_sdcc.
  F:    drivers/mmc/host/msm_sdcc.h
  F:    drivers/tty/serial/msm_serial.h
  F:    drivers/tty/serial/msm_serial.c
 -F:    drivers/platform/msm/
  F:    drivers/*/pm8???-*
  F:    include/linux/mfd/pm8xxx/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm.git
@@@ -1070,6 -1069,7 +1070,6 @@@ M:      Russell King <linux@arm.linux.org.uk
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  W:    http://www.arm.linux.org.uk/
  S:    Maintained
 -F:    arch/arm/common/time-acorn.c
  F:    arch/arm/include/asm/hardware/entry-macro-iomd.S
  F:    arch/arm/include/asm/hardware/ioc.h
  F:    arch/arm/include/asm/hardware/iomd.h
@@@ -1094,6 -1094,7 +1094,6 @@@ W:      http://www.fluff.org/ben/linux
  S:    Maintained
  F:    arch/arm/plat-samsung/
  F:    arch/arm/plat-s3c24xx/
 -F:    arch/arm/plat-s5p/
  F:    arch/arm/mach-s3c24*/
  F:    arch/arm/mach-s3c64xx/
  F:    drivers/*/*s3c2410*
@@@ -1124,6 -1125,7 +1124,6 @@@ M:      Sylwester Nawrocki <s.nawrocki@samsu
  L:    linux-arm-kernel@lists.infradead.org
  L:    linux-media@vger.kernel.org
  S:    Maintained
 -F:    arch/arm/plat-s5p/dev-fimc*
  F:    arch/arm/plat-samsung/include/plat/*fimc*
  F:    drivers/media/platform/s5p-fimc/
  
@@@ -1134,7 -1136,7 +1134,7 @@@ M:      Jeongtae Park <jtp.park@samsung.com
  L:    linux-arm-kernel@lists.infradead.org
  L:    linux-media@vger.kernel.org
  S:    Maintained
 -F:    arch/arm/plat-s5p/dev-mfc.c
 +F:    arch/arm/plat-samsung/s5p-dev-mfc.c
  F:    drivers/media/platform/s5p-mfc/
  
  ARM/SAMSUNG S5P SERIES TV SUBSYSTEM SUPPORT
@@@ -1252,7 -1254,7 +1252,7 @@@ F:      drivers/video/vt8500lcdfb.
  F:    drivers/video/wm8505fb*
  F:    drivers/video/wmt_ge_rops.*
  F:    drivers/tty/serial/vt8500_serial.c
 -F:    drivers/rtc/rtc-vt8500-c
 +F:    drivers/rtc/rtc-vt8500.c
  F:    drivers/mmc/host/wmt-sdmmc.c
  
  ARM/ZIPIT Z2 SUPPORT
@@@ -1303,7 -1305,7 +1303,7 @@@ F:      include/linux/dmaengine.
  F:    include/linux/async_tx.h
  
  AT24 EEPROM DRIVER
 -M:    Wolfram Sang <w.sang@pengutronix.de>
 +M:    Wolfram Sang <wsa@the-dreams.de>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/misc/eeprom/at24.c
@@@ -1351,14 -1353,6 +1351,14 @@@ W:    http://wireless.kernel.org/en/users/
  S:    Supported
  F:    drivers/net/wireless/ath/ath9k/
  
 +WILOCITY WIL6210 WIRELESS DRIVER
 +M:    Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
 +L:    linux-wireless@vger.kernel.org
 +L:    wil6210@qca.qualcomm.com
 +S:    Supported
 +W:    http://wireless.kernel.org/en/users/Drivers/wil6210
 +F:    drivers/net/wireless/ath/wil6210/
 +
  CARL9170 LINUX COMMUNITY WIRELESS DRIVER
  M:    Christian Lamparter <chunkeey@googlemail.com>
  L:    linux-wireless@vger.kernel.org
@@@ -1394,7 -1388,6 +1394,7 @@@ W:      http://linux-atm.sourceforge.ne
  S:    Maintained
  F:    drivers/atm/
  F:    include/linux/atm*
 +F:    include/uapi/linux/atm*
  
  ATMEL AT91 / AT32 MCI DRIVER
  M:    Ludovic Desroches <ludovic.desroches@atmel.com>
@@@ -1413,13 -1406,13 +1413,13 @@@ L:   linux-arm-kernel@lists.infradead.or
  S:    Supported
  F:    drivers/dma/at_hdmac.c
  F:    drivers/dma/at_hdmac_regs.h
 -F:    arch/arm/mach-at91/include/mach/at_hdmac.h
 +F:    include/linux/platform_data/dma-atmel.h
  
  ATMEL ISI DRIVER
  M:    Josh Wu <josh.wu@atmel.com>
  L:    linux-media@vger.kernel.org
  S:    Supported
 -F:    drivers/media/platform/atmel-isi.c
 +F:    drivers/media/platform/soc_camera/atmel-isi.c
  F:    include/media/atmel-isi.h
  
  ATMEL LCDFB DRIVER
@@@ -1474,7 -1467,6 +1474,7 @@@ W:      http://people.redhat.com/sgrubb/audi
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git
  S:    Maintained
  F:    include/linux/audit.h
 +F:    include/uapi/linux/audit.h
  F:    kernel/audit*
  
  AUXILIARY DISPLAY DRIVERS
@@@ -1489,7 -1481,7 +1489,7 @@@ AVR32 ARCHITECTUR
  M:    Haavard Skinnemoen <hskinnemoen@gmail.com>
  M:    Hans-Christian Egtvedt <egtvedt@samfundet.no>
  W:    http://www.atmel.com/products/AVR32/
 -W:    http://avr32linux.org/
 +W:    http://mirror.egtvedt.no/avr32linux.org/
  W:    http://avrfreaks.net/
  S:    Maintained
  F:    arch/avr32/
@@@ -1505,7 -1497,7 +1505,7 @@@ M:      Ralf Baechle <ralf@linux-mips.org
  L:    linux-hams@vger.kernel.org
  W:    http://www.linux-ax25.org/
  S:    Maintained
 -F:    include/linux/ax25.h
 +F:    include/uapi/linux/ax25.h
  F:    include/net/ax25.h
  F:    net/ax25/
  
@@@ -1566,7 -1558,7 +1566,7 @@@ M:      "Tigran A. Aivazian" <tigran@aivazia
  S:    Maintained
  F:    Documentation/filesystems/bfs.txt
  F:    fs/bfs/
 -F:    include/linux/bfs_fs.h
 +F:    include/uapi/linux/bfs_fs.h
  
  BLACKFIN ARCHITECTURE
  M:    Mike Frysinger <vapier@gentoo.org>
@@@ -1663,7 -1655,7 +1663,7 @@@ L:      netdev@vger.kernel.or
  W:    http://sourceforge.net/projects/bonding/
  S:    Supported
  F:    drivers/net/bonding/
 -F:    include/linux/if_bonding.h
 +F:    include/uapi/linux/if_bonding.h
  
  BROADCOM B44 10/100 ETHERNET DRIVER
  M:    Gary Zambrano <zambrano@broadcom.com>
@@@ -1742,7 -1734,6 +1742,7 @@@ L:      linux-scsi@vger.kernel.or
  S:    Supported
  F:    block/bsg.c
  F:    include/linux/bsg.h
 +F:    include/uapi/linux/bsg.h
  
  BT87X AUDIO DRIVER
  M:    Clemens Ladisch <clemens@ladisch.de>
@@@ -1813,7 -1804,7 +1813,7 @@@ L:      netdev@vger.kernel.or
  S:    Supported
  F:    Documentation/networking/caif/
  F:    drivers/net/caif/
 -F:    include/linux/caif/
 +F:    include/uapi/linux/caif/
  F:    include/net/caif/
  F:    net/caif/
  
@@@ -1834,11 -1825,11 +1834,11 @@@ W:   http://gitorious.org/linux-ca
  T:    git git://gitorious.org/linux-can/linux-can-next.git
  S:    Maintained
  F:    net/can/
 -F:    include/linux/can.h
  F:    include/linux/can/core.h
 -F:    include/linux/can/bcm.h
 -F:    include/linux/can/raw.h
 -F:    include/linux/can/gw.h
 +F:    include/uapi/linux/can.h
 +F:    include/uapi/linux/can/bcm.h
 +F:    include/uapi/linux/can/raw.h
 +F:    include/uapi/linux/can/gw.h
  
  CAN NETWORK DRIVERS
  M:    Wolfgang Grandegger <wg@grandegger.com>
@@@ -1849,16 -1840,15 +1849,16 @@@ T:   git git://gitorious.org/linux-can/li
  S:    Maintained
  F:    drivers/net/can/
  F:    include/linux/can/dev.h
 -F:    include/linux/can/error.h
 -F:    include/linux/can/netlink.h
  F:    include/linux/can/platform/
 +F:    include/uapi/linux/can/error.h
 +F:    include/uapi/linux/can/netlink.h
  
  CAPABILITIES
  M:    Serge Hallyn <serge.hallyn@canonical.com>
  L:    linux-security-module@vger.kernel.org
  S:    Supported
  F:    include/linux/capability.h
 +F:    include/uapi/linux/capability.h
  F:    security/capability.c
  F:    security/commoncap.c
  F:    kernel/capability.c
@@@ -1871,7 -1861,6 +1871,7 @@@ W:      http://www.ibm.com/developerworks/po
  S:    Supported
  F:    arch/powerpc/include/asm/cell*.h
  F:    arch/powerpc/include/asm/spu*.h
 +F:    arch/powerpc/include/uapi/asm/spu*.h
  F:    arch/powerpc/oprofile/*cell*
  F:    arch/powerpc/platforms/cell/
  
@@@ -1920,7 -1909,7 +1920,7 @@@ W:      http://wireless.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
  S:    Maintained
 -F:    include/linux/nl80211.h
 +F:    include/uapi/linux/nl80211.h
  F:    include/net/cfg80211.h
  F:    net/wireless/*
  X:    net/wireless/wext*
@@@ -1972,9 -1961,9 +1972,9 @@@ S:      Maintaine
  F:    drivers/usb/host/ohci-ep93xx.c
  
  CIRRUS LOGIC CS4270 SOUND DRIVER
 -M:    Timur Tabi <timur@freescale.com>
 +M:    Timur Tabi <timur@tabi.org>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
 -S:    Supported
 +S:    Odd Fixes
  F:    sound/soc/codecs/cs4270*
  
  CLEANCACHE API
@@@ -2023,7 -2012,6 +2023,7 @@@ S:      Maintaine
  F:    Documentation/filesystems/coda.txt
  F:    fs/coda/
  F:    include/linux/coda*.h
 +F:    include/uapi/linux/coda*.h
  
  COMMON CLK FRAMEWORK
  M:    Mike Turquette <mturquette@linaro.org>
@@@ -2140,10 -2128,10 +2140,10 @@@ S:   Maintaine
  F:    tools/power/cpupower
  
  CPUSETS
- M:    Paul Menage <paul@paulmenage.org>
+ M:    Li Zefan <lizefan@huawei.com>
  W:    http://www.bullopensource.org/cpuset/
  W:    http://oss.sgi.com/projects/cpusets/
- S:    Supported
+ S:    Maintained
  F:    Documentation/cgroups/cpusets.txt
  F:    include/linux/cpuset.h
  F:    kernel/cpuset.c
@@@ -2278,7 -2266,6 +2278,7 @@@ W:      http://www.cyclades.com
  S:    Orphan
  F:    drivers/tty/cyclades.c
  F:    include/linux/cyclades.h
 +F:    include/uapi/linux/cyclades.h
  
  CYCLADES PC300 DRIVER
  W:    http://www.cyclades.com/
@@@ -2336,7 -2323,6 +2336,7 @@@ L:      dccp@vger.kernel.or
  W:    http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp
  S:    Maintained
  F:    include/linux/dccp.h
 +F:    include/uapi/linux/dccp.h
  F:    include/linux/tfrc.h
  F:    net/dccp/
  
@@@ -2363,7 -2349,7 +2363,7 @@@ M:      Massimo Dal Zotto <dz@debian.org
  W:    http://www.debian.org/~dz/i8k/
  S:    Maintained
  F:    drivers/char/i8k.c
 -F:    include/linux/i8k.h
 +F:    include/uapi/linux/i8k.h
  
  DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
  M:    Doug Warzecha <Douglas_Warzecha@dell.com>
@@@ -2436,7 -2422,6 +2436,7 @@@ S:      Maintaine
  F:    Documentation/filesystems/quota.txt
  F:    fs/quota/
  F:    include/linux/quota*.h
 +F:    include/uapi/linux/quota*.h
  
  DISPLAYLINK USB 2.0 FRAMEBUFFER DRIVER (UDLFB)
  M:    Bernie Thompson <bernie@plugable.com>
@@@ -2543,7 -2528,6 +2543,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/gpu/drm/
  F:    include/drm/
 +F:    include/uapi/drm/
  
  INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
  M:    Daniel Vetter <daniel.vetter@ffwll.ch>
@@@ -2553,7 -2537,6 +2553,7 @@@ T:      git git://people.freedesktop.org/~da
  S:    Supported
  F:    drivers/gpu/drm/i915
  F:    include/drm/i915*
 +F:    include/uapi/drm/i915*
  
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <inki.dae@samsung.com>
@@@ -2565,7 -2548,6 +2565,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    drivers/gpu/drm/exynos
  F:    include/drm/exynos*
 +F:    include/uapi/drm/exynos*
  
  DRM DRIVERS FOR NVIDIA TEGRA
  M:    Thierry Reding <thierry.reding@avionic-design.de>
@@@ -2640,7 -2622,7 +2640,7 @@@ W:      http://github.com/mkrufk
  Q:    http://patchwork.linuxtv.org/project/linux-media/list/
  T:    git git://linuxtv.org/media_tree.git
  S:    Maintained
 -F:    drivers/media/usb/dvb-usb-v2/cxusb*
 +F:    drivers/media/usb/dvb-usb/cxusb*
  
  DVB_USB_CYPRESS_FIRMWARE MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
@@@ -2740,7 -2722,6 +2740,7 @@@ L:      netfilter-devel@vger.kernel.or
  W:    http://ebtables.sourceforge.net/
  S:    Maintained
  F:    include/linux/netfilter_bridge/ebt_*.h
 +F:    include/uapi/linux/netfilter_bridge/ebt_*.h
  F:    net/bridge/netfilter/ebt*.c
  
  EC100 MEDIA DRIVER
@@@ -2952,6 -2933,12 +2952,6 @@@ M:     Maxim Levitsky <maximlevitsky@gmail.
  S:    Maintained
  F:    drivers/media/rc/ene_ir.*
  
 -EPSON 1355 FRAMEBUFFER DRIVER
 -M:    Christopher Hoover <ch@murgatroid.com>
 -M:    Christopher Hoover <ch@hpl.hp.com>
 -S:    Maintained
 -F:    drivers/video/epson1355fb.c
 -
  EPSON S1D13XXX FRAMEBUFFER DRIVER
  M:    Kristoffer Ericson <kristoffer.ericson@gmail.com>
  S:    Maintained
@@@ -2966,7 -2953,7 +2966,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/i825xx/eexpress.*
  
  ETHERNET BRIDGE
 -M:    Stephen Hemminger <shemminger@vyatta.com>
 +M:    Stephen Hemminger <stephen@networkplumber.org>
  L:    bridge@lists.linux-foundation.org
  L:    netdev@vger.kernel.org
  W:    http://www.linuxfoundation.org/en/Net:Bridge
@@@ -3064,7 -3051,6 +3064,7 @@@ M:      Eric Paris <eparis@redhat.com
  S:    Maintained
  F:    fs/notify/fanotify/
  F:    include/linux/fanotify.h
 +F:    include/uapi/linux/fanotify.h
  
  FARSYNC SYNCHRONOUS DRIVER
  M:    Kevin Curtis <kevin.curtis@farsite.co.uk>
@@@ -3088,7 -3074,6 +3088,7 @@@ F:      drivers/scsi/fcoe
  F:    include/scsi/fc/
  F:    include/scsi/libfc.h
  F:    include/scsi/libfcoe.h
 +F:    include/uapi/scsi/fc/
  
  FILE LOCKING (flock() and fcntl()/lockf())
  M:    Matthew Wilcox <matthew@wil.cx>
@@@ -3096,8 -3081,6 +3096,8 @@@ L:      linux-fsdevel@vger.kernel.or
  S:    Maintained
  F:    include/linux/fcntl.h
  F:    include/linux/fs.h
 +F:    include/uapi/linux/fcntl.h
 +F:    include/uapi/linux/fs.h
  F:    fs/fcntl.c
  F:    fs/locks.c
  
@@@ -3187,13 -3170,11 +3187,13 @@@ F:   Documentation/devicetree/bindings/fb
  F:    drivers/video/
  F:    include/video/
  F:    include/linux/fb.h
 +F:    include/uapi/video/
 +F:    include/uapi/linux/fb.h
  
  FREESCALE DIU FRAMEBUFFER DRIVER
 -M:    Timur Tabi <timur@freescale.com>
 +M:    Timur Tabi <timur@tabi.org>
  L:    linux-fbdev@vger.kernel.org
 -S:    Supported
 +S:    Maintained
  F:    drivers/video/fsl-diu-fb.*
  
  FREESCALE DMA DRIVER
@@@ -3215,7 -3196,7 +3215,7 @@@ M:      Sascha Hauer <kernel@pengutronix.de
  L:    linux-fbdev@vger.kernel.org
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
 -F:    arch/arm/plat-mxc/include/mach/imxfb.h
 +F:    include/linux/platform_data/video-imxfb.h
  F:    drivers/video/imxfb.c
  
  FREESCALE SOC FS_ENET DRIVER
@@@ -3228,8 -3209,9 +3228,8 @@@ F:      drivers/net/ethernet/freescale/fs_en
  F:    include/linux/fs_enet_pd.h
  
  FREESCALE QUICC ENGINE LIBRARY
 -M:    Timur Tabi <timur@freescale.com>
  L:    linuxppc-dev@lists.ozlabs.org
 -S:    Supported
 +S:    Orphan
  F:    arch/powerpc/sysdev/qe_lib/
  F:    arch/powerpc/include/asm/*qe.h
  
@@@ -3248,16 -3230,16 +3248,16 @@@ S:   Maintaine
  F:    drivers/net/ethernet/freescale/ucc_geth*
  
  FREESCALE QUICC ENGINE UCC UART DRIVER
 -M:    Timur Tabi <timur@freescale.com>
 +M:    Timur Tabi <timur@tabi.org>
  L:    linuxppc-dev@lists.ozlabs.org
 -S:    Supported
 +S:    Maintained
  F:    drivers/tty/serial/ucc_uart.c
  
  FREESCALE SOC SOUND DRIVERS
 -M:    Timur Tabi <timur@freescale.com>
 +M:    Timur Tabi <timur@tabi.org>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  L:    linuxppc-dev@lists.ozlabs.org
 -S:    Supported
 +S:    Maintained
  F:    sound/soc/fsl/fsl*
  F:    sound/soc/fsl/mpc8610_hpcd.c
  
@@@ -3291,16 -3273,6 +3291,16 @@@ F:    Documentation/filesystems/caching
  F:    fs/fscache/
  F:    include/linux/fscache*.h
  
 +F2FS FILE SYSTEM
 +M:    Jaegeuk Kim <jaegeuk.kim@samsung.com>
 +L:    linux-f2fs-devel@lists.sourceforge.net
 +W:    http://en.wikipedia.org/wiki/F2FS
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
 +S:    Maintained
 +F:    Documentation/filesystems/f2fs.txt
 +F:    fs/f2fs/
 +F:    include/linux/f2fs_fs.h
 +
  FUJITSU FR-V (FRV) PORT
  M:    David Howells <dhowells@redhat.com>
  S:    Maintained
@@@ -3332,7 -3304,7 +3332,7 @@@ L:      fuse-devel@lists.sourceforge.ne
  W:    http://fuse.sourceforge.net/
  S:    Maintained
  F:    fs/fuse/
 -F:    include/linux/fuse.h
 +F:    include/uapi/linux/fuse.h
  
  FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
  M:    Rik Faith <faith@cs.unc.edu>
@@@ -3379,7 -3351,6 +3379,7 @@@ L:      linux-arch@vger.kernel.or
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git
  S:    Maintained
  F:    include/asm-generic
 +F:    include/uapi/asm-generic
  
  GENERIC UIO DRIVER FOR PCI DEVICES
  M:    "Michael S. Tsirkin" <mst@redhat.com>
@@@ -3396,7 -3367,7 +3396,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    Documentation/filesystems/gfs2*.txt
  F:    fs/gfs2/
 -F:    include/linux/gfs2_ondisk.h
 +F:    include/uapi/linux/gfs2_ondisk.h
  
  GIGASET ISDN DRIVERS
  M:    Hansjoerg Lipp <hjlipp@web.de>
@@@ -3406,7 -3377,7 +3406,7 @@@ W:      http://gigaset307x.sourceforge.net
  S:    Maintained
  F:    Documentation/isdn/README.gigaset
  F:    drivers/isdn/gigaset/
 -F:    include/linux/gigaset_dev.h
 +F:    include/uapi/linux/gigaset_dev.h
  
  GPIO SUBSYSTEM
  M:    Grant Likely <grant.likely@secretlab.ca>
@@@ -3563,7 -3534,6 +3563,7 @@@ S:      Supporte
  F:    Documentation/scsi/hpsa.txt
  F:    drivers/scsi/hpsa*.[ch]
  F:    include/linux/cciss*.h
 +F:    include/uapi/linux/cciss*.h
  
  HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
  M:    Mike Miller <mike.miller@hp.com>
@@@ -3572,7 -3542,6 +3572,7 @@@ S:      Supporte
  F:    Documentation/blockdev/cciss.txt
  F:    drivers/block/cciss*
  F:    include/linux/cciss_ioctl.h
 +F:    include/uapi/linux/cciss_ioctl.h
  
  HFS FILESYSTEM
  L:    linux-fsdevel@vger.kernel.org
@@@ -3607,7 -3576,6 +3607,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/hid/
  F:    include/linux/hid*
 +F:    include/uapi/linux/hid*
  
  HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS
  M:    Thomas Gleixner <tglx@linutronix.de>
@@@ -3639,7 -3607,7 +3639,7 @@@ M:      Jes Sorensen <jes@trained-monkey.org
  L:    linux-hippi@sunsite.dk
  S:    Maintained
  F:    include/linux/hippidevice.h
 -F:    include/linux/if_hippi.h
 +F:    include/uapi/linux/if_hippi.h
  F:    net/802/hippi.c
  F:    drivers/net/hippi/
  
@@@ -3667,7 -3635,6 +3667,7 @@@ S:      Maintaine
  F:    Documentation/timers/hpet.txt
  F:    drivers/char/hpet.c
  F:    include/linux/hpet.h
 +F:    include/uapi/linux/hpet.h
  
  HPET: x86
  M:    "Venkatesh Pallipadi (Venki)" <venki@google.com>
@@@ -3757,18 -3724,17 +3757,18 @@@ S:   Maintaine
  F:    drivers/i2c/i2c-stub.c
  
  I2C SUBSYSTEM
 -M:    Wolfram Sang <w.sang@pengutronix.de>
 +M:    Wolfram Sang <wsa@the-dreams.de>
  M:    "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
  L:    linux-i2c@vger.kernel.org
  W:    http://i2c.wiki.kernel.org/
 -T:    quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
 -T:    git git://git.pengutronix.de/git/wsa/linux.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
  S:    Maintained
  F:    Documentation/i2c/
  F:    drivers/i2c/
  F:    include/linux/i2c.h
  F:    include/linux/i2c-*.h
 +F:    include/uapi/linux/i2c.h
 +F:    include/uapi/linux/i2c-*.h
  
  I2C-TAOS-EVM DRIVER
  M:    Jean Delvare <khali@linux-fr.org>
@@@ -3884,7 -3850,7 +3884,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    net/ieee802154/
  F:    net/mac802154/
 -F:    drivers/ieee802154/
 +F:    drivers/net/ieee802154/
  
  IGUANAWORKS USB IR TRANSCEIVER
  M:    Sean Young <sean@mess.org>
@@@ -3935,7 -3901,7 +3935,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    Documentation/infiniband/
  F:    drivers/infiniband/
 -F:    include/linux/if_infiniband.h
 +F:    include/uapi/linux/if_infiniband.h
  
  INOTIFY
  M:    John McCutchan <john@johnmccutchan.com>
@@@ -3945,7 -3911,6 +3945,7 @@@ S:      Maintaine
  F:    Documentation/filesystems/inotify.txt
  F:    fs/notify/inotify/
  F:    include/linux/inotify.h
 +F:    include/uapi/linux/inotify.h
  
  INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
  M:    Dmitry Torokhov <dmitry.torokhov@gmail.com>
@@@ -3956,7 -3921,6 +3956,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/input/
  F:    include/linux/input.h
 +F:    include/uapi/linux/input.h
  F:    include/linux/input/
  
  INPUT MULTITOUCH (MT) PROTOCOL
@@@ -3977,6 -3941,7 +3977,6 @@@ L:      linux-scsi@vger.kernel.or
  T:    git git://git.code.sf.net/p/intel-sas/isci
  S:    Supported
  F:    drivers/scsi/isci/
 -F:    firmware/isci/
  
  INTEL IDLE DRIVER
  M:    Len Brown <lenb@kernel.org>
@@@ -4071,6 -4036,12 +4071,6 @@@ F:     Documentation/networking/ixgbe.tx
  F:    Documentation/networking/ixgbevf.txt
  F:    drivers/net/ethernet/intel/
  
 -INTEL MRST PMU DRIVER
 -M:    Len Brown <len.brown@intel.com>
 -L:    linux-pm@vger.kernel.org
 -S:    Supported
 -F:    arch/x86/platform/mrst/pmu.*
 -
  INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
  M:    Stanislav Yakovlev <stas.yakovlev@gmail.com>
  L:    linux-wireless@vger.kernel.org
@@@ -4099,7 -4070,7 +4099,7 @@@ S:      Supporte
  W:    http://linuxwimax.org
  F:    Documentation/wimax/README.i2400m
  F:    drivers/net/wimax/i2400m/
 -F:    include/linux/wimax/i2400m.h
 +F:    include/uapi/linux/wimax/i2400m.h
  
  INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
  M:    Stanislaw Gruszka <sgruszka@redhat.com>
@@@ -4121,9 -4092,9 +4121,9 @@@ INTEL MANAGEMENT ENGINE (mei
  M:    Tomas Winkler <tomas.winkler@intel.com>
  L:    linux-kernel@vger.kernel.org
  S:    Supported
 -F:    include/linux/mei.h
 +F:    include/uapi/linux/mei.h
  F:    drivers/misc/mei/*
 -F:    Documentation/mei/*
 +F:    Documentation/misc-devices/mei/*
  
  IOC3 ETHERNET DRIVER
  M:    Ralf Baechle <ralf@linux-mips.org>
@@@ -4163,7 -4134,6 +4163,7 @@@ S:      Supporte
  F:    Documentation/IPMI.txt
  F:    drivers/char/ipmi/
  F:    include/linux/ipmi*
 +F:    include/uapi/linux/ipmi*
  
  IPS SCSI RAID DRIVER
  M:    Adaptec OEM Raid Solutions <aacraid@adaptec.com>
@@@ -4181,7 -4151,7 +4181,7 @@@ L:      lvs-devel@vger.kernel.or
  S:    Maintained
  F:    Documentation/networking/ipvs-sysctl.txt
  F:    include/net/ip_vs.h
 -F:    include/linux/ip_vs.h
 +F:    include/uapi/linux/ip_vs.h
  F:    net/netfilter/ipvs/
  
  IPWIRELESS DRIVER
@@@ -4194,8 -4164,8 +4194,8 @@@ IPX NETWORK LAYE
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  L:    netdev@vger.kernel.org
  S:    Maintained
 -F:    include/linux/ipx.h
  F:    include/net/ipx.h
 +F:    include/uapi/linux/ipx.h
  F:    net/ipx/
  
  IRDA SUBSYSTEM
@@@ -4258,8 -4228,6 +4258,8 @@@ F:      Documentation/isdn
  F:    drivers/isdn/
  F:    include/linux/isdn.h
  F:    include/linux/isdn/
 +F:    include/uapi/linux/isdn.h
 +F:    include/uapi/linux/isdn/
  
  ISDN SUBSYSTEM (Eicon active card driver)
  M:    Armin Schindler <mac@melware.de>
@@@ -4300,7 -4268,7 +4300,7 @@@ W:      http://www.ivtvdriver.or
  S:    Maintained
  F:    Documentation/video4linux/*.ivtv
  F:    drivers/media/pci/ivtv/
 -F:    include/linux/ivtv*
 +F:    include/uapi/linux/ivtv*
  
  IX2505V MEDIA DRIVER
  M:    Malcolm Priestley <tvboxspy@gmail.com>
@@@ -4338,7 -4306,7 +4338,7 @@@ L:      linux-mtd@lists.infradead.or
  W:    http://www.linux-mtd.infradead.org/doc/jffs2.html
  S:    Maintained
  F:    fs/jffs2/
 -F:    include/linux/jffs2.h
 +F:    include/uapi/linux/jffs2.h
  
  JOURNALLING LAYER FOR BLOCK DEVICES (JBD)
  M:    Andrew Morton <akpm@linux-foundation.org>
@@@ -4421,13 -4389,11 +4421,13 @@@ W:   http://nfs.sourceforge.net
  S:    Supported
  F:    fs/nfsd/
  F:    include/linux/nfsd/
 +F:    include/uapi/linux/nfsd/
  F:    fs/lockd/
  F:    fs/nfs_common/
  F:    net/sunrpc/
  F:    include/linux/lockd/
  F:    include/linux/sunrpc/
 +F:    include/uapi/linux/sunrpc/
  
  KERNEL VIRTUAL MACHINE (KVM)
  M:    Marcelo Tosatti <mtosatti@redhat.com>
@@@ -4439,7 -4405,6 +4439,7 @@@ F:      Documentation/*/kvm.tx
  F:    arch/*/kvm/
  F:    arch/*/include/asm/kvm*
  F:    include/linux/kvm*
 +F:    include/uapi/linux/kvm*
  F:    virt/kvm/
  
  KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
@@@ -4486,7 -4451,6 +4486,7 @@@ W:      http://kernel.org/pub/linux/utils/ke
  L:    kexec@lists.infradead.org
  S:    Maintained
  F:    include/linux/kexec.h
 +F:    include/uapi/linux/kexec.h
  F:    kernel/kexec.c
  
  KEYS/KEYRINGS:
@@@ -4728,7 -4692,6 +4728,7 @@@ LLC (802.2
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  S:    Maintained
  F:    include/linux/llc.h
 +F:    include/uapi/linux/llc.h
  F:    include/net/llc*
  F:    net/llc/
  
@@@ -4904,7 -4867,7 +4904,7 @@@ S:      Maintaine
  
  MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
  M:    Mirko Lindner <mlindner@marvell.com>
 -M:    Stephen Hemminger <shemminger@vyatta.com>
 +M:    Stephen Hemminger <stephen@networkplumber.org>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/ethernet/marvell/sk*
@@@ -4949,7 -4912,7 +4949,7 @@@ MATROX FRAMEBUFFER DRIVE
  L:    linux-fbdev@vger.kernel.org
  S:    Orphan
  F:    drivers/video/matrox/matroxfb_*
 -F:    include/linux/matroxfb.h
 +F:    include/uapi/linux/matroxfb.h
  
  MAX16065 HARDWARE MONITOR DRIVER
  M:    Guenter Roeck <linux@roeck-us.net>
@@@ -5031,7 -4994,7 +5031,7 @@@ T:      git git://git.infradead.org/mtd-2.6.
  S:    Maintained
  F:    drivers/mtd/
  F:    include/linux/mtd/
 -F:    include/mtd/
 +F:    include/uapi/mtd/
  
  MICROBLAZE ARCHITECTURE
  M:    Michal Simek <monstr@monstr.eu>
@@@ -5069,6 -5032,12 +5069,6 @@@ F:     Documentation/video4linux/meye.tx
  F:    drivers/media/pci/meye/
  F:    include/uapi/linux/meye.h
  
 -MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
 -M:    Pavel Pisa <ppisa@pikron.com>
 -L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 -S:    Maintained
 -F:    drivers/mmc/host/imxmmc.*
 -
  MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
  M:    Jiri Slaby <jirislaby@gmail.com>
  S:    Maintained
@@@ -5083,7 -5052,7 +5083,7 @@@ S:      Maintaine
  F:    drivers/media/radio/radio-mr800.c
  
  MSI LAPTOP SUPPORT
 -M:    "Lee, Chun-Yi" <jlee@novell.com>
 +M:    "Lee, Chun-Yi" <jlee@suse.com>
  L:    platform-driver-x86@vger.kernel.org
  S:    Maintained
  F:    drivers/platform/x86/msi-laptop.c
@@@ -5107,7 -5076,6 +5107,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/mmc/
  F:    include/linux/mmc/
 +F:    include/uapi/linux/mmc/
  
  MULTIMEDIA CARD (MMC) ETC. OVER SPI
  S:    Orphan
@@@ -5179,7 -5147,7 +5179,7 @@@ S:      Supporte
  F:    drivers/infiniband/hw/nes/
  
  NETEM NETWORK EMULATOR
 -M:    Stephen Hemminger <shemminger@vyatta.com>
 +M:    Stephen Hemminger <stephen@networkplumber.org>
  L:    netem@lists.linux-foundation.org
  S:    Maintained
  F:    net/sched/sch_netem.c
@@@ -5208,8 -5176,6 +5208,8 @@@ S:      Supporte
  F:    include/linux/netfilter*
  F:    include/linux/netfilter/
  F:    include/net/netfilter/
 +F:    include/uapi/linux/netfilter*
 +F:    include/uapi/linux/netfilter/
  F:    net/*/netfilter.c
  F:    net/*/netfilter/
  F:    net/netfilter/
@@@ -5228,8 -5194,8 +5228,8 @@@ M:      Ralf Baechle <ralf@linux-mips.org
  L:    linux-hams@vger.kernel.org
  W:    http://www.linux-ax25.org/
  S:    Maintained
 -F:    include/linux/netrom.h
  F:    include/net/netrom.h
 +F:    include/uapi/linux/netrom.h
  F:    net/netrom/
  
  NETWORK BLOCK DEVICE (NBD)
@@@ -5238,7 -5204,6 +5238,7 @@@ S:      Maintaine
  F:    Documentation/blockdev/nbd.txt
  F:    drivers/block/nbd.c
  F:    include/linux/nbd.h
 +F:    include/uapi/linux/nbd.h
  
  NETWORK DROP MONITOR
  M:    Neil Horman <nhorman@tuxdriver.com>
@@@ -5260,9 -5225,6 +5260,9 @@@ F:      include/net
  F:    include/linux/in.h
  F:    include/linux/net.h
  F:    include/linux/netdevice.h
 +F:    include/uapi/linux/in.h
 +F:    include/uapi/linux/net.h
 +F:    include/uapi/linux/netdevice.h
  
  NETWORKING [IPv4/IPv6]
  M:    "David S. Miller" <davem@davemloft.net>
@@@ -5308,7 -5270,6 +5308,7 @@@ F:      net/rfkill
  F:    net/wireless/
  F:    include/net/ieee80211*
  F:    include/linux/wireless.h
 +F:    include/uapi/linux/wireless.h
  F:    include/net/iw_handler.h
  F:    drivers/net/wireless/
  
@@@ -5328,8 -5289,6 +5328,8 @@@ F:      include/linux/fcdevice.
  F:    include/linux/fddidevice.h
  F:    include/linux/hippidevice.h
  F:    include/linux/inetdevice.h
 +F:    include/uapi/linux/if_*
 +F:    include/uapi/linux/netdevice.h
  
  NETXEN (1/10) GbE SUPPORT
  M:    Sony Chacko <sony.chacko@qlogic.com>
@@@ -5347,8 -5306,8 +5347,8 @@@ L:      linux-wireless@vger.kernel.or
  L:    linux-nfc@lists.01.org (moderated for non-subscribers)
  S:    Maintained
  F:    net/nfc/
 -F:    include/linux/nfc.h
  F:    include/net/nfc/
 +F:    include/uapi/linux/nfc.h
  F:    drivers/nfc/
  F:    include/linux/platform_data/pn544.h
  
@@@ -5365,8 -5324,6 +5365,8 @@@ F:      net/sunrpc
  F:    include/linux/lockd/
  F:    include/linux/nfs*
  F:    include/linux/sunrpc/
 +F:    include/uapi/linux/nfs*
 +F:    include/uapi/linux/sunrpc/
  
  NI5010 NETWORK DRIVER
  M:    Jan-Pascal van Best <janpascal@vanbest.org>
@@@ -5513,7 -5470,8 +5513,7 @@@ M:      Benoît Cousson <b-cousson@ti.com
  M:    Paul Walmsley <paul@pwsan.com>
  L:    linux-omap@vger.kernel.org
  S:    Maintained
 -F:    arch/arm/mach-omap2/omap_hwmod.c
 -F:    arch/arm/plat-omap/include/plat/omap_hwmod.h
 +F:    arch/arm/mach-omap2/omap_hwmod.*
  
  OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
  M:    Benoît Cousson <b-cousson@ti.com>
@@@ -5555,7 -5513,6 +5555,7 @@@ M:      Harald Welte <laforge@gnumonks.org
  S:    Maintained
  F:    drivers/char/pcmcia/cm4000_cs.c
  F:    include/linux/cm4000_cs.h
 +F:    include/uapi/linux/cm4000_cs.h
  
  OMNIKEY CARDMAN 4040 DRIVER
  M:    Harald Welte <laforge@gnumonks.org>
@@@ -5714,7 -5671,7 +5714,7 @@@ S:      Orpha
  F:    drivers/parport/
  F:    include/linux/parport*.h
  F:    drivers/char/ppdev.c
 -F:    include/linux/ppdev.h
 +F:    include/uapi/linux/ppdev.h
  
  PARAVIRT_OPS INTERFACE
  M:    Jeremy Fitzhardinge <jeremy@goop.org>
@@@ -5777,6 -5734,15 +5777,6 @@@ L:     linux-i2c@vger.kernel.or
  S:    Maintained
  F:    drivers/i2c/muxes/i2c-mux-pca9541.c
  
 -PCA9564/PCA9665 I2C BUS DRIVER
 -M:    Wolfram Sang <w.sang@pengutronix.de>
 -L:    linux-i2c@vger.kernel.org
 -S:    Maintained
 -F:    drivers/i2c/algos/i2c-algo-pca.c
 -F:    drivers/i2c/busses/i2c-pca-*
 -F:    include/linux/i2c-algo-pca.h
 -F:    include/linux/i2c-pca-platform.h
 -
  PCDP - PRIMARY CONSOLE AND DEBUG PORT
  M:    Khalid Aziz <khalid@gonehiking.org>
  S:    Maintained
@@@ -5846,11 -5812,11 +5846,11 @@@ T:   git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    kernel/events/*
  F:    include/linux/perf_event.h
 +F:    include/uapi/linux/perf_event.h
  F:    arch/*/kernel/perf_event*.c
  F:    arch/*/kernel/*/perf_event*.c
  F:    arch/*/kernel/*/*/perf_event*.c
  F:    arch/*/include/asm/perf_event.h
 -F:    arch/*/lib/perf_event*.c
  F:    arch/*/kernel/perf_callchain.c
  F:    tools/perf/
  
@@@ -5859,7 -5825,6 +5859,7 @@@ M:      Christoph Hellwig <hch@infradead.org
  L:    linux-abi-devel@lists.sourceforge.net
  S:    Maintained
  F:    include/linux/personality.h
 +F:    include/uapi/linux/personality.h
  
  PHONET PROTOCOL
  M:    Remi Denis-Courmont <courmisch@gmail.com>
@@@ -5867,7 -5832,6 +5867,7 @@@ S:      Supporte
  F:    Documentation/networking/phonet.txt
  F:    include/linux/phonet.h
  F:    include/net/phonet/
 +F:    include/uapi/linux/phonet.h
  F:    net/phonet/
  
  PHRAM MTD DRIVER
@@@ -5916,7 -5880,6 +5916,7 @@@ M:      Jiri Kosina <jkosina@suse.cz
  S:    Maintained
  F:    drivers/block/pktcdvd.c
  F:    include/linux/pktcdvd.h
 +F:    include/uapi/linux/pktcdvd.h
  
  PKUNITY SOC DRIVERS
  M:    Guan Xuetao <gxt@mprc.pku.edu.cn>
@@@ -5991,7 -5954,7 +5991,7 @@@ PPP OVER ATM (RFC 2364
  M:    Mitchell Blank Jr <mitch@sfgoth.com>
  S:    Maintained
  F:    net/atm/pppoatm.c
 -F:    include/linux/atmppp.h
 +F:    include/uapi/linux/atmppp.h
  
  PPP OVER ETHERNET
  M:    Michal Ostrowski <mostrows@earthlink.net>
@@@ -6004,7 -5967,6 +6004,7 @@@ M:      James Chapman <jchapman@katalix.com
  S:    Maintained
  F:    net/l2tp/l2tp_ppp.c
  F:    include/linux/if_pppol2tp.h
 +F:    include/uapi/linux/if_pppol2tp.h
  
  PPS SUPPORT
  M:    Rodolfo Giometti <giometti@enneenne.com>
@@@ -6102,7 -6064,6 +6102,7 @@@ F:      include/asm-generic/syscall.
  F:    include/linux/ptrace.h
  F:    include/linux/regset.h
  F:    include/linux/tracehook.h
 +F:    include/uapi/linux/ptrace.h
  F:    kernel/ptrace.c
  
  PVRUSB2 VIDEO4LINUX DRIVER
@@@ -6131,6 -6092,7 +6131,6 @@@ T:      git git://gitorious.org/linux-pwm/li
  F:    Documentation/pwm.txt
  F:    Documentation/devicetree/bindings/pwm/
  F:    include/linux/pwm.h
 -F:    include/linux/of_pwm.h
  F:    drivers/pwm/
  F:    drivers/video/backlight/pwm_bl.c
  F:    include/linux/pwm_backlight.h
@@@ -6226,8 -6188,8 +6226,8 @@@ M:      Anders Larsen <al@alarsen.net
  W:    http://www.alarsen.net/linux/qnx4fs/
  S:    Maintained
  F:    fs/qnx4/
 -F:    include/linux/qnx4_fs.h
 -F:    include/linux/qnxtypes.h
 +F:    include/uapi/linux/qnx4_fs.h
 +F:    include/uapi/linux/qnxtypes.h
  
  QT1010 MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
@@@ -6261,7 -6223,7 +6261,7 @@@ M:      Benjamin Herrenschmidt <benh@kernel.
  L:    linux-fbdev@vger.kernel.org
  S:    Maintained
  F:    drivers/video/aty/radeon*
 -F:    include/linux/radeonfb.h
 +F:    include/uapi/linux/radeonfb.h
  
  RADIOSHARK RADIO DRIVER
  M:    Hans de Goede <hdegoede@redhat.com>
@@@ -6362,7 -6324,6 +6362,7 @@@ S:      Maintaine
  F:    Documentation/rtc.txt
  F:    drivers/rtc/
  F:    include/linux/rtc.h
 +F:    include/uapi/linux/rtc.h
  
  REISERFS FILE SYSTEM
  L:    reiserfs-devel@vger.kernel.org
@@@ -6417,8 -6378,8 +6417,8 @@@ M:      Ralf Baechle <ralf@linux-mips.org
  L:    linux-hams@vger.kernel.org
  W:    http://www.linux-ax25.org/
  S:    Maintained
 -F:    include/linux/rose.h
  F:    include/net/rose.h
 +F:    include/uapi/linux/rose.h
  F:    net/rose/
  
  RTL2830 MEDIA DRIVER
@@@ -6575,7 -6536,7 +6575,7 @@@ F:      drivers/media/platform/s3c-camif
  F:    include/media/s3c_camif.h
  
  SERIAL DRIVERS
 -M:    Alan Cox <alan@linux.intel.com>
 +M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  L:    linux-serial@vger.kernel.org
  S:    Maintained
  F:    drivers/tty/serial
@@@ -6588,15 -6549,13 +6588,15 @@@ F:   drivers/dma/dw_dmac_regs.
  F:    drivers/dma/dw_dmac.c
  
  TIMEKEEPING, NTP
 -M:    John Stultz <johnstul@us.ibm.com>
 +M:    John Stultz <john.stultz@linaro.org>
  M:    Thomas Gleixner <tglx@linutronix.de>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
  S:    Supported
  F:    include/linux/clocksource.h
  F:    include/linux/time.h
  F:    include/linux/timex.h
 +F:    include/uapi/linux/time.h
 +F:    include/uapi/linux/timex.h
  F:    kernel/time/clocksource.c
  F:    kernel/time/time*.c
  F:    kernel/time/ntp.c
@@@ -6621,7 -6580,6 +6621,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    kernel/sched/
  F:    include/linux/sched.h
 +F:    include/uapi/linux/sched.h
  
  SCORE ARCHITECTURE
  M:    Chen Liqin <liqin.chen@sunplusct.com>
@@@ -6775,7 -6733,7 +6775,7 @@@ SENSABLE PHANTO
  M:    Jiri Slaby <jirislaby@gmail.com>
  S:    Maintained
  F:    drivers/misc/phantom.c
 -F:    include/linux/phantom.h
 +F:    include/uapi/linux/phantom.h
  
  SERIAL ATA (SATA) SUBSYSTEM
  M:    Jeff Garzik <jgarzik@pobox.com>
@@@ -7033,7 -6991,6 +7033,7 @@@ L:      linux-raid@vger.kernel.or
  S:    Supported
  F:    drivers/md/
  F:    include/linux/raid/
 +F:    include/uapi/linux/raid/
  
  SONIC NETWORK DRIVER
  M:    Thomas Bogendoerfer <tsbogend@alpha.franken.de>
@@@ -7074,11 -7031,10 +7074,11 @@@ T:   git git://git.alsa-project.org/alsa-
  S:    Maintained
  F:    Documentation/sound/
  F:    include/sound/
 +F:    include/uapi/sound/
  F:    sound/
  
  SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
 -M:    Liam Girdwood <lrg@ti.com>
 +M:    Liam Girdwood <lgirdwood@gmail.com>
  M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
@@@ -7175,7 -7131,6 +7175,7 @@@ S:      Maintaine
  F:    Documentation/spi/
  F:    drivers/spi/
  F:    include/linux/spi/
 +F:    include/uapi/linux/spi/
  
  SPIDERNET NETWORK DRIVER for CELL
  M:    Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
@@@ -7312,7 -7267,7 +7312,7 @@@ F:      drivers/staging/rtl8712
  STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
  M:    Teddy Wang <teddy.wang@siliconmotion.com.cn>
  S:    Odd Fixes
 -F:    drivers/staging/sm7xx/
 +F:    drivers/staging/sm7xxfb/
  
  STAGING - SOFTLOGIC 6x10 MPEG CODEC
  M:    Ben Collins <bcollins@bluecherry.net>
@@@ -7330,7 -7285,7 +7330,7 @@@ S:      Odd Fixe
  F:    drivers/staging/speakup/
  
  STAGING - TI DSP BRIDGE DRIVERS
 -M:    Omar Ramirez Luna <omar.ramirez@ti.com>
 +M:    Omar Ramirez Luna <omar.ramirez@copitl.com>
  S:    Odd Fixes
  F:    drivers/staging/tidspbridge/
  
@@@ -7438,8 -7393,8 +7438,8 @@@ TC CLASSIFIE
  M:    Jamal Hadi Salim <jhs@mojatatu.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
 -F:    include/linux/pkt_cls.h
  F:    include/net/pkt_cls.h
 +F:    include/uapi/linux/pkt_cls.h
  F:    net/sched/
  
  TCP LOW PRIORITY MODULE
@@@ -7531,12 -7486,6 +7531,12 @@@ L:    netdev@vger.kernel.or
  S:    Supported
  F:    drivers/net/team/
  F:    include/linux/if_team.h
 +F:    include/uapi/linux/if_team.h
 +
 +TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
 +M:    Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>
 +S:    Maintained
 +F:    arch/x86/platform/ts5500/
  
  TECHNOTREND USB IR RECEIVER
  M:    Sean Young <sean@mess.org>
@@@ -7635,7 -7584,7 +7635,7 @@@ L:      netdev@vger.kernel.org (core kernel 
  L:    tipc-discussion@lists.sourceforge.net (user apps, general discussion)
  W:    http://tipc.sourceforge.net/
  S:    Maintained
 -F:    include/linux/tipc*.h
 +F:    include/uapi/linux/tipc*.h
  F:    net/tipc/
  
  TILE ARCHITECTURE
@@@ -7685,7 -7634,6 +7685,7 @@@ W:      http://www.buzzard.org.uk/toshiba
  S:    Maintained
  F:    drivers/char/toshiba.c
  F:    include/linux/toshiba.h
 +F:    include/uapi/linux/toshiba.h
  
  TMIO MMC DRIVER
  M:    Guennadi Liakhovetski <g.liakhovetski@gmx.de>
@@@ -7753,9 -7701,6 +7753,9 @@@ F:      drivers/tty/serial/serial_core.
  F:    include/linux/serial_core.h
  F:    include/linux/serial.h
  F:    include/linux/tty.h
 +F:    include/uapi/linux/serial_core.h
 +F:    include/uapi/linux/serial.h
 +F:    include/uapi/linux/tty.h
  
  TUA9001 MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
@@@ -7835,7 -7780,7 +7835,7 @@@ M:      David Herrmann <dh.herrmann@googlema
  L:    linux-input@vger.kernel.org
  S:    Maintained
  F:    drivers/hid/uhid.c
 -F:    include/linux/uhid.h
 +F:    include/uapi/linux/uhid.h
  
  ULTRA-WIDEBAND (UWB) SUBSYSTEM:
  L:    linux-usb@vger.kernel.org
@@@ -7864,7 -7809,6 +7864,7 @@@ S:      Maintaine
  F:    Documentation/cdrom/
  F:    drivers/cdrom/cdrom.c
  F:    include/linux/cdrom.h
 +F:    include/uapi/linux/cdrom.h
  
  UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
  M:    Vinayak Holikatti <vinholikatti@gmail.com>
@@@ -7882,7 -7826,7 +7882,7 @@@ T:      git git://git.infradead.org/ubi-2.6.
  S:    Maintained
  F:    drivers/mtd/ubi/
  F:    include/linux/mtd/ubi.h
 -F:    include/mtd/ubi-user.h
 +F:    include/uapi/mtd/ubi-user.h
  
  UNSORTED BLOCK IMAGES (UBI) Fastmap
  M:    Richard Weinberger <richard@nod.at>
@@@ -7916,7 -7860,7 +7916,7 @@@ M:      Oliver Neukum <oliver@neukum.org
  L:    linux-usb@vger.kernel.org
  S:    Maintained
  F:    drivers/net/usb/cdc_*.c
 -F:    include/linux/usb/cdc.h
 +F:    include/uapi/linux/usb/cdc.h
  
  USB CYPRESS C67X00 DRIVER
  M:    Peter Korsgaard <jacmet@sunsite.dk>
@@@ -8237,7 -8181,6 +8237,7 @@@ S:      Maintaine
  F:    Documentation/vfio.txt
  F:    drivers/vfio/
  F:    include/linux/vfio.h
 +F:    include/uapi/linux/vfio.h
  
  VIDEOBUF2 FRAMEWORK
  M:    Pawel Osciak <pawel@osciak.com>
@@@ -8254,7 -8197,6 +8254,7 @@@ L:      virtualization@lists.linux-foundatio
  S:    Maintained
  F:    drivers/char/virtio_console.c
  F:    include/linux/virtio_console.h
 +F:    include/uapi/linux/virtio_console.h
  
  VIRTIO CORE, NET AND BLOCK DRIVERS
  M:    Rusty Russell <rusty@rustcorp.com.au>
@@@ -8273,7 -8215,7 +8273,7 @@@ L:      virtualization@lists.linux-foundatio
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/vhost/
 -F:    include/linux/vhost.h
 +F:    include/uapi/linux/vhost.h
  
  VIA RHINE NETWORK DRIVER
  M:    Roger Luethi <rl@hellgate.ch>
@@@ -8413,7 -8355,6 +8413,7 @@@ S:      Maintaine
  F:    Documentation/watchdog/
  F:    drivers/watchdog/
  F:    include/linux/watchdog.h
 +F:    include/uapi/linux/watchdog.h
  
  WD7000 SCSI DRIVER
  M:    Miroslav Zagorac <zaga@fly.cc.fer.hr>
@@@ -8439,9 -8380,9 +8439,9 @@@ L:      wimax@linuxwimax.or
  S:    Supported
  W:    http://linuxwimax.org
  F:    Documentation/wimax/README.wimax
 -F:    include/linux/wimax.h
  F:    include/linux/wimax/debug.h
  F:    include/net/wimax.h
 +F:    include/uapi/linux/wimax.h
  F:    net/wimax/
  
  WISTRON LAPTOP BUTTON DRIVER
@@@ -8527,7 -8468,7 +8527,7 @@@ F:      Documentation/x86
  F:    arch/x86/
  
  X86 PLATFORM DRIVERS
 -M:    Matthew Garrett <mjg@redhat.com>
 +M:    Matthew Garrett <matthew.garrett@nebula.com>
  L:    platform-driver-x86@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
  S:    Maintained
@@@ -8559,7 -8500,6 +8559,7 @@@ F:      drivers/*/xen-*front.
  F:    drivers/xen/
  F:    arch/x86/include/asm/xen/
  F:    include/xen/
 +F:    include/uapi/xen/
  
  XEN HYPERVISOR ARM
  M:    Stefano Stabellini <stefano.stabellini@eu.citrix.com>
diff --combined kernel/cpuset.c
index 5bb9bf18438ca682b350eb506649c0cb35663f2e,16be7c9edfd7f2116d32f34ca9b4b99faf6d1e7c..4f9dfe43ecbd777d7bf03bed72c5da566e952b62
  #include <linux/workqueue.h>
  #include <linux/cgroup.h>
  
- /*
-  * Workqueue for cpuset related tasks.
-  *
-  * Using kevent workqueue may cause deadlock when memory_migrate
-  * is set. So we create a separate workqueue thread for cpuset.
-  */
- static struct workqueue_struct *cpuset_wq;
  /*
   * Tracks how many cpusets are currently defined in system.
   * When there is only one cpuset (the root cpuset) we can
@@@ -95,18 -87,21 +87,21 @@@ struct cpuset 
        cpumask_var_t cpus_allowed;     /* CPUs allowed to tasks in cpuset */
        nodemask_t mems_allowed;        /* Memory Nodes allowed to tasks */
  
-       struct cpuset *parent;          /* my parent */
        struct fmeter fmeter;           /* memory_pressure filter */
  
+       /*
+        * Tasks are being attached to this cpuset.  Used to prevent
+        * zeroing cpus/mems_allowed between ->can_attach() and ->attach().
+        */
+       int attach_in_progress;
        /* partition number for rebuild_sched_domains() */
        int pn;
  
        /* for custom sched domain */
        int relax_domain_level;
  
-       /* used for walking a cpuset hierarchy */
-       struct list_head stack_list;
+       struct work_struct hotplug_work;
  };
  
  /* Retrieve the cpuset for a cgroup */
@@@ -123,6 -118,15 +118,15 @@@ static inline struct cpuset *task_cs(st
                            struct cpuset, css);
  }
  
+ static inline struct cpuset *parent_cs(const struct cpuset *cs)
+ {
+       struct cgroup *pcgrp = cs->css.cgroup->parent;
+       if (pcgrp)
+               return cgroup_cs(pcgrp);
+       return NULL;
+ }
  #ifdef CONFIG_NUMA
  static inline bool task_has_mempolicy(struct task_struct *task)
  {
@@@ -138,6 -142,7 +142,7 @@@ static inline bool task_has_mempolicy(s
  
  /* bits in struct cpuset flags field */
  typedef enum {
+       CS_ONLINE,
        CS_CPU_EXCLUSIVE,
        CS_MEM_EXCLUSIVE,
        CS_MEM_HARDWALL,
        CS_SPREAD_SLAB,
  } cpuset_flagbits_t;
  
- /* the type of hotplug event */
- enum hotplug_event {
-       CPUSET_CPU_OFFLINE,
-       CPUSET_MEM_OFFLINE,
- };
  /* convenient tests for these bits */
+ static inline bool is_cpuset_online(const struct cpuset *cs)
+ {
+       return test_bit(CS_ONLINE, &cs->flags);
+ }
  static inline int is_cpu_exclusive(const struct cpuset *cs)
  {
        return test_bit(CS_CPU_EXCLUSIVE, &cs->flags);
@@@ -190,27 -194,52 +194,52 @@@ static inline int is_spread_slab(const 
  }
  
  static struct cpuset top_cpuset = {
-       .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)),
+       .flags = ((1 << CS_ONLINE) | (1 << CS_CPU_EXCLUSIVE) |
+                 (1 << CS_MEM_EXCLUSIVE)),
  };
  
+ /**
+  * cpuset_for_each_child - traverse online children of a cpuset
+  * @child_cs: loop cursor pointing to the current child
+  * @pos_cgrp: used for iteration
+  * @parent_cs: target cpuset to walk children of
+  *
+  * Walk @child_cs through the online children of @parent_cs.  Must be used
+  * with RCU read locked.
+  */
+ #define cpuset_for_each_child(child_cs, pos_cgrp, parent_cs)          \
+       cgroup_for_each_child((pos_cgrp), (parent_cs)->css.cgroup)      \
+               if (is_cpuset_online(((child_cs) = cgroup_cs((pos_cgrp)))))
+ /**
+  * cpuset_for_each_descendant_pre - pre-order walk of a cpuset's descendants
+  * @des_cs: loop cursor pointing to the current descendant
+  * @pos_cgrp: used for iteration
+  * @root_cs: target cpuset to walk ancestor of
+  *
+  * Walk @des_cs through the online descendants of @root_cs.  Must be used
+  * with RCU read locked.  The caller may modify @pos_cgrp by calling
+  * cgroup_rightmost_descendant() to skip subtree.
+  */
+ #define cpuset_for_each_descendant_pre(des_cs, pos_cgrp, root_cs)     \
+       cgroup_for_each_descendant_pre((pos_cgrp), (root_cs)->css.cgroup) \
+               if (is_cpuset_online(((des_cs) = cgroup_cs((pos_cgrp)))))
  /*
-  * There are two global mutexes guarding cpuset structures.  The first
-  * is the main control groups cgroup_mutex, accessed via
-  * cgroup_lock()/cgroup_unlock().  The second is the cpuset-specific
-  * callback_mutex, below. They can nest.  It is ok to first take
-  * cgroup_mutex, then nest callback_mutex.  We also require taking
-  * task_lock() when dereferencing a task's cpuset pointer.  See "The
-  * task_lock() exception", at the end of this comment.
-  *
-  * A task must hold both mutexes to modify cpusets.  If a task
-  * holds cgroup_mutex, then it blocks others wanting that mutex,
-  * ensuring that it is the only task able to also acquire callback_mutex
-  * and be able to modify cpusets.  It can perform various checks on
-  * the cpuset structure first, knowing nothing will change.  It can
-  * also allocate memory while just holding cgroup_mutex.  While it is
-  * performing these checks, various callback routines can briefly
-  * acquire callback_mutex to query cpusets.  Once it is ready to make
-  * the changes, it takes callback_mutex, blocking everyone else.
+  * There are two global mutexes guarding cpuset structures - cpuset_mutex
+  * and callback_mutex.  The latter may nest inside the former.  We also
+  * require taking task_lock() when dereferencing a task's cpuset pointer.
+  * See "The task_lock() exception", at the end of this comment.
+  *
+  * A task must hold both mutexes to modify cpusets.  If a task holds
+  * cpuset_mutex, then it blocks others wanting that mutex, ensuring that it
+  * is the only task able to also acquire callback_mutex and be able to
+  * modify cpusets.  It can perform various checks on the cpuset structure
+  * first, knowing nothing will change.  It can also allocate memory while
+  * just holding cpuset_mutex.  While it is performing these checks, various
+  * callback routines can briefly acquire callback_mutex to query cpusets.
+  * Once it is ready to make the changes, it takes callback_mutex, blocking
+  * everyone else.
   *
   * Calls to the kernel memory allocator can not be made while holding
   * callback_mutex, as that would risk double tripping on callback_mutex
   * guidelines for accessing subsystem state in kernel/cgroup.c
   */
  
+ static DEFINE_MUTEX(cpuset_mutex);
  static DEFINE_MUTEX(callback_mutex);
  
  /*
@@@ -245,6 -275,17 +275,17 @@@ static char cpuset_name[CPUSET_NAME_LEN
  static char cpuset_nodelist[CPUSET_NODELIST_LEN];
  static DEFINE_SPINLOCK(cpuset_buffer_lock);
  
+ /*
+  * CPU / memory hotplug is handled asynchronously.
+  */
+ static struct workqueue_struct *cpuset_propagate_hotplug_wq;
+ static void cpuset_hotplug_workfn(struct work_struct *work);
+ static void cpuset_propagate_hotplug_workfn(struct work_struct *work);
+ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs);
+ static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn);
  /*
   * This is ugly, but preserves the userspace API for existing cpuset
   * users. If someone tries to mount the "cpuset" filesystem, we
@@@ -289,7 -330,7 +330,7 @@@ static void guarantee_online_cpus(cons
                                  struct cpumask *pmask)
  {
        while (cs && !cpumask_intersects(cs->cpus_allowed, cpu_online_mask))
-               cs = cs->parent;
+               cs = parent_cs(cs);
        if (cs)
                cpumask_and(pmask, cs->cpus_allowed, cpu_online_mask);
        else
@@@ -314,7 -355,7 +355,7 @@@ static void guarantee_online_mems(cons
  {
        while (cs && !nodes_intersects(cs->mems_allowed,
                                        node_states[N_MEMORY]))
-               cs = cs->parent;
+               cs = parent_cs(cs);
        if (cs)
                nodes_and(*pmask, cs->mems_allowed,
                                        node_states[N_MEMORY]);
  /*
   * update task's spread flag if cpuset's page/slab spread flag is set
   *
-  * Called with callback_mutex/cgroup_mutex held
+  * Called with callback_mutex/cpuset_mutex held
   */
  static void cpuset_update_task_spread_flag(struct cpuset *cs,
                                        struct task_struct *tsk)
   *
   * One cpuset is a subset of another if all its allowed CPUs and
   * Memory Nodes are a subset of the other, and its exclusive flags
-  * are only set if the other's are set.  Call holding cgroup_mutex.
+  * are only set if the other's are set.  Call holding cpuset_mutex.
   */
  
  static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@@ -395,7 -436,7 +436,7 @@@ static void free_trial_cpuset(struct cp
   * If we replaced the flag and mask values of the current cpuset
   * (cur) with those values in the trial cpuset (trial), would
   * our various subset and exclusive rules still be valid?  Presumes
-  * cgroup_mutex held.
+  * cpuset_mutex held.
   *
   * 'cur' is the address of an actual, in-use cpuset.  Operations
   * such as list traversal that depend on the actual address of the
@@@ -412,48 -453,58 +453,58 @@@ static int validate_change(const struc
  {
        struct cgroup *cont;
        struct cpuset *c, *par;
+       int ret;
+       rcu_read_lock();
  
        /* Each of our child cpusets must be a subset of us */
-       list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
-               if (!is_cpuset_subset(cgroup_cs(cont), trial))
-                       return -EBUSY;
-       }
+       ret = -EBUSY;
+       cpuset_for_each_child(c, cont, cur)
+               if (!is_cpuset_subset(c, trial))
+                       goto out;
  
        /* Remaining checks don't apply to root cpuset */
+       ret = 0;
        if (cur == &top_cpuset)
-               return 0;
+               goto out;
  
-       par = cur->parent;
+       par = parent_cs(cur);
  
        /* We must be a subset of our parent cpuset */
+       ret = -EACCES;
        if (!is_cpuset_subset(trial, par))
-               return -EACCES;
+               goto out;
  
        /*
         * If either I or some sibling (!= me) is exclusive, we can't
         * overlap
         */
-       list_for_each_entry(cont, &par->css.cgroup->children, sibling) {
-               c = cgroup_cs(cont);
+       ret = -EINVAL;
+       cpuset_for_each_child(c, cont, par) {
                if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) &&
                    c != cur &&
                    cpumask_intersects(trial->cpus_allowed, c->cpus_allowed))
-                       return -EINVAL;
+                       goto out;
                if ((is_mem_exclusive(trial) || is_mem_exclusive(c)) &&
                    c != cur &&
                    nodes_intersects(trial->mems_allowed, c->mems_allowed))
-                       return -EINVAL;
+                       goto out;
        }
  
-       /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */
-       if (cgroup_task_count(cur->css.cgroup)) {
-               if (cpumask_empty(trial->cpus_allowed) ||
-                   nodes_empty(trial->mems_allowed)) {
-                       return -ENOSPC;
-               }
-       }
+       /*
+        * Cpusets with tasks - existing or newly being attached - can't
+        * have empty cpus_allowed or mems_allowed.
+        */
+       ret = -ENOSPC;
+       if ((cgroup_task_count(cur->css.cgroup) || cur->attach_in_progress) &&
+           (cpumask_empty(trial->cpus_allowed) ||
+            nodes_empty(trial->mems_allowed)))
+               goto out;
  
-       return 0;
+       ret = 0;
+ out:
+       rcu_read_unlock();
+       return ret;
  }
  
  #ifdef CONFIG_SMP
@@@ -474,31 -525,24 +525,24 @@@ update_domain_attr(struct sched_domain_
        return;
  }
  
- static void
update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c)
+ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
                                  struct cpuset *root_cs)
  {
-       LIST_HEAD(q);
-       list_add(&c->stack_list, &q);
-       while (!list_empty(&q)) {
-               struct cpuset *cp;
-               struct cgroup *cont;
-               struct cpuset *child;
-               cp = list_first_entry(&q, struct cpuset, stack_list);
-               list_del(q.next);
+       struct cpuset *cp;
+       struct cgroup *pos_cgrp;
  
-               if (cpumask_empty(cp->cpus_allowed))
+       rcu_read_lock();
+       cpuset_for_each_descendant_pre(cp, pos_cgrp, root_cs) {
+               /* skip the whole subtree if @cp doesn't have any CPU */
+               if (cpumask_empty(cp->cpus_allowed)) {
+                       pos_cgrp = cgroup_rightmost_descendant(pos_cgrp);
                        continue;
+               }
  
                if (is_sched_load_balance(cp))
                        update_domain_attr(dattr, cp);
-               list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
-                       child = cgroup_cs(cont);
-                       list_add_tail(&child->stack_list, &q);
-               }
        }
+       rcu_read_unlock();
  }
  
  /*
   * domains when operating in the severe memory shortage situations
   * that could cause allocation failures below.
   *
-  * Must be called with cgroup_lock held.
+  * Must be called with cpuset_mutex held.
   *
   * The three key local variables below are:
   *    q  - a linked-list queue of cpuset pointers, used to implement a
  static int generate_sched_domains(cpumask_var_t **domains,
                        struct sched_domain_attr **attributes)
  {
-       LIST_HEAD(q);           /* queue of cpusets to be scanned */
        struct cpuset *cp;      /* scans q */
        struct cpuset **csa;    /* array of all cpuset ptrs */
        int csn;                /* how many cpuset ptrs in csa so far */
        struct sched_domain_attr *dattr;  /* attributes for custom domains */
        int ndoms = 0;          /* number of sched domains in result */
        int nslot;              /* next empty doms[] struct cpumask slot */
+       struct cgroup *pos_cgrp;
  
        doms = NULL;
        dattr = NULL;
                goto done;
        csn = 0;
  
-       list_add(&top_cpuset.stack_list, &q);
-       while (!list_empty(&q)) {
-               struct cgroup *cont;
-               struct cpuset *child;   /* scans child cpusets of cp */
-               cp = list_first_entry(&q, struct cpuset, stack_list);
-               list_del(q.next);
-               if (cpumask_empty(cp->cpus_allowed))
-                       continue;
+       rcu_read_lock();
+       cpuset_for_each_descendant_pre(cp, pos_cgrp, &top_cpuset) {
                /*
-                * All child cpusets contain a subset of the parent's cpus, so
-                * just skip them, and then we call update_domain_attr_tree()
-                * to calc relax_domain_level of the corresponding sched
-                * domain.
+                * Continue traversing beyond @cp iff @cp has some CPUs and
+                * isn't load balancing.  The former is obvious.  The
+                * latter: All child cpusets contain a subset of the
+                * parent's cpus, so just skip them, and then we call
+                * update_domain_attr_tree() to calc relax_domain_level of
+                * the corresponding sched domain.
                 */
-               if (is_sched_load_balance(cp)) {
-                       csa[csn++] = cp;
+               if (!cpumask_empty(cp->cpus_allowed) &&
+                   !is_sched_load_balance(cp))
                        continue;
-               }
  
-               list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
-                       child = cgroup_cs(cont);
-                       list_add_tail(&child->stack_list, &q);
-               }
-       }
+               if (is_sched_load_balance(cp))
+                       csa[csn++] = cp;
+               /* skip @cp's subtree */
+               pos_cgrp = cgroup_rightmost_descendant(pos_cgrp);
+       }
+       rcu_read_unlock();
  
        for (i = 0; i < csn; i++)
                csa[i]->pn = i;
@@@ -725,25 -763,25 +763,25 @@@ done
  /*
   * Rebuild scheduler domains.
   *
-  * Call with neither cgroup_mutex held nor within get_online_cpus().
-  * Takes both cgroup_mutex and get_online_cpus().
+  * If the flag 'sched_load_balance' of any cpuset with non-empty
+  * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
+  * which has that flag enabled, or if any cpuset with a non-empty
+  * 'cpus' is removed, then call this routine to rebuild the
+  * scheduler's dynamic sched domains.
   *
-  * Cannot be directly called from cpuset code handling changes
-  * to the cpuset pseudo-filesystem, because it cannot be called
-  * from code that already holds cgroup_mutex.
+  * Call with cpuset_mutex held.  Takes get_online_cpus().
   */
- static void do_rebuild_sched_domains(struct work_struct *unused)
+ static void rebuild_sched_domains_locked(void)
  {
        struct sched_domain_attr *attr;
        cpumask_var_t *doms;
        int ndoms;
  
+       lockdep_assert_held(&cpuset_mutex);
        get_online_cpus();
  
        /* Generate domain masks and attrs */
-       cgroup_lock();
        ndoms = generate_sched_domains(&doms, &attr);
-       cgroup_unlock();
  
        /* Have scheduler rebuild the domains */
        partition_sched_domains(ndoms, doms, attr);
        put_online_cpus();
  }
  #else /* !CONFIG_SMP */
- static void do_rebuild_sched_domains(struct work_struct *unused)
+ static void rebuild_sched_domains_locked(void)
  {
  }
  
@@@ -763,44 -801,11 +801,11 @@@ static int generate_sched_domains(cpuma
  }
  #endif /* CONFIG_SMP */
  
- static DECLARE_WORK(rebuild_sched_domains_work, do_rebuild_sched_domains);
- /*
-  * Rebuild scheduler domains, asynchronously via workqueue.
-  *
-  * If the flag 'sched_load_balance' of any cpuset with non-empty
-  * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
-  * which has that flag enabled, or if any cpuset with a non-empty
-  * 'cpus' is removed, then call this routine to rebuild the
-  * scheduler's dynamic sched domains.
-  *
-  * The rebuild_sched_domains() and partition_sched_domains()
-  * routines must nest cgroup_lock() inside get_online_cpus(),
-  * but such cpuset changes as these must nest that locking the
-  * other way, holding cgroup_lock() for much of the code.
-  *
-  * So in order to avoid an ABBA deadlock, the cpuset code handling
-  * these user changes delegates the actual sched domain rebuilding
-  * to a separate workqueue thread, which ends up processing the
-  * above do_rebuild_sched_domains() function.
-  */
- static void async_rebuild_sched_domains(void)
- {
-       queue_work(cpuset_wq, &rebuild_sched_domains_work);
- }
- /*
-  * Accomplishes the same scheduler domain rebuild as the above
-  * async_rebuild_sched_domains(), however it directly calls the
-  * rebuild routine synchronously rather than calling it via an
-  * asynchronous work thread.
-  *
-  * This can only be called from code that is not holding
-  * cgroup_mutex (not nested in a cgroup_lock() call.)
-  */
  void rebuild_sched_domains(void)
  {
-       do_rebuild_sched_domains(NULL);
+       mutex_lock(&cpuset_mutex);
+       rebuild_sched_domains_locked();
+       mutex_unlock(&cpuset_mutex);
  }
  
  /**
   * @tsk: task to test
   * @scan: struct cgroup_scanner contained in its struct cpuset_hotplug_scanner
   *
-  * Call with cgroup_mutex held.  May take callback_mutex during call.
+  * Call with cpuset_mutex held.  May take callback_mutex during call.
   * Called for each task in a cgroup by cgroup_scan_tasks().
   * Return nonzero if this tasks's cpus_allowed mask should be changed (in other
   * words, if its mask is not equal to its cpuset's mask).
@@@ -829,7 -834,7 +834,7 @@@ static int cpuset_test_cpumask(struct t
   * cpus_allowed mask needs to be changed.
   *
   * We don't need to re-check for the cgroup/cpuset membership, since we're
-  * holding cgroup_lock() at this point.
+  * holding cpuset_mutex at this point.
   */
  static void cpuset_change_cpumask(struct task_struct *tsk,
                                  struct cgroup_scanner *scan)
   * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
   * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
   *
-  * Called with cgroup_mutex held
+  * Called with cpuset_mutex held
   *
   * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
   * calling callback functions for each.
@@@ -920,7 -925,7 +925,7 @@@ static int update_cpumask(struct cpuse
        heap_free(&heap);
  
        if (is_load_balanced)
-               async_rebuild_sched_domains();
+               rebuild_sched_domains_locked();
        return 0;
  }
  
   *    Temporarilly set tasks mems_allowed to target nodes of migration,
   *    so that the migration code can allocate pages on these nodes.
   *
-  *    Call holding cgroup_mutex, so current's cpuset won't change
+  *    Call holding cpuset_mutex, so current's cpuset won't change
   *    during this call, as manage_mutex holds off any cpuset_attach()
   *    calls.  Therefore we don't need to take task_lock around the
   *    call to guarantee_online_mems(), as we know no one is changing
@@@ -1007,7 -1012,7 +1012,7 @@@ static void cpuset_change_task_nodemask
  /*
   * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy
   * of it to cpuset's new mems_allowed, and migrate pages to new nodes if
-  * memory_migrate flag is set. Called with cgroup_mutex held.
+  * memory_migrate flag is set. Called with cpuset_mutex held.
   */
  static void cpuset_change_nodemask(struct task_struct *p,
                                   struct cgroup_scanner *scan)
        struct cpuset *cs;
        int migrate;
        const nodemask_t *oldmem = scan->data;
-       static nodemask_t newmems;      /* protected by cgroup_mutex */
+       static nodemask_t newmems;      /* protected by cpuset_mutex */
  
        cs = cgroup_cs(scan->cg);
        guarantee_online_mems(cs, &newmems);
@@@ -1043,7 -1048,7 +1048,7 @@@ static void *cpuset_being_rebound
   * @oldmem: old mems_allowed of cpuset cs
   * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
   *
-  * Called with cgroup_mutex held
+  * Called with cpuset_mutex held
   * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0
   * if @heap != NULL.
   */
@@@ -1065,7 -1070,7 +1070,7 @@@ static void update_tasks_nodemask(struc
         * take while holding tasklist_lock.  Forks can happen - the
         * mpol_dup() cpuset_being_rebound check will catch such forks,
         * and rebind their vma mempolicies too.  Because we still hold
-        * the global cgroup_mutex, we know that no other rebind effort
+        * the global cpuset_mutex, we know that no other rebind effort
         * will be contending for the global variable cpuset_being_rebound.
         * It's ok if we rebind the same mm twice; mpol_rebind_mm()
         * is idempotent.  Also migrate pages in each mm to new nodes.
   * mempolicies and if the cpuset is marked 'memory_migrate',
   * migrate the tasks pages to the new memory.
   *
-  * Call with cgroup_mutex held.  May take callback_mutex during call.
+  * Call with cpuset_mutex held.  May take callback_mutex during call.
   * Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
   * lock each such tasks mm->mmap_sem, scan its vma's and rebind
   * their mempolicies to the cpusets new mems_allowed.
@@@ -1168,7 -1173,7 +1173,7 @@@ static int update_relax_domain_level(st
                cs->relax_domain_level = val;
                if (!cpumask_empty(cs->cpus_allowed) &&
                    is_sched_load_balance(cs))
-                       async_rebuild_sched_domains();
+                       rebuild_sched_domains_locked();
        }
  
        return 0;
   * Called by cgroup_scan_tasks() for each task in a cgroup.
   *
   * We don't need to re-check for the cgroup/cpuset membership, since we're
-  * holding cgroup_lock() at this point.
+  * holding cpuset_mutex at this point.
   */
  static void cpuset_change_flag(struct task_struct *tsk,
                                struct cgroup_scanner *scan)
   * @cs: the cpuset in which each task's spread flags needs to be changed
   * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
   *
-  * Called with cgroup_mutex held
+  * Called with cpuset_mutex held
   *
   * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
   * calling callback functions for each.
@@@ -1220,7 -1225,7 +1225,7 @@@ static void update_tasks_flags(struct c
   * cs:                the cpuset to update
   * turning_on:        whether the flag is being set or cleared
   *
-  * Call with cgroup_mutex held.
+  * Call with cpuset_mutex held.
   */
  
  static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
        mutex_unlock(&callback_mutex);
  
        if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed)
-               async_rebuild_sched_domains();
+               rebuild_sched_domains_locked();
  
        if (spread_flag_changed)
                update_tasks_flags(cs, &heap);
@@@ -1368,24 -1373,18 +1373,18 @@@ static int fmeter_getrate(struct fmete
        return val;
  }
  
- /*
-  * Protected by cgroup_lock. The nodemasks must be stored globally because
-  * dynamically allocating them is not allowed in can_attach, and they must
-  * persist until attach.
-  */
- static cpumask_var_t cpus_attach;
- static nodemask_t cpuset_attach_nodemask_from;
- static nodemask_t cpuset_attach_nodemask_to;
- /* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */
+ /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
  static int cpuset_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
  {
        struct cpuset *cs = cgroup_cs(cgrp);
        struct task_struct *task;
        int ret;
  
+       mutex_lock(&cpuset_mutex);
+       ret = -ENOSPC;
        if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
-               return -ENOSPC;
+               goto out_unlock;
  
        cgroup_taskset_for_each(task, cgrp, tset) {
                /*
                 * set_cpus_allowed_ptr() on all attached tasks before
                 * cpus_allowed may be changed.
                 */
+               ret = -EINVAL;
                if (task->flags & PF_THREAD_BOUND)
-                       return -EINVAL;
-               if ((ret = security_task_setscheduler(task)))
-                       return ret;
+                       goto out_unlock;
+               ret = security_task_setscheduler(task);
+               if (ret)
+                       goto out_unlock;
        }
  
-       /* prepare for attach */
-       if (cs == &top_cpuset)
-               cpumask_copy(cpus_attach, cpu_possible_mask);
-       else
-               guarantee_online_cpus(cs, cpus_attach);
-       guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
+       /*
+        * Mark attach is in progress.  This makes validate_change() fail
+        * changes which zero cpus/mems_allowed.
+        */
+       cs->attach_in_progress++;
+       ret = 0;
+ out_unlock:
+       mutex_unlock(&cpuset_mutex);
+       return ret;
+ }
  
-       return 0;
+ static void cpuset_cancel_attach(struct cgroup *cgrp,
+                                struct cgroup_taskset *tset)
+ {
+       mutex_lock(&cpuset_mutex);
+       cgroup_cs(cgrp)->attach_in_progress--;
+       mutex_unlock(&cpuset_mutex);
  }
  
+ /*
+  * Protected by cpuset_mutex.  cpus_attach is used only by cpuset_attach()
+  * but we can't allocate it dynamically there.  Define it global and
+  * allocate from cpuset_init().
+  */
+ static cpumask_var_t cpus_attach;
  static void cpuset_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
  {
+       /* static bufs protected by cpuset_mutex */
+       static nodemask_t cpuset_attach_nodemask_from;
+       static nodemask_t cpuset_attach_nodemask_to;
        struct mm_struct *mm;
        struct task_struct *task;
        struct task_struct *leader = cgroup_taskset_first(tset);
        struct cpuset *cs = cgroup_cs(cgrp);
        struct cpuset *oldcs = cgroup_cs(oldcgrp);
  
+       mutex_lock(&cpuset_mutex);
+       /* prepare for attach */
+       if (cs == &top_cpuset)
+               cpumask_copy(cpus_attach, cpu_possible_mask);
+       else
+               guarantee_online_cpus(cs, cpus_attach);
+       guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
        cgroup_taskset_for_each(task, cgrp, tset) {
                /*
                 * can_attach beforehand should guarantee that this doesn't
                                          &cpuset_attach_nodemask_to);
                mmput(mm);
        }
+       cs->attach_in_progress--;
+       /*
+        * We may have raced with CPU/memory hotunplug.  Trigger hotplug
+        * propagation if @cs doesn't have any CPU or memory.  It will move
+        * the newly added tasks to the nearest parent which can execute.
+        */
+       if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
+               schedule_cpuset_propagate_hotplug(cs);
+       mutex_unlock(&cpuset_mutex);
  }
  
  /* The various types of files and directories in a cpuset file system */
@@@ -1469,12 -1510,13 +1510,13 @@@ typedef enum 
  
  static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
  {
-       int retval = 0;
        struct cpuset *cs = cgroup_cs(cgrp);
        cpuset_filetype_t type = cft->private;
+       int retval = -ENODEV;
  
-       if (!cgroup_lock_live_group(cgrp))
-               return -ENODEV;
+       mutex_lock(&cpuset_mutex);
+       if (!is_cpuset_online(cs))
+               goto out_unlock;
  
        switch (type) {
        case FILE_CPU_EXCLUSIVE:
                retval = -EINVAL;
                break;
        }
-       cgroup_unlock();
+ out_unlock:
+       mutex_unlock(&cpuset_mutex);
        return retval;
  }
  
  static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val)
  {
-       int retval = 0;
        struct cpuset *cs = cgroup_cs(cgrp);
        cpuset_filetype_t type = cft->private;
+       int retval = -ENODEV;
  
-       if (!cgroup_lock_live_group(cgrp))
-               return -ENODEV;
+       mutex_lock(&cpuset_mutex);
+       if (!is_cpuset_online(cs))
+               goto out_unlock;
  
        switch (type) {
        case FILE_SCHED_RELAX_DOMAIN_LEVEL:
                retval = -EINVAL;
                break;
        }
-       cgroup_unlock();
+ out_unlock:
+       mutex_unlock(&cpuset_mutex);
        return retval;
  }
  
  static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft,
                                const char *buf)
  {
-       int retval = 0;
        struct cpuset *cs = cgroup_cs(cgrp);
        struct cpuset *trialcs;
+       int retval = -ENODEV;
  
-       if (!cgroup_lock_live_group(cgrp))
-               return -ENODEV;
+       /*
+        * CPU or memory hotunplug may leave @cs w/o any execution
+        * resources, in which case the hotplug code asynchronously updates
+        * configuration and transfers all tasks to the nearest ancestor
+        * which can execute.
+        *
+        * As writes to "cpus" or "mems" may restore @cs's execution
+        * resources, wait for the previously scheduled operations before
+        * proceeding, so that we don't end up keep removing tasks added
+        * after execution capability is restored.
+        *
+        * Flushing cpuset_hotplug_work is enough to synchronize against
+        * hotplug hanlding; however, cpuset_attach() may schedule
+        * propagation work directly.  Flush the workqueue too.
+        */
+       flush_work(&cpuset_hotplug_work);
+       flush_workqueue(cpuset_propagate_hotplug_wq);
+       mutex_lock(&cpuset_mutex);
+       if (!is_cpuset_online(cs))
+               goto out_unlock;
  
        trialcs = alloc_trial_cpuset(cs);
        if (!trialcs) {
                retval = -ENOMEM;
-               goto out;
+               goto out_unlock;
        }
  
        switch (cft->private) {
        }
  
        free_trial_cpuset(trialcs);
- out:
-       cgroup_unlock();
+ out_unlock:
+       mutex_unlock(&cpuset_mutex);
        return retval;
  }
  
@@@ -1790,15 -1854,12 +1854,12 @@@ static struct cftype files[] = 
  
  static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cont)
  {
-       struct cgroup *parent_cg = cont->parent;
-       struct cgroup *tmp_cg;
-       struct cpuset *parent, *cs;
+       struct cpuset *cs;
  
-       if (!parent_cg)
+       if (!cont->parent)
                return &top_cpuset.css;
-       parent = cgroup_cs(parent_cg);
  
-       cs = kmalloc(sizeof(*cs), GFP_KERNEL);
+       cs = kzalloc(sizeof(*cs), GFP_KERNEL);
        if (!cs)
                return ERR_PTR(-ENOMEM);
        if (!alloc_cpumask_var(&cs->cpus_allowed, GFP_KERNEL)) {
                return ERR_PTR(-ENOMEM);
        }
  
-       cs->flags = 0;
-       if (is_spread_page(parent))
-               set_bit(CS_SPREAD_PAGE, &cs->flags);
-       if (is_spread_slab(parent))
-               set_bit(CS_SPREAD_SLAB, &cs->flags);
        set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
        cpumask_clear(cs->cpus_allowed);
        nodes_clear(cs->mems_allowed);
        fmeter_init(&cs->fmeter);
+       INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn);
        cs->relax_domain_level = -1;
  
-       cs->parent = parent;
+       return &cs->css;
+ }
+ static int cpuset_css_online(struct cgroup *cgrp)
+ {
+       struct cpuset *cs = cgroup_cs(cgrp);
+       struct cpuset *parent = parent_cs(cs);
+       struct cpuset *tmp_cs;
+       struct cgroup *pos_cg;
+       if (!parent)
+               return 0;
+       mutex_lock(&cpuset_mutex);
+       set_bit(CS_ONLINE, &cs->flags);
+       if (is_spread_page(parent))
+               set_bit(CS_SPREAD_PAGE, &cs->flags);
+       if (is_spread_slab(parent))
+               set_bit(CS_SPREAD_SLAB, &cs->flags);
        number_of_cpusets++;
  
-       if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &cont->flags))
-               goto skip_clone;
+       if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags))
+               goto out_unlock;
  
        /*
         * Clone @parent's configuration if CGRP_CPUSET_CLONE_CHILDREN is
         * changed to grant parent->cpus_allowed-sibling_cpus_exclusive
         * (and likewise for mems) to the new cgroup.
         */
-       list_for_each_entry(tmp_cg, &parent_cg->children, sibling) {
-               struct cpuset *tmp_cs = cgroup_cs(tmp_cg);
-               if (is_mem_exclusive(tmp_cs) || is_cpu_exclusive(tmp_cs))
-                       goto skip_clone;
+       rcu_read_lock();
+       cpuset_for_each_child(tmp_cs, pos_cg, parent) {
+               if (is_mem_exclusive(tmp_cs) || is_cpu_exclusive(tmp_cs)) {
+                       rcu_read_unlock();
+                       goto out_unlock;
+               }
        }
+       rcu_read_unlock();
  
        mutex_lock(&callback_mutex);
        cs->mems_allowed = parent->mems_allowed;
        cpumask_copy(cs->cpus_allowed, parent->cpus_allowed);
        mutex_unlock(&callback_mutex);
- skip_clone:
-       return &cs->css;
+ out_unlock:
+       mutex_unlock(&cpuset_mutex);
+       return 0;
+ }
+ static void cpuset_css_offline(struct cgroup *cgrp)
+ {
+       struct cpuset *cs = cgroup_cs(cgrp);
+       mutex_lock(&cpuset_mutex);
+       if (is_sched_load_balance(cs))
+               update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
+       number_of_cpusets--;
+       clear_bit(CS_ONLINE, &cs->flags);
+       mutex_unlock(&cpuset_mutex);
  }
  
  /*
   * If the cpuset being removed has its flag 'sched_load_balance'
   * enabled, then simulate turning sched_load_balance off, which
-  * will call async_rebuild_sched_domains().
+  * will call rebuild_sched_domains_locked().
   */
  
  static void cpuset_css_free(struct cgroup *cont)
  {
        struct cpuset *cs = cgroup_cs(cont);
  
-       if (is_sched_load_balance(cs))
-               update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
-       number_of_cpusets--;
        free_cpumask_var(cs->cpus_allowed);
        kfree(cs);
  }
  struct cgroup_subsys cpuset_subsys = {
        .name = "cpuset",
        .css_alloc = cpuset_css_alloc,
+       .css_online = cpuset_css_online,
+       .css_offline = cpuset_css_offline,
        .css_free = cpuset_css_free,
        .can_attach = cpuset_can_attach,
+       .cancel_attach = cpuset_cancel_attach,
        .attach = cpuset_attach,
        .subsys_id = cpuset_subsys_id,
        .base_cftypes = files,
@@@ -1924,7 -2018,9 +2018,9 @@@ static void cpuset_do_move_task(struct 
  {
        struct cgroup *new_cgroup = scan->data;
  
+       cgroup_lock();
        cgroup_attach_task(new_cgroup, tsk);
+       cgroup_unlock();
  }
  
  /**
   * @from: cpuset in which the tasks currently reside
   * @to: cpuset to which the tasks will be moved
   *
-  * Called with cgroup_mutex held
+  * Called with cpuset_mutex held
   * callback_mutex must not be held, as cpuset_attach() will take it.
   *
   * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
@@@ -1959,169 -2055,200 +2055,200 @@@ static void move_member_tasks_to_cpuset
   * removing that CPU or node from all cpusets.  If this removes the
   * last CPU or node from a cpuset, then move the tasks in the empty
   * cpuset to its next-highest non-empty parent.
-  *
-  * Called with cgroup_mutex held
-  * callback_mutex must not be held, as cpuset_attach() will take it.
   */
  static void remove_tasks_in_empty_cpuset(struct cpuset *cs)
  {
        struct cpuset *parent;
  
-       /*
-        * The cgroup's css_sets list is in use if there are tasks
-        * in the cpuset; the list is empty if there are none;
-        * the cs->css.refcnt seems always 0.
-        */
-       if (list_empty(&cs->css.cgroup->css_sets))
-               return;
        /*
         * Find its next-highest non-empty parent, (top cpuset
         * has online cpus, so can't be empty).
         */
-       parent = cs->parent;
+       parent = parent_cs(cs);
        while (cpumask_empty(parent->cpus_allowed) ||
                        nodes_empty(parent->mems_allowed))
-               parent = parent->parent;
+               parent = parent_cs(parent);
  
        move_member_tasks_to_cpuset(cs, parent);
  }
  
- /*
-  * Helper function to traverse cpusets.
-  * It can be used to walk the cpuset tree from top to bottom, completing
-  * one layer before dropping down to the next (thus always processing a
-  * node before any of its children).
+ /**
+  * cpuset_propagate_hotplug_workfn - propagate CPU/memory hotplug to a cpuset
+  * @cs: cpuset in interest
+  *
+  * Compare @cs's cpu and mem masks against top_cpuset and if some have gone
+  * offline, update @cs accordingly.  If @cs ends up with no CPU or memory,
+  * all its tasks are moved to the nearest ancestor with both resources.
   */
- static struct cpuset *cpuset_next(struct list_head *queue)
+ static void cpuset_propagate_hotplug_workfn(struct work_struct *work)
  {
-       struct cpuset *cp;
-       struct cpuset *child;   /* scans child cpusets of cp */
-       struct cgroup *cont;
+       static cpumask_t off_cpus;
+       static nodemask_t off_mems, tmp_mems;
+       struct cpuset *cs = container_of(work, struct cpuset, hotplug_work);
+       bool is_empty;
  
-       if (list_empty(queue))
-               return NULL;
+       mutex_lock(&cpuset_mutex);
+       cpumask_andnot(&off_cpus, cs->cpus_allowed, top_cpuset.cpus_allowed);
+       nodes_andnot(off_mems, cs->mems_allowed, top_cpuset.mems_allowed);
  
-       cp = list_first_entry(queue, struct cpuset, stack_list);
-       list_del(queue->next);
-       list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
-               child = cgroup_cs(cont);
-               list_add_tail(&child->stack_list, queue);
+       /* remove offline cpus from @cs */
+       if (!cpumask_empty(&off_cpus)) {
+               mutex_lock(&callback_mutex);
+               cpumask_andnot(cs->cpus_allowed, cs->cpus_allowed, &off_cpus);
+               mutex_unlock(&callback_mutex);
+               update_tasks_cpumask(cs, NULL);
        }
  
-       return cp;
+       /* remove offline mems from @cs */
+       if (!nodes_empty(off_mems)) {
+               tmp_mems = cs->mems_allowed;
+               mutex_lock(&callback_mutex);
+               nodes_andnot(cs->mems_allowed, cs->mems_allowed, off_mems);
+               mutex_unlock(&callback_mutex);
+               update_tasks_nodemask(cs, &tmp_mems, NULL);
+       }
+       is_empty = cpumask_empty(cs->cpus_allowed) ||
+               nodes_empty(cs->mems_allowed);
+       mutex_unlock(&cpuset_mutex);
+       /*
+        * If @cs became empty, move tasks to the nearest ancestor with
+        * execution resources.  This is full cgroup operation which will
+        * also call back into cpuset.  Should be done outside any lock.
+        */
+       if (is_empty)
+               remove_tasks_in_empty_cpuset(cs);
+       /* the following may free @cs, should be the last operation */
+       css_put(&cs->css);
  }
  
+ /**
+  * schedule_cpuset_propagate_hotplug - schedule hotplug propagation to a cpuset
+  * @cs: cpuset of interest
+  *
+  * Schedule cpuset_propagate_hotplug_workfn() which will update CPU and
+  * memory masks according to top_cpuset.
+  */
+ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs)
+ {
+       /*
+        * Pin @cs.  The refcnt will be released when the work item
+        * finishes executing.
+        */
+       if (!css_tryget(&cs->css))
+               return;
  
- /*
-  * Walk the specified cpuset subtree upon a hotplug operation (CPU/Memory
-  * online/offline) and update the cpusets accordingly.
-  * For regular CPU/Mem hotplug, look for empty cpusets; the tasks of such
-  * cpuset must be moved to a parent cpuset.
+       /*
+        * Queue @cs->hotplug_work.  If already pending, lose the css ref.
+        * cpuset_propagate_hotplug_wq is ordered and propagation will
+        * happen in the order this function is called.
+        */
+       if (!queue_work(cpuset_propagate_hotplug_wq, &cs->hotplug_work))
+               css_put(&cs->css);
+ }
+ /**
+  * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset
   *
-  * Called with cgroup_mutex held.  We take callback_mutex to modify
-  * cpus_allowed and mems_allowed.
+  * This function is called after either CPU or memory configuration has
+  * changed and updates cpuset accordingly.  The top_cpuset is always
+  * synchronized to cpu_active_mask and N_MEMORY, which is necessary in
+  * order to make cpusets transparent (of no affect) on systems that are
+  * actively using CPU hotplug but making no active use of cpusets.
   *
-  * This walk processes the tree from top to bottom, completing one layer
-  * before dropping down to the next.  It always processes a node before
-  * any of its children.
+  * Non-root cpusets are only affected by offlining.  If any CPUs or memory
+  * nodes have been taken down, cpuset_propagate_hotplug() is invoked on all
+  * descendants.
   *
-  * In the case of memory hot-unplug, it will remove nodes from N_MEMORY
-  * if all present pages from a node are offlined.
+  * Note that CPU offlining during suspend is ignored.  We don't modify
+  * cpusets across suspend/resume cycles at all.
   */
- static void
- scan_cpusets_upon_hotplug(struct cpuset *root, enum hotplug_event event)
+ static void cpuset_hotplug_workfn(struct work_struct *work)
  {
-       LIST_HEAD(queue);
-       struct cpuset *cp;              /* scans cpusets being updated */
-       static nodemask_t oldmems;      /* protected by cgroup_mutex */
+       static cpumask_t new_cpus, tmp_cpus;
+       static nodemask_t new_mems, tmp_mems;
+       bool cpus_updated, mems_updated;
+       bool cpus_offlined, mems_offlined;
  
-       list_add_tail((struct list_head *)&root->stack_list, &queue);
+       mutex_lock(&cpuset_mutex);
  
-       switch (event) {
-       case CPUSET_CPU_OFFLINE:
-               while ((cp = cpuset_next(&queue)) != NULL) {
+       /* fetch the available cpus/mems and find out which changed how */
+       cpumask_copy(&new_cpus, cpu_active_mask);
+       new_mems = node_states[N_MEMORY];
  
-                       /* Continue past cpusets with all cpus online */
-                       if (cpumask_subset(cp->cpus_allowed, cpu_active_mask))
-                               continue;
+       cpus_updated = !cpumask_equal(top_cpuset.cpus_allowed, &new_cpus);
+       cpus_offlined = cpumask_andnot(&tmp_cpus, top_cpuset.cpus_allowed,
+                                      &new_cpus);
  
-                       /* Remove offline cpus from this cpuset. */
-                       mutex_lock(&callback_mutex);
-                       cpumask_and(cp->cpus_allowed, cp->cpus_allowed,
-                                                       cpu_active_mask);
-                       mutex_unlock(&callback_mutex);
+       mems_updated = !nodes_equal(top_cpuset.mems_allowed, new_mems);
+       nodes_andnot(tmp_mems, top_cpuset.mems_allowed, new_mems);
+       mems_offlined = !nodes_empty(tmp_mems);
  
-                       /* Move tasks from the empty cpuset to a parent */
-                       if (cpumask_empty(cp->cpus_allowed))
-                               remove_tasks_in_empty_cpuset(cp);
-                       else
-                               update_tasks_cpumask(cp, NULL);
-               }
-               break;
+       /* synchronize cpus_allowed to cpu_active_mask */
+       if (cpus_updated) {
+               mutex_lock(&callback_mutex);
+               cpumask_copy(top_cpuset.cpus_allowed, &new_cpus);
+               mutex_unlock(&callback_mutex);
+               /* we don't mess with cpumasks of tasks in top_cpuset */
+       }
  
-       case CPUSET_MEM_OFFLINE:
-               while ((cp = cpuset_next(&queue)) != NULL) {
+       /* synchronize mems_allowed to N_MEMORY */
+       if (mems_updated) {
+               tmp_mems = top_cpuset.mems_allowed;
+               mutex_lock(&callback_mutex);
+               top_cpuset.mems_allowed = new_mems;
+               mutex_unlock(&callback_mutex);
+               update_tasks_nodemask(&top_cpuset, &tmp_mems, NULL);
+       }
  
-                       /* Continue past cpusets with all mems online */
-                       if (nodes_subset(cp->mems_allowed,
-                                       node_states[N_MEMORY]))
-                               continue;
+       /* if cpus or mems went down, we need to propagate to descendants */
+       if (cpus_offlined || mems_offlined) {
+               struct cpuset *cs;
+               struct cgroup *pos_cgrp;
  
-                       oldmems = cp->mems_allowed;
+               rcu_read_lock();
+               cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset)
+                       schedule_cpuset_propagate_hotplug(cs);
+               rcu_read_unlock();
+       }
  
-                       /* Remove offline mems from this cpuset. */
-                       mutex_lock(&callback_mutex);
-                       nodes_and(cp->mems_allowed, cp->mems_allowed,
-                                               node_states[N_MEMORY]);
-                       mutex_unlock(&callback_mutex);
+       mutex_unlock(&cpuset_mutex);
  
-                       /* Move tasks from the empty cpuset to a parent */
-                       if (nodes_empty(cp->mems_allowed))
-                               remove_tasks_in_empty_cpuset(cp);
-                       else
-                               update_tasks_nodemask(cp, &oldmems, NULL);
-               }
+       /* wait for propagations to finish */
+       flush_workqueue(cpuset_propagate_hotplug_wq);
+       /* rebuild sched domains if cpus_allowed has changed */
+       if (cpus_updated) {
+               struct sched_domain_attr *attr;
+               cpumask_var_t *doms;
+               int ndoms;
+               mutex_lock(&cpuset_mutex);
+               ndoms = generate_sched_domains(&doms, &attr);
+               mutex_unlock(&cpuset_mutex);
+               partition_sched_domains(ndoms, doms, attr);
        }
  }
  
- /*
-  * The top_cpuset tracks what CPUs and Memory Nodes are online,
-  * period.  This is necessary in order to make cpusets transparent
-  * (of no affect) on systems that are actively using CPU hotplug
-  * but making no active use of cpusets.
-  *
-  * The only exception to this is suspend/resume, where we don't
-  * modify cpusets at all.
-  *
-  * This routine ensures that top_cpuset.cpus_allowed tracks
-  * cpu_active_mask on each CPU hotplug (cpuhp) event.
-  *
-  * Called within get_online_cpus().  Needs to call cgroup_lock()
-  * before calling generate_sched_domains().
-  *
-  * @cpu_online: Indicates whether this is a CPU online event (true) or
-  * a CPU offline event (false).
-  */
  void cpuset_update_active_cpus(bool cpu_online)
  {
-       struct sched_domain_attr *attr;
-       cpumask_var_t *doms;
-       int ndoms;
-       cgroup_lock();
-       mutex_lock(&callback_mutex);
-       cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
-       mutex_unlock(&callback_mutex);
-       if (!cpu_online)
-               scan_cpusets_upon_hotplug(&top_cpuset, CPUSET_CPU_OFFLINE);
-       ndoms = generate_sched_domains(&doms, &attr);
-       cgroup_unlock();
-       /* Have scheduler rebuild the domains */
-       partition_sched_domains(ndoms, doms, attr);
+       /*
+        * We're inside cpu hotplug critical region which usually nests
+        * inside cgroup synchronization.  Bounce actual hotplug processing
+        * to a work item to avoid reverse locking order.
+        *
+        * We still need to do partition_sched_domains() synchronously;
+        * otherwise, the scheduler will get confused and put tasks to the
+        * dead CPU.  Fall back to the default single domain.
+        * cpuset_hotplug_workfn() will rebuild it as necessary.
+        */
+       partition_sched_domains(1, NULL, NULL);
+       schedule_work(&cpuset_hotplug_work);
  }
  
  #ifdef CONFIG_MEMORY_HOTPLUG
  static int cpuset_track_online_nodes(struct notifier_block *self,
                                unsigned long action, void *arg)
  {
-       static nodemask_t oldmems;      /* protected by cgroup_mutex */
-       cgroup_lock();
-       switch (action) {
-       case MEM_ONLINE:
-               oldmems = top_cpuset.mems_allowed;
-               mutex_lock(&callback_mutex);
-               top_cpuset.mems_allowed = node_states[N_MEMORY];
-               mutex_unlock(&callback_mutex);
-               update_tasks_nodemask(&top_cpuset, &oldmems, NULL);
-               break;
-       case MEM_OFFLINE:
-               /*
-                * needn't update top_cpuset.mems_allowed explicitly because
-                * scan_cpusets_upon_hotplug() will update it.
-                */
-               scan_cpusets_upon_hotplug(&top_cpuset, CPUSET_MEM_OFFLINE);
-               break;
-       default:
-               break;
-       }
-       cgroup_unlock();
+       schedule_work(&cpuset_hotplug_work);
        return NOTIFY_OK;
  }
  #endif
@@@ -2173,8 -2278,9 +2278,9 @@@ void __init cpuset_init_smp(void
  
        hotplug_memory_notifier(cpuset_track_online_nodes, 10);
  
-       cpuset_wq = create_singlethread_workqueue("cpuset");
-       BUG_ON(!cpuset_wq);
+       cpuset_propagate_hotplug_wq =
+               alloc_ordered_workqueue("cpuset_hotplug", 0);
+       BUG_ON(!cpuset_propagate_hotplug_wq);
  }
  
  /**
@@@ -2273,8 -2379,8 +2379,8 @@@ int cpuset_nodemask_valid_mems_allowed(
   */
  static const struct cpuset *nearest_hardwall_ancestor(const struct cpuset *cs)
  {
-       while (!(is_mem_exclusive(cs) || is_mem_hardwall(cs)) && cs->parent)
-               cs = cs->parent;
+       while (!(is_mem_exclusive(cs) || is_mem_hardwall(cs)) && parent_cs(cs))
+               cs = parent_cs(cs);
        return cs;
  }
  
@@@ -2411,17 -2517,6 +2517,6 @@@ int __cpuset_node_allowed_hardwall(int 
        return 0;
  }
  
- /**
-  * cpuset_unlock - release lock on cpuset changes
-  *
-  * Undo the lock taken in a previous cpuset_lock() call.
-  */
- void cpuset_unlock(void)
- {
-       mutex_unlock(&callback_mutex);
- }
  /**
   * cpuset_mem_spread_node() - On which node to begin search for a file page
   * cpuset_slab_spread_node() - On which node to begin search for a slab page
@@@ -2511,16 -2606,8 +2606,16 @@@ void cpuset_print_task_mems_allowed(str
  
        dentry = task_cs(tsk)->css.cgroup->dentry;
        spin_lock(&cpuset_buffer_lock);
 -      snprintf(cpuset_name, CPUSET_NAME_LEN,
 -               dentry ? (const char *)dentry->d_name.name : "/");
 +
 +      if (!dentry) {
 +              strcpy(cpuset_name, "/");
 +      } else {
 +              spin_lock(&dentry->d_lock);
 +              strlcpy(cpuset_name, (const char *)dentry->d_name.name,
 +                      CPUSET_NAME_LEN);
 +              spin_unlock(&dentry->d_lock);
 +      }
 +
        nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN,
                           tsk->mems_allowed);
        printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n",
@@@ -2568,7 -2655,7 +2663,7 @@@ void __cpuset_memory_pressure_bump(void
   *  - Used for /proc/<pid>/cpuset.
   *  - No need to task_lock(tsk) on this tsk->cpuset reference, as it
   *    doesn't really matter if tsk->cpuset changes after we read it,
-  *    and we take cgroup_mutex, keeping cpuset_attach() from changing it
+  *    and we take cpuset_mutex, keeping cpuset_attach() from changing it
   *    anyway.
   */
  static int proc_cpuset_show(struct seq_file *m, void *unused_v)
        if (!tsk)
                goto out_free;
  
-       retval = -EINVAL;
-       cgroup_lock();
+       rcu_read_lock();
        css = task_subsys_state(tsk, cpuset_subsys_id);
        retval = cgroup_path(css->cgroup, buf, PAGE_SIZE);
+       rcu_read_unlock();
        if (retval < 0)
-               goto out_unlock;
+               goto out_put_task;
        seq_puts(m, buf);
        seq_putc(m, '\n');
- out_unlock:
-       cgroup_unlock();
+ out_put_task:
        put_task_struct(tsk);
  out_free:
        kfree(buf);