Skip to content

Commit d443516

Browse files
sukadevgregkh
authored andcommitted
ibmvnic: init ->running_cap_crqs early
[ Upstream commit 151b6a5 ] We use ->running_cap_crqs to determine when the ibmvnic_tasklet() should send out the next protocol message type. i.e when we get back responses to all our QUERY_CAPABILITY CRQs we send out REQUEST_CAPABILITY crqs. Similiary, when we get responses to all the REQUEST_CAPABILITY crqs, we send out the QUERY_IP_OFFLOAD CRQ. We currently increment ->running_cap_crqs as we send out each CRQ and have the ibmvnic_tasklet() send out the next message type, when this running_cap_crqs count drops to 0. This assumes that all the CRQs of the current type were sent out before the count drops to 0. However it is possible that we send out say 6 CRQs, get preempted and receive all the 6 responses before we send out the remaining CRQs. This can result in ->running_cap_crqs count dropping to zero before all messages of the current type were sent and we end up sending the next protocol message too early. Instead initialize the ->running_cap_crqs upfront so the tasklet will only send the next protocol message after all responses are received. Use the cap_reqs local variable to also detect any discrepancy (either now or in future) in the number of capability requests we actually send. Currently only send_query_cap() is affected by this behavior (of sending next message early) since it is called from the worker thread (during reset) and from application thread (during ->ndo_open()) and they can be preempted. send_request_cap() is only called from the tasklet which processes CRQ responses sequentially, is not be affected. But to maintain the existing symmtery with send_query_capability() we update send_request_capability() also. Fixes: 249168a ("ibmvnic: Make CRQ interrupt tasklet wait for all capabilities crqs") Signed-off-by: Sukadev Bhattiprolu <[email protected]> Reviewed-by: Dany Madden <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent aa6ae23 commit d443516

File tree

1 file changed

+71
-35
lines changed

1 file changed

+71
-35
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3675,11 +3675,25 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry)
36753675
struct device *dev = &adapter->vdev->dev;
36763676
union ibmvnic_crq crq;
36773677
int max_entries;
3678+
int cap_reqs;
3679+
3680+
/* We send out 6 or 7 REQUEST_CAPABILITY CRQs below (depending on
3681+
* the PROMISC flag). Initialize this count upfront. When the tasklet
3682+
* receives a response to all of these, it will send the next protocol
3683+
* message (QUERY_IP_OFFLOAD).
3684+
*/
3685+
if (!(adapter->netdev->flags & IFF_PROMISC) ||
3686+
adapter->promisc_supported)
3687+
cap_reqs = 7;
3688+
else
3689+
cap_reqs = 6;
36783690

36793691
if (!retry) {
36803692
/* Sub-CRQ entries are 32 byte long */
36813693
int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4);
36823694

3695+
atomic_set(&adapter->running_cap_crqs, cap_reqs);
3696+
36833697
if (adapter->min_tx_entries_per_subcrq > entries_page ||
36843698
adapter->min_rx_add_entries_per_subcrq > entries_page) {
36853699
dev_err(dev, "Fatal, invalid entries per sub-crq\n");
@@ -3740,61 +3754,67 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry)
37403754
adapter->opt_rx_comp_queues;
37413755

37423756
adapter->req_rx_add_queues = adapter->max_rx_add_queues;
3757+
} else {
3758+
atomic_add(cap_reqs, &adapter->running_cap_crqs);
37433759
}
3744-
37453760
memset(&crq, 0, sizeof(crq));
37463761
crq.request_capability.first = IBMVNIC_CRQ_CMD;
37473762
crq.request_capability.cmd = REQUEST_CAPABILITY;
37483763

37493764
crq.request_capability.capability = cpu_to_be16(REQ_TX_QUEUES);
37503765
crq.request_capability.number = cpu_to_be64(adapter->req_tx_queues);
3751-
atomic_inc(&adapter->running_cap_crqs);
3766+
cap_reqs--;
37523767
ibmvnic_send_crq(adapter, &crq);
37533768

37543769
crq.request_capability.capability = cpu_to_be16(REQ_RX_QUEUES);
37553770
crq.request_capability.number = cpu_to_be64(adapter->req_rx_queues);
3756-
atomic_inc(&adapter->running_cap_crqs);
3771+
cap_reqs--;
37573772
ibmvnic_send_crq(adapter, &crq);
37583773

37593774
crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_QUEUES);
37603775
crq.request_capability.number = cpu_to_be64(adapter->req_rx_add_queues);
3761-
atomic_inc(&adapter->running_cap_crqs);
3776+
cap_reqs--;
37623777
ibmvnic_send_crq(adapter, &crq);
37633778

37643779
crq.request_capability.capability =
37653780
cpu_to_be16(REQ_TX_ENTRIES_PER_SUBCRQ);
37663781
crq.request_capability.number =
37673782
cpu_to_be64(adapter->req_tx_entries_per_subcrq);
3768-
atomic_inc(&adapter->running_cap_crqs);
3783+
cap_reqs--;
37693784
ibmvnic_send_crq(adapter, &crq);
37703785

37713786
crq.request_capability.capability =
37723787
cpu_to_be16(REQ_RX_ADD_ENTRIES_PER_SUBCRQ);
37733788
crq.request_capability.number =
37743789
cpu_to_be64(adapter->req_rx_add_entries_per_subcrq);
3775-
atomic_inc(&adapter->running_cap_crqs);
3790+
cap_reqs--;
37763791
ibmvnic_send_crq(adapter, &crq);
37773792

37783793
crq.request_capability.capability = cpu_to_be16(REQ_MTU);
37793794
crq.request_capability.number = cpu_to_be64(adapter->req_mtu);
3780-
atomic_inc(&adapter->running_cap_crqs);
3795+
cap_reqs--;
37813796
ibmvnic_send_crq(adapter, &crq);
37823797

37833798
if (adapter->netdev->flags & IFF_PROMISC) {
37843799
if (adapter->promisc_supported) {
37853800
crq.request_capability.capability =
37863801
cpu_to_be16(PROMISC_REQUESTED);
37873802
crq.request_capability.number = cpu_to_be64(1);
3788-
atomic_inc(&adapter->running_cap_crqs);
3803+
cap_reqs--;
37893804
ibmvnic_send_crq(adapter, &crq);
37903805
}
37913806
} else {
37923807
crq.request_capability.capability =
37933808
cpu_to_be16(PROMISC_REQUESTED);
37943809
crq.request_capability.number = cpu_to_be64(0);
3795-
atomic_inc(&adapter->running_cap_crqs);
3810+
cap_reqs--;
37963811
ibmvnic_send_crq(adapter, &crq);
37973812
}
3813+
3814+
/* Keep at end to catch any discrepancy between expected and actual
3815+
* CRQs sent.
3816+
*/
3817+
WARN_ON(cap_reqs != 0);
37983818
}
37993819

38003820
static int pending_scrq(struct ibmvnic_adapter *adapter,
@@ -4188,118 +4208,132 @@ static void send_query_map(struct ibmvnic_adapter *adapter)
41884208
static void send_query_cap(struct ibmvnic_adapter *adapter)
41894209
{
41904210
union ibmvnic_crq crq;
4211+
int cap_reqs;
4212+
4213+
/* We send out 25 QUERY_CAPABILITY CRQs below. Initialize this count
4214+
* upfront. When the tasklet receives a response to all of these, it
4215+
* can send out the next protocol messaage (REQUEST_CAPABILITY).
4216+
*/
4217+
cap_reqs = 25;
4218+
4219+
atomic_set(&adapter->running_cap_crqs, cap_reqs);
41914220

4192-
atomic_set(&adapter->running_cap_crqs, 0);
41934221
memset(&crq, 0, sizeof(crq));
41944222
crq.query_capability.first = IBMVNIC_CRQ_CMD;
41954223
crq.query_capability.cmd = QUERY_CAPABILITY;
41964224

41974225
crq.query_capability.capability = cpu_to_be16(MIN_TX_QUEUES);
4198-
atomic_inc(&adapter->running_cap_crqs);
41994226
ibmvnic_send_crq(adapter, &crq);
4227+
cap_reqs--;
42004228

42014229
crq.query_capability.capability = cpu_to_be16(MIN_RX_QUEUES);
4202-
atomic_inc(&adapter->running_cap_crqs);
42034230
ibmvnic_send_crq(adapter, &crq);
4231+
cap_reqs--;
42044232

42054233
crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_QUEUES);
4206-
atomic_inc(&adapter->running_cap_crqs);
42074234
ibmvnic_send_crq(adapter, &crq);
4235+
cap_reqs--;
42084236

42094237
crq.query_capability.capability = cpu_to_be16(MAX_TX_QUEUES);
4210-
atomic_inc(&adapter->running_cap_crqs);
42114238
ibmvnic_send_crq(adapter, &crq);
4239+
cap_reqs--;
42124240

42134241
crq.query_capability.capability = cpu_to_be16(MAX_RX_QUEUES);
4214-
atomic_inc(&adapter->running_cap_crqs);
42154242
ibmvnic_send_crq(adapter, &crq);
4243+
cap_reqs--;
42164244

42174245
crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_QUEUES);
4218-
atomic_inc(&adapter->running_cap_crqs);
42194246
ibmvnic_send_crq(adapter, &crq);
4247+
cap_reqs--;
42204248

42214249
crq.query_capability.capability =
42224250
cpu_to_be16(MIN_TX_ENTRIES_PER_SUBCRQ);
4223-
atomic_inc(&adapter->running_cap_crqs);
42244251
ibmvnic_send_crq(adapter, &crq);
4252+
cap_reqs--;
42254253

42264254
crq.query_capability.capability =
42274255
cpu_to_be16(MIN_RX_ADD_ENTRIES_PER_SUBCRQ);
4228-
atomic_inc(&adapter->running_cap_crqs);
42294256
ibmvnic_send_crq(adapter, &crq);
4257+
cap_reqs--;
42304258

42314259
crq.query_capability.capability =
42324260
cpu_to_be16(MAX_TX_ENTRIES_PER_SUBCRQ);
4233-
atomic_inc(&adapter->running_cap_crqs);
42344261
ibmvnic_send_crq(adapter, &crq);
4262+
cap_reqs--;
42354263

42364264
crq.query_capability.capability =
42374265
cpu_to_be16(MAX_RX_ADD_ENTRIES_PER_SUBCRQ);
4238-
atomic_inc(&adapter->running_cap_crqs);
42394266
ibmvnic_send_crq(adapter, &crq);
4267+
cap_reqs--;
42404268

42414269
crq.query_capability.capability = cpu_to_be16(TCP_IP_OFFLOAD);
4242-
atomic_inc(&adapter->running_cap_crqs);
42434270
ibmvnic_send_crq(adapter, &crq);
4271+
cap_reqs--;
42444272

42454273
crq.query_capability.capability = cpu_to_be16(PROMISC_SUPPORTED);
4246-
atomic_inc(&adapter->running_cap_crqs);
42474274
ibmvnic_send_crq(adapter, &crq);
4275+
cap_reqs--;
42484276

42494277
crq.query_capability.capability = cpu_to_be16(MIN_MTU);
4250-
atomic_inc(&adapter->running_cap_crqs);
42514278
ibmvnic_send_crq(adapter, &crq);
4279+
cap_reqs--;
42524280

42534281
crq.query_capability.capability = cpu_to_be16(MAX_MTU);
4254-
atomic_inc(&adapter->running_cap_crqs);
42554282
ibmvnic_send_crq(adapter, &crq);
4283+
cap_reqs--;
42564284

42574285
crq.query_capability.capability = cpu_to_be16(MAX_MULTICAST_FILTERS);
4258-
atomic_inc(&adapter->running_cap_crqs);
42594286
ibmvnic_send_crq(adapter, &crq);
4287+
cap_reqs--;
42604288

42614289
crq.query_capability.capability = cpu_to_be16(VLAN_HEADER_INSERTION);
4262-
atomic_inc(&adapter->running_cap_crqs);
42634290
ibmvnic_send_crq(adapter, &crq);
4291+
cap_reqs--;
42644292

42654293
crq.query_capability.capability = cpu_to_be16(RX_VLAN_HEADER_INSERTION);
4266-
atomic_inc(&adapter->running_cap_crqs);
42674294
ibmvnic_send_crq(adapter, &crq);
4295+
cap_reqs--;
42684296

42694297
crq.query_capability.capability = cpu_to_be16(MAX_TX_SG_ENTRIES);
4270-
atomic_inc(&adapter->running_cap_crqs);
42714298
ibmvnic_send_crq(adapter, &crq);
4299+
cap_reqs--;
42724300

42734301
crq.query_capability.capability = cpu_to_be16(RX_SG_SUPPORTED);
4274-
atomic_inc(&adapter->running_cap_crqs);
42754302
ibmvnic_send_crq(adapter, &crq);
4303+
cap_reqs--;
42764304

42774305
crq.query_capability.capability = cpu_to_be16(OPT_TX_COMP_SUB_QUEUES);
4278-
atomic_inc(&adapter->running_cap_crqs);
42794306
ibmvnic_send_crq(adapter, &crq);
4307+
cap_reqs--;
42804308

42814309
crq.query_capability.capability = cpu_to_be16(OPT_RX_COMP_QUEUES);
4282-
atomic_inc(&adapter->running_cap_crqs);
42834310
ibmvnic_send_crq(adapter, &crq);
4311+
cap_reqs--;
42844312

42854313
crq.query_capability.capability =
42864314
cpu_to_be16(OPT_RX_BUFADD_Q_PER_RX_COMP_Q);
4287-
atomic_inc(&adapter->running_cap_crqs);
42884315
ibmvnic_send_crq(adapter, &crq);
4316+
cap_reqs--;
42894317

42904318
crq.query_capability.capability =
42914319
cpu_to_be16(OPT_TX_ENTRIES_PER_SUBCRQ);
4292-
atomic_inc(&adapter->running_cap_crqs);
42934320
ibmvnic_send_crq(adapter, &crq);
4321+
cap_reqs--;
42944322

42954323
crq.query_capability.capability =
42964324
cpu_to_be16(OPT_RXBA_ENTRIES_PER_SUBCRQ);
4297-
atomic_inc(&adapter->running_cap_crqs);
42984325
ibmvnic_send_crq(adapter, &crq);
4326+
cap_reqs--;
42994327

43004328
crq.query_capability.capability = cpu_to_be16(TX_RX_DESC_REQ);
4301-
atomic_inc(&adapter->running_cap_crqs);
4329+
43024330
ibmvnic_send_crq(adapter, &crq);
4331+
cap_reqs--;
4332+
4333+
/* Keep at end to catch any discrepancy between expected and actual
4334+
* CRQs sent.
4335+
*/
4336+
WARN_ON(cap_reqs != 0);
43034337
}
43044338

43054339
static void send_query_ip_offload(struct ibmvnic_adapter *adapter)
@@ -4604,6 +4638,8 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
46044638
char *name;
46054639

46064640
atomic_dec(&adapter->running_cap_crqs);
4641+
netdev_dbg(adapter->netdev, "Outstanding request-caps: %d\n",
4642+
atomic_read(&adapter->running_cap_crqs));
46074643
switch (be16_to_cpu(crq->request_capability_rsp.capability)) {
46084644
case REQ_TX_QUEUES:
46094645
req_value = &adapter->req_tx_queues;

0 commit comments

Comments
 (0)