@@ -38,8 +38,13 @@ static irqreturn_t fnic_isr_legacy(int irq, void *data)
38
38
fnic_log_q_error (fnic );
39
39
}
40
40
41
+ if (pba & (1 << FNIC_INTX_DUMMY )) {
42
+ atomic64_inc (& fnic -> fnic_stats .misc_stats .intx_dummy );
43
+ vnic_intr_return_all_credits (& fnic -> intr [FNIC_INTX_DUMMY ]);
44
+ }
45
+
41
46
if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ )) {
42
- work_done += fnic_wq_copy_cmpl_handler (fnic , io_completions );
47
+ work_done += fnic_wq_copy_cmpl_handler (fnic , io_completions , FNIC_MQ_CQ_INDEX );
43
48
work_done += fnic_wq_cmpl_handler (fnic , -1 );
44
49
work_done += fnic_rq_cmpl_handler (fnic , -1 );
45
50
@@ -60,7 +65,7 @@ static irqreturn_t fnic_isr_msi(int irq, void *data)
60
65
fnic -> fnic_stats .misc_stats .last_isr_time = jiffies ;
61
66
atomic64_inc (& fnic -> fnic_stats .misc_stats .isr_count );
62
67
63
- work_done += fnic_wq_copy_cmpl_handler (fnic , io_completions );
68
+ work_done += fnic_wq_copy_cmpl_handler (fnic , io_completions , FNIC_MQ_CQ_INDEX );
64
69
work_done += fnic_wq_cmpl_handler (fnic , -1 );
65
70
work_done += fnic_rq_cmpl_handler (fnic , -1 );
66
71
@@ -109,12 +114,22 @@ static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data)
109
114
{
110
115
struct fnic * fnic = data ;
111
116
unsigned long wq_copy_work_done = 0 ;
117
+ int i ;
112
118
113
119
fnic -> fnic_stats .misc_stats .last_isr_time = jiffies ;
114
120
atomic64_inc (& fnic -> fnic_stats .misc_stats .isr_count );
115
121
116
- wq_copy_work_done = fnic_wq_copy_cmpl_handler (fnic , io_completions );
117
- vnic_intr_return_credits (& fnic -> intr [FNIC_MSIX_WQ_COPY ],
122
+ i = irq - fnic -> msix [0 ].irq_num ;
123
+ if (i >= fnic -> wq_copy_count + fnic -> copy_wq_base ||
124
+ i < 0 || fnic -> msix [i ].irq_num != irq ) {
125
+ for (i = fnic -> copy_wq_base ; i < fnic -> wq_copy_count + fnic -> copy_wq_base ; i ++ ) {
126
+ if (fnic -> msix [i ].irq_num == irq )
127
+ break ;
128
+ }
129
+ }
130
+
131
+ wq_copy_work_done = fnic_wq_copy_cmpl_handler (fnic , io_completions , i );
132
+ vnic_intr_return_credits (& fnic -> intr [i ],
118
133
wq_copy_work_done ,
119
134
1 /* unmask intr */ ,
120
135
1 /* reset intr timer */ );
@@ -128,7 +143,7 @@ static irqreturn_t fnic_isr_msix_err_notify(int irq, void *data)
128
143
fnic -> fnic_stats .misc_stats .last_isr_time = jiffies ;
129
144
atomic64_inc (& fnic -> fnic_stats .misc_stats .isr_count );
130
145
131
- vnic_intr_return_all_credits (& fnic -> intr [FNIC_MSIX_ERR_NOTIFY ]);
146
+ vnic_intr_return_all_credits (& fnic -> intr [fnic -> err_intr_offset ]);
132
147
fnic_log_q_error (fnic );
133
148
fnic_handle_link_event (fnic );
134
149
@@ -186,26 +201,30 @@ int fnic_request_intr(struct fnic *fnic)
186
201
fnic -> msix [FNIC_MSIX_WQ ].isr = fnic_isr_msix_wq ;
187
202
fnic -> msix [FNIC_MSIX_WQ ].devid = fnic ;
188
203
189
- sprintf (fnic -> msix [FNIC_MSIX_WQ_COPY ].devname ,
190
- "%.11s-scsi-wq" , fnic -> name );
191
- fnic -> msix [FNIC_MSIX_WQ_COPY ].isr = fnic_isr_msix_wq_copy ;
192
- fnic -> msix [FNIC_MSIX_WQ_COPY ].devid = fnic ;
204
+ for (i = fnic -> copy_wq_base ; i < fnic -> wq_copy_count + fnic -> copy_wq_base ; i ++ ) {
205
+ sprintf (fnic -> msix [i ].devname ,
206
+ "%.11s-scsi-wq-%d" , fnic -> name , i - FNIC_MSIX_WQ_COPY );
207
+ fnic -> msix [i ].isr = fnic_isr_msix_wq_copy ;
208
+ fnic -> msix [i ].devid = fnic ;
209
+ }
193
210
194
- sprintf (fnic -> msix [FNIC_MSIX_ERR_NOTIFY ].devname ,
211
+ sprintf (fnic -> msix [fnic -> err_intr_offset ].devname ,
195
212
"%.11s-err-notify" , fnic -> name );
196
- fnic -> msix [FNIC_MSIX_ERR_NOTIFY ].isr =
213
+ fnic -> msix [fnic -> err_intr_offset ].isr =
197
214
fnic_isr_msix_err_notify ;
198
- fnic -> msix [FNIC_MSIX_ERR_NOTIFY ].devid = fnic ;
215
+ fnic -> msix [fnic -> err_intr_offset ].devid = fnic ;
199
216
200
- for (i = 0 ; i < ARRAY_SIZE (fnic -> msix ); i ++ ) {
201
- err = request_irq (pci_irq_vector (fnic -> pdev , i ),
202
- fnic -> msix [i ].isr , 0 ,
203
- fnic -> msix [i ].devname ,
204
- fnic -> msix [i ].devid );
217
+ for (i = 0 ; i < fnic -> intr_count ; i ++ ) {
218
+ fnic -> msix [i ].irq_num = pci_irq_vector (fnic -> pdev , i );
219
+
220
+ err = request_irq (fnic -> msix [i ].irq_num ,
221
+ fnic -> msix [i ].isr , 0 ,
222
+ fnic -> msix [i ].devname ,
223
+ fnic -> msix [i ].devid );
205
224
if (err ) {
206
- shost_printk (KERN_ERR , fnic -> lport -> host ,
207
- "MSIX: request_irq"
208
- " failed %d\n" , err );
225
+ FNIC_ISR_DBG (KERN_ERR , fnic -> lport -> host , fnic -> fnic_num ,
226
+ "request_irq failed with error: %d\n" ,
227
+ err );
209
228
fnic_free_intr (fnic );
210
229
break ;
211
230
}
@@ -220,44 +239,99 @@ int fnic_request_intr(struct fnic *fnic)
220
239
return err ;
221
240
}
222
241
223
- int fnic_set_intr_mode (struct fnic * fnic )
242
+ int fnic_set_intr_mode_msix (struct fnic * fnic )
224
243
{
225
244
unsigned int n = ARRAY_SIZE (fnic -> rq );
226
245
unsigned int m = ARRAY_SIZE (fnic -> wq );
227
246
unsigned int o = ARRAY_SIZE (fnic -> hw_copy_wq );
247
+ unsigned int min_irqs = n + m + 1 + 1 ; /*rq, raw wq, wq, err*/
228
248
229
249
/*
230
- * Set interrupt mode (INTx, MSI, MSI-X) depending
231
- * system capabilities.
232
- *
233
- * Try MSI-X first
234
- *
235
250
* We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs
236
251
* (last INTR is used for WQ/RQ errors and notification area)
237
252
*/
238
- if (fnic -> rq_count >= n &&
239
- fnic -> raw_wq_count >= m &&
240
- fnic -> wq_copy_count >= o &&
241
- fnic -> cq_count >= n + m + o ) {
242
- int vecs = n + m + o + 1 ;
243
-
244
- if (pci_alloc_irq_vectors (fnic -> pdev , vecs , vecs ,
245
- PCI_IRQ_MSIX ) == vecs ) {
253
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
254
+ "rq-array size: %d wq-array size: %d copy-wq array size: %d\n" ,
255
+ n , m , o );
256
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
257
+ "rq_count: %d raw_wq_count: %d wq_copy_count: %d cq_count: %d\n" ,
258
+ fnic -> rq_count , fnic -> raw_wq_count ,
259
+ fnic -> wq_copy_count , fnic -> cq_count );
260
+
261
+ if (fnic -> rq_count <= n && fnic -> raw_wq_count <= m &&
262
+ fnic -> wq_copy_count <= o ) {
263
+ int vec_count = 0 ;
264
+ int vecs = fnic -> rq_count + fnic -> raw_wq_count + fnic -> wq_copy_count + 1 ;
265
+
266
+ vec_count = pci_alloc_irq_vectors (fnic -> pdev , min_irqs , vecs ,
267
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY );
268
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
269
+ "allocated %d MSI-X vectors\n" ,
270
+ vec_count );
271
+
272
+ if (vec_count > 0 ) {
273
+ if (vec_count < vecs ) {
274
+ FNIC_ISR_DBG (KERN_ERR , fnic -> lport -> host , fnic -> fnic_num ,
275
+ "interrupts number mismatch: vec_count: %d vecs: %d\n" ,
276
+ vec_count , vecs );
277
+ if (vec_count < min_irqs ) {
278
+ FNIC_ISR_DBG (KERN_ERR , fnic -> lport -> host , fnic -> fnic_num ,
279
+ "no interrupts for copy wq\n" );
280
+ return 1 ;
281
+ }
282
+ }
283
+
246
284
fnic -> rq_count = n ;
247
285
fnic -> raw_wq_count = m ;
248
- fnic -> wq_copy_count = o ;
249
- fnic -> wq_count = m + o ;
250
- fnic -> cq_count = n + m + o ;
251
- fnic -> intr_count = vecs ;
252
- fnic -> err_intr_offset = FNIC_MSIX_ERR_NOTIFY ;
253
-
254
- FNIC_ISR_DBG (KERN_DEBUG , fnic -> lport -> host ,
255
- "Using MSI-X Interrupts\n" );
256
- vnic_dev_set_intr_mode (fnic -> vdev ,
257
- VNIC_DEV_INTR_MODE_MSIX );
286
+ fnic -> copy_wq_base = fnic -> rq_count + fnic -> raw_wq_count ;
287
+ fnic -> wq_copy_count = vec_count - n - m - 1 ;
288
+ fnic -> wq_count = fnic -> raw_wq_count + fnic -> wq_copy_count ;
289
+ if (fnic -> cq_count != vec_count - 1 ) {
290
+ FNIC_ISR_DBG (KERN_ERR , fnic -> lport -> host , fnic -> fnic_num ,
291
+ "CQ count: %d does not match MSI-X vector count: %d\n" ,
292
+ fnic -> cq_count , vec_count );
293
+ fnic -> cq_count = vec_count - 1 ;
294
+ }
295
+ fnic -> intr_count = vec_count ;
296
+ fnic -> err_intr_offset = fnic -> rq_count + fnic -> wq_count ;
297
+
298
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
299
+ "rq_count: %d raw_wq_count: %d copy_wq_base: %d\n" ,
300
+ fnic -> rq_count ,
301
+ fnic -> raw_wq_count , fnic -> copy_wq_base );
302
+
303
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
304
+ "wq_copy_count: %d wq_count: %d cq_count: %d\n" ,
305
+ fnic -> wq_copy_count ,
306
+ fnic -> wq_count , fnic -> cq_count );
307
+
308
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
309
+ "intr_count: %d err_intr_offset: %u" ,
310
+ fnic -> intr_count ,
311
+ fnic -> err_intr_offset );
312
+
313
+ vnic_dev_set_intr_mode (fnic -> vdev , VNIC_DEV_INTR_MODE_MSIX );
314
+ FNIC_ISR_DBG (KERN_INFO , fnic -> lport -> host , fnic -> fnic_num ,
315
+ "fnic using MSI-X\n" );
258
316
return 0 ;
259
317
}
260
318
}
319
+ return 1 ;
320
+ }
321
+
322
+ int fnic_set_intr_mode (struct fnic * fnic )
323
+ {
324
+ int ret_status = 0 ;
325
+
326
+ /*
327
+ * Set interrupt mode (INTx, MSI, MSI-X) depending
328
+ * system capabilities.
329
+ *
330
+ * Try MSI-X first
331
+ */
332
+ ret_status = fnic_set_intr_mode_msix (fnic );
333
+ if (ret_status == 0 )
334
+ return ret_status ;
261
335
262
336
/*
263
337
* Next try MSI
@@ -277,7 +351,7 @@ int fnic_set_intr_mode(struct fnic *fnic)
277
351
fnic -> intr_count = 1 ;
278
352
fnic -> err_intr_offset = 0 ;
279
353
280
- FNIC_ISR_DBG (KERN_DEBUG , fnic -> lport -> host ,
354
+ FNIC_ISR_DBG (KERN_DEBUG , fnic -> lport -> host , fnic -> fnic_num ,
281
355
"Using MSI Interrupts\n" );
282
356
vnic_dev_set_intr_mode (fnic -> vdev , VNIC_DEV_INTR_MODE_MSI );
283
357
@@ -303,7 +377,7 @@ int fnic_set_intr_mode(struct fnic *fnic)
303
377
fnic -> cq_count = 3 ;
304
378
fnic -> intr_count = 3 ;
305
379
306
- FNIC_ISR_DBG (KERN_DEBUG , fnic -> lport -> host ,
380
+ FNIC_ISR_DBG (KERN_DEBUG , fnic -> lport -> host , fnic -> fnic_num ,
307
381
"Using Legacy Interrupts\n" );
308
382
vnic_dev_set_intr_mode (fnic -> vdev , VNIC_DEV_INTR_MODE_INTX );
309
383
0 commit comments