mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 17:12:55 +00:00
0861e41de5
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>
58 lines
1.1 KiB
C
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);
|
|
}
|