@@ -90,7 +90,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
90
90
91
91
static int ibmvnic_version = IBMVNIC_INITIAL_VERSION ;
92
92
static int ibmvnic_remove (struct vio_dev * );
93
- static void release_sub_crqs (struct ibmvnic_adapter * );
93
+ static void release_sub_crqs (struct ibmvnic_adapter * , bool );
94
94
static int ibmvnic_reset_crq (struct ibmvnic_adapter * );
95
95
static int ibmvnic_send_crq_init (struct ibmvnic_adapter * );
96
96
static int ibmvnic_reenable_crq_queue (struct ibmvnic_adapter * );
@@ -740,7 +740,7 @@ static int ibmvnic_login(struct net_device *netdev)
740
740
do {
741
741
if (adapter -> renegotiate ) {
742
742
adapter -> renegotiate = false;
743
- release_sub_crqs (adapter );
743
+ release_sub_crqs (adapter , 1 );
744
744
745
745
reinit_completion (& adapter -> init_done );
746
746
send_cap_queries (adapter );
@@ -1648,7 +1648,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
1648
1648
if (adapter -> reset_reason == VNIC_RESET_CHANGE_PARAM ||
1649
1649
adapter -> wait_for_reset ) {
1650
1650
release_resources (adapter );
1651
- release_sub_crqs (adapter );
1651
+ release_sub_crqs (adapter , 1 );
1652
1652
release_crq_queue (adapter );
1653
1653
}
1654
1654
@@ -2288,24 +2288,27 @@ static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter)
2288
2288
}
2289
2289
2290
2290
static void release_sub_crq_queue (struct ibmvnic_adapter * adapter ,
2291
- struct ibmvnic_sub_crq_queue * scrq )
2291
+ struct ibmvnic_sub_crq_queue * scrq ,
2292
+ bool do_h_free )
2292
2293
{
2293
2294
struct device * dev = & adapter -> vdev -> dev ;
2294
2295
long rc ;
2295
2296
2296
2297
netdev_dbg (adapter -> netdev , "Releasing sub-CRQ\n" );
2297
2298
2298
- /* Close the sub-crqs */
2299
- do {
2300
- rc = plpar_hcall_norets (H_FREE_SUB_CRQ ,
2301
- adapter -> vdev -> unit_address ,
2302
- scrq -> crq_num );
2303
- } while (rc == H_BUSY || H_IS_LONG_BUSY (rc ));
2299
+ if (do_h_free ) {
2300
+ /* Close the sub-crqs */
2301
+ do {
2302
+ rc = plpar_hcall_norets (H_FREE_SUB_CRQ ,
2303
+ adapter -> vdev -> unit_address ,
2304
+ scrq -> crq_num );
2305
+ } while (rc == H_BUSY || H_IS_LONG_BUSY (rc ));
2304
2306
2305
- if (rc ) {
2306
- netdev_err (adapter -> netdev ,
2307
- "Failed to release sub-CRQ %16lx, rc = %ld\n" ,
2308
- scrq -> crq_num , rc );
2307
+ if (rc ) {
2308
+ netdev_err (adapter -> netdev ,
2309
+ "Failed to release sub-CRQ %16lx, rc = %ld\n" ,
2310
+ scrq -> crq_num , rc );
2311
+ }
2309
2312
}
2310
2313
2311
2314
dma_unmap_single (dev , scrq -> msg_token , 4 * PAGE_SIZE ,
@@ -2373,12 +2376,21 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter
2373
2376
return NULL ;
2374
2377
}
2375
2378
2376
- static void release_sub_crqs (struct ibmvnic_adapter * adapter )
2379
+ static void release_sub_crqs (struct ibmvnic_adapter * adapter , bool do_h_free )
2377
2380
{
2381
+ u64 num_tx_scrqs , num_rx_scrqs ;
2378
2382
int i ;
2379
2383
2384
+ if (adapter -> state == VNIC_PROBED ) {
2385
+ num_tx_scrqs = adapter -> req_tx_queues ;
2386
+ num_rx_scrqs = adapter -> req_rx_queues ;
2387
+ } else {
2388
+ num_tx_scrqs = adapter -> num_active_tx_scrqs ;
2389
+ num_rx_scrqs = adapter -> num_active_rx_scrqs ;
2390
+ }
2391
+
2380
2392
if (adapter -> tx_scrq ) {
2381
- for (i = 0 ; i < adapter -> req_tx_queues ; i ++ ) {
2393
+ for (i = 0 ; i < num_tx_scrqs ; i ++ ) {
2382
2394
if (!adapter -> tx_scrq [i ])
2383
2395
continue ;
2384
2396
@@ -2391,15 +2403,16 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
2391
2403
adapter -> tx_scrq [i ]-> irq = 0 ;
2392
2404
}
2393
2405
2394
- release_sub_crq_queue (adapter , adapter -> tx_scrq [i ]);
2406
+ release_sub_crq_queue (adapter , adapter -> tx_scrq [i ],
2407
+ do_h_free );
2395
2408
}
2396
2409
2397
2410
kfree (adapter -> tx_scrq );
2398
2411
adapter -> tx_scrq = NULL ;
2399
2412
}
2400
2413
2401
2414
if (adapter -> rx_scrq ) {
2402
- for (i = 0 ; i < adapter -> req_rx_queues ; i ++ ) {
2415
+ for (i = 0 ; i < num_rx_scrqs ; i ++ ) {
2403
2416
if (!adapter -> rx_scrq [i ])
2404
2417
continue ;
2405
2418
@@ -2412,7 +2425,8 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
2412
2425
adapter -> rx_scrq [i ]-> irq = 0 ;
2413
2426
}
2414
2427
2415
- release_sub_crq_queue (adapter , adapter -> rx_scrq [i ]);
2428
+ release_sub_crq_queue (adapter , adapter -> rx_scrq [i ],
2429
+ do_h_free );
2416
2430
}
2417
2431
2418
2432
kfree (adapter -> rx_scrq );
@@ -2622,7 +2636,7 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter)
2622
2636
free_irq (adapter -> tx_scrq [j ]-> irq , adapter -> tx_scrq [j ]);
2623
2637
irq_dispose_mapping (adapter -> rx_scrq [j ]-> irq );
2624
2638
}
2625
- release_sub_crqs (adapter );
2639
+ release_sub_crqs (adapter , 1 );
2626
2640
return rc ;
2627
2641
}
2628
2642
@@ -2704,7 +2718,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
2704
2718
adapter -> tx_scrq = NULL ;
2705
2719
tx_failed :
2706
2720
for (i = 0 ; i < registered_queues ; i ++ )
2707
- release_sub_crq_queue (adapter , allqueues [i ]);
2721
+ release_sub_crq_queue (adapter , allqueues [i ], 1 );
2708
2722
kfree (allqueues );
2709
2723
return -1 ;
2710
2724
}
@@ -4331,6 +4345,7 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4331
4345
{
4332
4346
struct device * dev = & adapter -> vdev -> dev ;
4333
4347
unsigned long timeout = msecs_to_jiffies (30000 );
4348
+ u64 old_num_rx_queues , old_num_tx_queues ;
4334
4349
int rc ;
4335
4350
4336
4351
if (adapter -> resetting && !adapter -> wait_for_reset ) {
@@ -4348,6 +4363,9 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4348
4363
4349
4364
adapter -> from_passive_init = false;
4350
4365
4366
+ old_num_rx_queues = adapter -> req_rx_queues ;
4367
+ old_num_tx_queues = adapter -> req_tx_queues ;
4368
+
4351
4369
init_completion (& adapter -> init_done );
4352
4370
adapter -> init_done_rc = 0 ;
4353
4371
ibmvnic_send_crq_init (adapter );
@@ -4367,10 +4385,18 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
4367
4385
return -1 ;
4368
4386
}
4369
4387
4370
- if (adapter -> resetting && !adapter -> wait_for_reset )
4371
- rc = reset_sub_crq_queues (adapter );
4372
- else
4388
+ if (adapter -> resetting && !adapter -> wait_for_reset ) {
4389
+ if (adapter -> req_rx_queues != old_num_rx_queues ||
4390
+ adapter -> req_tx_queues != old_num_tx_queues ) {
4391
+ release_sub_crqs (adapter , 0 );
4392
+ rc = init_sub_crqs (adapter );
4393
+ } else {
4394
+ rc = reset_sub_crq_queues (adapter );
4395
+ }
4396
+ } else {
4373
4397
rc = init_sub_crqs (adapter );
4398
+ }
4399
+
4374
4400
if (rc ) {
4375
4401
dev_err (dev , "Initialization of sub crqs failed\n" );
4376
4402
release_crq_queue (adapter );
@@ -4470,7 +4496,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
4470
4496
device_remove_file (& dev -> dev , & dev_attr_failover );
4471
4497
4472
4498
ibmvnic_init_fail :
4473
- release_sub_crqs (adapter );
4499
+ release_sub_crqs (adapter , 1 );
4474
4500
release_crq_queue (adapter );
4475
4501
free_netdev (netdev );
4476
4502
@@ -4487,7 +4513,7 @@ static int ibmvnic_remove(struct vio_dev *dev)
4487
4513
mutex_lock (& adapter -> reset_lock );
4488
4514
4489
4515
release_resources (adapter );
4490
- release_sub_crqs (adapter );
4516
+ release_sub_crqs (adapter , 1 );
4491
4517
release_crq_queue (adapter );
4492
4518
4493
4519
adapter -> state = VNIC_REMOVED ;
0 commit comments