]> www.infradead.org Git - users/willy/xarray.git/commitdiff
rpmsg: Convert riids to XArray
authorMatthew Wilcox <willy@infradead.org>
Tue, 8 Jan 2019 18:38:28 +0000 (13:38 -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 acd486d18bd8c6675aec33ed1620443fa492ff54..108a101f7da5a1b49736e4eb6fae644493645050 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright (c) 2016-2017, Linaro Ltd
  */
 
-#include <linux/idr.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/list.h>
@@ -134,10 +133,10 @@ enum {
  * @name:      unique channel name/identifier
  * @lcid:      channel id, in local space
  * @rcid:      channel id, in remote space
- * @intent_lock: lock for protection of @riids
  * @liids:     all local intents
- * @riids:     idr of all remote intents
+ * @riids:     all remote intents
  * @intent_work: worker responsible for transmitting rx_done packets
+ * @intent_lock: protects @done_intents
  * @done_intents: list of intents that needs to be announced rx_done
  * @buf:       receive buffer, for gathering fragments
  * @buf_offset:        write offset in @buf
@@ -162,11 +161,11 @@ struct glink_channel {
        unsigned int lcid;
        unsigned int rcid;
 
-       spinlock_t intent_lock;
        struct xarray liids;
-       struct idr riids;
+       struct xarray riids;
        struct work_struct intent_work;
        u32 liid_next;
+       spinlock_t intent_lock;
        struct list_head done_intents;
 
        struct glink_core_rx_intent *buf;
@@ -230,7 +229,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
 
        xa_init_flags(&channel->liids, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_IRQ);
        channel->liid_next = 1;
-       idr_init(&channel->riids);
+       xa_init_flags(&channel->riids, XA_FLAGS_LOCK_IRQ);
        kref_init(&channel->refcount);
 
        return channel;
@@ -240,13 +239,9 @@ static void qcom_glink_channel_release(struct kref *ref)
 {
        struct glink_channel *channel = container_of(ref, struct glink_channel,
                                                     refcount);
-       unsigned long flags;
 
        xa_destroy(&channel->liids);
-       spin_lock_irqsave(&channel->intent_lock, flags);
-       idr_destroy(&channel->riids);
-       spin_unlock_irqrestore(&channel->intent_lock, flags);
-
+       xa_destroy(&channel->riids);
        kfree(channel->name);
        kfree(channel);
 }
@@ -661,11 +656,11 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
                return;
        }
 
-       spin_lock_irqsave(&channel->intent_lock, flags);
-       intent = idr_find(&channel->riids, iid);
+       xa_lock_irqsave(&channel->riids, flags);
+       intent = xa_load(&channel->riids, iid);
 
        if (!intent) {
-               spin_unlock_irqrestore(&channel->intent_lock, flags);
+               xa_unlock_irqrestore(&channel->riids, flags);
                dev_err(glink->dev, "invalid intent id received\n");
                return;
        }
@@ -673,10 +668,10 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
        intent->in_use = false;
 
        if (!reuse) {
-               idr_remove(&channel->riids, intent->id);
+               __xa_erase(&channel->riids, intent->id);
                kfree(intent);
        }
-       spin_unlock_irqrestore(&channel->intent_lock, flags);
+       xa_unlock_irqrestore(&channel->riids, flags);
 }
 
 /**
@@ -891,10 +886,10 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
                intent->id = le32_to_cpu(msg->intents[i].iid);
                intent->size = le32_to_cpu(msg->intents[i].size);
 
-               spin_lock_irqsave(&channel->intent_lock, flags);
-               ret = idr_alloc(&channel->riids, intent,
-                               intent->id, intent->id + 1, GFP_ATOMIC);
-               spin_unlock_irqrestore(&channel->intent_lock, flags);
+               xa_lock_irqsave(&channel->riids, flags);
+               ret = __xa_insert(&channel->riids, intent->id, intent,
+                               GFP_ATOMIC);
+               xa_unlock_irqrestore(&channel->riids, flags);
 
                if (ret < 0)
                        dev_err(glink->dev, "failed to store remote intent\n");
@@ -1201,7 +1196,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
        struct qcom_glink *glink = channel->glink;
        struct glink_core_rx_intent *intent = NULL;
        struct glink_core_rx_intent *tmp;
-       int iid = 0;
+       unsigned long iid = 0;
        struct {
                struct glink_msg msg;
                __le32 chunk_size;
@@ -1212,8 +1207,8 @@ static int __qcom_glink_send(struct glink_channel *channel,
 
        if (!glink->intentless) {
                while (!intent) {
-                       spin_lock_irqsave(&channel->intent_lock, flags);
-                       idr_for_each_entry(&channel->riids, tmp, iid) {
+                       xa_lock_irqsave(&channel->riids, flags);
+                       xa_for_each(&channel->riids, iid, tmp) {
                                if (tmp->size >= len && !tmp->in_use) {
                                        if (!intent)
                                                intent = tmp;
@@ -1225,7 +1220,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
                        }
                        if (intent)
                                intent->in_use = true;
-                       spin_unlock_irqrestore(&channel->intent_lock, flags);
+                       xa_unlock_irqrestore(&channel->riids, flags);
 
                        /* We found an available intent */
                        if (intent)