2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-28 23:23:55 +08:00
linux-next/drivers/misc/habanalabs/asid.c
Oded Gabbay 0861e41de5 habanalabs: add context and ASID modules
This patch adds two modules - ASID and context.

Each user process that opens a device's file must have at least one
context before it is able to "work" with the device. Each context has its
own device address-space and contains information about its runtime state
(its active command submissions).

To have address-space separation between contexts, each context is assigned
a unique ASID, which stands for "address-space id". Goya supports up to
1024 ASIDs.

Currently, the driver doesn't support multiple contexts. Therefore, the
user doesn't need to actively create a context. A "primary context" is
created automatically when the user opens the device's file.

Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-02-18 09:46:44 +01:00

58 lines
1.1 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2016-2019 HabanaLabs, Ltd.
* All Rights Reserved.
*/
#include "habanalabs.h"
#include <linux/slab.h>
int hl_asid_init(struct hl_device *hdev)
{
hdev->asid_bitmap = kcalloc(BITS_TO_LONGS(hdev->asic_prop.max_asid),
sizeof(*hdev->asid_bitmap), GFP_KERNEL);
if (!hdev->asid_bitmap)
return -ENOMEM;
mutex_init(&hdev->asid_mutex);
/* ASID 0 is reserved for KMD */
set_bit(0, hdev->asid_bitmap);
return 0;
}
void hl_asid_fini(struct hl_device *hdev)
{
mutex_destroy(&hdev->asid_mutex);
kfree(hdev->asid_bitmap);
}
unsigned long hl_asid_alloc(struct hl_device *hdev)
{
unsigned long found;
mutex_lock(&hdev->asid_mutex);
found = find_first_zero_bit(hdev->asid_bitmap,
hdev->asic_prop.max_asid);
if (found == hdev->asic_prop.max_asid)
found = 0;
else
set_bit(found, hdev->asid_bitmap);
mutex_unlock(&hdev->asid_mutex);
return found;
}
void hl_asid_free(struct hl_device *hdev, unsigned long asid)
{
if (WARN((asid == 0 || asid >= hdev->asic_prop.max_asid),
"Invalid ASID %lu", asid))
return;
clear_bit(asid, hdev->asid_bitmap);
}