diff options
Diffstat (limited to 'drivers/soc/qcom/glink.c')
| -rw-r--r-- | drivers/soc/qcom/glink.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 277ab978..f41dca07 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -1146,6 +1146,7 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, { struct glink_core_rx_intent *intent; struct glink_core_rx_intent *intent_tmp; + struct glink_core_rx_intent *best_intent = NULL; unsigned long flags; if (GLINK_MAX_PKT_SIZE < size) { @@ -1168,20 +1169,28 @@ int ch_pop_remote_rx_intent(struct channel_ctx *ctx, size_t size, list_for_each_entry_safe(intent, intent_tmp, &ctx->rmt_rx_intent_list, list) { if (intent->intent_size >= size) { - list_del(&intent->list); - GLINK_DBG_CH(ctx, - "%s: R[%u]:%zu Removed remote intent\n", - __func__, - intent->id, - intent->intent_size); - *riid_ptr = intent->id; - *intent_size = intent->intent_size; - kfree(intent); - spin_unlock_irqrestore( - &ctx->rmt_rx_intent_lst_lock_lhc2, flags); - return 0; + if (!best_intent) + best_intent = intent; + else if (best_intent->intent_size > intent->intent_size) + best_intent = intent; + if (best_intent->intent_size == size) + break; } } + if (best_intent) { + list_del(&best_intent->list); + GLINK_DBG_CH(ctx, + "%s: R[%u]:%zu Removed remote intent\n", + __func__, + best_intent->id, + best_intent->intent_size); + *riid_ptr = best_intent->id; + *intent_size = best_intent->intent_size; + kfree(best_intent); + spin_unlock_irqrestore( + &ctx->rmt_rx_intent_lst_lock_lhc2, flags); + return 0; + } spin_unlock_irqrestore(&ctx->rmt_rx_intent_lst_lock_lhc2, flags); return -EAGAIN; } @@ -2663,7 +2672,7 @@ int glink_close(void *handle) { struct glink_core_xprt_ctx *xprt_ctx = NULL; struct channel_ctx *ctx = (struct channel_ctx *)handle; - int ret; + int ret = 0; unsigned long flags; bool is_empty = false; @@ -2824,7 +2833,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, tracer_pkt_log_event(data, GLINK_CORE_TX); } - /* find matching rx intent (first-fit algorithm for now) */ + /* find matching rx intent (best-fit algorithm for now) */ if (ch_pop_remote_rx_intent(ctx, size, &riid, &intent_size)) { if (!(tx_flags & GLINK_TX_REQ_INTENT)) { /* no rx intent available */ @@ -5228,7 +5237,7 @@ static int glink_scheduler_tx(struct channel_ctx *ctx, size_t txd_len = 0; size_t tx_len = 0; uint32_t num_pkts = 0; - int ret; + int ret = 0; spin_lock_irqsave(&ctx->tx_lists_lock_lhc3, flags); while (txd_len < xprt_ctx->mtu && |
