]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.drivers/bnx2x-Using-singlethread-work-queue.patch
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / bnx2x-Using-singlethread-work-queue.patch
1 From 1cf167f27ad2720af11ee8aa350009342f909e70 Mon Sep 17 00:00:00 2001
2 From: Eilon Greenstein <eilong@broadcom.com>
3 Date: Wed, 14 Jan 2009 21:22:18 -0800
4 Subject: bnx2x: Using singlethread work queue
5 Acked-by: Karsten Keil <kkeil@novell.com>
6 Reference: bnc#472500
7
8 Since slow-path events, including link update, are handled in
9 work-queue, a race condition was introduced in the self-test that
10 sometimes caused the link status to fail: the self-test was running
11 under RTNL lock, and if the link-watch was scheduled it stoped the
12 shared work-queue (waiting for the RTNL lock) and so the link update
13 event was not handled until the self-test ended (releasing the RTNL
14 lock) with failure (since the link status was not updated)
15
16 Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 ---
19 drivers/net/bnx2x.h | 2 +-
20 drivers/net/bnx2x_main.c | 20 +++++++++++++++-----
21 2 files changed, 16 insertions(+), 6 deletions(-)
22
23 Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x.h
24 ===================================================================
25 --- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x.h
26 +++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x.h
27 @@ -811,7 +811,7 @@ struct bnx2x {
28 int pm_cap;
29 int pcie_cap;
30
31 - struct work_struct sp_task;
32 + struct delayed_work sp_task;
33 struct work_struct reset_task;
34
35 struct timer_list timer;
36 Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
37 ===================================================================
38 --- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x_main.c
39 +++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x_main.c
40 @@ -95,6 +95,7 @@ MODULE_PARM_DESC(debug, "default debug m
41 module_param(use_multi, int, 0);
42 MODULE_PARM_DESC(use_multi, "use per-CPU queues");
43 #endif
44 +static struct workqueue_struct *bnx2x_wq;
45
46 enum bnx2x_board_type {
47 BCM57710 = 0,
48 @@ -671,7 +672,8 @@ static void bnx2x_int_disable_sync(struc
49 synchronize_irq(bp->pdev->irq);
50
51 /* make sure sp_task is not running */
52 - cancel_work_sync(&bp->sp_task);
53 + cancel_delayed_work(&bp->sp_task);
54 + flush_workqueue(bnx2x_wq);
55 }
56
57 /* fast path */
58 @@ -1663,7 +1665,7 @@ static irqreturn_t bnx2x_interrupt(int i
59
60
61 if (unlikely(status & 0x1)) {
62 - schedule_work(&bp->sp_task);
63 + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
64
65 status &= ~0x1;
66 if (!status)
67 @@ -2823,7 +2825,7 @@ static void bnx2x_attn_int(struct bnx2x
68
69 static void bnx2x_sp_task(struct work_struct *work)
70 {
71 - struct bnx2x *bp = container_of(work, struct bnx2x, sp_task);
72 + struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work);
73 u16 status;
74
75
76 @@ -2878,7 +2880,7 @@ static irqreturn_t bnx2x_msix_sp_int(int
77 return IRQ_HANDLED;
78 #endif
79
80 - schedule_work(&bp->sp_task);
81 + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
82
83 return IRQ_HANDLED;
84 }
85 @@ -7504,7 +7506,7 @@ static int __devinit bnx2x_init_bp(struc
86
87 mutex_init(&bp->port.phy_mutex);
88
89 - INIT_WORK(&bp->sp_task, bnx2x_sp_task);
90 + INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task);
91 INIT_WORK(&bp->reset_task, bnx2x_reset_task);
92
93 rc = bnx2x_get_hwinfo(bp);
94 @@ -10522,12 +10524,20 @@ static struct pci_driver bnx2x_pci_drive
95
96 static int __init bnx2x_init(void)
97 {
98 + bnx2x_wq = create_singlethread_workqueue("bnx2x");
99 + if (bnx2x_wq == NULL) {
100 + printk(KERN_ERR PFX "Cannot create workqueue\n");
101 + return -ENOMEM;
102 + }
103 +
104 return pci_register_driver(&bnx2x_pci_driver);
105 }
106
107 static void __exit bnx2x_cleanup(void)
108 {
109 pci_unregister_driver(&bnx2x_pci_driver);
110 +
111 + destroy_workqueue(bnx2x_wq);
112 }
113
114 module_init(bnx2x_init);