@@ -40,10 +40,7 @@ enum {
40
40
MLX4_CATAS_POLL_INTERVAL = 5 * HZ ,
41
41
};
42
42
43
- static DEFINE_SPINLOCK (catas_lock );
44
43
45
- static LIST_HEAD (catas_list );
46
- static struct work_struct catas_work ;
47
44
48
45
static int internal_err_reset = 1 ;
49
46
module_param (internal_err_reset , int , 0644 );
@@ -77,13 +74,9 @@ static void poll_catas(unsigned long dev_ptr)
77
74
dump_err_buf (dev );
78
75
mlx4_dispatch_event (dev , MLX4_DEV_EVENT_CATASTROPHIC_ERROR , 0 );
79
76
80
- if (internal_err_reset ) {
81
- spin_lock (& catas_lock );
82
- list_add (& priv -> catas_err .list , & catas_list );
83
- spin_unlock (& catas_lock );
84
-
85
- queue_work (mlx4_wq , & catas_work );
86
- }
77
+ if (internal_err_reset )
78
+ queue_work (dev -> persist -> catas_wq ,
79
+ & dev -> persist -> catas_work );
87
80
}
88
81
} else
89
82
mod_timer (& priv -> catas_err .timer ,
@@ -92,34 +85,23 @@ static void poll_catas(unsigned long dev_ptr)
92
85
93
86
static void catas_reset (struct work_struct * work )
94
87
{
95
- struct mlx4_priv * priv , * tmppriv ;
96
- struct mlx4_dev * dev ;
97
- struct mlx4_dev_persistent * persist ;
98
-
99
- LIST_HEAD (tlist );
88
+ struct mlx4_dev_persistent * persist =
89
+ container_of (work , struct mlx4_dev_persistent ,
90
+ catas_work );
91
+ struct pci_dev * pdev = persist -> pdev ;
100
92
int ret ;
101
93
102
- spin_lock_irq (& catas_lock );
103
- list_splice_init (& catas_list , & tlist );
104
- spin_unlock_irq (& catas_lock );
105
-
106
- list_for_each_entry_safe (priv , tmppriv , & tlist , catas_err .list ) {
107
- struct pci_dev * pdev = priv -> dev .persist -> pdev ;
108
-
109
- /* If the device is off-line, we cannot reset it */
110
- if (pci_channel_offline (pdev ))
111
- continue ;
94
+ /* If the device is off-line, we cannot reset it */
95
+ if (pci_channel_offline (pdev ))
96
+ return ;
112
97
113
- ret = mlx4_restart_one (priv -> dev .persist -> pdev );
114
- /* 'priv' now is not valid */
115
- if (ret )
116
- pr_err ("mlx4 %s: Reset failed (%d)\n" ,
117
- pci_name (pdev ), ret );
118
- else {
119
- persist = pci_get_drvdata (pdev );
120
- mlx4_dbg (persist -> dev , "Reset succeeded\n" );
121
- }
122
- }
98
+ ret = mlx4_restart_one (pdev );
99
+ /* 'priv' now is not valid */
100
+ if (ret )
101
+ pr_err ("mlx4 %s: Reset failed (%d)\n" ,
102
+ pci_name (pdev ), ret );
103
+ else
104
+ mlx4_dbg (persist -> dev , "Reset succeeded\n" );
123
105
}
124
106
125
107
void mlx4_start_catas_poll (struct mlx4_dev * dev )
@@ -158,15 +140,26 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
158
140
159
141
del_timer_sync (& priv -> catas_err .timer );
160
142
161
- if (priv -> catas_err .map )
143
+ if (priv -> catas_err .map ) {
162
144
iounmap (priv -> catas_err .map );
145
+ priv -> catas_err .map = NULL ;
146
+ }
147
+ }
163
148
164
- spin_lock_irq (& catas_lock );
165
- list_del (& priv -> catas_err .list );
166
- spin_unlock_irq (& catas_lock );
149
+ int mlx4_catas_init (struct mlx4_dev * dev )
150
+ {
151
+ INIT_WORK (& dev -> persist -> catas_work , catas_reset );
152
+ dev -> persist -> catas_wq = create_singlethread_workqueue ("mlx4_health" );
153
+ if (!dev -> persist -> catas_wq )
154
+ return - ENOMEM ;
155
+
156
+ return 0 ;
167
157
}
168
158
169
- void __init mlx4_catas_init ( void )
159
+ void mlx4_catas_end ( struct mlx4_dev * dev )
170
160
{
171
- INIT_WORK (& catas_work , catas_reset );
161
+ if (dev -> persist -> catas_wq ) {
162
+ destroy_workqueue (dev -> persist -> catas_wq );
163
+ dev -> persist -> catas_wq = NULL ;
164
+ }
172
165
}
0 commit comments