| 5064 | } |
| 5065 | |
| 5066 | static int |
| 5067 | i40e_res_pool_alloc(struct i40e_res_pool_info *pool, |
| 5068 | uint16_t num) |
| 5069 | { |
| 5070 | struct pool_entry *entry, *valid_entry; |
| 5071 | |
| 5072 | if (pool == NULL || num == 0) { |
| 5073 | PMD_DRV_LOG(ERR, "Invalid parameter"); |
| 5074 | return -EINVAL; |
| 5075 | } |
| 5076 | |
| 5077 | if (pool->num_free < num) { |
| 5078 | PMD_DRV_LOG(ERR, "No resource. ask:%u, available:%u", |
| 5079 | num, pool->num_free); |
| 5080 | return -ENOMEM; |
| 5081 | } |
| 5082 | |
| 5083 | valid_entry = NULL; |
| 5084 | /* Lookup in free list and find most fit one */ |
| 5085 | LIST_FOREACH(entry, &pool->free_list, next) { |
| 5086 | if (entry->len >= num) { |
| 5087 | /* Find best one */ |
| 5088 | if (entry->len == num) { |
| 5089 | valid_entry = entry; |
| 5090 | break; |
| 5091 | } |
| 5092 | if (valid_entry == NULL || valid_entry->len > entry->len) |
| 5093 | valid_entry = entry; |
| 5094 | } |
| 5095 | } |
| 5096 | |
| 5097 | /* Not find one to satisfy the request, return */ |
| 5098 | if (valid_entry == NULL) { |
| 5099 | PMD_DRV_LOG(ERR, "No valid entry found"); |
| 5100 | return -ENOMEM; |
| 5101 | } |
| 5102 | /** |
| 5103 | * The entry have equal queue number as requested, |
| 5104 | * remove it from alloc_list. |
| 5105 | */ |
| 5106 | if (valid_entry->len == num) { |
| 5107 | LIST_REMOVE(valid_entry, next); |
| 5108 | } else { |
| 5109 | /** |
| 5110 | * The entry have more numbers than requested, |
| 5111 | * create a new entry for alloc_list and minus its |
| 5112 | * queue base and number in free_list. |
| 5113 | */ |
| 5114 | entry = rte_zmalloc("res_pool", sizeof(*entry), 0); |
| 5115 | if (entry == NULL) { |
| 5116 | PMD_DRV_LOG(ERR, |
| 5117 | "Failed to allocate memory for resource pool"); |
| 5118 | return -ENOMEM; |
| 5119 | } |
| 5120 | entry->base = valid_entry->base; |
| 5121 | entry->len = num; |
| 5122 | valid_entry->base += num; |
| 5123 | valid_entry->len -= num; |
no test coverage detected