* 2 of the License, or (at your option) any later version.
*/
+#include <linux/idr.h>
+
#include <misc/ocxl.h>
#include "backend.h"
if (unlikely(!ctx)) {
dev_err(dev, "%s: Context allocation failed\n", __func__);
rc = -ENOMEM;
- goto err;
+ goto err1;
+ }
+
+ idr_preload(GFP_KERNEL);
+ rc = idr_alloc(&afu->idr, ctx, 0, afu->max_pasid, GFP_NOWAIT);
+ idr_preload_end();
+ if (unlikely(rc < 0)) {
+ dev_err(dev, "%s: idr_alloc failed rc=%d\n", __func__, rc);
+ goto err2;
}
+ ctx->pe = rc;
ctx->master = false;
ctx->hw_afu = afu;
out:
return ctx;
-err:
+err2:
+ kfree(ctx);
+err1:
ctx = ERR_PTR(rc);
goto out;
}
if (!ctx)
goto out;
+ idr_remove(&ctx->hw_afu->idr, ctx->pe);
kfree(ctx);
out:
return rc;
return;
ocxlflash_release_context(afu->ocxl_ctx);
+ idr_destroy(&afu->idr);
kfree(afu);
}
afu->pdev = pdev;
afu->dev = dev;
+ idr_init(&afu->idr);
rc = ocxlflash_config_fn(pdev, afu);
if (unlikely(rc)) {
out:
return afu;
err1:
+ idr_destroy(&afu->idr);
kfree(afu);
afu = NULL;
goto out;
int afu_actag_base; /* AFU acTag base */
int afu_actag_enabled; /* AFU acTag number enabled */
+ struct idr idr; /* IDR to manage contexts */
int max_pasid; /* Maximum number of contexts */
bool is_present; /* Function has AFUs defined */
};
struct ocxlflash_context {
struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */
bool master; /* Whether this is a master context */
+ int pe; /* Process element */
};