Explorar el Código

qcacld-3.0: Bypass hif_completion_thread in recv

We want to process the completions in parallel.
Upper layer should take care of its own thread safety.
hif_completion_thread is a legacy function that does in
context serialization of hif completions. Bypass it.

Change-Id: I7953545b55dae093931741359bbf985e2fb9faca
CRs-Fixed: 941358
Houston Hoffman hace 9 años
padre
commit
910c626231
Se han modificado 1 ficheros con 33 adiciones y 55 borrados
  1. 33 55
      core/hif/src/ce/ce_main.c

+ 33 - 55
core/hif/src/ce/ce_main.c

@@ -719,6 +719,33 @@ hif_pci_ce_send_done(struct CE_handle *copyeng, void *ce_context,
 			&toeplitz_hash_result) == CDF_STATUS_SUCCESS);
 }
 
+/**
+ * hif_ce_do_recv(): send message from copy engine to upper layers
+ * @msg_callbacks: structure containing callback and callback context
+ * @netbuff: skb containing message
+ * @nbytes: number of bytes in the message
+ * @pipe_info: used for the pipe_number info
+ *
+ * Checks the packet length, configures the lenght in the netbuff,
+ * and calls the upper layer callback.
+ *
+ * return: None
+ */
+static inline void hif_ce_do_recv(struct hif_msg_callbacks *msg_callbacks,
+		cdf_nbuf_t netbuf, int nbytes,
+		struct HIF_CE_pipe_info *pipe_info) {
+	if (nbytes <= pipe_info->buf_sz) {
+		cdf_nbuf_set_pktlen(netbuf, nbytes);
+		msg_callbacks->
+			rxCompletionHandler(msg_callbacks->Context,
+					netbuf, pipe_info->pipe_num);
+	} else {
+		HIF_ERROR("%s: Invalid Rx msg buf:%p nbytes:%d",
+				__func__, netbuf, nbytes);
+		cdf_nbuf_free(netbuf);
+	}
+}
+
 /* Called by lower (CE) layer when data is received from the Target. */
 void
 hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
@@ -731,50 +758,18 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
 	struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state;
 	struct CE_state *ce_state = (struct CE_state *) copyeng;
 	struct ol_softc *scn = hif_state->scn;
-	struct HIF_CE_completion_state *compl_state;
-	struct HIF_CE_completion_state *compl_queue_head, *compl_queue_tail;
+	struct hif_msg_callbacks *msg_callbacks =
+		&hif_state->msg_callbacks_current;
 
-	compl_queue_head = compl_queue_tail = NULL;
 	do {
-		cdf_spin_lock(&pipe_info->completion_freeq_lock);
-		compl_state = pipe_info->completion_freeq_head;
-		ASSERT(compl_state != NULL);
-		pipe_info->completion_freeq_head = compl_state->next;
-		cdf_spin_unlock(&pipe_info->completion_freeq_lock);
-
-		compl_state->next = NULL;
-		compl_state->send_or_recv = HIF_CE_COMPLETE_RECV;
-		compl_state->copyeng = copyeng;
-		compl_state->ce_context = ce_context;
-		compl_state->transfer_context = transfer_context;
-		compl_state->data = CE_data;
-		compl_state->nbytes = nbytes;
-		compl_state->transfer_id = transfer_id;
-		compl_state->flags = flags;
-
-		/* Enqueue at end of local queue */
-		if (compl_queue_tail) {
-			compl_queue_tail->next = compl_state;
-		} else {
-			compl_queue_head = compl_state;
-		}
-		compl_queue_tail = compl_state;
-
 		cdf_nbuf_unmap_single(scn->cdf_dev,
 				      (cdf_nbuf_t) transfer_context,
 				      CDF_DMA_FROM_DEVICE);
 
-		/*
-		 * EV #112693 - [Peregrine][ES1][WB342][Win8x86][Performance]
-		 * BSoD_0x133 occurred in VHT80 UDP_DL
-		 * Break out DPC by force if number of loops in
-		 * hif_pci_ce_recv_data reaches MAX_NUM_OF_RECEIVES to avoid
-		 * spending too long time in DPC for each interrupt handling.
-		 * Schedule another DPC to avoid data loss if we had taken
-		 * force-break action before apply to Windows OS only
-		 * currently, Linux/MAC os can expand to their platform
-		 * if necessary
-		 */
+		atomic_inc(&pipe_info->recv_bufs_needed);
+		hif_post_recv_buffers_for_pipe(pipe_info);
+		hif_ce_do_recv(msg_callbacks, transfer_context, nbytes,
+			pipe_info);
 
 		/* Set up force_break flag if num of receices reaches
 		 * MAX_NUM_OF_RECEIVES */
@@ -787,23 +782,6 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
 	} while (ce_completed_recv_next(copyeng, &ce_context, &transfer_context,
 					&CE_data, &nbytes, &transfer_id,
 					&flags) == CDF_STATUS_SUCCESS);
-
-	cdf_spin_lock(&hif_state->completion_pendingq_lock);
-
-	/* Enqueue the local completion queue on the
-	 * per-device completion queue */
-	if (hif_state->completion_pendingq_head) {
-		hif_state->completion_pendingq_tail->next = compl_queue_head;
-		hif_state->completion_pendingq_tail = compl_queue_tail;
-		cdf_spin_unlock(&hif_state->completion_pendingq_lock);
-	} else {
-		hif_state->completion_pendingq_head = compl_queue_head;
-		hif_state->completion_pendingq_tail = compl_queue_tail;
-		cdf_spin_unlock(&hif_state->completion_pendingq_lock);
-
-		/* Alert the recv completion service thread */
-		hif_completion_thread(hif_state);
-	}
 }
 
 /* TBDXXX: Set CE High Watermark; invoke txResourceAvailHandler in response */