18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * lib/parman.c - Manager for linear priority array areas 38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 48c2ecf20Sopenharmony_ci * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 108c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 118c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 128c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 138c2ecf20Sopenharmony_ci * documentation and/or other materials provided with the distribution. 148c2ecf20Sopenharmony_ci * 3. Neither the names of the copyright holders nor the names of its 158c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived from 168c2ecf20Sopenharmony_ci * this software without specific prior written permission. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 198c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 208c2ecf20Sopenharmony_ci * Software Foundation. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 238c2ecf20Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 248c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 258c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 268c2ecf20Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 278c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 288c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 298c2ecf20Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 308c2ecf20Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 318c2ecf20Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 328c2ecf20Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/kernel.h> 368c2ecf20Sopenharmony_ci#include <linux/module.h> 378c2ecf20Sopenharmony_ci#include <linux/slab.h> 388c2ecf20Sopenharmony_ci#include <linux/export.h> 398c2ecf20Sopenharmony_ci#include <linux/list.h> 408c2ecf20Sopenharmony_ci#include <linux/err.h> 418c2ecf20Sopenharmony_ci#include <linux/parman.h> 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct parman_algo { 448c2ecf20Sopenharmony_ci int (*item_add)(struct parman *parman, struct parman_prio *prio, 458c2ecf20Sopenharmony_ci struct parman_item *item); 468c2ecf20Sopenharmony_ci void (*item_remove)(struct parman *parman, struct parman_prio *prio, 478c2ecf20Sopenharmony_ci struct parman_item *item); 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistruct parman { 518c2ecf20Sopenharmony_ci const struct parman_ops *ops; 528c2ecf20Sopenharmony_ci void *priv; 538c2ecf20Sopenharmony_ci const struct parman_algo *algo; 548c2ecf20Sopenharmony_ci unsigned long count; 558c2ecf20Sopenharmony_ci unsigned long limit_count; 568c2ecf20Sopenharmony_ci struct list_head prio_list; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic int parman_enlarge(struct parman *parman) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci unsigned long new_count = parman->limit_count + 628c2ecf20Sopenharmony_ci parman->ops->resize_step; 638c2ecf20Sopenharmony_ci int err; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci err = parman->ops->resize(parman->priv, new_count); 668c2ecf20Sopenharmony_ci if (err) 678c2ecf20Sopenharmony_ci return err; 688c2ecf20Sopenharmony_ci parman->limit_count = new_count; 698c2ecf20Sopenharmony_ci return 0; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int parman_shrink(struct parman *parman) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci unsigned long new_count = parman->limit_count - 758c2ecf20Sopenharmony_ci parman->ops->resize_step; 768c2ecf20Sopenharmony_ci int err; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (new_count < parman->ops->base_count) 798c2ecf20Sopenharmony_ci return 0; 808c2ecf20Sopenharmony_ci err = parman->ops->resize(parman->priv, new_count); 818c2ecf20Sopenharmony_ci if (err) 828c2ecf20Sopenharmony_ci return err; 838c2ecf20Sopenharmony_ci parman->limit_count = new_count; 848c2ecf20Sopenharmony_ci return 0; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic bool parman_prio_used(struct parman_prio *prio) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci return !list_empty(&prio->item_list); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic struct parman_item *parman_prio_first_item(struct parman_prio *prio) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci return list_first_entry(&prio->item_list, 968c2ecf20Sopenharmony_ci typeof(struct parman_item), list); 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic unsigned long parman_prio_first_index(struct parman_prio *prio) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci return parman_prio_first_item(prio)->index; 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic struct parman_item *parman_prio_last_item(struct parman_prio *prio) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci return list_last_entry(&prio->item_list, 1078c2ecf20Sopenharmony_ci typeof(struct parman_item), list); 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic unsigned long parman_prio_last_index(struct parman_prio *prio) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci return parman_prio_last_item(prio)->index; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic unsigned long parman_lsort_new_index_find(struct parman *parman, 1168c2ecf20Sopenharmony_ci struct parman_prio *prio) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci list_for_each_entry_from_reverse(prio, &parman->prio_list, list) { 1198c2ecf20Sopenharmony_ci if (!parman_prio_used(prio)) 1208c2ecf20Sopenharmony_ci continue; 1218c2ecf20Sopenharmony_ci return parman_prio_last_index(prio) + 1; 1228c2ecf20Sopenharmony_ci } 1238c2ecf20Sopenharmony_ci return 0; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic void __parman_prio_move(struct parman *parman, struct parman_prio *prio, 1278c2ecf20Sopenharmony_ci struct parman_item *item, unsigned long to_index, 1288c2ecf20Sopenharmony_ci unsigned long count) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci parman->ops->move(parman->priv, item->index, to_index, count); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic void parman_prio_shift_down(struct parman *parman, 1348c2ecf20Sopenharmony_ci struct parman_prio *prio) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci struct parman_item *item; 1378c2ecf20Sopenharmony_ci unsigned long to_index; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci if (!parman_prio_used(prio)) 1408c2ecf20Sopenharmony_ci return; 1418c2ecf20Sopenharmony_ci item = parman_prio_first_item(prio); 1428c2ecf20Sopenharmony_ci to_index = parman_prio_last_index(prio) + 1; 1438c2ecf20Sopenharmony_ci __parman_prio_move(parman, prio, item, to_index, 1); 1448c2ecf20Sopenharmony_ci list_move_tail(&item->list, &prio->item_list); 1458c2ecf20Sopenharmony_ci item->index = to_index; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic void parman_prio_shift_up(struct parman *parman, 1498c2ecf20Sopenharmony_ci struct parman_prio *prio) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct parman_item *item; 1528c2ecf20Sopenharmony_ci unsigned long to_index; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (!parman_prio_used(prio)) 1558c2ecf20Sopenharmony_ci return; 1568c2ecf20Sopenharmony_ci item = parman_prio_last_item(prio); 1578c2ecf20Sopenharmony_ci to_index = parman_prio_first_index(prio) - 1; 1588c2ecf20Sopenharmony_ci __parman_prio_move(parman, prio, item, to_index, 1); 1598c2ecf20Sopenharmony_ci list_move(&item->list, &prio->item_list); 1608c2ecf20Sopenharmony_ci item->index = to_index; 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic void parman_prio_item_remove(struct parman *parman, 1648c2ecf20Sopenharmony_ci struct parman_prio *prio, 1658c2ecf20Sopenharmony_ci struct parman_item *item) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci struct parman_item *last_item; 1688c2ecf20Sopenharmony_ci unsigned long to_index; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci last_item = parman_prio_last_item(prio); 1718c2ecf20Sopenharmony_ci if (last_item == item) { 1728c2ecf20Sopenharmony_ci list_del(&item->list); 1738c2ecf20Sopenharmony_ci return; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci to_index = item->index; 1768c2ecf20Sopenharmony_ci __parman_prio_move(parman, prio, last_item, to_index, 1); 1778c2ecf20Sopenharmony_ci list_del(&last_item->list); 1788c2ecf20Sopenharmony_ci list_replace(&item->list, &last_item->list); 1798c2ecf20Sopenharmony_ci last_item->index = to_index; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic int parman_lsort_item_add(struct parman *parman, 1838c2ecf20Sopenharmony_ci struct parman_prio *prio, 1848c2ecf20Sopenharmony_ci struct parman_item *item) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci struct parman_prio *prio2; 1878c2ecf20Sopenharmony_ci unsigned long new_index; 1888c2ecf20Sopenharmony_ci int err; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (parman->count + 1 > parman->limit_count) { 1918c2ecf20Sopenharmony_ci err = parman_enlarge(parman); 1928c2ecf20Sopenharmony_ci if (err) 1938c2ecf20Sopenharmony_ci return err; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci new_index = parman_lsort_new_index_find(parman, prio); 1978c2ecf20Sopenharmony_ci list_for_each_entry_reverse(prio2, &parman->prio_list, list) { 1988c2ecf20Sopenharmony_ci if (prio2 == prio) 1998c2ecf20Sopenharmony_ci break; 2008c2ecf20Sopenharmony_ci parman_prio_shift_down(parman, prio2); 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci item->index = new_index; 2038c2ecf20Sopenharmony_ci list_add_tail(&item->list, &prio->item_list); 2048c2ecf20Sopenharmony_ci parman->count++; 2058c2ecf20Sopenharmony_ci return 0; 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic void parman_lsort_item_remove(struct parman *parman, 2098c2ecf20Sopenharmony_ci struct parman_prio *prio, 2108c2ecf20Sopenharmony_ci struct parman_item *item) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci parman_prio_item_remove(parman, prio, item); 2138c2ecf20Sopenharmony_ci list_for_each_entry_continue(prio, &parman->prio_list, list) 2148c2ecf20Sopenharmony_ci parman_prio_shift_up(parman, prio); 2158c2ecf20Sopenharmony_ci parman->count--; 2168c2ecf20Sopenharmony_ci if (parman->limit_count - parman->count >= parman->ops->resize_step) 2178c2ecf20Sopenharmony_ci parman_shrink(parman); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic const struct parman_algo parman_lsort = { 2218c2ecf20Sopenharmony_ci .item_add = parman_lsort_item_add, 2228c2ecf20Sopenharmony_ci .item_remove = parman_lsort_item_remove, 2238c2ecf20Sopenharmony_ci}; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic const struct parman_algo *parman_algos[] = { 2268c2ecf20Sopenharmony_ci &parman_lsort, 2278c2ecf20Sopenharmony_ci}; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci/** 2308c2ecf20Sopenharmony_ci * parman_create - creates a new parman instance 2318c2ecf20Sopenharmony_ci * @ops: caller-specific callbacks 2328c2ecf20Sopenharmony_ci * @priv: pointer to a private data passed to the ops 2338c2ecf20Sopenharmony_ci * 2348c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 2358c2ecf20Sopenharmony_ci * 2368c2ecf20Sopenharmony_ci * Each parman instance manages an array area with chunks of entries 2378c2ecf20Sopenharmony_ci * with the same priority. Consider following example: 2388c2ecf20Sopenharmony_ci * 2398c2ecf20Sopenharmony_ci * item 1 with prio 10 2408c2ecf20Sopenharmony_ci * item 2 with prio 10 2418c2ecf20Sopenharmony_ci * item 3 with prio 10 2428c2ecf20Sopenharmony_ci * item 4 with prio 20 2438c2ecf20Sopenharmony_ci * item 5 with prio 20 2448c2ecf20Sopenharmony_ci * item 6 with prio 30 2458c2ecf20Sopenharmony_ci * item 7 with prio 30 2468c2ecf20Sopenharmony_ci * item 8 with prio 30 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * In this example, there are 3 priority chunks. The order of the priorities 2498c2ecf20Sopenharmony_ci * matters, however the order of items within a single priority chunk does not 2508c2ecf20Sopenharmony_ci * matter. So the same array could be ordered as follows: 2518c2ecf20Sopenharmony_ci * 2528c2ecf20Sopenharmony_ci * item 2 with prio 10 2538c2ecf20Sopenharmony_ci * item 3 with prio 10 2548c2ecf20Sopenharmony_ci * item 1 with prio 10 2558c2ecf20Sopenharmony_ci * item 5 with prio 20 2568c2ecf20Sopenharmony_ci * item 4 with prio 20 2578c2ecf20Sopenharmony_ci * item 7 with prio 30 2588c2ecf20Sopenharmony_ci * item 8 with prio 30 2598c2ecf20Sopenharmony_ci * item 6 with prio 30 2608c2ecf20Sopenharmony_ci * 2618c2ecf20Sopenharmony_ci * The goal of parman is to maintain the priority ordering. The caller 2628c2ecf20Sopenharmony_ci * provides @ops with callbacks parman uses to move the items 2638c2ecf20Sopenharmony_ci * and resize the array area. 2648c2ecf20Sopenharmony_ci * 2658c2ecf20Sopenharmony_ci * Returns a pointer to newly created parman instance in case of success, 2668c2ecf20Sopenharmony_ci * otherwise it returns NULL. 2678c2ecf20Sopenharmony_ci */ 2688c2ecf20Sopenharmony_cistruct parman *parman_create(const struct parman_ops *ops, void *priv) 2698c2ecf20Sopenharmony_ci{ 2708c2ecf20Sopenharmony_ci struct parman *parman; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci parman = kzalloc(sizeof(*parman), GFP_KERNEL); 2738c2ecf20Sopenharmony_ci if (!parman) 2748c2ecf20Sopenharmony_ci return NULL; 2758c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&parman->prio_list); 2768c2ecf20Sopenharmony_ci parman->ops = ops; 2778c2ecf20Sopenharmony_ci parman->priv = priv; 2788c2ecf20Sopenharmony_ci parman->limit_count = ops->base_count; 2798c2ecf20Sopenharmony_ci parman->algo = parman_algos[ops->algo]; 2808c2ecf20Sopenharmony_ci return parman; 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_create); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/** 2858c2ecf20Sopenharmony_ci * parman_destroy - destroys existing parman instance 2868c2ecf20Sopenharmony_ci * @parman: parman instance 2878c2ecf20Sopenharmony_ci * 2888c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 2898c2ecf20Sopenharmony_ci */ 2908c2ecf20Sopenharmony_civoid parman_destroy(struct parman *parman) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci WARN_ON(!list_empty(&parman->prio_list)); 2938c2ecf20Sopenharmony_ci kfree(parman); 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_destroy); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci/** 2988c2ecf20Sopenharmony_ci * parman_prio_init - initializes a parman priority chunk 2998c2ecf20Sopenharmony_ci * @parman: parman instance 3008c2ecf20Sopenharmony_ci * @prio: parman prio structure to be initialized 3018c2ecf20Sopenharmony_ci * @prority: desired priority of the chunk 3028c2ecf20Sopenharmony_ci * 3038c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 3048c2ecf20Sopenharmony_ci * 3058c2ecf20Sopenharmony_ci * Before caller could add an item with certain priority, he has to 3068c2ecf20Sopenharmony_ci * initialize a priority chunk for it using this function. 3078c2ecf20Sopenharmony_ci */ 3088c2ecf20Sopenharmony_civoid parman_prio_init(struct parman *parman, struct parman_prio *prio, 3098c2ecf20Sopenharmony_ci unsigned long priority) 3108c2ecf20Sopenharmony_ci{ 3118c2ecf20Sopenharmony_ci struct parman_prio *prio2; 3128c2ecf20Sopenharmony_ci struct list_head *pos; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&prio->item_list); 3158c2ecf20Sopenharmony_ci prio->priority = priority; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* Position inside the list according to priority */ 3188c2ecf20Sopenharmony_ci list_for_each(pos, &parman->prio_list) { 3198c2ecf20Sopenharmony_ci prio2 = list_entry(pos, typeof(*prio2), list); 3208c2ecf20Sopenharmony_ci if (prio2->priority > prio->priority) 3218c2ecf20Sopenharmony_ci break; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci list_add_tail(&prio->list, pos); 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_prio_init); 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci/** 3288c2ecf20Sopenharmony_ci * parman_prio_fini - finalizes use of parman priority chunk 3298c2ecf20Sopenharmony_ci * @prio: parman prio structure 3308c2ecf20Sopenharmony_ci * 3318c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 3328c2ecf20Sopenharmony_ci */ 3338c2ecf20Sopenharmony_civoid parman_prio_fini(struct parman_prio *prio) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci WARN_ON(parman_prio_used(prio)); 3368c2ecf20Sopenharmony_ci list_del(&prio->list); 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_prio_fini); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci/** 3418c2ecf20Sopenharmony_ci * parman_item_add - adds a parman item under defined priority 3428c2ecf20Sopenharmony_ci * @parman: parman instance 3438c2ecf20Sopenharmony_ci * @prio: parman prio instance to add the item to 3448c2ecf20Sopenharmony_ci * @item: parman item instance 3458c2ecf20Sopenharmony_ci * 3468c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 3478c2ecf20Sopenharmony_ci * 3488c2ecf20Sopenharmony_ci * Adds item to a array managed by parman instance under the specified priority. 3498c2ecf20Sopenharmony_ci * 3508c2ecf20Sopenharmony_ci * Returns 0 in case of success, negative number to indicate an error. 3518c2ecf20Sopenharmony_ci */ 3528c2ecf20Sopenharmony_ciint parman_item_add(struct parman *parman, struct parman_prio *prio, 3538c2ecf20Sopenharmony_ci struct parman_item *item) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci return parman->algo->item_add(parman, prio, item); 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_item_add); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci/** 3608c2ecf20Sopenharmony_ci * parman_item_del - deletes parman item 3618c2ecf20Sopenharmony_ci * @parman: parman instance 3628c2ecf20Sopenharmony_ci * @prio: parman prio instance to delete the item from 3638c2ecf20Sopenharmony_ci * @item: parman item instance 3648c2ecf20Sopenharmony_ci * 3658c2ecf20Sopenharmony_ci * Note: all locking must be provided by the caller. 3668c2ecf20Sopenharmony_ci */ 3678c2ecf20Sopenharmony_civoid parman_item_remove(struct parman *parman, struct parman_prio *prio, 3688c2ecf20Sopenharmony_ci struct parman_item *item) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci parman->algo->item_remove(parman, prio, item); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(parman_item_remove); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 3758c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); 3768c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Priority-based array manager"); 377