* Checks if hash needs resizing and performs this resize if necessary * */
| 234 | * |
| 235 | */ |
| 236 | static void |
| 237 | consider_resize(struct nh_control *ctl, uint32_t new_nh_buckets, uint32_t new_idx_items) |
| 238 | { |
| 239 | void *nh_ptr, *nh_idx_ptr; |
| 240 | void *old_idx_ptr; |
| 241 | size_t alloc_size; |
| 242 | |
| 243 | nh_ptr = NULL; |
| 244 | if (new_nh_buckets != 0) { |
| 245 | alloc_size = CHT_SLIST_GET_RESIZE_SIZE(new_nh_buckets); |
| 246 | nh_ptr = malloc(alloc_size, M_NHOP, M_NOWAIT | M_ZERO); |
| 247 | } |
| 248 | |
| 249 | nh_idx_ptr = NULL; |
| 250 | if (new_idx_items != 0) { |
| 251 | alloc_size = bitmask_get_size(new_idx_items); |
| 252 | nh_idx_ptr = malloc(alloc_size, M_NHOP, M_NOWAIT | M_ZERO); |
| 253 | } |
| 254 | |
| 255 | if (nh_ptr == NULL && nh_idx_ptr == NULL) { |
| 256 | /* Either resize is not required or allocations have failed. */ |
| 257 | return; |
| 258 | } |
| 259 | |
| 260 | DPRINTF("going to resize: nh:[ptr:%p sz:%u] idx:[ptr:%p sz:%u]", nh_ptr, |
| 261 | new_nh_buckets, nh_idx_ptr, new_idx_items); |
| 262 | |
| 263 | old_idx_ptr = NULL; |
| 264 | |
| 265 | NHOPS_WLOCK(ctl); |
| 266 | if (nh_ptr != NULL) { |
| 267 | CHT_SLIST_RESIZE(&ctl->nh_head, nhops, nh_ptr, new_nh_buckets); |
| 268 | } |
| 269 | if (nh_idx_ptr != NULL) { |
| 270 | if (bitmask_copy(&ctl->nh_idx_head, nh_idx_ptr, new_idx_items) == 0) |
| 271 | bitmask_swap(&ctl->nh_idx_head, nh_idx_ptr, new_idx_items, &old_idx_ptr); |
| 272 | } |
| 273 | NHOPS_WUNLOCK(ctl); |
| 274 | |
| 275 | if (nh_ptr != NULL) |
| 276 | free(nh_ptr, M_NHOP); |
| 277 | if (old_idx_ptr != NULL) |
| 278 | free(old_idx_ptr, M_NHOP); |
| 279 | } |
| 280 | |
| 281 | /* |
| 282 | * Links nextop @nh_priv to the nexhop hash table and allocates |
no test coverage detected