int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
struct address_space *mapping)
{
- int pasid;
+ struct xa_limit limit = XA_LIMIT(afu->pasid_base,
+ afu->pasid_base + afu->pasid_max - 1);
+ int err;
struct ocxl_context *ctx;
*context = kzalloc(sizeof(struct ocxl_context), GFP_KERNEL);
ctx = *context;
ctx->afu = afu;
- mutex_lock(&afu->contexts_lock);
- pasid = idr_alloc(&afu->contexts_idr, ctx, afu->pasid_base,
- afu->pasid_base + afu->pasid_max, GFP_KERNEL);
- if (pasid < 0) {
- mutex_unlock(&afu->contexts_lock);
- return pasid;
- }
- afu->pasid_count++;
- mutex_unlock(&afu->contexts_lock);
- ctx->pasid = pasid;
+ xa_lock(&afu->contexts);
+ err = __xa_alloc(&afu->contexts, &ctx->pasid, ctx, limit, GFP_KERNEL);
+ if (err == 0)
+ afu->pasid_count++;
+ xa_unlock(&afu->contexts);
+ if (err < 0)
+ return err;
+
ctx->status = OPENED;
mutex_init(&ctx->status_mutex);
ctx->mapping = mapping;
void ocxl_context_detach_all(struct ocxl_afu *afu)
{
struct ocxl_context *ctx;
- int tmp;
+ unsigned long index;
- mutex_lock(&afu->contexts_lock);
- idr_for_each_entry(&afu->contexts_idr, ctx, tmp) {
+ xa_for_each(&afu->contexts, index, ctx) {
ocxl_context_detach(ctx);
/*
* We are force detaching - remove any active mmio
unmap_mapping_range(ctx->mapping, 0, 0, 1);
mutex_unlock(&ctx->mapping_lock);
}
- mutex_unlock(&afu->contexts_lock);
}
void ocxl_context_free(struct ocxl_context *ctx)
{
- mutex_lock(&ctx->afu->contexts_lock);
+ xa_lock(&ctx->afu->contexts);
ctx->afu->pasid_count--;
- idr_remove(&ctx->afu->contexts_idr, ctx->pasid);
- mutex_unlock(&ctx->afu->contexts_lock);
+ __xa_erase(&ctx->afu->contexts, ctx->pasid);
+ xa_unlock(&ctx->afu->contexts);
ocxl_afu_irq_free_all(ctx);
/* reference to the AFU taken in ocxl_context_init */
return NULL;
kref_init(&afu->kref);
- mutex_init(&afu->contexts_lock);
mutex_init(&afu->afu_control_lock);
- idr_init(&afu->contexts_idr);
+ xa_init_flags(&afu->contexts, XA_FLAGS_ALLOC);
afu->fn = fn;
ocxl_fn_get(fn);
return afu;
{
struct ocxl_afu *afu = container_of(kref, struct ocxl_afu, kref);
- idr_destroy(&afu->contexts_idr);
+ BUG_ON(!xa_empty(&afu->contexts));
ocxl_fn_put(afu->fn);
kfree(afu);
}