diff options
| -rw-r--r-- | drivers/soc/qcom/glink.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index af7d22e7bb23..76b99500c760 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -375,7 +375,7 @@ static void tx_func(struct kthread_work *work); static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name); + const char *name, bool local); static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid, void *cookie); @@ -1870,13 +1870,14 @@ static void glink_ch_ctx_release(struct rwref_lock *ch_st_lock) * it is not found and get reference of context. * @xprt_ctx: Transport to search for a matching channel. * @name: Name of the desired channel. + * @local: If called from local open or not * * Return: The channel corresponding to @name, NULL if a matching channel was * not found AND a new channel could not be created. */ static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name) + const char *name, bool local) { struct channel_ctx *entry; struct channel_ctx *ctx; @@ -1920,10 +1921,23 @@ check_ctx: list_for_each_entry_safe(entry, temp, &xprt_ctx->channels, port_list_node) if (!strcmp(entry->name, name) && !entry->pending_delete) { + rwref_get(&entry->ch_state_lhb2); + /* port already exists */ + if (entry->local_open_state != GLINK_CHANNEL_CLOSED + && local) { + /* not ready to be re-opened */ + GLINK_INFO_CH_XPRT(entry, xprt_ctx, + "%s: Ch not ready. State: %u\n", + __func__, entry->local_open_state); + rwref_put(&entry->ch_state_lhb2); + entry = NULL; + } else if (local) { + entry->local_open_state = + GLINK_CHANNEL_OPENING; + } spin_unlock_irqrestore(&xprt_ctx->xprt_ctx_lock_lhb1, flags); kfree(ctx); - rwref_get(&entry->ch_state_lhb2); rwref_write_put(&xprt_ctx->xprt_state_lhb0); return entry; } @@ -1954,6 +1968,8 @@ check_ctx: ctx->transport_ptr = xprt_ctx; rwref_get(&ctx->ch_state_lhb2); + if (local) + ctx->local_open_state = GLINK_CHANNEL_OPENING; list_add_tail(&ctx->port_list_node, &xprt_ctx->channels); GLINK_INFO_PERF_CH_XPRT(ctx, xprt_ctx, @@ -2639,23 +2655,13 @@ void *glink_open(const struct glink_open_config *cfg) * look for an existing port structure which can occur in * reopen and remote-open-first cases */ - ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name); + ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name, true); if (ctx == NULL) { GLINK_ERR("%s:%s %s: Error - unable to allocate new channel\n", cfg->transport, cfg->edge, __func__); return ERR_PTR(-ENOMEM); } - /* port already exists */ - if (ctx->local_open_state != GLINK_CHANNEL_CLOSED) { - /* not ready to be re-opened */ - GLINK_INFO_CH_XPRT(ctx, transport_ptr, - "%s: Channel not ready to be re-opened. State: %u\n", - __func__, ctx->local_open_state); - rwref_put(&ctx->ch_state_lhb2); - return ERR_PTR(-EBUSY); - } - /* initialize port structure */ ctx->user_priv = cfg->priv; ctx->rx_intent_req_timeout_jiffies = @@ -2686,7 +2692,6 @@ void *glink_open(const struct glink_open_config *cfg) ctx->local_xprt_req = best_id; ctx->no_migrate = cfg->transport && !(cfg->options & GLINK_OPT_INITIAL_XPORT); - ctx->local_open_state = GLINK_CHANNEL_OPENING; GLINK_INFO_PERF_CH(ctx, "%s: local:GLINK_CHANNEL_CLOSED->GLINK_CHANNEL_OPENING\n", __func__); @@ -4944,7 +4949,7 @@ static void glink_core_rx_cmd_ch_remote_open(struct glink_transport_if *if_ptr, bool do_migrate; glink_core_migration_edge_lock(if_ptr->glink_core_priv); - ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name); + ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name, false); if (ctx == NULL) { GLINK_ERR_XPRT(if_ptr->glink_core_priv, "%s: invalid rcid %u received, name '%s'\n", @@ -5046,6 +5051,7 @@ static void glink_core_rx_cmd_ch_remote_close( struct channel_ctx *ctx; bool is_ch_fully_closed; struct glink_core_xprt_ctx *xprt_ptr = if_ptr->glink_core_priv; + unsigned long flags; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { @@ -5063,11 +5069,13 @@ static void glink_core_rx_cmd_ch_remote_close( rwref_put(&ctx->ch_state_lhb2); return; } + spin_lock_irqsave(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); + ctx->pending_delete = true; + spin_unlock_irqrestore(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); GLINK_INFO_CH(ctx, "%s: remote: OPENED->CLOSED\n", __func__); is_ch_fully_closed = glink_core_remote_close_common(ctx, false); - ctx->pending_delete = true; if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid); if (is_ch_fully_closed) { |
