1. 17 Jan, 2014 2 commits
    • Tejun Heo's avatar
      kernfs: associate a new kernfs_node with its parent on creation · db4aad20
      Tejun Heo authored
      Once created, a kernfs_node is always destroyed by kernfs_put().
      Since ba7443bc ("sysfs, kernfs: implement
      kernfs_create/destroy_root()"), kernfs_put() depends on kernfs_root()
      to locate the ino_ida.  kernfs_root() in turn depends on
      kernfs_node->parent being set for !dir nodes.  This means that
      kernfs_put() of a !dir node requires its ->parent to be initialized.
      
      This leads to oops when a newly created !dir node is destroyed without
      going through kernfs_add_one() or after failing kernfs_add_one()
      before ->parent is set.  kernfs_root() invoked from kernfs_put() will
      try to dereference NULL parent.
      
      Fix it by moving parent association to kernfs_new_node() from
      kernfs_add_one().  kernfs_new_node() now takes @parent instead of
      @root and determines the root from the parent and also sets the new
      node's parent properly.  @parent parameter is removed from
      kernfs_add_one().  As there's no parent when creating the root node,
      __kernfs_new_node() which takes @root as before and doesn't set the
      parent is used in that case.
      
      This ensures that a kernfs_node in any stage in its life has its
      parent associated and thus can be put.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      db4aad20
    • Tejun Heo's avatar
      kernfs: add struct dentry declaration in kernfs.h · 917f56ca
      Tejun Heo authored
      Hello, Greg.
      
      Two misc fixes for kernfs.
      
      Thanks.
      ------- 8< -------
      struct dentry is used in kernfs.h but its declaration was missing,
      leading to compilation errors unless its declaration gets pulled in in
      some other way.  Add the declaration.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      917f56ca
  2. 14 Jan, 2014 1 commit
    • Tejun Heo's avatar
      kernfs: fix get_active failure handling in kernfs_seq_*() · bb305947
      Tejun Heo authored
      When kernfs_seq_start() fails to obtain an active reference, it
      returns ERR_PTR(-ENODEV).  kernfs_seq_stop() is then invoked with the
      error pointer value; however, it still proceeds to invoke
      kernfs_put_active() on the node leading to unbalanced put.
      
      If kernfs_seq_stop() is called even after active ref failure, it
      should skip invocation of @ops->seq_stop() and put_active.
      Unfortunately, this is a bit complicated because active ref failure
      isn't the only thing which may fail with ERR_PTR(-ENODEV).
      @ops->seq_start/next() may also fail with the error value and
      kernfs_seq_stop() doesn't have a way to tell apart those failures.
      
      Work it around by factoring out the active part of kernfs_seq_stop()
      into kernfs_seq_stop_active() and invoking it directly if
      @ops->seq_start/next() fail with ERR_PTR(-ENODEV) and updating
      kernfs_seq_stop() to skip kernfs_seq_stop_active() on
      ERR_PTR(-ENODEV).  This is a bit nasty but ensures that the active put
      is skipped iff get_active failed in kernfs_seq_start().
      
      tj: This was originally committed as d92d2e6b but got reverted by
          683bb276 along with other kernfs self removal patches.
          However, this one is an independent fix and shouldn't have been
          reverted together.  Reinstate the change.  Sorry about the mess.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Sasha Levin <sasha.levin@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bb305947
  3. 13 Jan, 2014 15 commits
  4. 11 Jan, 2014 3 commits
    • Tejun Heo's avatar
      kernfs: remove unnecessary NULL check in __kernfs_remove() · 88533f99
      Tejun Heo authored
      895a068a ("kernfs: make kernfs_get_active() block if the node is
      deactivated but not removed") added "struct kernfs_root *root =
      kernfs_root(kn);" at the head of the function; however, the parameter
      @kn is checked for later implying that the function may be called with
      NULL.  This means that we may end up invoking kernfs_root() with NULL
      which will oops.  None of the existing users invokes removal with NULL
      @kn, so this bug doesn't actually trigger.
      
      We can relocate kernfs_root() invocation after NULL check; however,
      allowing NULL param tends to cause more confusion than actually
      helping anything.  As there's no existing user, let's remove the
      spurious NULL check.
      
      This bug was detected by smatch.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      88533f99
    • Russell King's avatar
      drivers/base: provide an infrastructure for componentised subsystems · 2a41e607
      Russell King authored
      Subsystems such as ALSA, DRM and others require a single card-level
      device structure to represent a subsystem.  However, firmware tends to
      describe the individual devices and the connections between them.
      
      Therefore, we need a way to gather up the individual component devices
      together, and indicate when we have all the component devices.
      
      We do this in DT by providing a "superdevice" node which specifies
      the components, eg:
      
      	imx-drm {
      		compatible = "fsl,drm";
      		crtcs = <&ipu1>;
      		connectors = <&hdmi>;
      	};
      
      The superdevice is declared into the component support, along with the
      subcomponents.  The superdevice receives callbacks to locate the
      subcomponents, and identify when all components are present.  At this
      point, we bind the superdevice, which causes the appropriate subsystem
      to be initialised in the conventional way.
      
      When any of the components or superdevice are removed from the system,
      we unbind the superdevice, thereby taking the subsystem down.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2a41e607
    • Tejun Heo's avatar
      sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner() · d1ba277e
      Tejun Heo authored
      All device_schedule_callback_owner() users are converted to use
      device_remove_file_self().  Remove now unused
      {sysfs|device}_schedule_callback_owner().
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d1ba277e
  5. 10 Jan, 2014 13 commits
    • Tejun Heo's avatar
      s390: use device_remove_file_self() instead of device_schedule_callback() · bdbb0a13
      Tejun Heo authored
      driver-core now supports synchrnous self-deletion of attributes and
      the asynchrnous removal mechanism is scheduled for removal.  Use it
      instead of device_schedule_callback().
      
      * Conversions in arch/s390/pci/pci_sysfs.c and
        drivers/s390/block/dcssblk.c are straightforward.
      
      * drivers/s390/cio/ccwgroup.c is a bit more tricky because
        ccwgroup_notifier() was (ab)using device_schedule_callback() to
        purely obtain a process context to kick off ungroup operation which
        may block from a notifier callback.
      
        Rename ccwgroup_ungroup_callback() to ccwgroup_ungroup() and make it
        take ccwgroup_device * instead.  The new function is now called
        directly from ccwgroup_ungroup_store().
      
        ccwgroup_notifier() chain is updated to explicitly bounce through
        ccwgroup_device->ungroup_work.  This also removes possible failure
        from memory pressure.
      
      Only compile-tested.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
      Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
      Cc: linux390@de.ibm.com
      Cc: linux-s390@vger.kernel.org
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bdbb0a13
    • Tejun Heo's avatar
      scsi: use device_remove_file_self() instead of device_schedule_callback() · de1dee78
      Tejun Heo authored
      driver-core now supports synchrnous self-deletion of attributes and
      the asynchrnous removal mechanism is scheduled for removal.  Use it
      instead of device_schedule_callback().  This makes "delete" behave
      synchronously.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
      Cc: linux-scsi@vger.kernel.org
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      de1dee78
    • Tejun Heo's avatar
      pci: use device_remove_file_self() instead of device_schedule_callback() · 6716d289
      Tejun Heo authored
      driver-core now supports synchrnous self-deletion of attributes and
      the asynchrnous removal mechanism is scheduled for removal.  Use it
      instead of device_schedule_callback().  This makes "remove" behave
      synchronously.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Bjorn Helgaas <bhelgaas@google.com>
      Cc: linux-pci@vger.kernel.org
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6716d289
    • Tejun Heo's avatar
      kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers · 1ae06819
      Tejun Heo authored
      Sometimes it's necessary to implement a node which wants to delete
      nodes including itself.  This isn't straightforward because of kernfs
      active reference.  While a file operation is in progress, an active
      reference is held and kernfs_remove() waits for all such references to
      drain before completing.  For a self-deleting node, this is a deadlock
      as kernfs_remove() ends up waiting for an active reference that itself
      is sitting on top of.
      
      This currently is worked around in the sysfs layer using
      sysfs_schedule_callback() which makes such removals asynchronous.
      While it works, it's rather cumbersome and inherently breaks
      synchronicity of the operation - the file operation which triggered
      the operation may complete before the removal is finished (or even
      started) and the removal may fail asynchronously.  If a removal
      operation is immmediately followed by another operation which expects
      the specific name to be available (e.g. removal followed by rename
      onto the same name), there's no way to make the latter operation
      reliable.
      
      The thing is there's no inherent reason for this to be asynchrnous.
      All that's necessary to do this synchronous is a dedicated operation
      which drops its own active ref and deactivates self.  This patch
      implements kernfs_remove_self() and its wrappers in sysfs and driver
      core.  kernfs_remove_self() is to be called from one of the file
      operations, drops the active ref and deactivates using
      __kernfs_deactivate_self(), removes the self node, and restores active
      ref to the dead node using __kernfs_reactivate_self() so that the ref
      is balanced afterwards.  __kernfs_remove() is updated so that it takes
      an early exit if the target node is already fully removed so that the
      active ref restored by kernfs_remove_self() after removal doesn't
      confuse the deactivation path.
      
      This makes implementing self-deleting nodes very easy.  The normal
      removal path doesn't even need to be changed to use
      kernfs_remove_self() for the self-deleting node.  The method can
      invoke kernfs_remove_self() on itself before proceeding the normal
      removal path.  kernfs_remove() invoked on the node by the normal
      deletion path will simply be ignored.
      
      This will replace sysfs_schedule_callback().  A subtle feature of
      sysfs_schedule_callback() is that it collapses multiple invocations -
      even if multiple removals are triggered, the removal callback is run
      only once.  An equivalent effect can be achieved by testing the return
      value of kernfs_remove_self() - only the one which gets %true return
      value should proceed with actual deletion.  All other instances of
      kernfs_remove_self() will wait till the enclosing kernfs operation
      which invoked the winning instance of kernfs_remove_self() finishes
      and then return %false.  This trivially makes all users of
      kernfs_remove_self() automatically show correct synchronous behavior
      even when there are multiple concurrent operations - all "echo 1 >
      delete" instances will finish only after the whole operation is
      completed by one of the instances.
      
      v2: For !CONFIG_SYSFS, dummy version kernfs_remove_self() was missing
          and sysfs_remove_file_self() had incorrect return type.  Fix it.
          Reported by kbuild test bot.
      
      v3: Updated to use __kernfs_{de|re}activate_self().
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Alan Stern <stern@rowland.harvard.edu>
      Cc: kbuild test robot <fengguang.wu@intel.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1ae06819
    • Tejun Heo's avatar
      kernfs: implement kernfs_{de|re}activate[_self]() · 9f010c2a
      Tejun Heo authored
      This patch implements four functions to manipulate deactivation state
      - deactivate, reactivate and the _self suffixed pair.  A new fields
      kernfs_node->deact_depth is added so that concurrent and nested
      deactivations are handled properly.  kernfs_node->hash is moved so
      that it's paired with the new field so that it doesn't increase the
      size of kernfs_node.
      
      A kernfs user's lock would normally nest inside active ref but during
      removal the user may want to perform kernfs_remove() while holding the
      said lock, which would introduce a reverse locking dependency.  This
      function can be used to break such reverse dependency by allowing
      deactivation step to performed separately outside user's critical
      section.
      
      This will also be used implement kernfs_remove_self().
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9f010c2a
    • Tejun Heo's avatar
      kernfs: make kernfs_get_active() block if the node is deactivated but not removed · 895a068a
      Tejun Heo authored
      Currently, kernfs_get_active() fails if the target node is
      deactivated.  This is fine as a node always gets removed after
      deactivation; however, we're gonna add reactivation so the assumption
      won't hold.  It'd be incorrect for kernfs_get_active() to fail for a
      node which was deactivated only temporarily.
      
      This patch makes kernfs_get_active() block if the node is deactivated
      but not removed.  If the node gets reactivated (not yet implemented),
      it will be retried and succeed.  If the node gets removed, it will be
      woken up and fail.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      895a068a
    • Tejun Heo's avatar
      kernfs: remove kernfs_addrm_cxt · 99177a34
      Tejun Heo authored
      kernfs_addrm_cxt and the accompanying kernfs_addrm_start/finish() were
      added because there were operations which should be performed outside
      kernfs_mutex after adding and removing kernfs_nodes.  The necessary
      operations were recorded in kernfs_addrm_cxt and performed by
      kernfs_addrm_finish(); however, after the recent changes which
      relocated deactivation and unmapping so that they're performed
      directly during removal, the only operation kernfs_addrm_finish()
      performs is kernfs_put(), which can be moved inside the removal path
      too.
      
      This patch moves the kernfs_put() of the base ref to __kernfs_remove()
      and remove kernfs_addrm_cxt and kernfs_addrm_start/finish().
      
      * kernfs_add_one() is updated to grab and release the parent's active
        ref and kernfs_mutex itself.  kernfs_get/put_active() and
        kernfs_addrm_start/finish() invocations around it are removed from
        all users.
      
      * __kernfs_remove() puts an unlinked node directly instead of chaining
        it to kernfs_addrm_cxt.  Its callers are updated to grab and release
        kernfs_mutex instead of calling kernfs_addrm_start/finish() around
        it.
      
      v2: Updated to fit the v2 restructuring of removal path.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      99177a34
    • Tejun Heo's avatar
      kernfs: invoke kernfs_unmap_bin_file() directly from __kernfs_remove() · f601f9a2
      Tejun Heo authored
      kernfs_unmap_bin_file() is supposed to unmap all memory mappings of
      the target file before kernfs_remove() finishes; however, it currently
      is being called from kernfs_addrm_finish() and has the same race
      problem as the original implementation of deactivation when there are
      multiple removers - only the remover which snatches the node to its
      addrm_cxt->removed list is guaranteed to wait for its completion
      before returning.
      
      It can be fixed by moving kernfs_unmap_bin_file() invocation from
      kernfs_addrm_finish() to __kernfs_remove().  The function may be
      called multiple times but that shouldn't do any harm.
      
      We end up dropping kernfs_mutex in the removal loop and the node may
      be removed inbetween by someone else.  kernfs_unlink_sibling() is
      updated to test whether the node has already been removed and return
      accordingly.  __kernfs_remove() in turn performs post-unlinking
      cleanup only if it actually unlinked the node.
      
      KERNFS_HAS_MMAP test is moved out of the unmap function into
      __kernfs_remove() so that we don't unlock kernfs_mutex unnecessarily.
      While at it, drop the now meaningless "bin" qualifier from the
      function name.
      
      v2: Rewritten to fit the v2 restructuring of removal path.  HAS_MMAP
          test relocated.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f601f9a2
    • Tejun Heo's avatar
      kernfs: restructure removal path to fix possible premature return · 45a140e5
      Tejun Heo authored
      The recursive nature of kernfs_remove() means that, even if
      kernfs_remove() is not allowed to be called multiple times on the same
      node, there may be race conditions between removal of parent and its
      descendants.  While we can claim that kernfs_remove() shouldn't be
      called on one of the descendants while the removal of an ancestor is
      in progress, such rule is unnecessarily restrictive and very difficult
      to enforce.  It's better to simply allow invoking kernfs_remove() as
      the caller sees fit as long as the caller ensures that the node is
      accessible.
      
      The current behavior in such situations is broken.  Whoever enters
      removal path first takes the node off the hierarchy and then
      deactivates.  Following removers either return as soon as it notices
      that it's not the first one or can't even find the target node as it
      has already been removed from the hierarchy.  In both cases, the
      following removers may finish prematurely while the nodes which should
      be removed and drained are still being processed by the first one.
      
      This patch restructures so that multiple removers, whether through
      recursion or direction invocation, always follow the following rules.
      
      * When there are multiple concurrent removers, only one puts the base
        ref.
      
      * Regardless of which one puts the base ref, all removers are blocked
        until the target node is fully deactivated and removed.
      
      To achieve the above, removal path now first deactivates the subtree,
      drains it and then unlinks one-by-one.  __kernfs_deactivate() is
      called directly from __kernfs_removal() and drops and regrabs
      kernfs_mutex for each descendant to drain active refs.  As this means
      that multiple removers can enter __kernfs_deactivate() for the same
      node, the function is updated so that it can handle multiple
      deactivators of the same node - only one actually deactivates but all
      wait till drain completion.
      
      The restructured removal path guarantees that a removed node gets
      unlinked only after the node is deactivated and drained.  Combined
      with proper multiple deactivator handling, this guarantees that any
      invocation of kernfs_remove() returns only after the node itself and
      all its descendants are deactivated, drained and removed.
      
      v2: Draining separated into a separate loop (used to be in the same
          loop as unlink) and done from __kernfs_deactivate().  This is to
          allow exposing deactivation as a separate interface later.
      
          Root node removal was broken in v1 patch.  Fixed.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      45a140e5
    • Tejun Heo's avatar
      kernfs: remove KERNFS_REMOVED · ae34372e
      Tejun Heo authored
      KERNFS_REMOVED is used to mark half-initialized and dying nodes so
      that they don't show up in lookups and deny adding new nodes under or
      renaming it; however, its role overlaps those of deactivation and
      removal from rbtree.
      
      It's necessary to deny addition of new children while removal is in
      progress; however, this role considerably intersects with deactivation
      - KERNFS_REMOVED prevents new children while deactivation prevents new
      file operations.  There's no reason to have them separate making
      things more complex than necessary.
      
      KERNFS_REMOVED is also used to decide whether a node is still visible
      to vfs layer, which is rather redundant as equivalent determination
      can be made by testing whether the node is on its parent's children
      rbtree or not.
      
      This patch removes KERNFS_REMOVED.
      
      * Instead of KERNFS_REMOVED, each node now starts its life
        deactivated.  This means that we now use both atomic_add() and
        atomic_sub() on KN_DEACTIVATED_BIAS, which is INT_MIN.  The compiler
        generates an overflow warnings when negating INT_MIN as the negation
        can't be represented as a positive number.  Nothing is actually
        broken but let's bump BIAS by one to avoid the warnings for archs
        which negates the subtrahend..
      
      * KERNFS_REMOVED tests in add and rename paths are replaced with
        kernfs_get/put_active() of the target nodes.  Due to the way the add
        path is structured now, active ref handling is done in the callers
        of kernfs_add_one().  This will be consolidated up later.
      
      * kernfs_remove_one() is updated to deactivate instead of setting
        KERNFS_REMOVED.  This removes deactivation from kernfs_deactivate(),
        which is now renamed to kernfs_drain().
      
      * kernfs_dop_revalidate() now tests RB_EMPTY_NODE(&kn->rb) instead of
        KERNFS_REMOVED and KERNFS_REMOVED test in kernfs_dir_pos() is
        dropped.  A node which is removed from the children rbtree is not
        included in the iteration in the first place.  This means that a
        node may be visible through vfs a bit longer - it's now also visible
        after deactivation until the actual removal.  This slightly enlarged
        window difference doesn't make any difference to the userland.
      
      * Sanity check on KERNFS_REMOVED in kernfs_put() is replaced with
        checks on the active ref.
      
      * Some comment style updates in the affected area.
      
      v2: Reordered before removal path restructuring.  kernfs_active()
          dropped and kernfs_get/put_active() used instead.  RB_EMPTY_NODE()
          used in the lookup paths.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ae34372e
    • Tejun Heo's avatar
      kernfs: remove KERNFS_ACTIVE_REF and add kernfs_lockdep() · a69d001c
      Tejun Heo authored
      There currently are two mechanisms gating active ref lockdep
      annotations - KERNFS_LOCKDEP flag and KERNFS_ACTIVE_REF type mask.
      The former disables lockdep annotations in kernfs_get/put_active()
      while the latter disables all of kernfs_deactivate().
      
      While KERNFS_ACTIVE_REF also behaves as an optimization to skip the
      deactivation step for non-file nodes, the benefit is marginal and it
      needlessly diverges code paths.  Let's drop KERNFS_ACTIVE_REF and use
      KERNFS_LOCKDEP in kernfs_deactivate() too.
      
      While at it, add a test helper kernfs_lockdep() to test KERNFS_LOCKDEP
      flag so that it's more convenient and the related code can be compiled
      out when not enabled.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a69d001c
    • Tejun Heo's avatar
      kernfs: replace kernfs_node->u.completion with kernfs_root->deactivate_waitq · ea1c472d
      Tejun Heo authored
      kernfs_node->u.completion is used to notify deactivation completion
      from kernfs_put_active() to kernfs_deactivate().  We now allow
      multiple racing removals of the same node and the current removal
      scheme is no longer correct - kernfs_remove() invocation may return
      before the node is properly deactivated if it races against another
      removal.  The removal path will be restructured to address the issue.
      
      To help such restructure which requires supporting multiple waiters,
      this patch replaces kernfs_node->u.completion with
      kernfs_root->deactivate_waitq.  This makes deactivation event
      notifications share a per-root waitqueue_head; however, the wait path
      is quite cold and this will also allow shaving one pointer off
      kernfs_node.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ea1c472d
    • Tejun Heo's avatar
      kernfs: fix get_active failure handling in kernfs_seq_*() · d92d2e6b
      Tejun Heo authored
      When kernfs_seq_start() fails to obtain an active reference, it
      returns ERR_PTR(-ENODEV).  kernfs_seq_stop() is then invoked with the
      error pointer value; however, it still proceeds to invoke
      kernfs_put_active() on the node leading to unbalanced put.
      
      If kernfs_seq_stop() is called even after active ref failure, it
      should skip invocation of @ops->seq_stop() and put_active.
      Unfortunately, this is a bit complicated because active ref failure
      isn't the only thing which may fail with ERR_PTR(-ENODEV).
      @ops->seq_start/next() may also fail with the error value and
      kernfs_seq_stop() doesn't have a way to tell apart those failures.
      
      Work it around by factoring out the active part of kernfs_seq_stop()
      into kernfs_seq_stop_active() and invoking it directly if
      @ops->seq_start/next() fail with ERR_PTR(-ENODEV) and updating
      kernfs_seq_stop() to skip kernfs_seq_stop_active() on
      ERR_PTR(-ENODEV).  This is a bit nasty but ensures that the active put
      is skipped iff get_active failed in kernfs_seq_start().
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Sasha Levin <sasha.levin@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d92d2e6b
  6. 09 Jan, 2014 1 commit
  7. 08 Jan, 2014 3 commits
    • Bart Van Assche's avatar
      driver-core: Fix use-after-free triggered by bus_unregister() · 174be70b
      Bart Van Assche authored
      Avoid that bus_unregister() triggers a use-after-free with
      CONFIG_DEBUG_KOBJECT_RELEASE=y. This patch avoids that the
      following sequence triggers a kernel crash with memory poisoning
      enabled:
      * bus_register()
      * driver_register()
      * driver_unregister()
      * bus_unregister()
      
      The above sequence causes the bus private data to be freed from
      inside the bus_unregister() call although it is not guaranteed in
      that function that the reference count on the bus private data has
      dropped to zero. As an example, with CONFIG_DEBUG_KOBJECT_RELEASE=y
      the ${bus}/drivers kobject is still holding a reference on
      bus->p->subsys.kobj via its parent pointer at the time the bus
      private data is freed. Fix this by deferring freeing the bus private
      data until the last kobject_put() call on bus->p->subsys.kobj.
      
      The kernel oops triggered by the above sequence and with memory
      poisoning enabled and that is fixed by this patch is as follows:
      
      general protection fault: 0000 [#1] PREEMPT SMP
      CPU: 3 PID: 2711 Comm: kworker/3:32 Tainted: G        W  O 3.13.0-rc4-debug+ #1
      Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
      Workqueue: events kobject_delayed_cleanup
      task: ffff880037f866d0 ti: ffff88003b638000 task.ti: ffff88003b638000
      Call Trace:
       [<ffffffff81263105>] ? kobject_get_path+0x25/0x100
       [<ffffffff81264354>] kobject_uevent_env+0x134/0x600
       [<ffffffff8126482b>] kobject_uevent+0xb/0x10
       [<ffffffff81262fa2>] kobject_delayed_cleanup+0xc2/0x1b0
       [<ffffffff8106c047>] process_one_work+0x217/0x700
       [<ffffffff8106bfdb>] ? process_one_work+0x1ab/0x700
       [<ffffffff8106c64b>] worker_thread+0x11b/0x3a0
       [<ffffffff8106c530>] ? process_one_work+0x700/0x700
       [<ffffffff81074b70>] kthread+0xf0/0x110
       [<ffffffff81074a80>] ? insert_kthread_work+0x80/0x80
       [<ffffffff815673bc>] ret_from_fork+0x7c/0xb0
       [<ffffffff81074a80>] ? insert_kthread_work+0x80/0x80
      Code: 89 f8 48 89 e5 f6 82 c0 27 63 81 20 74 15 0f 1f 44 00 00 48 83 c0 01 0f b6 10 f6 82 c0 27 63 81 20 75 f0 5d c3 66 0f 1f 44 00 00 <80> 3f 00 55 48 89 e5 74 15 48 89 f8 0f 1f 40 00 48 83 c0 01 80
      RIP  [<ffffffff81267ed0>] strlen+0x0/0x30
       RSP <ffff88003b639c70>
      ---[ end trace 210f883ef80376aa ]---
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarMing Lei <ming.lei@canonical.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      174be70b
    • Bart Van Assche's avatar
      firmware loader: Add sparse annotation · 98233b21
      Bart Van Assche authored
      Avoid that sparse reports the following warning on __fw_free_buf():
      
      drivers/base/firmware_class.c:230:9: warning: context imbalance in '__fw_free_buf' - unexpected unlock
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Acked-by: default avatarMing Lei <ming.lei@canonical.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      98233b21
    • Bart Van Assche's avatar
  8. 05 Jan, 2014 1 commit
  9. 24 Dec, 2013 1 commit