]> www.infradead.org Git - users/willy/xarray.git/commitdiff
rpmsg: Convert rcids to XArray
authorMatthew Wilcox <willy@infradead.org>
Tue, 8 Jan 2019 17:20:22 +0000 (12:20 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:14 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/rpmsg/qcom_glink_native.c

index a177d13a1c4e0c2947a764b152dc384f8d624d70..48fb7195d9b3fc4f896f363706480cb353354e9e 100644 (file)
@@ -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);