]>
Commit | Line | Data |
---|---|---|
38f540a8 GKH |
1 | From stable-bounces@linux.kernel.org Thu Oct 18 03:05:10 2007 |
2 | From: Karsten Keil <kkeil@suse.de> | |
3 | Date: Thu, 18 Oct 2007 03:04:32 -0700 | |
4 | Subject: i4l: Fix random hard freeze with AVM c4 card | |
5 | To: torvalds@linux-foundation.org | |
6 | Cc: stable@kernel.org, akpm@linux-foundation.org, rainer.brestan@frequentis.com, kkeil@suse.de, rsc@runtux.com | |
7 | Message-ID: <200710181004.l9IA4WtD005633@imap1.linux-foundation.org> | |
8 | ||
9 | ||
10 | From: Karsten Keil <kkeil@suse.de> | |
11 | ||
12 | patch 1ccfd63367c1a6aaf8b33943f18856dde85f2f0b in mainline. | |
13 | ||
14 | The patch | |
15 | - Includes the call to capilib_data_b3_req in the spinlock. This routine | |
16 | in turn calls the offending mq_enqueue routine that triggered the | |
17 | freeze if not locked. This should also fix other indicators of | |
18 | incosistent capilib_msgidqueue list, that trigger messages like: | |
19 | Oct 5 03:05:57 BERL0 kernel: kcapi: msgid 3019 ncci 0x30301 not on queue | |
20 | that we saw several times a day (usually several in a row). | |
21 | - Fixes all occurrences of c4_dispatch_tx to be called with active | |
22 | spinlock, there were some instances where no lock was active. Mostly | |
23 | these are in very infrequently called routines, so the additional | |
24 | performance penalty is minimal. | |
25 | ||
26 | Signed-off-by: Karsten Keil <kkeil@suse.de> | |
27 | Signed-off-by: Rainer Brestan <rainer.brestan@frequentis.com> | |
28 | Signed-off-by: Ralf Schlatterbeck <rsc@runtux.com> | |
29 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
30 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
31 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
32 | ||
33 | --- | |
34 | drivers/isdn/hardware/avm/c4.c | 14 +++++++++++--- | |
35 | 1 file changed, 11 insertions(+), 3 deletions(-) | |
36 | ||
37 | --- a/drivers/isdn/hardware/avm/c4.c | |
38 | +++ b/drivers/isdn/hardware/avm/c4.c | |
39 | @@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card) | |
40 | { | |
41 | struct sk_buff *skb; | |
42 | void *p; | |
43 | + unsigned long flags; | |
44 | ||
45 | skb = alloc_skb(15, GFP_ATOMIC); | |
46 | if (!skb) { | |
47 | @@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card) | |
48 | skb_put(skb, (u8 *)p - (u8 *)skb->data); | |
49 | ||
50 | skb_queue_tail(&card->dma->send_queue, skb); | |
51 | + spin_lock_irqsave(&card->lock, flags); | |
52 | c4_dispatch_tx(card); | |
53 | + spin_unlock_irqrestore(&card->lock, flags); | |
54 | } | |
55 | ||
56 | static int queue_sendconfigword(avmcard *card, u32 val) | |
57 | { | |
58 | struct sk_buff *skb; | |
59 | + unsigned long flags; | |
60 | void *p; | |
61 | ||
62 | skb = alloc_skb(3+4, GFP_ATOMIC); | |
63 | @@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard | |
64 | skb_put(skb, (u8 *)p - (u8 *)skb->data); | |
65 | ||
66 | skb_queue_tail(&card->dma->send_queue, skb); | |
67 | + spin_lock_irqsave(&card->lock, flags); | |
68 | c4_dispatch_tx(card); | |
69 | + spin_unlock_irqrestore(&card->lock, flags); | |
70 | return 0; | |
71 | } | |
72 | ||
73 | @@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_ | |
74 | struct sk_buff *skb; | |
75 | void *p; | |
76 | ||
77 | + spin_lock_irqsave(&card->lock, flags); | |
78 | capilib_release_appl(&cinfo->ncci_head, appl); | |
79 | + spin_unlock_irqrestore(&card->lock, flags); | |
80 | ||
81 | if (ctrl->cnr == card->cardnr) { | |
82 | skb = alloc_skb(7, GFP_ATOMIC); | |
83 | @@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_c | |
84 | u16 retval = CAPI_NOERROR; | |
85 | unsigned long flags; | |
86 | ||
87 | - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { | |
88 | + spin_lock_irqsave(&card->lock, flags); | |
89 | + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { | |
90 | retval = capilib_data_b3_req(&cinfo->ncci_head, | |
91 | CAPIMSG_APPID(skb->data), | |
92 | CAPIMSG_NCCI(skb->data), | |
93 | @@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_c | |
94 | } | |
95 | if (retval == CAPI_NOERROR) { | |
96 | skb_queue_tail(&card->dma->send_queue, skb); | |
97 | - spin_lock_irqsave(&card->lock, flags); | |
98 | c4_dispatch_tx(card); | |
99 | - spin_unlock_irqrestore(&card->lock, flags); | |
100 | } | |
101 | + spin_unlock_irqrestore(&card->lock, flags); | |
102 | return retval; | |
103 | } | |
104 |