From b6f9709526f8b879d91579fe687f52f719347f05 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 8 Jan 2019 12:50:33 -0500 Subject: [PATCH] rpmsg; Convert liids to XArray Signed-off-by: Matthew Wilcox --- drivers/rpmsg/qcom_glink_native.c | 37 +++++++++++-------------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 48fb7195d9b3..acd486d18bd8 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -134,8 +134,8 @@ enum { * @name: unique channel name/identifier * @lcid: channel id, in local space * @rcid: channel id, in remote space - * @intent_lock: lock for protection of @liids, @riids - * @liids: idr of all local intents + * @intent_lock: lock for protection of @riids + * @liids: all local intents * @riids: idr of all remote intents * @intent_work: worker responsible for transmitting rx_done packets * @done_intents: list of intents that needs to be announced rx_done @@ -163,9 +163,10 @@ struct glink_channel { unsigned int rcid; spinlock_t intent_lock; - struct idr liids; + struct xarray liids; struct idr riids; struct work_struct intent_work; + u32 liid_next; struct list_head done_intents; struct glink_core_rx_intent *buf; @@ -227,7 +228,8 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, INIT_LIST_HEAD(&channel->done_intents); INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work); - idr_init(&channel->liids); + xa_init_flags(&channel->liids, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_IRQ); + channel->liid_next = 1; idr_init(&channel->riids); kref_init(&channel->refcount); @@ -240,8 +242,8 @@ static void qcom_glink_channel_release(struct kref *ref) refcount); unsigned long flags; + xa_destroy(&channel->liids); spin_lock_irqsave(&channel->intent_lock, flags); - idr_destroy(&channel->liids); idr_destroy(&channel->riids); spin_unlock_irqrestore(&channel->intent_lock, flags); @@ -484,11 +486,8 @@ static void qcom_glink_rx_done(struct qcom_glink *glink, } /* Take it off the tree of receive intents */ - if (!intent->reuse) { - spin_lock(&channel->intent_lock); - idr_remove(&channel->liids, intent->id); - spin_unlock(&channel->intent_lock); - } + if (!intent->reuse) + xa_erase(&channel->liids, intent->id); /* Schedule the sending of a rx_done indication */ spin_lock(&channel->intent_lock); @@ -620,7 +619,6 @@ qcom_glink_alloc_intent(struct qcom_glink *glink, { struct glink_core_rx_intent *intent; int ret; - unsigned long flags; intent = kzalloc(sizeof(*intent), GFP_KERNEL); if (!intent) @@ -630,15 +628,11 @@ qcom_glink_alloc_intent(struct qcom_glink *glink, if (!intent->data) goto free_intent; - spin_lock_irqsave(&channel->intent_lock, flags); - ret = idr_alloc_cyclic(&channel->liids, intent, 1, -1, GFP_ATOMIC); - if (ret < 0) { - spin_unlock_irqrestore(&channel->intent_lock, flags); + ret = xa_alloc_cyclic_irq(&channel->liids, &intent->id, intent, + xa_limit_32b, &channel->liid_next, GFP_KERNEL); + if (ret < 0) goto free_data; - } - spin_unlock_irqrestore(&channel->intent_lock, flags); - intent->id = ret; intent->size = size; intent->reuse = reuseable; @@ -758,7 +752,6 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) unsigned int rcid; unsigned int liid; int ret = 0; - unsigned long flags; if (avail < sizeof(hdr)) { dev_dbg(glink->dev, "Not enough data in fifo\n"); @@ -807,11 +800,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) } } else { liid = le32_to_cpu(hdr.msg.param2); - - spin_lock_irqsave(&channel->intent_lock, flags); - intent = idr_find(&channel->liids, liid); - spin_unlock_irqrestore(&channel->intent_lock, flags); - + intent = xa_load(&channel->liids, liid); if (!intent) { dev_err(glink->dev, "no intent found for channel %s intent %d", -- 2.50.1