From: Matthew Wilcox Date: Tue, 8 Jan 2019 17:20:22 +0000 (-0500) Subject: rpmsg: Convert rcids to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=1ff8b3fea749489144ed3f8fc366bad2c7a7f46c;p=users%2Fwilly%2Fxarray.git rpmsg: Convert rcids to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index a177d13a1c4e..48fb7195d9b3 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -85,9 +85,8 @@ struct glink_core_rx_intent { * @rx_lock: protects the @rx_queue * @rx_queue: queue of received control messages to be processed in @rx_work * @tx_lock: synchronizes operations on the tx fifo - * @idr_lock: synchronizes @rcids modifications * @lcids: all channels with a known local channel id - * @rcids: idr of all channels with a known remote channel id + * @rcids: all channels with a known remote channel id * @features: remote features * @intentless: flag to indicate that there is no intent */ @@ -110,10 +109,9 @@ struct qcom_glink { spinlock_t tx_lock; - spinlock_t idr_lock; u32 lcid_next; struct xarray lcids; - struct idr rcids; + struct xarray rcids; unsigned long features; bool intentless; @@ -358,9 +356,9 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, struct glink_channel *channel; unsigned long flags; - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, cid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + xa_lock_irqsave(&glink->rcids, flags); + channel = xa_load(&glink->rcids, cid); + xa_unlock_irqrestore(&glink->rcids, flags); if (!channel) { dev_err(glink->dev, "unable to find channel\n"); return; @@ -661,9 +659,9 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink, struct glink_channel *channel; unsigned long flags; - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, cid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + xa_lock_irqsave(&glink->rcids, flags); + channel = xa_load(&glink->rcids, cid); + xa_unlock_irqrestore(&glink->rcids, flags); if (!channel) { dev_err(glink->dev, "invalid channel id received\n"); return; @@ -702,11 +700,8 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink, { struct glink_core_rx_intent *intent; struct glink_channel *channel; - unsigned long flags; - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, cid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + channel = xa_load(&glink->rcids, cid); if (!channel) { pr_err("%s channel not found for cid %d\n", __func__, cid); @@ -780,9 +775,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) } rcid = le16_to_cpu(hdr.msg.param1); - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, rcid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + channel = xa_load(&glink->rcids, rcid); if (!channel) { dev_dbg(glink->dev, "Data on non-existing channel\n"); @@ -889,9 +882,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, return; } - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, cid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + channel = xa_load(&glink->rcids, cid); if (!channel) { dev_err(glink->dev, "intents for non-existing channel\n"); return; @@ -1097,16 +1088,13 @@ static struct rpmsg_endpoint *qcom_glink_create_ept(struct rpmsg_device *rpdev, struct qcom_glink *glink = parent->glink; struct rpmsg_endpoint *ept; const char *name = chinfo.name; - int cid; + unsigned long cid; int ret; - unsigned long flags; - spin_lock_irqsave(&glink->idr_lock, flags); - idr_for_each_entry(&glink->rcids, channel, cid) { + xa_for_each(&glink->rcids, cid, channel) { if (!strcmp(channel->name, name)) break; } - spin_unlock_irqrestore(&glink->idr_lock, flags); if (!channel) { channel = qcom_glink_create_local(glink, name); @@ -1364,15 +1352,12 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, create_device = true; } - spin_lock_irq(&glink->idr_lock); - ret = idr_alloc(&glink->rcids, channel, rcid, rcid + 1, GFP_ATOMIC); + channel->rcid = rcid; + ret = xa_insert_irq(&glink->rcids, rcid, channel, GFP_KERNEL); if (ret < 0) { - dev_err(glink->dev, "Unable to insert channel into rcid list\n"); - spin_unlock_irq(&glink->idr_lock); + dev_err(glink->dev, "Unable to insert channel into rcids\n"); goto free_channel; } - channel->rcid = ret; - spin_unlock_irq(&glink->idr_lock); complete(&channel->open_req); @@ -1406,10 +1391,8 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, free_rpdev: kfree(rpdev); rcid_remove: - spin_lock_irq(&glink->idr_lock); - idr_remove(&glink->rcids, channel->rcid); + xa_erase_irq(&glink->rcids, channel->rcid); channel->rcid = 0; - spin_unlock_irq(&glink->idr_lock); free_channel: /* Release the reference, iff we took it */ if (create_device) @@ -1422,11 +1405,8 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) { struct rpmsg_channel_info chinfo; struct glink_channel *channel; - unsigned long flags; - spin_lock_irqsave(&glink->idr_lock, flags); - channel = idr_find(&glink->rcids, rcid); - spin_unlock_irqrestore(&glink->idr_lock, flags); + channel = xa_load(&glink->rcids, rcid); if (WARN(!channel, "close request on unknown channel\n")) return; @@ -1443,10 +1423,8 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) qcom_glink_send_close_ack(glink, channel->rcid); - spin_lock_irqsave(&glink->idr_lock, flags); - idr_remove(&glink->rcids, channel->rcid); + xa_erase_irq(&glink->rcids, channel->rcid); channel->rcid = 0; - spin_unlock_irqrestore(&glink->idr_lock, flags); kref_put(&channel->refcount, qcom_glink_channel_release); } @@ -1547,10 +1525,9 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, INIT_LIST_HEAD(&glink->rx_queue); INIT_WORK(&glink->rx_work, qcom_glink_work); - spin_lock_init(&glink->idr_lock); xa_init_flags(&glink->lcids, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); glink->lcid_next = 0; - idr_init(&glink->rcids); + xa_init_flags(&glink->rcids, XA_FLAGS_LOCK_IRQ); ret = of_property_read_string(dev->of_node, "label", &glink->name); if (ret < 0) @@ -1613,7 +1590,7 @@ void qcom_glink_native_remove(struct qcom_glink *glink) xa_unlock_irqrestore(&glink->lcids, flags); xa_destroy(&glink->lcids); - idr_destroy(&glink->rcids); + xa_destroy(&glink->rcids); mbox_free_channel(glink->mbox_chan); } EXPORT_SYMBOL_GPL(qcom_glink_native_remove);