xref: /linux/lib/parman.c (revision c95c2d32)
144091d29SJiri Pirko /*
244091d29SJiri Pirko  * lib/parman.c - Manager for linear priority array areas
344091d29SJiri Pirko  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
444091d29SJiri Pirko  * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
544091d29SJiri Pirko  *
644091d29SJiri Pirko  * Redistribution and use in source and binary forms, with or without
744091d29SJiri Pirko  * modification, are permitted provided that the following conditions are met:
844091d29SJiri Pirko  *
944091d29SJiri Pirko  * 1. Redistributions of source code must retain the above copyright
1044091d29SJiri Pirko  *    notice, this list of conditions and the following disclaimer.
1144091d29SJiri Pirko  * 2. Redistributions in binary form must reproduce the above copyright
1244091d29SJiri Pirko  *    notice, this list of conditions and the following disclaimer in the
1344091d29SJiri Pirko  *    documentation and/or other materials provided with the distribution.
1444091d29SJiri Pirko  * 3. Neither the names of the copyright holders nor the names of its
1544091d29SJiri Pirko  *    contributors may be used to endorse or promote products derived from
1644091d29SJiri Pirko  *    this software without specific prior written permission.
1744091d29SJiri Pirko  *
1844091d29SJiri Pirko  * Alternatively, this software may be distributed under the terms of the
1944091d29SJiri Pirko  * GNU General Public License ("GPL") version 2 as published by the Free
2044091d29SJiri Pirko  * Software Foundation.
2144091d29SJiri Pirko  *
2244091d29SJiri Pirko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2344091d29SJiri Pirko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2444091d29SJiri Pirko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2544091d29SJiri Pirko  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2644091d29SJiri Pirko  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2744091d29SJiri Pirko  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2844091d29SJiri Pirko  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2944091d29SJiri Pirko  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3044091d29SJiri Pirko  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3144091d29SJiri Pirko  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3244091d29SJiri Pirko  * POSSIBILITY OF SUCH DAMAGE.
3344091d29SJiri Pirko  */
3444091d29SJiri Pirko 
3544091d29SJiri Pirko #include <linux/kernel.h>
3644091d29SJiri Pirko #include <linux/module.h>
3744091d29SJiri Pirko #include <linux/slab.h>
3844091d29SJiri Pirko #include <linux/export.h>
3944091d29SJiri Pirko #include <linux/list.h>
4044091d29SJiri Pirko #include <linux/err.h>
4144091d29SJiri Pirko #include <linux/parman.h>
4244091d29SJiri Pirko 
4344091d29SJiri Pirko struct parman_algo {
4444091d29SJiri Pirko 	int (*item_add)(struct parman *parman, struct parman_prio *prio,
4544091d29SJiri Pirko 			struct parman_item *item);
4644091d29SJiri Pirko 	void (*item_remove)(struct parman *parman, struct parman_prio *prio,
4744091d29SJiri Pirko 			    struct parman_item *item);
4844091d29SJiri Pirko };
4944091d29SJiri Pirko 
5044091d29SJiri Pirko struct parman {
5144091d29SJiri Pirko 	const struct parman_ops *ops;
5244091d29SJiri Pirko 	void *priv;
5344091d29SJiri Pirko 	const struct parman_algo *algo;
5444091d29SJiri Pirko 	unsigned long count;
5544091d29SJiri Pirko 	unsigned long limit_count;
5644091d29SJiri Pirko 	struct list_head prio_list;
5744091d29SJiri Pirko };
5844091d29SJiri Pirko 
parman_enlarge(struct parman * parman)5944091d29SJiri Pirko static int parman_enlarge(struct parman *parman)
6044091d29SJiri Pirko {
6144091d29SJiri Pirko 	unsigned long new_count = parman->limit_count +
6244091d29SJiri Pirko 				  parman->ops->resize_step;
6344091d29SJiri Pirko 	int err;
6444091d29SJiri Pirko 
6544091d29SJiri Pirko 	err = parman->ops->resize(parman->priv, new_count);
6644091d29SJiri Pirko 	if (err)
6744091d29SJiri Pirko 		return err;
6844091d29SJiri Pirko 	parman->limit_count = new_count;
6944091d29SJiri Pirko 	return 0;
7044091d29SJiri Pirko }
7144091d29SJiri Pirko 
parman_shrink(struct parman * parman)7244091d29SJiri Pirko static int parman_shrink(struct parman *parman)
7344091d29SJiri Pirko {
7444091d29SJiri Pirko 	unsigned long new_count = parman->limit_count -
7544091d29SJiri Pirko 				  parman->ops->resize_step;
7644091d29SJiri Pirko 	int err;
7744091d29SJiri Pirko 
7844091d29SJiri Pirko 	if (new_count < parman->ops->base_count)
7944091d29SJiri Pirko 		return 0;
8044091d29SJiri Pirko 	err = parman->ops->resize(parman->priv, new_count);
8144091d29SJiri Pirko 	if (err)
8244091d29SJiri Pirko 		return err;
8344091d29SJiri Pirko 	parman->limit_count = new_count;
8444091d29SJiri Pirko 	return 0;
8544091d29SJiri Pirko }
8644091d29SJiri Pirko 
parman_prio_used(struct parman_prio * prio)8744091d29SJiri Pirko static bool parman_prio_used(struct parman_prio *prio)
8844091d29SJiri Pirko {
8944091d29SJiri Pirko 	return !list_empty(&prio->item_list);
9044091d29SJiri Pirko }
9144091d29SJiri Pirko 
parman_prio_first_item(struct parman_prio * prio)9244091d29SJiri Pirko static struct parman_item *parman_prio_first_item(struct parman_prio *prio)
9344091d29SJiri Pirko {
9444091d29SJiri Pirko 	return list_first_entry(&prio->item_list,
9544091d29SJiri Pirko 				typeof(struct parman_item), list);
9644091d29SJiri Pirko }
9744091d29SJiri Pirko 
parman_prio_first_index(struct parman_prio * prio)9844091d29SJiri Pirko static unsigned long parman_prio_first_index(struct parman_prio *prio)
9944091d29SJiri Pirko {
10044091d29SJiri Pirko 	return parman_prio_first_item(prio)->index;
10144091d29SJiri Pirko }
10244091d29SJiri Pirko 
parman_prio_last_item(struct parman_prio * prio)10344091d29SJiri Pirko static struct parman_item *parman_prio_last_item(struct parman_prio *prio)
10444091d29SJiri Pirko {
10544091d29SJiri Pirko 	return list_last_entry(&prio->item_list,
10644091d29SJiri Pirko 			       typeof(struct parman_item), list);
10744091d29SJiri Pirko }
10844091d29SJiri Pirko 
parman_prio_last_index(struct parman_prio * prio)10944091d29SJiri Pirko static unsigned long parman_prio_last_index(struct parman_prio *prio)
11044091d29SJiri Pirko {
11144091d29SJiri Pirko 	return parman_prio_last_item(prio)->index;
11244091d29SJiri Pirko }
11344091d29SJiri Pirko 
parman_lsort_new_index_find(struct parman * parman,struct parman_prio * prio)11444091d29SJiri Pirko static unsigned long parman_lsort_new_index_find(struct parman *parman,
11544091d29SJiri Pirko 						 struct parman_prio *prio)
11644091d29SJiri Pirko {
11744091d29SJiri Pirko 	list_for_each_entry_from_reverse(prio, &parman->prio_list, list) {
11844091d29SJiri Pirko 		if (!parman_prio_used(prio))
11944091d29SJiri Pirko 			continue;
12044091d29SJiri Pirko 		return parman_prio_last_index(prio) + 1;
12144091d29SJiri Pirko 	}
12244091d29SJiri Pirko 	return 0;
12344091d29SJiri Pirko }
12444091d29SJiri Pirko 
__parman_prio_move(struct parman * parman,struct parman_prio * prio,struct parman_item * item,unsigned long to_index,unsigned long count)12544091d29SJiri Pirko static void __parman_prio_move(struct parman *parman, struct parman_prio *prio,
12644091d29SJiri Pirko 			       struct parman_item *item, unsigned long to_index,
12744091d29SJiri Pirko 			       unsigned long count)
12844091d29SJiri Pirko {
12944091d29SJiri Pirko 	parman->ops->move(parman->priv, item->index, to_index, count);
13044091d29SJiri Pirko }
13144091d29SJiri Pirko 
parman_prio_shift_down(struct parman * parman,struct parman_prio * prio)13244091d29SJiri Pirko static void parman_prio_shift_down(struct parman *parman,
13344091d29SJiri Pirko 				   struct parman_prio *prio)
13444091d29SJiri Pirko {
13544091d29SJiri Pirko 	struct parman_item *item;
13644091d29SJiri Pirko 	unsigned long to_index;
13744091d29SJiri Pirko 
13844091d29SJiri Pirko 	if (!parman_prio_used(prio))
13944091d29SJiri Pirko 		return;
14044091d29SJiri Pirko 	item = parman_prio_first_item(prio);
14144091d29SJiri Pirko 	to_index = parman_prio_last_index(prio) + 1;
14244091d29SJiri Pirko 	__parman_prio_move(parman, prio, item, to_index, 1);
14344091d29SJiri Pirko 	list_move_tail(&item->list, &prio->item_list);
14444091d29SJiri Pirko 	item->index = to_index;
14544091d29SJiri Pirko }
14644091d29SJiri Pirko 
parman_prio_shift_up(struct parman * parman,struct parman_prio * prio)14744091d29SJiri Pirko static void parman_prio_shift_up(struct parman *parman,
14844091d29SJiri Pirko 				 struct parman_prio *prio)
14944091d29SJiri Pirko {
15044091d29SJiri Pirko 	struct parman_item *item;
15144091d29SJiri Pirko 	unsigned long to_index;
15244091d29SJiri Pirko 
15344091d29SJiri Pirko 	if (!parman_prio_used(prio))
15444091d29SJiri Pirko 		return;
15544091d29SJiri Pirko 	item = parman_prio_last_item(prio);
15644091d29SJiri Pirko 	to_index = parman_prio_first_index(prio) - 1;
15744091d29SJiri Pirko 	__parman_prio_move(parman, prio, item, to_index, 1);
15844091d29SJiri Pirko 	list_move(&item->list, &prio->item_list);
15944091d29SJiri Pirko 	item->index = to_index;
16044091d29SJiri Pirko }
16144091d29SJiri Pirko 
parman_prio_item_remove(struct parman * parman,struct parman_prio * prio,struct parman_item * item)16244091d29SJiri Pirko static void parman_prio_item_remove(struct parman *parman,
16344091d29SJiri Pirko 				    struct parman_prio *prio,
16444091d29SJiri Pirko 				    struct parman_item *item)
16544091d29SJiri Pirko {
16644091d29SJiri Pirko 	struct parman_item *last_item;
16744091d29SJiri Pirko 	unsigned long to_index;
16844091d29SJiri Pirko 
16944091d29SJiri Pirko 	last_item = parman_prio_last_item(prio);
17044091d29SJiri Pirko 	if (last_item == item) {
17144091d29SJiri Pirko 		list_del(&item->list);
17244091d29SJiri Pirko 		return;
17344091d29SJiri Pirko 	}
17444091d29SJiri Pirko 	to_index = item->index;
17544091d29SJiri Pirko 	__parman_prio_move(parman, prio, last_item, to_index, 1);
17644091d29SJiri Pirko 	list_del(&last_item->list);
17744091d29SJiri Pirko 	list_replace(&item->list, &last_item->list);
17844091d29SJiri Pirko 	last_item->index = to_index;
17944091d29SJiri Pirko }
18044091d29SJiri Pirko 
parman_lsort_item_add(struct parman * parman,struct parman_prio * prio,struct parman_item * item)18144091d29SJiri Pirko static int parman_lsort_item_add(struct parman *parman,
18244091d29SJiri Pirko 				 struct parman_prio *prio,
18344091d29SJiri Pirko 				 struct parman_item *item)
18444091d29SJiri Pirko {
18544091d29SJiri Pirko 	struct parman_prio *prio2;
18644091d29SJiri Pirko 	unsigned long new_index;
18744091d29SJiri Pirko 	int err;
18844091d29SJiri Pirko 
18944091d29SJiri Pirko 	if (parman->count + 1 > parman->limit_count) {
19044091d29SJiri Pirko 		err = parman_enlarge(parman);
19144091d29SJiri Pirko 		if (err)
19244091d29SJiri Pirko 			return err;
19344091d29SJiri Pirko 	}
19444091d29SJiri Pirko 
19544091d29SJiri Pirko 	new_index = parman_lsort_new_index_find(parman, prio);
19644091d29SJiri Pirko 	list_for_each_entry_reverse(prio2, &parman->prio_list, list) {
19744091d29SJiri Pirko 		if (prio2 == prio)
19844091d29SJiri Pirko 			break;
19944091d29SJiri Pirko 		parman_prio_shift_down(parman, prio2);
20044091d29SJiri Pirko 	}
20144091d29SJiri Pirko 	item->index = new_index;
20244091d29SJiri Pirko 	list_add_tail(&item->list, &prio->item_list);
20344091d29SJiri Pirko 	parman->count++;
20444091d29SJiri Pirko 	return 0;
20544091d29SJiri Pirko }
20644091d29SJiri Pirko 
parman_lsort_item_remove(struct parman * parman,struct parman_prio * prio,struct parman_item * item)20744091d29SJiri Pirko static void parman_lsort_item_remove(struct parman *parman,
20844091d29SJiri Pirko 				     struct parman_prio *prio,
20944091d29SJiri Pirko 				     struct parman_item *item)
21044091d29SJiri Pirko {
21144091d29SJiri Pirko 	parman_prio_item_remove(parman, prio, item);
21244091d29SJiri Pirko 	list_for_each_entry_continue(prio, &parman->prio_list, list)
21344091d29SJiri Pirko 		parman_prio_shift_up(parman, prio);
21444091d29SJiri Pirko 	parman->count--;
21544091d29SJiri Pirko 	if (parman->limit_count - parman->count >= parman->ops->resize_step)
21644091d29SJiri Pirko 		parman_shrink(parman);
21744091d29SJiri Pirko }
21844091d29SJiri Pirko 
21944091d29SJiri Pirko static const struct parman_algo parman_lsort = {
22044091d29SJiri Pirko 	.item_add	= parman_lsort_item_add,
22144091d29SJiri Pirko 	.item_remove	= parman_lsort_item_remove,
22244091d29SJiri Pirko };
22344091d29SJiri Pirko 
22444091d29SJiri Pirko static const struct parman_algo *parman_algos[] = {
22544091d29SJiri Pirko 	&parman_lsort,
22644091d29SJiri Pirko };
22744091d29SJiri Pirko 
22844091d29SJiri Pirko /**
22944091d29SJiri Pirko  * parman_create - creates a new parman instance
23044091d29SJiri Pirko  * @ops:	caller-specific callbacks
23144091d29SJiri Pirko  * @priv:	pointer to a private data passed to the ops
23244091d29SJiri Pirko  *
23344091d29SJiri Pirko  * Note: all locking must be provided by the caller.
23444091d29SJiri Pirko  *
23544091d29SJiri Pirko  * Each parman instance manages an array area with chunks of entries
23644091d29SJiri Pirko  * with the same priority. Consider following example:
23744091d29SJiri Pirko  *
23844091d29SJiri Pirko  * item 1 with prio 10
23944091d29SJiri Pirko  * item 2 with prio 10
24044091d29SJiri Pirko  * item 3 with prio 10
24144091d29SJiri Pirko  * item 4 with prio 20
24244091d29SJiri Pirko  * item 5 with prio 20
24344091d29SJiri Pirko  * item 6 with prio 30
24444091d29SJiri Pirko  * item 7 with prio 30
24544091d29SJiri Pirko  * item 8 with prio 30
24644091d29SJiri Pirko  *
24744091d29SJiri Pirko  * In this example, there are 3 priority chunks. The order of the priorities
24844091d29SJiri Pirko  * matters, however the order of items within a single priority chunk does not
24944091d29SJiri Pirko  * matter. So the same array could be ordered as follows:
25044091d29SJiri Pirko  *
25144091d29SJiri Pirko  * item 2 with prio 10
25244091d29SJiri Pirko  * item 3 with prio 10
25344091d29SJiri Pirko  * item 1 with prio 10
25444091d29SJiri Pirko  * item 5 with prio 20
25544091d29SJiri Pirko  * item 4 with prio 20
25644091d29SJiri Pirko  * item 7 with prio 30
25744091d29SJiri Pirko  * item 8 with prio 30
25844091d29SJiri Pirko  * item 6 with prio 30
25944091d29SJiri Pirko  *
26044091d29SJiri Pirko  * The goal of parman is to maintain the priority ordering. The caller
26144091d29SJiri Pirko  * provides @ops with callbacks parman uses to move the items
26244091d29SJiri Pirko  * and resize the array area.
26344091d29SJiri Pirko  *
26444091d29SJiri Pirko  * Returns a pointer to newly created parman instance in case of success,
26544091d29SJiri Pirko  * otherwise it returns NULL.
26644091d29SJiri Pirko  */
parman_create(const struct parman_ops * ops,void * priv)26744091d29SJiri Pirko struct parman *parman_create(const struct parman_ops *ops, void *priv)
26844091d29SJiri Pirko {
26944091d29SJiri Pirko 	struct parman *parman;
27044091d29SJiri Pirko 
27144091d29SJiri Pirko 	parman = kzalloc(sizeof(*parman), GFP_KERNEL);
27244091d29SJiri Pirko 	if (!parman)
27344091d29SJiri Pirko 		return NULL;
27444091d29SJiri Pirko 	INIT_LIST_HEAD(&parman->prio_list);
27544091d29SJiri Pirko 	parman->ops = ops;
27644091d29SJiri Pirko 	parman->priv = priv;
27744091d29SJiri Pirko 	parman->limit_count = ops->base_count;
27844091d29SJiri Pirko 	parman->algo = parman_algos[ops->algo];
27944091d29SJiri Pirko 	return parman;
28044091d29SJiri Pirko }
28144091d29SJiri Pirko EXPORT_SYMBOL(parman_create);
28244091d29SJiri Pirko 
28344091d29SJiri Pirko /**
28444091d29SJiri Pirko  * parman_destroy - destroys existing parman instance
28544091d29SJiri Pirko  * @parman:	parman instance
28644091d29SJiri Pirko  *
28744091d29SJiri Pirko  * Note: all locking must be provided by the caller.
28844091d29SJiri Pirko  */
parman_destroy(struct parman * parman)28944091d29SJiri Pirko void parman_destroy(struct parman *parman)
29044091d29SJiri Pirko {
29144091d29SJiri Pirko 	WARN_ON(!list_empty(&parman->prio_list));
29244091d29SJiri Pirko 	kfree(parman);
29344091d29SJiri Pirko }
29444091d29SJiri Pirko EXPORT_SYMBOL(parman_destroy);
29544091d29SJiri Pirko 
29644091d29SJiri Pirko /**
29744091d29SJiri Pirko  * parman_prio_init - initializes a parman priority chunk
29844091d29SJiri Pirko  * @parman:	parman instance
29944091d29SJiri Pirko  * @prio:	parman prio structure to be initialized
300*c95c2d32SRandy Dunlap  * @priority:	desired priority of the chunk
30144091d29SJiri Pirko  *
30244091d29SJiri Pirko  * Note: all locking must be provided by the caller.
30344091d29SJiri Pirko  *
30444091d29SJiri Pirko  * Before caller could add an item with certain priority, he has to
30544091d29SJiri Pirko  * initialize a priority chunk for it using this function.
30644091d29SJiri Pirko  */
parman_prio_init(struct parman * parman,struct parman_prio * prio,unsigned long priority)30744091d29SJiri Pirko void parman_prio_init(struct parman *parman, struct parman_prio *prio,
30844091d29SJiri Pirko 		      unsigned long priority)
30944091d29SJiri Pirko {
31044091d29SJiri Pirko 	struct parman_prio *prio2;
31144091d29SJiri Pirko 	struct list_head *pos;
31244091d29SJiri Pirko 
31344091d29SJiri Pirko 	INIT_LIST_HEAD(&prio->item_list);
31444091d29SJiri Pirko 	prio->priority = priority;
31544091d29SJiri Pirko 
31644091d29SJiri Pirko 	/* Position inside the list according to priority */
31744091d29SJiri Pirko 	list_for_each(pos, &parman->prio_list) {
31844091d29SJiri Pirko 		prio2 = list_entry(pos, typeof(*prio2), list);
31944091d29SJiri Pirko 		if (prio2->priority > prio->priority)
32044091d29SJiri Pirko 			break;
32144091d29SJiri Pirko 	}
32244091d29SJiri Pirko 	list_add_tail(&prio->list, pos);
32344091d29SJiri Pirko }
32444091d29SJiri Pirko EXPORT_SYMBOL(parman_prio_init);
32544091d29SJiri Pirko 
32644091d29SJiri Pirko /**
32744091d29SJiri Pirko  * parman_prio_fini - finalizes use of parman priority chunk
32844091d29SJiri Pirko  * @prio:	parman prio structure
32944091d29SJiri Pirko  *
33044091d29SJiri Pirko  * Note: all locking must be provided by the caller.
33144091d29SJiri Pirko  */
parman_prio_fini(struct parman_prio * prio)33244091d29SJiri Pirko void parman_prio_fini(struct parman_prio *prio)
33344091d29SJiri Pirko {
33444091d29SJiri Pirko 	WARN_ON(parman_prio_used(prio));
33544091d29SJiri Pirko 	list_del(&prio->list);
33644091d29SJiri Pirko }
33744091d29SJiri Pirko EXPORT_SYMBOL(parman_prio_fini);
33844091d29SJiri Pirko 
33944091d29SJiri Pirko /**
34044091d29SJiri Pirko  * parman_item_add - adds a parman item under defined priority
34144091d29SJiri Pirko  * @parman:	parman instance
34244091d29SJiri Pirko  * @prio:	parman prio instance to add the item to
34344091d29SJiri Pirko  * @item:	parman item instance
34444091d29SJiri Pirko  *
34544091d29SJiri Pirko  * Note: all locking must be provided by the caller.
34644091d29SJiri Pirko  *
34744091d29SJiri Pirko  * Adds item to a array managed by parman instance under the specified priority.
34844091d29SJiri Pirko  *
34944091d29SJiri Pirko  * Returns 0 in case of success, negative number to indicate an error.
35044091d29SJiri Pirko  */
parman_item_add(struct parman * parman,struct parman_prio * prio,struct parman_item * item)35144091d29SJiri Pirko int parman_item_add(struct parman *parman, struct parman_prio *prio,
35244091d29SJiri Pirko 		    struct parman_item *item)
35344091d29SJiri Pirko {
35444091d29SJiri Pirko 	return parman->algo->item_add(parman, prio, item);
35544091d29SJiri Pirko }
35644091d29SJiri Pirko EXPORT_SYMBOL(parman_item_add);
35744091d29SJiri Pirko 
35844091d29SJiri Pirko /**
359*c95c2d32SRandy Dunlap  * parman_item_remove - deletes parman item
36044091d29SJiri Pirko  * @parman:	parman instance
36144091d29SJiri Pirko  * @prio:	parman prio instance to delete the item from
36244091d29SJiri Pirko  * @item:	parman item instance
36344091d29SJiri Pirko  *
36444091d29SJiri Pirko  * Note: all locking must be provided by the caller.
36544091d29SJiri Pirko  */
parman_item_remove(struct parman * parman,struct parman_prio * prio,struct parman_item * item)36644091d29SJiri Pirko void parman_item_remove(struct parman *parman, struct parman_prio *prio,
36744091d29SJiri Pirko 			struct parman_item *item)
36844091d29SJiri Pirko {
36944091d29SJiri Pirko 	parman->algo->item_remove(parman, prio, item);
37044091d29SJiri Pirko }
37144091d29SJiri Pirko EXPORT_SYMBOL(parman_item_remove);
37244091d29SJiri Pirko 
37344091d29SJiri Pirko MODULE_LICENSE("Dual BSD/GPL");
37444091d29SJiri Pirko MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
37544091d29SJiri Pirko MODULE_DESCRIPTION("Priority-based array manager");
376