Skip to content

Commit 151b6a5

Browse files
sukadevdavem330
authored andcommitted
ibmvnic: init ->running_cap_crqs early
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]>
1 parent db9f0e8 commit 151b6a5

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
@@ -3857,11 +3857,25 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry)
38573857
struct device *dev = &adapter->vdev->dev;
38583858
union ibmvnic_crq crq;
38593859
int max_entries;
3860+
int cap_reqs;
3861+
3862+
/* We send out 6 or 7 REQUEST_CAPABILITY CRQs below (depending on
3863+
* the PROMISC flag). Initialize this count upfront. When the tasklet
3864+
* receives a response to all of these, it will send the next protocol
3865+
* message (QUERY_IP_OFFLOAD).
3866+
*/
3867+
if (!(adapter->netdev->flags & IFF_PROMISC) ||
3868+
adapter->promisc_supported)
3869+
cap_reqs = 7;
3870+
else
3871+
cap_reqs = 6;
38603872

38613873
if (!retry) {
38623874
/* Sub-CRQ entries are 32 byte long */
38633875
int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4);
38643876

3877+
atomic_set(&adapter->running_cap_crqs, cap_reqs);
3878+
38653879
if (adapter->min_tx_entries_per_subcrq > entries_page ||
38663880
adapter->min_rx_add_entries_per_subcrq > entries_page) {
38673881
dev_err(dev, "Fatal, invalid entries per sub-crq\n");
@@ -3922,61 +3936,67 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry)
39223936
adapter->opt_rx_comp_queues;
39233937

39243938
adapter->req_rx_add_queues = adapter->max_rx_add_queues;
3939+
} else {
3940+
atomic_add(cap_reqs, &adapter->running_cap_crqs);
39253941
}
3926-
39273942
memset(&crq, 0, sizeof(crq));
39283943
crq.request_capability.first = IBMVNIC_CRQ_CMD;
39293944
crq.request_capability.cmd = REQUEST_CAPABILITY;
39303945

39313946
crq.request_capability.capability = cpu_to_be16(REQ_TX_QUEUES);
39323947
crq.request_capability.number = cpu_to_be64(adapter->req_tx_queues);
3933-
atomic_inc(&adapter->running_cap_crqs);
3948+
cap_reqs--;
39343949
ibmvnic_send_crq(adapter, &crq);
39353950

39363951
crq.request_capability.capability = cpu_to_be16(REQ_RX_QUEUES);
39373952
crq.request_capability.number = cpu_to_be64(adapter->req_rx_queues);
3938-
atomic_inc(&adapter->running_cap_crqs);
3953+
cap_reqs--;
39393954
ibmvnic_send_crq(adapter, &crq);
39403955

39413956
crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_QUEUES);
39423957
crq.request_capability.number = cpu_to_be64(adapter->req_rx_add_queues);
3943-
atomic_inc(&adapter->running_cap_crqs);
3958+
cap_reqs--;
39443959
ibmvnic_send_crq(adapter, &crq);
39453960

39463961
crq.request_capability.capability =
39473962
cpu_to_be16(REQ_TX_ENTRIES_PER_SUBCRQ);
39483963
crq.request_capability.number =
39493964
cpu_to_be64(adapter->req_tx_entries_per_subcrq);
3950-
atomic_inc(&adapter->running_cap_crqs);
3965+
cap_reqs--;
39513966
ibmvnic_send_crq(adapter, &crq);
39523967

39533968
crq.request_capability.capability =
39543969
cpu_to_be16(REQ_RX_ADD_ENTRIES_PER_SUBCRQ);
39553970
crq.request_capability.number =
39563971
cpu_to_be64(adapter->req_rx_add_entries_per_subcrq);
3957-
atomic_inc(&adapter->running_cap_crqs);
3972+
cap_reqs--;
39583973
ibmvnic_send_crq(adapter, &crq);
39593974

39603975
crq.request_capability.capability = cpu_to_be16(REQ_MTU);
39613976
crq.request_capability.number = cpu_to_be64(adapter->req_mtu);
3962-
atomic_inc(&adapter->running_cap_crqs);
3977+
cap_reqs--;
39633978
ibmvnic_send_crq(adapter, &crq);
39643979

39653980
if (adapter->netdev->flags & IFF_PROMISC) {
39663981
if (adapter->promisc_supported) {
39673982
crq.request_capability.capability =
39683983
cpu_to_be16(PROMISC_REQUESTED);
39693984
crq.request_capability.number = cpu_to_be64(1);
3970-
atomic_inc(&adapter->running_cap_crqs);
3985+
cap_reqs--;
39713986
ibmvnic_send_crq(adapter, &crq);
39723987
}
39733988
} else {
39743989
crq.request_capability.capability =
39753990
cpu_to_be16(PROMISC_REQUESTED);
39763991
crq.request_capability.number = cpu_to_be64(0);
3977-
atomic_inc(&adapter->running_cap_crqs);
3992+
cap_reqs--;
39783993
ibmvnic_send_crq(adapter, &crq);
39793994
}
3995+
3996+
/* Keep at end to catch any discrepancy between expected and actual
3997+
* CRQs sent.
3998+
*/
3999+
WARN_ON(cap_reqs != 0);
39804000
}
39814001

39824002
static int pending_scrq(struct ibmvnic_adapter *adapter,
@@ -4370,118 +4390,132 @@ static void send_query_map(struct ibmvnic_adapter *adapter)
43704390
static void send_query_cap(struct ibmvnic_adapter *adapter)
43714391
{
43724392
union ibmvnic_crq crq;
4393+
int cap_reqs;
4394+
4395+
/* We send out 25 QUERY_CAPABILITY CRQs below. Initialize this count
4396+
* upfront. When the tasklet receives a response to all of these, it
4397+
* can send out the next protocol messaage (REQUEST_CAPABILITY).
4398+
*/
4399+
cap_reqs = 25;
4400+
4401+
atomic_set(&adapter->running_cap_crqs, cap_reqs);
43734402

4374-
atomic_set(&adapter->running_cap_crqs, 0);
43754403
memset(&crq, 0, sizeof(crq));
43764404
crq.query_capability.first = IBMVNIC_CRQ_CMD;
43774405
crq.query_capability.cmd = QUERY_CAPABILITY;
43784406

43794407
crq.query_capability.capability = cpu_to_be16(MIN_TX_QUEUES);
4380-
atomic_inc(&adapter->running_cap_crqs);
43814408
ibmvnic_send_crq(adapter, &crq);
4409+
cap_reqs--;
43824410

43834411
crq.query_capability.capability = cpu_to_be16(MIN_RX_QUEUES);
4384-
atomic_inc(&adapter->running_cap_crqs);
43854412
ibmvnic_send_crq(adapter, &crq);
4413+
cap_reqs--;
43864414

43874415
crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_QUEUES);
4388-
atomic_inc(&adapter->running_cap_crqs);
43894416
ibmvnic_send_crq(adapter, &crq);
4417+
cap_reqs--;
43904418

43914419
crq.query_capability.capability = cpu_to_be16(MAX_TX_QUEUES);
4392-
atomic_inc(&adapter->running_cap_crqs);
43934420
ibmvnic_send_crq(adapter, &crq);
4421+
cap_reqs--;
43944422

43954423
crq.query_capability.capability = cpu_to_be16(MAX_RX_QUEUES);
4396-
atomic_inc(&adapter->running_cap_crqs);
43974424
ibmvnic_send_crq(adapter, &crq);
4425+
cap_reqs--;
43984426

43994427
crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_QUEUES);
4400-
atomic_inc(&adapter->running_cap_crqs);
44014428
ibmvnic_send_crq(adapter, &crq);
4429+
cap_reqs--;
44024430

44034431
crq.query_capability.capability =
44044432
cpu_to_be16(MIN_TX_ENTRIES_PER_SUBCRQ);
4405-
atomic_inc(&adapter->running_cap_crqs);
44064433
ibmvnic_send_crq(adapter, &crq);
4434+
cap_reqs--;
44074435

44084436
crq.query_capability.capability =
44094437
cpu_to_be16(MIN_RX_ADD_ENTRIES_PER_SUBCRQ);
4410-
atomic_inc(&adapter->running_cap_crqs);
44114438
ibmvnic_send_crq(adapter, &crq);
4439+
cap_reqs--;
44124440

44134441
crq.query_capability.capability =
44144442
cpu_to_be16(MAX_TX_ENTRIES_PER_SUBCRQ);
4415-
atomic_inc(&adapter->running_cap_crqs);
44164443
ibmvnic_send_crq(adapter, &crq);
4444+
cap_reqs--;
44174445

44184446
crq.query_capability.capability =
44194447
cpu_to_be16(MAX_RX_ADD_ENTRIES_PER_SUBCRQ);
4420-
atomic_inc(&adapter->running_cap_crqs);
44214448
ibmvnic_send_crq(adapter, &crq);
4449+
cap_reqs--;
44224450

44234451
crq.query_capability.capability = cpu_to_be16(TCP_IP_OFFLOAD);
4424-
atomic_inc(&adapter->running_cap_crqs);
44254452
ibmvnic_send_crq(adapter, &crq);
4453+
cap_reqs--;
44264454

44274455
crq.query_capability.capability = cpu_to_be16(PROMISC_SUPPORTED);
4428-
atomic_inc(&adapter->running_cap_crqs);
44294456
ibmvnic_send_crq(adapter, &crq);
4457+
cap_reqs--;
44304458

44314459
crq.query_capability.capability = cpu_to_be16(MIN_MTU);
4432-
atomic_inc(&adapter->running_cap_crqs);
44334460
ibmvnic_send_crq(adapter, &crq);
4461+
cap_reqs--;
44344462

44354463
crq.query_capability.capability = cpu_to_be16(MAX_MTU);
4436-
atomic_inc(&adapter->running_cap_crqs);
44374464
ibmvnic_send_crq(adapter, &crq);
4465+
cap_reqs--;
44384466

44394467
crq.query_capability.capability = cpu_to_be16(MAX_MULTICAST_FILTERS);
4440-
atomic_inc(&adapter->running_cap_crqs);
44414468
ibmvnic_send_crq(adapter, &crq);
4469+
cap_reqs--;
44424470

44434471
crq.query_capability.capability = cpu_to_be16(VLAN_HEADER_INSERTION);
4444-
atomic_inc(&adapter->running_cap_crqs);
44454472
ibmvnic_send_crq(adapter, &crq);
4473+
cap_reqs--;
44464474

44474475
crq.query_capability.capability = cpu_to_be16(RX_VLAN_HEADER_INSERTION);
4448-
atomic_inc(&adapter->running_cap_crqs);
44494476
ibmvnic_send_crq(adapter, &crq);
4477+
cap_reqs--;
44504478

44514479
crq.query_capability.capability = cpu_to_be16(MAX_TX_SG_ENTRIES);
4452-
atomic_inc(&adapter->running_cap_crqs);
44534480
ibmvnic_send_crq(adapter, &crq);
4481+
cap_reqs--;
44544482

44554483
crq.query_capability.capability = cpu_to_be16(RX_SG_SUPPORTED);
4456-
atomic_inc(&adapter->running_cap_crqs);
44574484
ibmvnic_send_crq(adapter, &crq);
4485+
cap_reqs--;
44584486

44594487
crq.query_capability.capability = cpu_to_be16(OPT_TX_COMP_SUB_QUEUES);
4460-
atomic_inc(&adapter->running_cap_crqs);
44614488
ibmvnic_send_crq(adapter, &crq);
4489+
cap_reqs--;
44624490

44634491
crq.query_capability.capability = cpu_to_be16(OPT_RX_COMP_QUEUES);
4464-
atomic_inc(&adapter->running_cap_crqs);
44654492
ibmvnic_send_crq(adapter, &crq);
4493+
cap_reqs--;
44664494

44674495
crq.query_capability.capability =
44684496
cpu_to_be16(OPT_RX_BUFADD_Q_PER_RX_COMP_Q);
4469-
atomic_inc(&adapter->running_cap_crqs);
44704497
ibmvnic_send_crq(adapter, &crq);
4498+
cap_reqs--;
44714499

44724500
crq.query_capability.capability =
44734501
cpu_to_be16(OPT_TX_ENTRIES_PER_SUBCRQ);
4474-
atomic_inc(&adapter->running_cap_crqs);
44754502
ibmvnic_send_crq(adapter, &crq);
4503+
cap_reqs--;
44764504

44774505
crq.query_capability.capability =
44784506
cpu_to_be16(OPT_RXBA_ENTRIES_PER_SUBCRQ);
4479-
atomic_inc(&adapter->running_cap_crqs);
44804507
ibmvnic_send_crq(adapter, &crq);
4508+
cap_reqs--;
44814509

44824510
crq.query_capability.capability = cpu_to_be16(TX_RX_DESC_REQ);
4483-
atomic_inc(&adapter->running_cap_crqs);
4511+
44844512
ibmvnic_send_crq(adapter, &crq);
4513+
cap_reqs--;
4514+
4515+
/* Keep at end to catch any discrepancy between expected and actual
4516+
* CRQs sent.
4517+
*/
4518+
WARN_ON(cap_reqs != 0);
44854519
}
44864520

44874521
static void send_query_ip_offload(struct ibmvnic_adapter *adapter)
@@ -4785,6 +4819,8 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
47854819
char *name;
47864820

47874821
atomic_dec(&adapter->running_cap_crqs);
4822+
netdev_dbg(adapter->netdev, "Outstanding request-caps: %d\n",
4823+
atomic_read(&adapter->running_cap_crqs));
47884824
switch (be16_to_cpu(crq->request_capability_rsp.capability)) {
47894825
case REQ_TX_QUEUES:
47904826
req_value = &adapter->req_tx_queues;

0 commit comments

Comments
 (0)