aboutsummaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/glink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/qcom/glink.c')
-rw-r--r--drivers/soc/qcom/glink.c39
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 &&