On Tue, 2015-08-11 at 13:42 +1000, Cyril Bur wrote:
> On Tue, 28 Jul 2015 15:28:35 +1000
> Daniel Axtens <d...@axtens.net> wrote:
> 
> > Previously the SPA was allocated and freed upon entering and leaving
> > AFU-directed mode. This causes some issues for error recovery - contexts
> > hold a pointer inside the SPA, and they may persist after the AFU has
> > been detached.
> > 
> > We would ideally like to allocate the SPA when the AFU is allocated, and
> > release it until the AFU is released. However, we don't know how big the
> > SPA needs to be until we read the AFU descriptor.
> > 
> > Therefore, restructure the code:
> > 
> >  - Allocate the SPA only once, on the first attach.
> > 
> >  - Release the SPA only when the entire AFU is being released (not
> >    detached). Guard the release with a NULL check, so we don't free
> >    if it was never allocated (e.g. dedicated mode)
> > 
> 
> I'm sure you tested this :), looks fine to me, from an outsiders perspective
> code appears to do what the commit message says.
> 
> Just one super minor question, you do the NULL check in the caller. How 
> obvious
> is the error if/when a caller forgets?
> 
Good point. The SPA is only released when releasing the entire AFU, so
it doesn't really matter at this point, but in case we ever move around
the assignment/release of the SPA (dynamic reprogramming comes to mind)
I've moved the check and added an explicit NULLing of the SPA pointer.

> Acked-by: Cyril Bur <cyril...@gmail.com>
> 
Thanks!
> > Signed-off-by: Daniel Axtens <d...@axtens.net>
> > ---
> >  drivers/misc/cxl/cxl.h    |  3 +++
> >  drivers/misc/cxl/native.c | 28 ++++++++++++++++++----------
> >  drivers/misc/cxl/pci.c    |  3 +++
> >  3 files changed, 24 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
> > index 47eadbcfd379..88a88c445e2a 100644
> > --- a/drivers/misc/cxl/cxl.h
> > +++ b/drivers/misc/cxl/cxl.h
> > @@ -603,6 +603,9 @@ void unregister_cxl_calls(struct cxl_calls *calls);
> >  int cxl_alloc_adapter_nr(struct cxl *adapter);
> >  void cxl_remove_adapter_nr(struct cxl *adapter);
> >  
> > +int cxl_alloc_spa(struct cxl_afu *afu);
> > +void cxl_release_spa(struct cxl_afu *afu);
> > +
> >  int cxl_file_init(void);
> >  void cxl_file_exit(void);
> >  int cxl_register_adapter(struct cxl *adapter);
> > diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
> > index 16948915eb0d..debd97147b58 100644
> > --- a/drivers/misc/cxl/native.c
> > +++ b/drivers/misc/cxl/native.c
> > @@ -182,10 +182,8 @@ static int spa_max_procs(int spa_size)
> >     return ((spa_size / 8) - 96) / 17;
> >  }
> >  
> > -static int alloc_spa(struct cxl_afu *afu)
> > +int cxl_alloc_spa(struct cxl_afu *afu)
> >  {
> > -   u64 spap;
> > -
> >     /* Work out how many pages to allocate */
> >     afu->spa_order = 0;
> >     do {
> > @@ -204,6 +202,13 @@ static int alloc_spa(struct cxl_afu *afu)
> >     pr_devel("spa pages: %i afu->spa_max_procs: %i   afu->num_procs: %i\n",
> >              1<<afu->spa_order, afu->spa_max_procs, afu->num_procs);
> >  
> > +   return 0;
> > +}
> > +
> > +static void attach_spa(struct cxl_afu *afu)
> > +{
> > +   u64 spap;
> > +
> >     afu->sw_command_status = (__be64 *)((char *)afu->spa +
> >                                         ((afu->spa_max_procs + 3) * 128));
> >  
> > @@ -212,13 +217,15 @@ static int alloc_spa(struct cxl_afu *afu)
> >     spap |= CXL_PSL_SPAP_V;
> >     pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, 
> > sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", afu->spa, 
> > afu->spa_max_procs, afu->sw_command_status, spap);
> >     cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
> > -
> > -   return 0;
> >  }
> >  
> > -static void release_spa(struct cxl_afu *afu)
> > +static inline void detach_spa(struct cxl_afu *afu)
> >  {
> >     cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0);
> > +}
> > +
> > +void cxl_release_spa(struct cxl_afu *afu)
> > +{
> >     free_pages((unsigned long) afu->spa, afu->spa_order);
> >  }
> >  
> > @@ -446,8 +453,11 @@ static int activate_afu_directed(struct cxl_afu *afu)
> >  
> >     dev_info(&afu->dev, "Activating AFU directed mode\n");
> >  
> > -   if (alloc_spa(afu))
> > -           return -ENOMEM;
> > +   if (afu->spa == NULL) {
> > +           if (cxl_alloc_spa(afu))
> > +                   return -ENOMEM;
> > +   }
> > +   attach_spa(afu);
> >  
> >     cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_AFU);
> >     cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
> > @@ -560,8 +570,6 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
> >     cxl_afu_disable(afu);
> >     cxl_psl_purge(afu);
> >  
> > -   release_spa(afu);
> > -
> >     return 0;
> >  }
> >  
> > diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
> > index 32ad09705949..1849c1785b49 100644
> > --- a/drivers/misc/cxl/pci.c
> > +++ b/drivers/misc/cxl/pci.c
> > @@ -551,6 +551,9 @@ static void cxl_release_afu(struct device *dev)
> >  
> >     pr_devel("cxl_release_afu\n");
> >  
> > +   if (afu->spa)
> > +           cxl_release_spa(afu);
> > +
> >     kfree(afu);
> >  }
> >  
> 

-- 
Regards,
Daniel

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to