Re: 2.6.17-rc6-mm1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



* J.A. Magallón <[email protected]> wrote:

> > - Many more lockdep updates
> 
> One missing ;)

ok, could you try the annotation patch below? ieee1394 uses skb-queues 
in a nontraditional way which collides with the customal skb-queue 
locking observed by the lock validator in the networking code. So i've 
split the affected ieee1394 skb-queue's lock type from the networking 
lock type. This way the validator will still fully validate the ieee1394 
locking rules, but separates them from the other skb-queue rules.

	Ingo

----------
Subject: lock validator: annotate ieee1394 skb-head locking
From: Ingo Molnar <[email protected]>

ieee1394 reuses the skb infrastructure of the networking code,
and uses two skb-head queues: ->pending_packet_queue and
hpsbpkt_queue. The latter is used in the usual fashion: processed
from a kernel thread. The other one, ->pending_packet_queue is also
processed from hardirq context (f.e. in hpsb_bus_reset()), which is
not what the networking code usually does (which completes from
softirq or process context). This locking assymetry can be totally
correct if done carefully, but it can also be dangerous if
networking helper functions are reused, which could assume
traditional networking use.

It would probably be more robust to push this completion into
a workqueue - but technically the code can be 100% correct, and
lockdep has to be taught about it. The solution is to split the
->pending_packet_queue skb-head->lock type from the networking
lock-type by using a private lock-validator key.

This way the validator will still fully validate the ieee1394 locking 
rules, but separates them from the other skb-queue rules.

Signed-off-by: Ingo Molnar <[email protected]>
---
 drivers/ieee1394/hosts.c |   11 ++++++++++-
 include/linux/skbuff.h   |    3 +++
 net/core/skbuff.c        |   13 +++++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)

Index: linux/drivers/ieee1394/hosts.c
===================================================================
--- linux.orig/drivers/ieee1394/hosts.c
+++ linux/drivers/ieee1394/hosts.c
@@ -108,6 +108,14 @@ static int alloc_hostnum_cb(struct hpsb_
  */
 static DEFINE_MUTEX(host_num_alloc);
 
+/*
+ * The pending_packet_queue is special in that it's processed
+ * from hardirq context too (such as hpsb_bus_reset()). Hence
+ * split the lock type from the usual networking skb-head
+ * lock type by using a separate key for it:
+ */
+static struct lockdep_type_key pending_packet_queue_key;
+
 struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 				  struct device *dev)
 {
@@ -128,7 +136,8 @@ struct hpsb_host *hpsb_alloc_host(struct
 	h->hostdata = h + 1;
 	h->driver = drv;
 
-	skb_queue_head_init(&h->pending_packet_queue);
+	skb_queue_head_init_key(&h->pending_packet_queue,
+				&pending_packet_queue_key);
 	INIT_LIST_HEAD(&h->addr_space);
 
 	for (i = 2; i < 16; i++)
Index: linux/include/linux/skbuff.h
===================================================================
--- linux.orig/include/linux/skbuff.h
+++ linux/include/linux/skbuff.h
@@ -18,6 +18,7 @@
 #include <linux/compiler.h>
 #include <linux/time.h>
 #include <linux/cache.h>
+#include <linux/lockdep.h>
 
 #include <asm/atomic.h>
 #include <asm/types.h>
@@ -589,6 +590,8 @@ static inline __u32 skb_queue_len(const 
 }
 
 extern void skb_queue_head_init(struct sk_buff_head *list);
+extern void skb_queue_head_init_key(struct sk_buff_head *list,
+				    struct lockdep_type_key *key);
 
 /*
  *	Insert an sk_buff at the start of a list.
Index: linux/net/core/skbuff.c
===================================================================
--- linux.orig/net/core/skbuff.c
+++ linux/net/core/skbuff.c
@@ -80,6 +80,19 @@ void skb_queue_head_init(struct sk_buff_
 EXPORT_SYMBOL(skb_queue_head_init);
 
 /*
+ * Use this to initialize your skb-heads if you have special locking
+ * rules for skb queues and process them from say hardirq contexts:
+ */
+void skb_queue_head_init_key(struct sk_buff_head *list,
+			     struct lockdep_type_key *key)
+{
+	spin_lock_init_key(&list->lock, key);
+	list->prev = list->next = (struct sk_buff *)list;
+	list->qlen = 0;
+}
+EXPORT_SYMBOL(skb_queue_head_init_key);
+
+/*
  *	Keep out-of-line to prevent kernel bloat.
  *	__builtin_return_address is not used because it is not always
  *	reliable.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux