1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4 * Copyright 2016-2019 HabanaLabs, Ltd.
5 * All Rights Reserved.
6 */
7
8 #include "habanalabs.h"
9
10 #include <linux/slab.h>
11
hl_asid_init(struct hl_device * hdev)12 int hl_asid_init(struct hl_device *hdev)
13 {
14 hdev->asid_bitmap = kcalloc(BITS_TO_LONGS(hdev->asic_prop.max_asid),
15 sizeof(*hdev->asid_bitmap), GFP_KERNEL);
16 if (!hdev->asid_bitmap)
17 return -ENOMEM;
18
19 mutex_init(&hdev->asid_mutex);
20
21 /* ASID 0 is reserved for the kernel driver and device CPU */
22 set_bit(0, hdev->asid_bitmap);
23
24 return 0;
25 }
26
hl_asid_fini(struct hl_device * hdev)27 void hl_asid_fini(struct hl_device *hdev)
28 {
29 mutex_destroy(&hdev->asid_mutex);
30 kfree(hdev->asid_bitmap);
31 }
32
hl_asid_alloc(struct hl_device * hdev)33 unsigned long hl_asid_alloc(struct hl_device *hdev)
34 {
35 unsigned long found;
36
37 mutex_lock(&hdev->asid_mutex);
38
39 found = find_first_zero_bit(hdev->asid_bitmap,
40 hdev->asic_prop.max_asid);
41 if (found == hdev->asic_prop.max_asid)
42 found = 0;
43 else
44 set_bit(found, hdev->asid_bitmap);
45
46 mutex_unlock(&hdev->asid_mutex);
47
48 return found;
49 }
50
hl_asid_free(struct hl_device * hdev,unsigned long asid)51 void hl_asid_free(struct hl_device *hdev, unsigned long asid)
52 {
53 if (WARN((asid == 0 || asid >= hdev->asic_prop.max_asid),
54 "Invalid ASID %lu", asid))
55 return;
56 clear_bit(asid, hdev->asid_bitmap);
57 }
58