28 Jul, 2015

1 commit

  • klist_prev() gets the previous element in the list. It is useful to traverse
    through the list in reverse order, for example, to provide LIFO (last in first
    out) variant of access.

    Signed-off-by: Andy Shevchenko
    Acked-by: Greg Kroah-Hartman
    Signed-off-by: Lee Jones

    Andy Shevchenko
     

07 Aug, 2014

1 commit

  • The name was modified from hlist_add_after() to hlist_add_behind() when
    adjusting the order of arguments to match the one with
    klist_add_after(). This is necessary to break old code when it would
    use it the wrong way.

    Make klist follow this naming scheme for consistency.

    Signed-off-by: Ken Helias
    Cc: "Paul E. McKenney"
    Cc: Christoph Hellwig
    Cc: Hugh Dickins
    Cc: Jeff Kirsher
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ken Helias
     

14 Feb, 2011

1 commit

  • Commit c0e69a5bbc6f ("klist.c: bit 0 in pointer can't be used as flag")
    intended to make sure that all klist objects were at least pointer size
    aligned, but used the constant "4" which only works on 32-bit.

    Use "sizeof(void *)" which is correct in all cases.

    Signed-off-by: David S. Miller
    Acked-by: Jesper Nilsson
    Cc: stable
    Cc: Greg Kroah-Hartman
    Signed-off-by: Linus Torvalds

    David Miller
     

21 Jan, 2009

1 commit

  • The commit a1ed5b0cffe4b16a93a6a3390e8cee0fbef94f86
    (klist: don't iterate over deleted entries) introduces use of the
    low bit in a pointer to indicate if the knode is dead or not,
    assuming that this bit is always free.

    This is not true for all architectures, CRIS for example may align data
    on byte borders.

    The result is a bunch of warnings on bootup, devices not being
    added correctly etc, reported by Hinko Kocevar :

    ------------[ cut here ]------------
    WARNING: at lib/klist.c:62 ()
    Modules linked in:

    Stack from c1fe1cf0:
    c01cc7f4 c1fe1d11 c000eb4e c000e4de 00000000 00000000 c1f4f78f c1f50c2d
    c01d008c c1fdd1a0 c1fdd1a0 c1fe1d38 c0192954 c1fe0000 00000000 c1fe1dc0
    00000002 7fffffff c1fe1da8 c0192d50 c1fe1dc0 00000002 7fffffff c1ff9fcc
    Call Trace: [] [] [] [] [] [] []
    [] [] [] [] [] [] [] []
    [] [] [] [] [] [] [] []
    [] [] [] [] [] [] [] []
    [] [] ---[ end trace 4eaa2a86a8e2da22 ]---
    ------------[ cut here ]------------
    Repeat ad nauseam.

    Wed, Jan 14, 2009 at 12:11:32AM +0100, Bastien ROUCARIES wrote:
    > Perhaps using a pointerhackalign trick on this structure where
    > #define pointerhackalign(x) __attribute__ ((aligned (x)))
    > and declare
    > struct klist_node {
    > ...
    > } pointerhackalign(2);
    >
    > Because __attribute__ ((aligned (x))) could only increase alignment
    > it will safe to do that and serve as documentation purpose :)

    That works, but we need to do it not for the struct klist_node,
    but for the struct we insert into the void * in klist_node,
    which is struct klist.

    Reported-by: Hinko Kocevar
    Signed-off-by: Jesper Nilsson
    Cc: stable
    Signed-off-by: Greg Kroah-Hartman

    Jesper Nilsson
     

07 Jan, 2009

1 commit


09 Oct, 2008

1 commit

  • 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: Tejun Heo
    Cc: Greg Kroah-Hartman
    Cc: Alan Stern
    Cc: Jens Axboe
    Signed-off-by: Jens Axboe

    Tejun Heo
     

01 May, 2008

3 commits


08 Sep, 2005

1 commit

  • The problem is that klists claim to provide semantics for safe traversal of
    lists which are being modified. The failure case is when traversal of a
    list causes element removal (a fairly common case). The issue is that
    although the list node is refcounted, if it is embedded in an object (which
    is universally the case), then the object will be freed regardless of the
    klist refcount leading to slab corruption because the klist iterator refers
    to the prior element to get the next.

    The solution is to make the klist take and release references to the
    embedding object meaning that the embedding object won't be released until
    the list relinquishes the reference to it.

    (akpm: fast-track this because it's needed for the 2.6.13 scsi merge)

    Signed-off-by: James Bottomley
    Signed-off-by: Greg Kroah-Hartman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    James Bottomley
     

06 Sep, 2005

1 commit


21 Jun, 2005

2 commits

  • Signed-off-by: Patrick Mochel
    Signed-off-by: Greg Kroah-Hartman

    diff -Nru a/include/linux/klist.h b/include/linux/klist.h

    mochel@digitalimplant.org
     
  • 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: Patrick Mochel
    Signed-off-by: Greg Kroah-Hartman

    diff -Nru a/include/linux/klist.h b/include/linux/klist.h

    mochel@digitalimplant.org