brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · d14cb56 Raw
108 lines · c
1// SPDX-License-Identifier: GPL-2.0+2// Copyright 2017 IBM Corp.3#include "ocxl_internal.h"4 5 6struct id_range {7	struct list_head list;8	u32 start;9	u32 end;10};11 12#ifdef DEBUG13static void dump_list(struct list_head *head, char *type_str)14{15	struct id_range *cur;16 17	pr_debug("%s ranges allocated:\n", type_str);18	list_for_each_entry(cur, head, list) {19		pr_debug("Range %d->%d\n", cur->start, cur->end);20	}21}22#endif23 24static int range_alloc(struct list_head *head, u32 size, int max_id,25		char *type_str)26{27	struct list_head *pos;28	struct id_range *cur, *new;29	int rc, last_end;30 31	new = kmalloc(sizeof(struct id_range), GFP_KERNEL);32	if (!new)33		return -ENOMEM;34 35	pos = head;36	last_end = -1;37	list_for_each_entry(cur, head, list) {38		if ((cur->start - last_end) > size)39			break;40		last_end = cur->end;41		pos = &cur->list;42	}43 44	new->start = last_end + 1;45	new->end = new->start + size - 1;46 47	if (new->end > max_id) {48		kfree(new);49		rc = -ENOSPC;50	} else {51		list_add(&new->list, pos);52		rc = new->start;53	}54 55#ifdef DEBUG56	dump_list(head, type_str);57#endif58	return rc;59}60 61static void range_free(struct list_head *head, u32 start, u32 size,62		char *type_str)63{64	bool found = false;65	struct id_range *cur, *tmp;66 67	list_for_each_entry_safe(cur, tmp, head, list) {68		if (cur->start == start && cur->end == (start + size - 1)) {69			found = true;70			list_del(&cur->list);71			kfree(cur);72			break;73		}74	}75	WARN_ON(!found);76#ifdef DEBUG77	dump_list(head, type_str);78#endif79}80 81int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size)82{83	int max_pasid;84 85	if (fn->config.max_pasid_log < 0)86		return -ENOSPC;87	max_pasid = 1 << fn->config.max_pasid_log;88	return range_alloc(&fn->pasid_list, size, max_pasid, "afu pasid");89}90 91void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size)92{93	return range_free(&fn->pasid_list, start, size, "afu pasid");94}95 96int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size)97{98	int max_actag;99 100	max_actag = fn->actag_enabled;101	return range_alloc(&fn->actag_list, size, max_actag, "afu actag");102}103 104void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size)105{106	return range_free(&fn->actag_list, start, size, "afu actag");107}108