All of lore.kernel.org
 help / color / mirror / Atom feed
* lib/klist.c: bit 0 in pointer can't be used as flag
@ 2009-01-13 15:14 Jesper Nilsson
  2009-01-13 21:10 ` David Miller
  0 siblings, 1 reply; 20+ messages in thread
From: Jesper Nilsson @ 2009-01-13 15:14 UTC (permalink / raw)
  To: Tejun Heo, Greg Kroah-Hartman, Alan Stern, jens.axboe,
	Hinko Kocevar
  Cc: linux-kernel

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 <hinko.kocevar@cetrtapot.si>:

------------[ 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: [<c000eb4e>] [<c000e4de>] [<c0192954>] [<c0192d50>] [<c001d49e>] [<c000b688>] [<c0192a3c>] 
       [<c000b63e>] [<c000b63e>] [<c001a542>] [<c00b55b0>] [<c00411c0>] [<c00b559c>] [<c01918e6>] [<c0191988>] 
       [<c01919d0>] [<c00cd9c8>] [<c00cdd6a>] [<c0034178>] [<c000409a>] [<c0015576>] [<c0029130>] [<c0029078>] 
       [<c0029170>] [<c0012336>] [<c00b4076>] [<c00b4770>] [<c006d6e4>] [<c006d974>] [<c006dca0>] [<c0028d6c>] 
       [<c0028e12>] [<c0006424>] <4>---[ end trace 4eaa2a86a8e2da22 ]---
------------[ cut here ]------------
Repeat ad nauseam.

The following naive patch fixes the problem by moving the flag to a
separate field in struct klist_node, but perhaps there is a better solution?

Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
---
 include/linux/klist.h |    1 +
 lib/klist.c           |    8 +++-----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/linux/klist.h b/include/linux/klist.h
index d5a27af..e542629 100644
--- a/include/linux/klist.h
+++ b/include/linux/klist.h
@@ -40,6 +40,7 @@ struct klist_node {
 	void			*n_klist;	/* never access directly */
 	struct list_head	n_node;
 	struct kref		n_ref;
+	unsigned int		flags;
 };
 
 extern void klist_add_tail(struct klist_node *n, struct klist *k);
diff --git a/lib/klist.c b/lib/klist.c
index 573d606..72ec552 100644
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -43,17 +43,15 @@
  * dead ones from iteration.
  */
 #define KNODE_DEAD		1LU
-#define KNODE_KLIST_MASK	~KNODE_DEAD
 
 static struct klist *knode_klist(struct klist_node *knode)
 {
-	return (struct klist *)
-		((unsigned long)knode->n_klist & KNODE_KLIST_MASK);
+	return (struct klist *)knode->n_klist;
 }
 
 static bool knode_dead(struct klist_node *knode)
 {
-	return (unsigned long)knode->n_klist & KNODE_DEAD;
+	return knode->flags & KNODE_DEAD;
 }
 
 static void knode_set_klist(struct klist_node *knode, struct klist *klist)
@@ -67,7 +65,7 @@ static void knode_kill(struct klist_node *knode)
 {
 	/* and no knode should die twice ever either, see we're very humane */
 	WARN_ON(knode_dead(knode));
-	*(unsigned long *)&knode->n_klist |= KNODE_DEAD;
+	knode->flags |= KNODE_DEAD;
 }
 
 /**



/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson@axis.com

^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2009-01-14 21:54 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-13 15:14 lib/klist.c: bit 0 in pointer can't be used as flag Jesper Nilsson
2009-01-13 21:10 ` David Miller
2009-01-13 22:12   ` Jesper Nilsson
2009-01-13 22:40     ` KOSAKI Motohiro
2009-01-13 22:45       ` David Miller
2009-01-13 23:11         ` Bastien ROUCARIES
2009-01-14 10:19           ` Jesper Nilsson
2009-01-14 10:21             ` David Miller
2009-01-14 10:36               ` Jesper Nilsson
2009-01-14 10:45                 ` David Miller
2009-01-14 11:02                   ` Jesper Nilsson
2009-01-14 15:12                   ` Jesper Nilsson
2009-01-14 18:17                     ` Greg KH
2009-01-14 21:53                       ` Jesper Nilsson
2009-01-13 23:54         ` KOSAKI Motohiro
2009-01-13 23:59           ` Greg KH
2009-01-14 10:25             ` Jesper Nilsson
2009-01-14  0:33         ` Hugh Dickins
2009-01-14 10:18         ` Jesper Nilsson
2009-01-13 22:42     ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.