Skip to content

Commit

Permalink
ibmvnic: Initialize completion variables before starting work
Browse files Browse the repository at this point in the history
Initialize condition variables prior to invoking any work that can
mark them complete. This resolves a race in the ibmvnic driver where
the driver faults trying to complete an uninitialized condition
variable.

Signed-off-by: Nathan Fontenot <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
nfont authored and davem330 committed Feb 12, 2017
1 parent 1ee1832 commit db5d0b5
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions drivers/net/ethernet/ibm/ibmvnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,10 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
}
ltb->map_id = adapter->map_id;
adapter->map_id++;

init_completion(&adapter->fw_done);
send_request_map(adapter, ltb->addr,
ltb->size, ltb->map_id);
init_completion(&adapter->fw_done);
wait_for_completion(&adapter->fw_done);
return 0;
}
Expand Down Expand Up @@ -1121,10 +1122,10 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev,
crq.request_statistics.ioba = cpu_to_be32(adapter->stats_token);
crq.request_statistics.len =
cpu_to_be32(sizeof(struct ibmvnic_statistics));
ibmvnic_send_crq(adapter, &crq);

/* Wait for data to be written */
init_completion(&adapter->stats_done);
ibmvnic_send_crq(adapter, &crq);
wait_for_completion(&adapter->stats_done);

for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++)
Expand Down Expand Up @@ -2799,9 +2800,9 @@ static ssize_t trace_read(struct file *file, char __user *user_buf, size_t len,
crq.collect_fw_trace.correlator = adapter->ras_comps[num].correlator;
crq.collect_fw_trace.ioba = cpu_to_be32(trace_tok);
crq.collect_fw_trace.len = adapter->ras_comps[num].trace_buff_size;
ibmvnic_send_crq(adapter, &crq);

init_completion(&adapter->fw_done);
ibmvnic_send_crq(adapter, &crq);
wait_for_completion(&adapter->fw_done);

if (*ppos + len > be32_to_cpu(adapter->ras_comps[num].trace_buff_size))
Expand Down Expand Up @@ -3581,9 +3582,9 @@ static int ibmvnic_dump_show(struct seq_file *seq, void *v)
memset(&crq, 0, sizeof(crq));
crq.request_dump_size.first = IBMVNIC_CRQ_CMD;
crq.request_dump_size.cmd = REQUEST_DUMP_SIZE;
ibmvnic_send_crq(adapter, &crq);

init_completion(&adapter->fw_done);
ibmvnic_send_crq(adapter, &crq);
wait_for_completion(&adapter->fw_done);

seq_write(seq, adapter->dump_data, adapter->dump_data_size);
Expand Down Expand Up @@ -3629,8 +3630,8 @@ static void handle_crq_init_rsp(struct work_struct *work)
}
}

send_version_xchg(adapter);
reinit_completion(&adapter->init_done);
send_version_xchg(adapter);
if (!wait_for_completion_timeout(&adapter->init_done, timeout)) {
dev_err(dev, "Passive init timeout\n");
goto task_failed;
Expand All @@ -3640,9 +3641,9 @@ static void handle_crq_init_rsp(struct work_struct *work)
if (adapter->renegotiate) {
adapter->renegotiate = false;
release_sub_crqs_no_irqs(adapter);
send_cap_queries(adapter);

reinit_completion(&adapter->init_done);
send_cap_queries(adapter);
if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) {
dev_err(dev, "Passive init timeout\n");
Expand Down Expand Up @@ -3772,19 +3773,19 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
adapter->debugfs_dump = ent;
}
}
ibmvnic_send_crq_init(adapter);

init_completion(&adapter->init_done);
ibmvnic_send_crq_init(adapter);
if (!wait_for_completion_timeout(&adapter->init_done, timeout))
return 0;

do {
if (adapter->renegotiate) {
adapter->renegotiate = false;
release_sub_crqs_no_irqs(adapter);
send_cap_queries(adapter);

reinit_completion(&adapter->init_done);
send_cap_queries(adapter);
if (!wait_for_completion_timeout(&adapter->init_done,
timeout))
return 0;
Expand Down

0 comments on commit db5d0b5

Please sign in to comment.