diff mbox

[v2,12/38] cxlflash: Use IDR to manage adapter contexts

Message ID 1519683712-17186-1-git-send-email-ukrishn@linux.vnet.ibm.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Uma Krishnan Feb. 26, 2018, 10:21 p.m. UTC
A range of PASIDs are used as identifiers for the adapter contexts. These
contexts may be destroyed and created randomly. Use an IDR to keep track
of contexts that are in use and assign a unique identifier to new ones.

Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
---
 drivers/scsi/cxlflash/ocxl_hw.c | 20 ++++++++++++++++++--
 drivers/scsi/cxlflash/ocxl_hw.h |  2 ++
 2 files changed, 20 insertions(+), 2 deletions(-)

Comments

Frederic Barrat March 22, 2018, 4:40 p.m. UTC | #1
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> A range of PASIDs are used as identifiers for the adapter contexts. These
> contexts may be destroyed and created randomly. Use an IDR to keep track
> of contexts that are in use and assign a unique identifier to new ones.
> 
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
>   drivers/scsi/cxlflash/ocxl_hw.c | 20 ++++++++++++++++++--
>   drivers/scsi/cxlflash/ocxl_hw.h |  2 ++
>   2 files changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index d75b873..6472210 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -12,6 +12,8 @@
>    * 2 of the License, or (at your option) any later version.
>    */
> 
> +#include <linux/idr.h>
> +
>   #include <misc/ocxl.h>
> 
>   #include "backend.h"
> @@ -60,14 +62,25 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
>   	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();


I believe we can call idr_alloc(... GFP_KERNEL) directly in that
context now.


> +	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;
>   }
> @@ -86,6 +99,7 @@ static int ocxlflash_release_context(void *ctx_cookie)
>   	if (!ctx)
>   		goto out;
> 
> +	idr_remove(&ctx->hw_afu->idr, ctx->pe);
>   	kfree(ctx);
>   out:
>   	return rc;
> @@ -103,6 +117,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
>   		return;
> 
>   	ocxlflash_release_context(afu->ocxl_ctx);
> +	idr_destroy(&afu->idr);
>   	kfree(afu);
>   }
> 
> @@ -237,6 +252,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
>   		goto err1;
>   	}
> 
> +	idr_init(&afu->idr);

You initialize the IDR too late. ocxlflash_dev_context_init() was called 
just above and allocated a PE.

   Fred


>   	afu->ocxl_ctx = ctx;
>   out:
>   	return afu;
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index de43c04..0381682 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -26,10 +26,12 @@ struct ocxl_hw_afu {
>   	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 */
>   };
> 
>   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 */
>   };
>
Uma Krishnan March 22, 2018, 10:26 p.m. UTC | #2
> On Mar 22, 2018, at 11:40 AM, Frederic Barrat <fbarrat@linux.vnet.ibm.com> wrote:
> 
> 
> 
> Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
>> A range of PASIDs are used as identifiers for the adapter contexts. These
>> contexts may be destroyed and created randomly. Use an IDR to keep track
>> of contexts that are in use and assign a unique identifier to new ones.
>> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
>> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
>> ---
>>  drivers/scsi/cxlflash/ocxl_hw.c | 20 ++++++++++++++++++--
>>  drivers/scsi/cxlflash/ocxl_hw.h |  2 ++
>>  2 files changed, 20 insertions(+), 2 deletions(-)
>> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
>> index d75b873..6472210 100644
>> --- a/drivers/scsi/cxlflash/ocxl_hw.c
>> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
>> @@ -12,6 +12,8 @@
>>   * 2 of the License, or (at your option) any later version.
>>   */
>> +#include <linux/idr.h>
>> +
>>  #include <misc/ocxl.h>
>>  #include "backend.h"
>> @@ -60,14 +62,25 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
>>  	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();
> 
> 
> I believe we can call idr_alloc(... GFP_KERNEL) directly in that
> context now.
> 
> 
>> +	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;
>>  }
>> @@ -86,6 +99,7 @@ static int ocxlflash_release_context(void *ctx_cookie)
>>  	if (!ctx)
>>  		goto out;
>> +	idr_remove(&ctx->hw_afu->idr, ctx->pe);
>>  	kfree(ctx);
>>  out:
>>  	return rc;
>> @@ -103,6 +117,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
>>  		return;
>>  	ocxlflash_release_context(afu->ocxl_ctx);
>> +	idr_destroy(&afu->idr);
>>  	kfree(afu);
>>  }
>> @@ -237,6 +252,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
>>  		goto err1;
>>  	}
>> +	idr_init(&afu->idr);
> 
> You initialize the IDR too late. ocxlflash_dev_context_init() was called just above and allocated a PE.
> 
>  Fred

Good Catch. I will fix this bug and send out a V3 soon. Thanks for the review !!

> 
>>  	afu->ocxl_ctx = ctx;
>>  out:
>>  	return afu;
>> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
>> index de43c04..0381682 100644
>> --- a/drivers/scsi/cxlflash/ocxl_hw.h
>> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
>> @@ -26,10 +26,12 @@ struct ocxl_hw_afu {
>>  	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 */
>>  };
>>  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 */
>>  };
>
diff mbox

Patch

diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
index d75b873..6472210 100644
--- a/drivers/scsi/cxlflash/ocxl_hw.c
+++ b/drivers/scsi/cxlflash/ocxl_hw.c
@@ -12,6 +12,8 @@ 
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/idr.h>
+
 #include <misc/ocxl.h>
 
 #include "backend.h"
@@ -60,14 +62,25 @@  static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
 	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;
 }
@@ -86,6 +99,7 @@  static int ocxlflash_release_context(void *ctx_cookie)
 	if (!ctx)
 		goto out;
 
+	idr_remove(&ctx->hw_afu->idr, ctx->pe);
 	kfree(ctx);
 out:
 	return rc;
@@ -103,6 +117,7 @@  static void ocxlflash_destroy_afu(void *afu_cookie)
 		return;
 
 	ocxlflash_release_context(afu->ocxl_ctx);
+	idr_destroy(&afu->idr);
 	kfree(afu);
 }
 
@@ -237,6 +252,7 @@  static void *ocxlflash_create_afu(struct pci_dev *pdev)
 		goto err1;
 	}
 
+	idr_init(&afu->idr);
 	afu->ocxl_ctx = ctx;
 out:
 	return afu;
diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
index de43c04..0381682 100644
--- a/drivers/scsi/cxlflash/ocxl_hw.h
+++ b/drivers/scsi/cxlflash/ocxl_hw.h
@@ -26,10 +26,12 @@  struct ocxl_hw_afu {
 	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 */
 };
 
 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 */
 };