Commit 54303a1a authored by Oded Gabbay's avatar Oded Gabbay

habanalabs: split mmu/no-mmu code paths in memory ioctl

To make the memory ioctl code more readable, this patch moves the
legacy/debug code path of mmu-disabled to a separate function, which is
called (if necessary) from the main memory ioctl function.
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 29593840
...@@ -1090,6 +1090,64 @@ static int unmap_device_va(struct hl_ctx *ctx, u64 vaddr) ...@@ -1090,6 +1090,64 @@ static int unmap_device_va(struct hl_ctx *ctx, u64 vaddr)
return rc; return rc;
} }
static int mem_ioctl_no_mmu(struct hl_fpriv *hpriv, union hl_mem_args *args)
{
struct hl_device *hdev = hpriv->hdev;
struct hl_ctx *ctx = hpriv->ctx;
u64 device_addr = 0;
u32 handle = 0;
int rc;
switch (args->in.op) {
case HL_MEM_OP_ALLOC:
if (args->in.alloc.mem_size == 0) {
dev_err(hdev->dev,
"alloc size must be larger than 0\n");
rc = -EINVAL;
goto out;
}
/* Force contiguous as there are no real MMU
* translations to overcome physical memory gaps
*/
args->in.flags |= HL_MEM_CONTIGUOUS;
rc = alloc_device_memory(ctx, &args->in, &handle);
memset(args, 0, sizeof(*args));
args->out.handle = (__u64) handle;
break;
case HL_MEM_OP_FREE:
rc = free_device_memory(ctx, args->in.free.handle);
break;
case HL_MEM_OP_MAP:
if (args->in.flags & HL_MEM_USERPTR) {
device_addr = args->in.map_host.host_virt_addr;
rc = 0;
} else {
rc = get_paddr_from_handle(ctx, &args->in,
&device_addr);
}
memset(args, 0, sizeof(*args));
args->out.device_virt_addr = device_addr;
break;
case HL_MEM_OP_UNMAP:
rc = 0;
break;
default:
dev_err(hdev->dev, "Unknown opcode for memory IOCTL\n");
rc = -ENOTTY;
break;
}
out:
return rc;
}
int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data)
{ {
union hl_mem_args *args = data; union hl_mem_args *args = data;
...@@ -1105,100 +1163,49 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) ...@@ -1105,100 +1163,49 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data)
return -EBUSY; return -EBUSY;
} }
if (hdev->mmu_enable) { if (!hdev->mmu_enable)
switch (args->in.op) { return mem_ioctl_no_mmu(hpriv, args);
case HL_MEM_OP_ALLOC:
if (!hdev->dram_supports_virtual_memory) {
dev_err(hdev->dev,
"DRAM alloc is not supported\n");
rc = -EINVAL;
goto out;
}
if (args->in.alloc.mem_size == 0) {
dev_err(hdev->dev,
"alloc size must be larger than 0\n");
rc = -EINVAL;
goto out;
}
rc = alloc_device_memory(ctx, &args->in, &handle);
memset(args, 0, sizeof(*args));
args->out.handle = (__u64) handle;
break;
case HL_MEM_OP_FREE:
if (!hdev->dram_supports_virtual_memory) {
dev_err(hdev->dev,
"DRAM free is not supported\n");
rc = -EINVAL;
goto out;
}
rc = free_device_memory(ctx, args->in.free.handle);
break;
case HL_MEM_OP_MAP:
rc = map_device_va(ctx, &args->in, &device_addr);
memset(args, 0, sizeof(*args));
args->out.device_virt_addr = device_addr;
break;
case HL_MEM_OP_UNMAP: switch (args->in.op) {
rc = unmap_device_va(ctx, case HL_MEM_OP_ALLOC:
args->in.unmap.device_virt_addr); if (!hdev->dram_supports_virtual_memory) {
break; dev_err(hdev->dev, "DRAM alloc is not supported\n");
rc = -EINVAL;
default: goto out;
dev_err(hdev->dev, "Unknown opcode for memory IOCTL\n");
rc = -ENOTTY;
break;
} }
} else {
switch (args->in.op) {
case HL_MEM_OP_ALLOC:
if (args->in.alloc.mem_size == 0) {
dev_err(hdev->dev,
"alloc size must be larger than 0\n");
rc = -EINVAL;
goto out;
}
/* Force contiguous as there are no real MMU if (args->in.alloc.mem_size == 0) {
* translations to overcome physical memory gaps dev_err(hdev->dev,
*/ "alloc size must be larger than 0\n");
args->in.flags |= HL_MEM_CONTIGUOUS; rc = -EINVAL;
rc = alloc_device_memory(ctx, &args->in, &handle); goto out;
}
rc = alloc_device_memory(ctx, &args->in, &handle);
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
args->out.handle = (__u64) handle; args->out.handle = (__u64) handle;
break; break;
case HL_MEM_OP_FREE: case HL_MEM_OP_FREE:
rc = free_device_memory(ctx, args->in.free.handle); rc = free_device_memory(ctx, args->in.free.handle);
break; break;
case HL_MEM_OP_MAP: case HL_MEM_OP_MAP:
if (args->in.flags & HL_MEM_USERPTR) { rc = map_device_va(ctx, &args->in, &device_addr);
device_addr = args->in.map_host.host_virt_addr;
rc = 0;
} else {
rc = get_paddr_from_handle(ctx, &args->in,
&device_addr);
}
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
args->out.device_virt_addr = device_addr; args->out.device_virt_addr = device_addr;
break; break;
case HL_MEM_OP_UNMAP: case HL_MEM_OP_UNMAP:
rc = 0; rc = unmap_device_va(ctx,
break; args->in.unmap.device_virt_addr);
break;
default: default:
dev_err(hdev->dev, "Unknown opcode for memory IOCTL\n"); dev_err(hdev->dev, "Unknown opcode for memory IOCTL\n");
rc = -ENOTTY; rc = -ENOTTY;
break; break;
}
} }
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment