#include <linux/mm.h>
#include <linux/of.h>
#include <linux/slab.h>
-#include <linux/idr.h>
#include <linux/pci.h>
#include <linux/sched/task.h>
+#include <linux/xarray.h>
#include <asm/cputable.h>
#include <misc/cxl-base.h>
#include "cxl.h"
#include "trace.h"
-static DEFINE_SPINLOCK(adapter_idr_lock);
-static DEFINE_IDR(cxl_adapter_idr);
+static DEFINE_XARRAY_ALLOC(cxl_adapters);
uint cxl_verbose;
module_param_named(verbose, cxl_verbose, uint, 0600);
struct cxl *adapter;
struct cxl_afu *afu;
struct cxl_context *ctx;
- unsigned long index;
- int card, slice;
+ unsigned long card, index;
+ int slice;
pr_devel("%s called\n", __func__);
- spin_lock(&adapter_idr_lock);
- idr_for_each_entry(&cxl_adapter_idr, adapter, card) {
+ xa_lock(&cxl_adapters);
+ xa_for_each(&cxl_adapters, card, adapter) {
/* XXX: Make this lookup faster with link from mm to ctx */
spin_lock(&adapter->afu_list_lock);
for (slice = 0; slice < adapter->slices; slice++) {
}
spin_unlock(&adapter->afu_list_lock);
}
- spin_unlock(&adapter_idr_lock);
+ xa_unlock(&cxl_adapters);
}
static struct cxl_calls cxl_calls = {
{
struct cxl *adapter;
- spin_lock(&adapter_idr_lock);
- if ((adapter = idr_find(&cxl_adapter_idr, num)))
+ xa_lock(&cxl_adapters);
+ adapter = xa_load(&cxl_adapters, num);
+ if (adapter)
get_device(&adapter->dev);
- spin_unlock(&adapter_idr_lock);
+ xa_unlock(&cxl_adapters);
return adapter;
}
static int cxl_alloc_adapter_nr(struct cxl *adapter)
{
- int i;
-
- idr_preload(GFP_KERNEL);
- spin_lock(&adapter_idr_lock);
- i = idr_alloc(&cxl_adapter_idr, adapter, 0, 0, GFP_NOWAIT);
- spin_unlock(&adapter_idr_lock);
- idr_preload_end();
- if (i < 0)
- return i;
-
- adapter->adapter_num = i;
-
- return 0;
+ return xa_alloc(&cxl_adapters, &adapter->adapter_num, adapter,
+ xa_limit_32b, GFP_KERNEL);
}
void cxl_remove_adapter_nr(struct cxl *adapter)
{
- idr_remove(&cxl_adapter_idr, adapter->adapter_num);
+ xa_erase(&cxl_adapters, adapter->adapter_num);
}
struct cxl *cxl_alloc_adapter(void)
cxl_file_exit();
if (cxl_is_power8())
unregister_cxl_calls(&cxl_calls);
- idr_destroy(&cxl_adapter_idr);
}
module_init(init_cxl);
* in that case we ignore the value and I'd rather not risk
* breaking any existing dedicated process AFUs that left it as
* 0 (not that I'm aware of any). It is clearly an error for an
- * AFU directed AFU to set this to 0, and would have previously
- * triggered a bug resulting in the maximum not being enforced
- * at all since idr_alloc treats 0 as no maximum.
+ * AFU directed AFU to set this to 0.
*/
dev_err(&afu->dev, "AFU does not support any processes\n");
return -EINVAL;