Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-27 Thread Scott Wood
On Mon, 2020-04-27 at 09:13 -0500, Rob Herring wrote:
> On Sun, Apr 19, 2020 at 10:06 PM Wang Wenhu  wrote:
> > 
> > A generic User-Kernel interface that allows a misc device created
> > by it to support file-operations of ioctl and mmap to access SRAM
> > memory from user level. Different kinds of SRAM alloction and free
> > APIs could be registered by specific SRAM hardware level driver to
> > the available list and then be chosen by users to allocate and map
> > SRAM memory from user level.
> > 
> > It is extremely helpful for the user space applications that require
> > high performance memory accesses, such as embedded networking devices
> > that would process data in user space, and PowerPC e500 is a case.
> > 
> > Signed-off-by: Wang Wenhu 
> > Cc: Greg Kroah-Hartman 
> > Cc: Arnd Bergmann 
> > Cc: Christophe Leroy 
> > Cc: Scott Wood 
> > Cc: Michael Ellerman 
> > Cc: Randy Dunlap 
> > Cc: linuxppc-dev@lists.ozlabs.org
> > ---
> > Changes since v1: addressed comments from Arnd
> >  * Changed the ioctl cmd definitions using _IO micros
> >  * Export interfaces for HW-SRAM drivers to register apis to available
> > list
> >  * Modified allocation alignment to PAGE_SIZE
> >  * Use phys_addr_t as type of SRAM resource size and offset
> >  * Support compat_ioctl
> >  * Misc device name:sram
> > 
> > Note: From this on, the SRAM_UAPI driver is independent to any hardware
> > drivers, so I would only commit the patch itself as v2, while the v1 of
> > it was wrapped together with patches for Freescale L2-Cache-SRAM device.
> > Then after, I'd create patches for Freescale L2-Cache-SRAM device as
> > another series.
> 
> There's work to add SRAM support to dma-buf heaps[1]. Take a look and
> see if that works for you.
> 
> Rob
> 
> [1] https://lore.kernel.org/lkml/20200424222740.16259-1-...@ti.com/
> 

The dma heap API itself (what makes it specific to DMA, rather than any
special-purpose allocator?) seems like it could be what we're looking for. 
The issue with drivers/misc/sram.c is that it seems like its main purpose is
to get sram description from the device tree, but this sram isn't static (it's
a reconfiguration of L2 cache into SRAM mode) and thus can't be described by
mmio-sram.

-Scott




Re: [PATCH v2, RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-27 Thread Rob Herring
On Sun, Apr 19, 2020 at 10:06 PM Wang Wenhu  wrote:
>
> A generic User-Kernel interface that allows a misc device created
> by it to support file-operations of ioctl and mmap to access SRAM
> memory from user level. Different kinds of SRAM alloction and free
> APIs could be registered by specific SRAM hardware level driver to
> the available list and then be chosen by users to allocate and map
> SRAM memory from user level.
>
> It is extremely helpful for the user space applications that require
> high performance memory accesses, such as embedded networking devices
> that would process data in user space, and PowerPC e500 is a case.
>
> Signed-off-by: Wang Wenhu 
> Cc: Greg Kroah-Hartman 
> Cc: Arnd Bergmann 
> Cc: Christophe Leroy 
> Cc: Scott Wood 
> Cc: Michael Ellerman 
> Cc: Randy Dunlap 
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> Changes since v1: addressed comments from Arnd
>  * Changed the ioctl cmd definitions using _IO micros
>  * Export interfaces for HW-SRAM drivers to register apis to available list
>  * Modified allocation alignment to PAGE_SIZE
>  * Use phys_addr_t as type of SRAM resource size and offset
>  * Support compat_ioctl
>  * Misc device name:sram
>
> Note: From this on, the SRAM_UAPI driver is independent to any hardware
> drivers, so I would only commit the patch itself as v2, while the v1 of
> it was wrapped together with patches for Freescale L2-Cache-SRAM device.
> Then after, I'd create patches for Freescale L2-Cache-SRAM device as
> another series.

There's work to add SRAM support to dma-buf heaps[1]. Take a look and
see if that works for you.

Rob

[1] https://lore.kernel.org/lkml/20200424222740.16259-1-...@ti.com/


Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-26 Thread Scott Wood
On Tue, 2020-04-21 at 11:34 +0200, Greg KH wrote:
> On Tue, Apr 21, 2020 at 05:09:47PM +0800, 王文虎 wrote:
> > Hi, Greg, Arnd,
> > 
> > Thank you for your comments first, and then really very very very sorry
> > for driving Greg to sigh and I hope there would be chance to share Moutai
> > (rather than whisky, we drink it much, a kind of Baijiu), after the virus.
> > 
> > Back to the comments, I'd like to do a bit of documentation or explanation
> > first,
> > which should have been done early or else there would not be so much to
> > explain:
> > 1. What I have been trying to do is to access the Freescale Cache-SRAM
> > device form
> > user level;
> > 2. I implemented it using UIO, which was thought of non-proper;
> 
> I still think that using uio is the best way to do this, and never said
> it was "non-proper".  All we got bogged down in was the DT
> representation of stuff from what I remember.  That should be worked
> through.

The hardware is already reperesented in the DT (the various "fsl,-l2-
cache-controller" nodes).  What is there to "work through"?

I didn't say UIO was "non-proper" though I did question whether it was the
best fit.  We don't need the IRQ stuff, and we do want some means of
allocating multiple regions to different users (at least, that seems to be a
requirement for Wenhu, and it leaves open the possibility of a kernel driver
allocating some SRAM for itself which appears to be what
arch/powerpc/sysdev/fsl_85xx_cache_sram.c was originally meant for) and I
don't see how you'd do that through UIO.

So that leaves either a separate interface for dynamic region allocation (in
which case why not map through that interface), static allocation via
boot/module parameters which you didn't like, or abusing the device tree with
something that's not hardware description (why don't we replace kmalloc with
some device tree nodes while we're at it).

-Scott




Re:Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-22 Thread 王文虎
>Hi, Scott, Greg,
>
>Thank you for your helpful comments.
>For that Greg mentioned that the patch (or patch series) via UIO should worked 
>through,
>so I want to make it clear that if it would go upstream?(And if so, when? No 
>push, just ask)
>
>Also I have been wondering how the patches with components in different 
>subsystems
>go get upstream to the mainline? Like patch 1-3 are of linuxppc-dev, and patch 
>4 is of
>subsystem UIO, and if acceptable, how would you deal with them?
>
>Back to the devicetree thing, I make it detached from hardware compatibilities 
>which belong
>to the hardware level driver and also used module parameter for of_id 
>definition as dt-binding
>is not allowed for UIO now. So as I can see, things may go well and there is 
>no harm to anything,
>I hope you(Scott) please take a re-consideration. 
>

I mean I have get some new work done based on the comments of Arnd, Scott and 
Greg. Also a lot of tests done.
So it would be better to make it clear whether I shoud keep the work going or 
the UIO version is to be accepted
to go upstream recently in the future.

Thanks & regards,
Wenhu
>
>>On Sun, 2020-04-19 at 20:05 -0700, Wang Wenhu wrote:
>>> +static void sram_uapi_res_insert(struct sram_uapi *uapi,
>>> +struct sram_resource *res)
>>> +{
>>> +   struct sram_resource *cur, *tmp;
>>> +   struct list_head *head = >res_list;
>>> +
>>> +   list_for_each_entry_safe(cur, tmp, head, list) {
>>> +   if (>list != head &&
>>> +   (cur->info.offset + cur->info.size + res->info.size <=
>>> +   tmp->info.offset)) {
>>> +   res->info.offset = cur->info.offset + cur->info.size;
>>> +   res->parent = uapi;
>>> +   list_add(>list, >list);
>>> +   return;
>>> +   }
>>> +   }
>>
>>We don't need yet another open coded allocator.  If you really need to do this
>>then use include/linux/genalloc.h, but maybe keep it simple and just have one
>>allocaton per file descriptor so you don't need to manage fd offsets?
>>
>>> +static struct sram_resource *sram_uapi_find_res(struct sram_uapi *uapi,
>>> +   __u32 offset)
>>> +{
>>> +   struct sram_resource *res;
>>> +
>>> +   list_for_each_entry(res, >res_list, list) {
>>> +   if (res->info.offset == offset)
>>> +   return res;
>>> +   }
>>> +
>>> +   return NULL;
>>> +}
>>
>>What if the allocation is more than one page, and the user mmaps starting
>>somewhere other than the first page?
>>
>>> +   switch (cmd) {
>>> +   case SRAM_UAPI_IOC_SET_SRAM_TYPE:
>>> +   if (uapi->sa)
>>> +   return -EEXIST;
>>> +
>>> +   get_user(type, (const __u32 __user *)arg);
>>> +   uapi->sa = get_sram_api_from_type(type);
>>> +   if (uapi->sa)
>>> +   ret = 0;
>>> +   else
>>> +   ret = -ENODEV;
>>> +
>>> +   break;
>>> +
>>
>>Just expose one device per backing SRAM, especially if the user has any reason
>>to care about where the SRAM is coming from (correlating sysfs nodes is much
>>more expressive than some vague notion of "type").
>>
>>> +   case SRAM_UAPI_IOC_ALLOC:
>>> +   if (!uapi->sa)
>>> +   return -EINVAL;
>>> +
>>> +   res = kzalloc(sizeof(*res), GFP_KERNEL);
>>> +   if (!res)
>>> +   return -ENOMEM;
>>> +
>>> +   size = copy_from_user((void *)>info,
>>> + (const void __user *)arg,
>>> + sizeof(res->info));
>>> +   if (!PAGE_ALIGNED(res->info.size) || !res->info.size)
>>> +   return -EINVAL;
>>
>>Missing EFAULT test (here and elsewhere), and res leaks on error.
>>
>>> +
>>> +   res->virt = (void *)uapi->sa->sram_alloc(res->info.size,
>>> +>phys,
>>> +PAGE_SIZE);
>>
>>Do we really need multiple allocators, or could the backend be limited to just
>>adding regions to a generic allocator (with that allocator also serving in-
>>kernel users)?
>>
>>If sram_alloc is supposed to return a virtual address, why isn't that the
>>return type?
>>
>>> +   if (!res->virt) {
>>> +   kfree(res);
>>> +   return -ENOMEM;
>>> +   }
>>
>>ENOSPC might be more appropriate, as this isn't general-purpose RAM.
>>
>>> +
>>> +   sram_uapi_res_insert(uapi, res);
>>> +   size = copy_to_user((void __user *)arg,
>>> +   (const void *)>info,
>>> +   sizeof(res->info));
>>> +
>>> +   ret = 0;
>>> +   break;
>>> +
>>> +   case SRAM_UAPI_IOC_FREE:
>>> +   if (!uapi->sa)
>>> +   return -EINVAL;
>>> +
>>> +   size = copy_from_user((void *), (const void __user *)arg,
>>> + 

Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-22 Thread 王文虎
Hi, Scott, Greg,

Thank you for your helpful comments.
For that Greg mentioned that the patch (or patch series) via UIO should worked 
through,
so I want to make it clear that if it would go upstream?(And if so, when? No 
push, just ask)

Also I have been wondering how the patches with components in different 
subsystems
go get upstream to the mainline? Like patch 1-3 are of linuxppc-dev, and patch 
4 is of
subsystem UIO, and if acceptable, how would you deal with them?

Back to the devicetree thing, I make it detached from hardware compatibilities 
which belong
to the hardware level driver and also used module parameter for of_id 
definition as dt-binding
is not allowed for UIO now. So as I can see, things may go well and there is no 
harm to anything,
I hope you(Scott) please take a re-consideration. 

Thanks & regards,
Wenhu

>On Sun, 2020-04-19 at 20:05 -0700, Wang Wenhu wrote:
>> +static void sram_uapi_res_insert(struct sram_uapi *uapi,
>> + struct sram_resource *res)
>> +{
>> +struct sram_resource *cur, *tmp;
>> +struct list_head *head = >res_list;
>> +
>> +list_for_each_entry_safe(cur, tmp, head, list) {
>> +if (>list != head &&
>> +(cur->info.offset + cur->info.size + res->info.size <=
>> +tmp->info.offset)) {
>> +res->info.offset = cur->info.offset + cur->info.size;
>> +res->parent = uapi;
>> +list_add(>list, >list);
>> +return;
>> +}
>> +}
>
>We don't need yet another open coded allocator.  If you really need to do this
>then use include/linux/genalloc.h, but maybe keep it simple and just have one
>allocaton per file descriptor so you don't need to manage fd offsets?
>
>> +static struct sram_resource *sram_uapi_find_res(struct sram_uapi *uapi,
>> +__u32 offset)
>> +{
>> +struct sram_resource *res;
>> +
>> +list_for_each_entry(res, >res_list, list) {
>> +if (res->info.offset == offset)
>> +return res;
>> +}
>> +
>> +return NULL;
>> +}
>
>What if the allocation is more than one page, and the user mmaps starting
>somewhere other than the first page?
>
>> +switch (cmd) {
>> +case SRAM_UAPI_IOC_SET_SRAM_TYPE:
>> +if (uapi->sa)
>> +return -EEXIST;
>> +
>> +get_user(type, (const __u32 __user *)arg);
>> +uapi->sa = get_sram_api_from_type(type);
>> +if (uapi->sa)
>> +ret = 0;
>> +else
>> +ret = -ENODEV;
>> +
>> +break;
>> +
>
>Just expose one device per backing SRAM, especially if the user has any reason
>to care about where the SRAM is coming from (correlating sysfs nodes is much
>more expressive than some vague notion of "type").
>
>> +case SRAM_UAPI_IOC_ALLOC:
>> +if (!uapi->sa)
>> +return -EINVAL;
>> +
>> +res = kzalloc(sizeof(*res), GFP_KERNEL);
>> +if (!res)
>> +return -ENOMEM;
>> +
>> +size = copy_from_user((void *)>info,
>> +  (const void __user *)arg,
>> +  sizeof(res->info));
>> +if (!PAGE_ALIGNED(res->info.size) || !res->info.size)
>> +return -EINVAL;
>
>Missing EFAULT test (here and elsewhere), and res leaks on error.
>
>> +
>> +res->virt = (void *)uapi->sa->sram_alloc(res->info.size,
>> + >phys,
>> + PAGE_SIZE);
>
>Do we really need multiple allocators, or could the backend be limited to just
>adding regions to a generic allocator (with that allocator also serving in-
>kernel users)?
>
>If sram_alloc is supposed to return a virtual address, why isn't that the
>return type?
>
>> +if (!res->virt) {
>> +kfree(res);
>> +return -ENOMEM;
>> +}
>
>ENOSPC might be more appropriate, as this isn't general-purpose RAM.
>
>> +
>> +sram_uapi_res_insert(uapi, res);
>> +size = copy_to_user((void __user *)arg,
>> +(const void *)>info,
>> +sizeof(res->info));
>> +
>> +ret = 0;
>> +break;
>> +
>> +case SRAM_UAPI_IOC_FREE:
>> +if (!uapi->sa)
>> +return -EINVAL;
>> +
>> +size = copy_from_user((void *), (const void __user *)arg,
>> +  sizeof(info));
>> +
>> +res = sram_uapi_res_delete(uapi, );
>> +if (!res) {
>> +pr_err("error no sram resource found\n");
>> +return -EINVAL;
>> +}
>> +
>> +uapi->sa->sram_free(res->virt);
>> +kfree(res);
>> +
>> +ret 

Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-21 Thread 王文虎
>On Tue, Apr 21, 2020 at 05:09:47PM +0800, 王文虎 wrote:
>> Hi, Greg, Arnd,
>> 
>> Thank you for your comments first, and then really very very very sorry
>> for driving Greg to sigh and I hope there would be chance to share Moutai
>> (rather than whisky, we drink it much, a kind of Baijiu), after the virus.
>> 
>> Back to the comments, I'd like to do a bit of documentation or explanation 
>> first,
>> which should have been done early or else there would not be so much to 
>> explain:
>> 1. What I have been trying to do is to access the Freescale Cache-SRAM 
>> device form
>> user level;
>> 2. I implemented it using UIO, which was thought of non-proper;
>
>I still think that using uio is the best way to do this, and never said
>it was "non-proper".  All we got bogged down in was the DT
>representation of stuff from what I remember.  That should be worked
>through.
>
>thanks,
>
>greg k-h

Surely, but so how would things go? Scott said not fit for him. And he was
gonna to write a new patch(Oh,  that is what I have been doing.,and I really
donot think he need to do it)

This is the final version using UIO, and even Christophe had Reviewed-by,
https://lore.kernel.org/patchwork/patch/1226225/

If no ending reaches, I have to make a step forward to keep working with
the misc device version.

Thanks, and regards,
Wenhu




Re: [PATCH v2, RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-21 Thread Greg KH
On Tue, Apr 21, 2020 at 05:09:47PM +0800, 王文虎 wrote:
> Hi, Greg, Arnd,
> 
> Thank you for your comments first, and then really very very very sorry
> for driving Greg to sigh and I hope there would be chance to share Moutai
> (rather than whisky, we drink it much, a kind of Baijiu), after the virus.
> 
> Back to the comments, I'd like to do a bit of documentation or explanation 
> first,
> which should have been done early or else there would not be so much to 
> explain:
> 1. What I have been trying to do is to access the Freescale Cache-SRAM device 
> form
> user level;
> 2. I implemented it using UIO, which was thought of non-proper;

I still think that using uio is the best way to do this, and never said
it was "non-proper".  All we got bogged down in was the DT
representation of stuff from what I remember.  That should be worked
through.

thanks,

greg k-h


Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-21 Thread 王文虎
Hi, Greg, Arnd,

Thank you for your comments first, and then really very very very sorry
for driving Greg to sigh and I hope there would be chance to share Moutai
(rather than whisky, we drink it much, a kind of Baijiu), after the virus.

Back to the comments, I'd like to do a bit of documentation or explanation 
first,
which should have been done early or else there would not be so much to explain:
1. What I have been trying to do is to access the Freescale Cache-SRAM device 
form
user level;
2. I implemented it using UIO, which was thought of non-proper;
3. So I implemented it here to create a misc device as a interface between 
Kernel
and user space applications, as the comments of Scott suggested;
[Link for 2 & 3: https://lore.kernel.org/patchwork/patch/1225798/]
4. This is exactly a shim of Cache-SRAM hardware level driver, and it would use
apis provided by the hardware driver to do the allocation and free work of
SRAM memory;
5. The file drivers/misc/sram.c actually has done some abstractions for SRAM 
access,
but it is used as a static way that resources are defined within devicetree;
6. This patch is to reach a way that allocate and release SRAM memory 
dynamically
which is much more convenient for user space applications, and for another 
reason,
the Cache-SRAM of Freescale is kind of not compatible with drivers/misc/sram.c;

So I implemented the sram_uapi.c as following:
1. Create a misc device as a interface that support ioctl and mmap for memory 
access;
2. For that I think this could be used for any SRAM devices that would support 
dynamic
memory allocation and release, I create sram_api_list as follow:

static DEFINE_MUTEX(sram_api_list_lock);
static LIST_HEAD(sram_api_list);

and different SRAM devices could add their apis to the sram_api_list
which could be used for the allocation from them;
a. int sram_api_register(struct sram_api *sa);
b. int sram_api_unregister(struct sram_api *sa);
c. ioctl case SRAM_UAPI_IOC_SET_SRAM_TYPE;
the register and unregister api are exported for any SRAM drivers to do this,
and maybe user could chose one with ioctl to allocate;
[maybe only one SRAM device available currently and the implementation is 
redundant]
3. For each fd that opened, a sram_uapi would be created:

struct sram_uapi {
struct list_headres_list;
struct sram_api *sa;
};

The res_list would be a list of resources that allocated attached to it:

struct sram_resource {
struct list_headlist;
struct res_info info;
phys_addr_t phys;
void*virt;
struct vm_area_struct   *vma;
struct sram_uapi*parent;
};

The sa is a pointer to the apis registered by hardware SRAM driver as descibed 
earlier,
and when a fd is attached to it, kref it once;
And for the resources, it is accessed by the process only so I did not use a 
lock here,
and as Greg commented, lock is needed for the fd sharement.
4. The exported apis are currently not reference and I would add another patch 
series
for Freescale Cache-SRAM to use the api sram_api_register to register its 
allocation
and free api, as well as sram_api_unregister for unregistering;

Actually, I implemented the api list another way in v1, but was commented by 
Arnd not a
better way.
[https://lore.kernel.org/patchwork/patch/1226689/]

Then for the comments:
1. Ioctl: I will move the block to uapi, and use static length definition of 
__be64;
2. Naming: as Greg commented, so hard, and how do you think of
sram_dynamic(as compared to drivers/misc/sram.c)?
3. API list: only one SRAM device? But however, this is a shim, and hardware 
level
SRAM driver(s) should be enabled to register or init the apis for real 
allocation;
4. Test: My team and me myself did not cover it, especially newly added kref, 
and that
is really really so wrong of us, and I will make efforts to test for every 
logical path
next time, and this would never ever happen. Really sorry for it.

>On Sun, Apr 19, 2020 at 08:05:38PM -0700, Wang Wenhu wrote:
>> A generic User-Kernel interface that allows a misc device created
>> by it to support file-operations of ioctl and mmap to access SRAM
>> memory from user level. Different kinds of SRAM alloction and free
>> APIs could be registered by specific SRAM hardware level driver to
>> the available list and then be chosen by users to allocate and map
>> SRAM memory from user level.
>> 
>> It is extremely helpful for the user space applications that require
>> high performance memory accesses, such as embedded networking devices
>> that would process data in user space, and PowerPC e500 is a case.
>> 
>> Signed-off-by: Wang Wenhu 
>> Cc: Greg Kroah-Hartman 
>> Cc: Arnd Bergmann 
>> Cc: Christophe Leroy 
>> Cc: Scott Wood 
>> Cc: Michael Ellerman 
>> Cc: Randy Dunlap 
>> Cc: 

Re: [PATCH v2,RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-21 Thread Scott Wood
On Sun, 2020-04-19 at 20:05 -0700, Wang Wenhu wrote:
> +static void sram_uapi_res_insert(struct sram_uapi *uapi,
> +  struct sram_resource *res)
> +{
> + struct sram_resource *cur, *tmp;
> + struct list_head *head = >res_list;
> +
> + list_for_each_entry_safe(cur, tmp, head, list) {
> + if (>list != head &&
> + (cur->info.offset + cur->info.size + res->info.size <=
> + tmp->info.offset)) {
> + res->info.offset = cur->info.offset + cur->info.size;
> + res->parent = uapi;
> + list_add(>list, >list);
> + return;
> + }
> + }

We don't need yet another open coded allocator.  If you really need to do this
then use include/linux/genalloc.h, but maybe keep it simple and just have one
allocaton per file descriptor so you don't need to manage fd offsets?

> +static struct sram_resource *sram_uapi_find_res(struct sram_uapi *uapi,
> + __u32 offset)
> +{
> + struct sram_resource *res;
> +
> + list_for_each_entry(res, >res_list, list) {
> + if (res->info.offset == offset)
> + return res;
> + }
> +
> + return NULL;
> +}

What if the allocation is more than one page, and the user mmaps starting
somewhere other than the first page?

> + switch (cmd) {
> + case SRAM_UAPI_IOC_SET_SRAM_TYPE:
> + if (uapi->sa)
> + return -EEXIST;
> +
> + get_user(type, (const __u32 __user *)arg);
> + uapi->sa = get_sram_api_from_type(type);
> + if (uapi->sa)
> + ret = 0;
> + else
> + ret = -ENODEV;
> +
> + break;
> +

Just expose one device per backing SRAM, especially if the user has any reason
to care about where the SRAM is coming from (correlating sysfs nodes is much
more expressive than some vague notion of "type").

> + case SRAM_UAPI_IOC_ALLOC:
> + if (!uapi->sa)
> + return -EINVAL;
> +
> + res = kzalloc(sizeof(*res), GFP_KERNEL);
> + if (!res)
> + return -ENOMEM;
> +
> + size = copy_from_user((void *)>info,
> +   (const void __user *)arg,
> +   sizeof(res->info));
> + if (!PAGE_ALIGNED(res->info.size) || !res->info.size)
> + return -EINVAL;

Missing EFAULT test (here and elsewhere), and res leaks on error.

> +
> + res->virt = (void *)uapi->sa->sram_alloc(res->info.size,
> +  >phys,
> +  PAGE_SIZE);

Do we really need multiple allocators, or could the backend be limited to just
adding regions to a generic allocator (with that allocator also serving in-
kernel users)?

If sram_alloc is supposed to return a virtual address, why isn't that the
return type?

> + if (!res->virt) {
> + kfree(res);
> + return -ENOMEM;
> + }

ENOSPC might be more appropriate, as this isn't general-purpose RAM.

> +
> + sram_uapi_res_insert(uapi, res);
> + size = copy_to_user((void __user *)arg,
> + (const void *)>info,
> + sizeof(res->info));
> +
> + ret = 0;
> + break;
> +
> + case SRAM_UAPI_IOC_FREE:
> + if (!uapi->sa)
> + return -EINVAL;
> +
> + size = copy_from_user((void *), (const void __user *)arg,
> +   sizeof(info));
> +
> + res = sram_uapi_res_delete(uapi, );
> + if (!res) {
> + pr_err("error no sram resource found\n");
> + return -EINVAL;
> + }
> +
> + uapi->sa->sram_free(res->virt);
> + kfree(res);
> +
> + ret = 0;
> + break;

So you can just delete any arbitrary offset, even if you weren't the one that
allocated it?  Even if this isn't meant for unprivileged use it seems error-
prone.  

> +
> + default:
> + pr_err("error no cmd not supported\n");
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static int sram_uapi_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> + struct sram_uapi *uapi = filp->private_data;
> + struct sram_resource *res;
> +
> + res = sram_uapi_find_res(uapi, vma->vm_pgoff);
> + if (!res)
> + return -EINVAL;
> +
> + if (vma->vm_end - vma->vm_start > res->info.size)
> + return -EINVAL;
> +
> + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +
> + return remap_pfn_range(vma, vma->vm_start,
> +res->phys >> PAGE_SHIFT,
> 

Re: [PATCH v2, RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-20 Thread Greg KH
On Sun, Apr 19, 2020 at 08:05:38PM -0700, Wang Wenhu wrote:
> A generic User-Kernel interface that allows a misc device created
> by it to support file-operations of ioctl and mmap to access SRAM
> memory from user level. Different kinds of SRAM alloction and free
> APIs could be registered by specific SRAM hardware level driver to
> the available list and then be chosen by users to allocate and map
> SRAM memory from user level.
> 
> It is extremely helpful for the user space applications that require
> high performance memory accesses, such as embedded networking devices
> that would process data in user space, and PowerPC e500 is a case.
> 
> Signed-off-by: Wang Wenhu 
> Cc: Greg Kroah-Hartman 
> Cc: Arnd Bergmann 
> Cc: Christophe Leroy 
> Cc: Scott Wood 
> Cc: Michael Ellerman 
> Cc: Randy Dunlap 
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> Changes since v1: addressed comments from Arnd
>  * Changed the ioctl cmd definitions using _IO micros
>  * Export interfaces for HW-SRAM drivers to register apis to available list
>  * Modified allocation alignment to PAGE_SIZE
>  * Use phys_addr_t as type of SRAM resource size and offset
>  * Support compat_ioctl
>  * Misc device name:sram
> 
> Note: From this on, the SRAM_UAPI driver is independent to any hardware
> drivers, so I would only commit the patch itself as v2, while the v1 of
> it was wrapped together with patches for Freescale L2-Cache-SRAM device.
> Then after, I'd create patches for Freescale L2-Cache-SRAM device as
> another series.
> 
> Link for v1:
>  * https://lore.kernel.org/lkml/20200418162157.50428-5-wenhu.w...@vivo.com/

Why was this a RESEND?  What was wrong with the original v2 version?

Anyway, minor review comments:

> ---
>  drivers/misc/Kconfig  |  11 ++
>  drivers/misc/Makefile |   1 +
>  drivers/misc/sram_uapi.c  | 352 ++
>  include/linux/sram_uapi.h |  28 +++
>  4 files changed, 392 insertions(+)
>  create mode 100644 drivers/misc/sram_uapi.c
>  create mode 100644 include/linux/sram_uapi.h
> 
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 99e151475d8f..b19c8b24f18e 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -465,6 +465,17 @@ config PVPANIC
> a paravirtualized device provided by QEMU; it lets a virtual machine
> (guest) communicate panic events to the host.
>  
> +config SRAM_UAPI
> + bool "Generic SRAM User Level API driver"
> + help
> +   This driver allows you to create a misc device which could be used
> +   as an interface to allocate SRAM memory from user level.
> +
> +   It is extremely helpful for some user space applications that require
> +   high performance memory accesses.
> +
> +   If unsure, say N.

Naming is hard, but shouldn't this just be "sram" and drop the whole
"UAPI" stuff everywhere?  That doesn't make much sense as drivers are
just interfaces to userspace...


> +
>  source "drivers/misc/c2port/Kconfig"
>  source "drivers/misc/eeprom/Kconfig"
>  source "drivers/misc/cb710/Kconfig"
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 9abf2923d831..794447ca07ca 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -46,6 +46,7 @@ obj-$(CONFIG_VMWARE_VMCI)   += vmw_vmci/
>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)+= lattice-ecp3-config.o
>  obj-$(CONFIG_SRAM)   += sram.o
>  obj-$(CONFIG_SRAM_EXEC)  += sram-exec.o
> +obj-$(CONFIG_SRAM_UAPI)  += sram_uapi.o
>  obj-y+= mic/
>  obj-$(CONFIG_GENWQE) += genwqe/
>  obj-$(CONFIG_ECHO)   += echo/
> diff --git a/drivers/misc/sram_uapi.c b/drivers/misc/sram_uapi.c
> new file mode 100644
> index ..66c7b56b635f
> --- /dev/null
> +++ b/drivers/misc/sram_uapi.c
> @@ -0,0 +1,352 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
> + * Copyright (C) 2020 Wang Wenhu 
> + * All rights reserved.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DRIVER_NAME  "sram_uapi"

If you really need this, just use KBUILD_MODNAME instead.  But I don't
think you need it, as most drivers do not.


> +
> +struct res_info {
> + phys_addr_t offset;
> + phys_addr_t size;
> +};
> +
> +struct sram_resource {
> + struct list_headlist;
> + struct res_info info;
> + phys_addr_t phys;
> + void*virt;
> + struct vm_area_struct   *vma;
> + struct sram_uapi*parent;
> +};
> +
> +struct sram_uapi {
> + struct list_headres_list;
> + struct sram_api *sa;
> +};
> +
> +static DEFINE_MUTEX(sram_api_list_lock);
> +static LIST_HEAD(sram_api_list);
> +
> +long sram_api_register(struct sram_api *sa)

Why are all of these functions global?

And shouldn't this return an 'int'?

> +{
> + struct sram_api *cur;
> +
> +  

Re: [PATCH v2, RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-20 Thread Arnd Bergmann
On Mon, Apr 20, 2020 at 5:06 AM Wang Wenhu  wrote:
>
> A generic User-Kernel interface that allows a misc device created
> by it to support file-operations of ioctl and mmap to access SRAM
> memory from user level. Different kinds of SRAM alloction and free
> APIs could be registered by specific SRAM hardware level driver to
> the available list and then be chosen by users to allocate and map
> SRAM memory from user level.
>
> It is extremely helpful for the user space applications that require
> high performance memory accesses, such as embedded networking devices
> that would process data in user space, and PowerPC e500 is a case.
>
> Signed-off-by: Wang Wenhu 
> Cc: Greg Kroah-Hartman 
> Cc: Arnd Bergmann 
> Cc: Christophe Leroy 
> Cc: Scott Wood 
> Cc: Michael Ellerman 
> Cc: Randy Dunlap 
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> Changes since v1: addressed comments from Arnd
>  * Changed the ioctl cmd definitions using _IO micros
>  * Export interfaces for HW-SRAM drivers to register apis to available list
>  * Modified allocation alignment to PAGE_SIZE
>  * Use phys_addr_t as type of SRAM resource size and offset
>  * Support compat_ioctl
>  * Misc device name:sram

Looks much better already.

> Note: From this on, the SRAM_UAPI driver is independent to any hardware
> drivers, so I would only commit the patch itself as v2, while the v1 of
> it was wrapped together with patches for Freescale L2-Cache-SRAM device.
> Then after, I'd create patches for Freescale L2-Cache-SRAM device as
> another series.

What I meant to suggest was actually to tie it more closely to
the code we already have in drivers/misc/sram.c, which already
has some form of abstraction.

> +static int __init sram_uapi_init(void)
> +{
> +   int ret;
> +
> +   INIT_LIST_HEAD(_api_list);
> +   mutex_init(_api_list_lock);
> +
> +   ret = misc_register(_uapi_miscdev);
> +   if (ret)
> +   pr_err("failed to register sram uapi misc device\n");

The mutex and listhead are already initialized, so this can
be a one-line function

return misc_register(_uapi_miscdev);

> --- /dev/null
> +++ b/include/linux/sram_uapi.h

The ioctl definitions need to be in include/uapi/linux/

> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __SRAM_UAPI_H
> +#define __SRAM_UAPI_H
> +
> +/* Set SRAM type to be accessed */
> +#define SRAM_UAPI_IOC_SET_SRAM_TYPE_IOW('S', 0, __u32)
> +
> +/* Allocate resource from SRAM */
> +#define SRAM_UAPI_IOC_ALLOC_IOWR('S', 1, struct res_info)
> +
> +/* Free allocated resource of SRAM */
> +#define SRAM_UAPI_IOC_FREE _IOW('S', 2, struct res_info)

struct res_info needs to also be defined here, so user applications can
see the definition, and it has to use __u64, not phys_addr_t, to ensure
the API does not depend on kernel configuraiton.

Arnd


[PATCH v2, RESEND] misc: new driver sram_uapi for user level SRAM access

2020-04-19 Thread Wang Wenhu
A generic User-Kernel interface that allows a misc device created
by it to support file-operations of ioctl and mmap to access SRAM
memory from user level. Different kinds of SRAM alloction and free
APIs could be registered by specific SRAM hardware level driver to
the available list and then be chosen by users to allocate and map
SRAM memory from user level.

It is extremely helpful for the user space applications that require
high performance memory accesses, such as embedded networking devices
that would process data in user space, and PowerPC e500 is a case.

Signed-off-by: Wang Wenhu 
Cc: Greg Kroah-Hartman 
Cc: Arnd Bergmann 
Cc: Christophe Leroy 
Cc: Scott Wood 
Cc: Michael Ellerman 
Cc: Randy Dunlap 
Cc: linuxppc-dev@lists.ozlabs.org
---
Changes since v1: addressed comments from Arnd
 * Changed the ioctl cmd definitions using _IO micros
 * Export interfaces for HW-SRAM drivers to register apis to available list
 * Modified allocation alignment to PAGE_SIZE
 * Use phys_addr_t as type of SRAM resource size and offset
 * Support compat_ioctl
 * Misc device name:sram

Note: From this on, the SRAM_UAPI driver is independent to any hardware
drivers, so I would only commit the patch itself as v2, while the v1 of
it was wrapped together with patches for Freescale L2-Cache-SRAM device.
Then after, I'd create patches for Freescale L2-Cache-SRAM device as
another series.

Link for v1:
 * https://lore.kernel.org/lkml/20200418162157.50428-5-wenhu.w...@vivo.com/
---
 drivers/misc/Kconfig  |  11 ++
 drivers/misc/Makefile |   1 +
 drivers/misc/sram_uapi.c  | 352 ++
 include/linux/sram_uapi.h |  28 +++
 4 files changed, 392 insertions(+)
 create mode 100644 drivers/misc/sram_uapi.c
 create mode 100644 include/linux/sram_uapi.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 99e151475d8f..b19c8b24f18e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -465,6 +465,17 @@ config PVPANIC
  a paravirtualized device provided by QEMU; it lets a virtual machine
  (guest) communicate panic events to the host.
 
+config SRAM_UAPI
+   bool "Generic SRAM User Level API driver"
+   help
+ This driver allows you to create a misc device which could be used
+ as an interface to allocate SRAM memory from user level.
+
+ It is extremely helpful for some user space applications that require
+ high performance memory accesses.
+
+ If unsure, say N.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9abf2923d831..794447ca07ca 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)  += lattice-ecp3-config.o
 obj-$(CONFIG_SRAM) += sram.o
 obj-$(CONFIG_SRAM_EXEC)+= sram-exec.o
+obj-$(CONFIG_SRAM_UAPI)+= sram_uapi.o
 obj-y  += mic/
 obj-$(CONFIG_GENWQE)   += genwqe/
 obj-$(CONFIG_ECHO) += echo/
diff --git a/drivers/misc/sram_uapi.c b/drivers/misc/sram_uapi.c
new file mode 100644
index ..66c7b56b635f
--- /dev/null
+++ b/drivers/misc/sram_uapi.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Vivo Communication Technology Co. Ltd.
+ * Copyright (C) 2020 Wang Wenhu 
+ * All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRIVER_NAME"sram_uapi"
+
+struct res_info {
+   phys_addr_t offset;
+   phys_addr_t size;
+};
+
+struct sram_resource {
+   struct list_headlist;
+   struct res_info info;
+   phys_addr_t phys;
+   void*virt;
+   struct vm_area_struct   *vma;
+   struct sram_uapi*parent;
+};
+
+struct sram_uapi {
+   struct list_headres_list;
+   struct sram_api *sa;
+};
+
+static DEFINE_MUTEX(sram_api_list_lock);
+static LIST_HEAD(sram_api_list);
+
+long sram_api_register(struct sram_api *sa)
+{
+   struct sram_api *cur;
+
+   if (!sa || !sa->name || !sa->sram_alloc || !sa->sram_free)
+   return -EINVAL;
+
+   mutex_lock(_api_list_lock);
+   list_for_each_entry(cur, _api_list, list) {
+   if (cur->type == sa->type) {
+   pr_err("error sram %s type %d exists\n", sa->name,
+  sa->type);
+   mutex_unlock(_api_list_lock);
+   return -EEXIST;
+   }
+   }
+
+   kref_init(>kref);
+   list_add_tail(>list, _api_list);
+   pr_info("sram %s type %d registered\n", sa->name, sa->type);
+
+   mutex_unlock(_api_list_lock);
+
+   return 0;
+};
+EXPORT_SYMBOL(sram_api_register);
+
+long sram_api_unregister(struct