[PATCH v10 2/4] uacce: add uacce driver
zhangfei.gao at foxmail.com
zhangfei.gao at foxmail.com
Fri Jan 10 17:55:39 AEDT 2020
On 2020/1/10 上午1:38, Jonathan Cameron wrote:
> On Mon, 16 Dec 2019 11:08:15 +0800
> Zhangfei Gao <zhangfei.gao at linaro.org> wrote:
>
>> From: Kenneth Lee <liguozhu at hisilicon.com>
>>
>> Uacce (Unified/User-space-access-intended Accelerator Framework) targets to
>> provide Shared Virtual Addressing (SVA) between accelerators and processes.
>> So accelerator can access any data structure of the main cpu.
>> This differs from the data sharing between cpu and io device, which share
>> only data content rather than address.
>> Since unified address, hardware and user space of process can share the
>> same virtual address in the communication.
>>
>> Uacce create a chrdev for every registration, the queue is allocated to
>> the process when the chrdev is opened. Then the process can access the
>> hardware resource by interact with the queue file. By mmap the queue
>> file space to user space, the process can directly put requests to the
>> hardware without syscall to the kernel space.
>>
>> The IOMMU core only tracks mm<->device bonds at the moment, because it
>> only needs to handle IOTLB invalidation and PASID table entries. However
>> uacce needs a finer granularity since multiple queues from the same
>> device can be bound to an mm. When the mm exits, all bound queues must
>> be stopped so that the IOMMU can safely clear the PASID table entry and
>> reallocate the PASID.
>>
>> An intermediate struct uacce_mm links uacce devices and queues.
>> Note that an mm may be bound to multiple devices but an uacce_mm
>> structure only ever belongs to a single device, because we don't need
>> anything more complex (if multiple devices are bound to one mm, then
>> we'll create one uacce_mm for each bond).
>>
>> uacce_device --+-- uacce_mm --+-- uacce_queue
>> | '-- uacce_queue
>> |
>> '-- uacce_mm --+-- uacce_queue
>> +-- uacce_queue
>> '-- uacce_queue
>>
>> Signed-off-by: Kenneth Lee <liguozhu at hisilicon.com>
>> Signed-off-by: Zaibo Xu <xuzaibo at huawei.com>
>> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
>> Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao at linaro.org>
> Hi,
>
> Two small things I'd missed previously. Fix those and for
> what it's worth
>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Thanks Jonathan
>
>> ---
>> Documentation/ABI/testing/sysfs-driver-uacce | 37 ++
>> drivers/misc/Kconfig | 1 +
>> drivers/misc/Makefile | 1 +
>> drivers/misc/uacce/Kconfig | 13 +
>> drivers/misc/uacce/Makefile | 2 +
>> drivers/misc/uacce/uacce.c | 628 +++++++++++++++++++++++++++
>> include/linux/uacce.h | 161 +++++++
>> include/uapi/misc/uacce/uacce.h | 38 ++
>> 8 files changed, 881 insertions(+)
>> create mode 100644 Documentation/ABI/testing/sysfs-driver-uacce
>> create mode 100644 drivers/misc/uacce/Kconfig
>> create mode 100644 drivers/misc/uacce/Makefile
>> create mode 100644 drivers/misc/uacce/uacce.c
>> create mode 100644 include/linux/uacce.h
>> create mode 100644 include/uapi/misc/uacce/uacce.h
>>
> ...
>> +
>> +What: /sys/class/uacce/<dev_name>/available_instances
>> +Date: Dec 2019
>> +KernelVersion: 5.6
>> +Contact: linux-accelerators at lists.ozlabs.org
>> +Description: Available instances left of the device
>> + Return -ENODEV if uacce_ops get_available_instances is not provided
>> +
> See below. It doesn't "return" it prints it currently.
Will update to
'unknown' if uacce_ops get_available_instances is not provided
>
> ...
>
>> +static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma)
>> +{
>> + struct uacce_queue *q = filep->private_data;
>> + struct uacce_device *uacce = q->uacce;
>> + struct uacce_qfile_region *qfr;
>> + enum uacce_qfrt type = UACCE_MAX_REGION;
>> + int ret = 0;
>> +
>> + if (vma->vm_pgoff < UACCE_MAX_REGION)
>> + type = vma->vm_pgoff;
>> + else
>> + return -EINVAL;
>> +
>> + qfr = kzalloc(sizeof(*qfr), GFP_KERNEL);
>> + if (!qfr)
>> + return -ENOMEM;
>> +
>> + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK;
>> + vma->vm_ops = &uacce_vm_ops;
>> + vma->vm_private_data = q;
>> + qfr->type = type;
>> +
>> + mutex_lock(&uacce_mutex);
>> +
>> + if (q->state != UACCE_Q_INIT && q->state != UACCE_Q_STARTED) {
>> + ret = -EINVAL;
>> + goto out_with_lock;
>> + }
>> +
>> + if (q->qfrs[type]) {
>> + ret = -EEXIST;
>> + goto out_with_lock;
>> + }
>> +
>> + switch (type) {
>> + case UACCE_QFRT_MMIO:
>> + if (!uacce->ops->mmap) {
>> + ret = -EINVAL;
>> + goto out_with_lock;
>> + }
>> +
>> + ret = uacce->ops->mmap(q, vma, qfr);
>> + if (ret)
>> + goto out_with_lock;
>> +
>> + break;
>> +
>> + case UACCE_QFRT_DUS:
>> + if (uacce->flags & UACCE_DEV_SVA) {
>> + if (!uacce->ops->mmap) {
>> + ret = -EINVAL;
>> + goto out_with_lock;
>> + }
>> +
>> + ret = uacce->ops->mmap(q, vma, qfr);
>> + if (ret)
>> + goto out_with_lock;
>> + }
> Slightly odd corner case, but what stops us getting here with
> the UACCE_DEV_SVA flag not set? If that happened I'd expect to
> return an error but looks like we return 0.
The check with flag UACCE_DEV_SVA can be removed here, non-sva also has
dus region.
We have removed the check when we add non-sva support.
> ...
>
>> +static ssize_t available_instances_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct uacce_device *uacce = to_uacce_device(dev);
>> + int val = -ENODEV;
>> +
>> + if (uacce->ops->get_available_instances)
>> + val = uacce->ops->get_available_instances(uacce);
>> +
>> + return sprintf(buf, "%d\n", val);
> It's unusual to pass an error value back as a string.
> I'd expect some logic like..
>
> if (val < 0)
> return val;
>
> return sprintf(buf, "%d\n", val);
>
> Note this is the documented behavior "returns -ENODEV".
If return -ENODEV,
cat /sys/class/uacce/hisi_zip-0/available_instances
cat: /sys/class/uacce/hisi_zip-0/available_instances: No such device
I think print "unknown" maybe better, like cpufreq.c
if (uacce->ops->get_available_instances)
return sprintf(buf, "%d\n",
uacce->ops->get_available_instances(uacce));
return sprintf(buf, "unknown\n");
Thanks
More information about the Linux-accelerators
mailing list