1. 08 Feb, 2016 1 commit
    • James Bottomley's avatar
      klist: fix starting point removed bug in klist iterators · 00cd29b7
      James Bottomley authored
      The starting node for a klist iteration is often passed in from
      somewhere way above the klist infrastructure, meaning there's no
      guarantee the node is still on the list.  We've seen this in SCSI where
      we use bus_find_device() to iterate through a list of devices.  In the
      face of heavy hotplug activity, the last device returned by
      bus_find_device() can be removed before the next call.  This leads to
      
      Dec  3 13:22:02 localhost kernel: WARNING: CPU: 2 PID: 28073 at include/linux/kref.h:47 klist_iter_init_node+0x3d/0x50()
      Dec  3 13:22:02 localhost kernel: Modules linked in: scsi_debug x86_pkg_temp_thermal kvm_intel kvm irqbypass crc32c_intel joydev iTCO_wdt dcdbas ipmi_devintf acpi_power_meter iTCO_vendor_support ipmi_si imsghandler pcspkr wmi acpi_cpufreq tpm_tis tpm shpchp lpc_ich mfd_core nfsd nfs_acl lockd grace sunrpc tg3 ptp pps_core
      Dec  3 13:22:02 localhost kernel: CPU: 2 PID: 28073 Comm: cat Not tainted 4.4.0-rc1+ #2
      Dec  3 13:22:02 localhost kernel: Hardware name: Dell Inc. PowerEdge R320/08VT7V, BIOS 2.0.22 11/19/2013
      Dec  3 13:22:02 localhost kernel: ffffffff81a20e77 ffff880613acfd18 ffffffff81321eef 0000000000000000
      Dec  3 13:22:02 localhost kernel: ffff880613acfd50 ffffffff8107ca52 ffff88061176b198 0000000000000000
      Dec  3 13:22:02 localhost kernel: ffffffff814542b0 ffff880610cfb100 ffff88061176b198 ffff880613acfd60
      Dec  3 13:22:02 localhost kernel: Call Trace:
      Dec  3 13:22:02 localhost kernel: [<ffffffff81321eef>] dump_stack+0x44/0x55
      Dec  3 13:22:02 localhost kernel: [<ffffffff8107ca52>] warn_slowpath_common+0x82/0xc0
      Dec  3 13:22:02 localhost kernel: [<ffffffff814542b0>] ? proc_scsi_show+0x20/0x20
      Dec  3 13:22:02 localhost kernel: [<ffffffff8107cb4a>] warn_slowpath_null+0x1a/0x20
      Dec  3 13:22:02 localhost kernel: [<ffffffff8167225d>] klist_iter_init_node+0x3d/0x50
      Dec  3 13:22:02 localhost kernel: [<ffffffff81421d41>] bus_find_device+0x51/0xb0
      Dec  3 13:22:02 localhost kernel: [<ffffffff814545ad>] scsi_seq_next+0x2d/0x40
      [...]
      
      And an eventual crash. It can actually occur in any hotplug system
      which has a device finder and a starting device.
      
      We can fix this globally by making sure the starting node for
      klist_iter_init_node() is actually a member of the list before using it
      (and by starting from the beginning if it isn't).
      Reported-by: default avatarEwan D. Milne <emilne@redhat.com>
      Tested-by: default avatarEwan D. Milne <emilne@redhat.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      00cd29b7
  2. 28 Jul, 2015 1 commit
  3. 07 Aug, 2014 1 commit
  4. 21 May, 2013 1 commit
  5. 20 Apr, 2012 1 commit
  6. 18 Apr, 2012 1 commit
  7. 07 Mar, 2012 1 commit
  8. 06 Jan, 2009 1 commit
  9. 09 Oct, 2008 1 commit
    • Tejun Heo's avatar
      klist: don't iterate over deleted entries · a1ed5b0c
      Tejun Heo authored
      A klist entry is kept on the list till all its current iterations are
      finished; however, a new iteration after deletion also iterates over
      deleted entries as long as their reference count stays above zero.
      This causes problems for cases where there are users which iterate
      over the list while synchronized against list manipulations and
      natuarally expect already deleted entries to not show up during
      iteration.
      
      This patch implements dead flag which gets set on deletion so that
      iteration can skip already deleted entries.  The dead flag piggy backs
      on the lowest bit of knode->n_klist and only visible to klist
      implementation proper.
      
      While at it, drop klist_iter->i_head as it's redundant and doesn't
      offer anything in semantics or performance wise as klist_iter->i_klist
      is dereferenced on every iteration anyway.
      Signed-off-by: default avatarTejun Heo <tj@kernel.org>
      Cc: Greg Kroah-Hartman <gregkh@suse.de>
      Cc: Alan Stern <stern@rowland.harvard.edu>
      Cc: Jens Axboe <jens.axboe@oracle.com>
      Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
      a1ed5b0c
  10. 30 Apr, 2008 2 commits
  11. 26 Sep, 2006 1 commit
    • Alan Stern's avatar
      Driver core: Don't call put methods while holding a spinlock · 7e9f4b2d
      Alan Stern authored
      The klist utility routines currently call _put methods while holding a
      spinlock.  This is of course illegal; a put routine could try to
      unregister a device and hence need to sleep.
      
      No problems have arisen until now because in many cases klist removals
      were done synchronously, so the _put methods were never actually used.
      In other cases we may simply have been lucky.
      
      This patch (as784) reworks the klist routines so that _put methods are
      called only _after_ the klist's spinlock has been released.
      Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
      7e9f4b2d
  12. 05 Jan, 2006 1 commit
    • Frank Pavlic's avatar
      [PATCH] klist: Fix broken kref counting in find functions · e22dafbc
      Frank Pavlic authored
      The klist reference counting in the find functions that use
      klist_iter_init_node is broken.  If the function (for example
      driver_find_device) is called with a NULL start object then everything is
      fine, the first call to next_device()/klist_next increases the ref-count of
      the first node on the list and does nothing for the start object which is
      NULL.
      
      If they are called with a valid start object then klist_next will decrement
      the ref-count for the start object but nobody has incremented it.  Logical
      place to fix this would be klist_iter_init_node because the function puts a
      reference of the object into the klist_iter struct.
      Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
      Signed-off-by: default avatarFrank Pavlic <pavlic@de.ibm.com>
      Cc: Patrick Mochel <mochel@digitalimplant.org>
      Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
      e22dafbc
  13. 08 Sep, 2005 1 commit
  14. 05 Sep, 2005 1 commit
  15. 20 Jun, 2005 3 commits
    • mochel@digitalimplant.org's avatar
      [PATCH] Don't reference NULL klist pointer in klist_remove(). · 0293a509
      mochel@digitalimplant.org authored
      Signed-off-by: default avatarPatrick Mochel <mochel@digitalimplant.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
      
      diff -Nru a/lib/klist.c b/lib/klist.c
      0293a509
    • mochel@digitalimplant.org's avatar
      [PATCH] add klist_node_attached() to determine if a node is on a list or not. · 8b0c250b
      mochel@digitalimplant.org authored
      Signed-off-by: default avatarPatrick Mochel <mochel@digitalimplant.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
      
      diff -Nru a/include/linux/klist.h b/include/linux/klist.h
      8b0c250b
    • mochel@digitalimplant.org's avatar
      [PATCH] Add initial implementation of klist helpers. · 9a19fea4
      mochel@digitalimplant.org authored
      This klist interface provides a couple of structures that wrap around
      struct list_head to provide explicit list "head" (struct klist) and
      list "node" (struct klist_node) objects. For struct klist, a spinlock
      is included that protects access to the actual list itself. struct
      klist_node provides a pointer to the klist that owns it and a kref
      reference count that indicates the number of current users of that node
      in the list.
      
      The entire point is to provide an interface for iterating over a list
      that is safe and allows for modification of the list during the
      iteration (e.g. insertion and removal), including modification of the
      current node on the list.
      
      It works using a 3rd object type - struct klist_iter - that is declared
      and initialized before an iteration. klist_next() is used to acquire the
      next element in the list. It returns NULL if there are no more items.
      This klist interface provides a couple of structures that wrap around
      struct list_head to provide explicit list "head" (struct klist) and
      list "node" (struct klist_node) objects. For struct klist, a spinlock
      is included that protects access to the actual list itself. struct
      klist_node provides a pointer to the klist that owns it and a kref
      reference count that indicates the number of current users of that node
      in the list.
      
      The entire point is to provide an interface for iterating over a list
      that is safe and allows for modification of the list during the
      iteration (e.g. insertion and removal), including modification of the
      current node on the list.
      
      It works using a 3rd object type - struct klist_iter - that is declared
      and initialized before an iteration. klist_next() is used to acquire the
      next element in the list. It returns NULL if there are no more items.
      Internally, that routine takes the klist's lock, decrements the reference
      count of the previous klist_node and increments the count of the next
      klist_node. It then drops the lock and returns.
      
      There are primitives for adding and removing nodes to/from a klist.
      When deleting, klist_del() will simply decrement the reference count.
      Only when the count goes to 0 is the node removed from the list.
      klist_remove() will try to delete the node from the list and block
      until it is actually removed. This is useful for objects (like devices)
      that have been removed from the system and must be freed (but must wait
      until all accessors have finished).
      
      Internally, that routine takes the klist's lock, decrements the reference
      count of the previous klist_node and increments the count of the next
      klist_node. It then drops the lock and returns.
      
      There are primitives for adding and removing nodes to/from a klist.
      When deleting, klist_del() will simply decrement the reference count.
      Only when the count goes to 0 is the node removed from the list.
      klist_remove() will try to delete the node from the list and block
      until it is actually removed. This is useful for objects (like devices)
      that have been removed from the system and must be freed (but must wait
      until all accessors have finished).
      Signed-off-by: default avatarPatrick Mochel <mochel@digitalimplant.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
      
      diff -Nru a/include/linux/klist.h b/include/linux/klist.h
      9a19fea4