/* runs when user space has closed the file */ static int flowtab_release(struct inode *inode, struct file *filep) { int i; struct flowtab_info *info; /* find the name of file opened (index into flowtab_info) */ sscanf(filep->f_path.dentry->d_iname, PNA_PROCFILE, &i); info = &flowtab_info[i]; /* dump a little info about that table */ if (pna_perfmon) { pr_info("pna table%d_inserts:%u,table%d_drops:%u\n", i, info->nflows, i, info->nflows_missed); } /* clear out the table */ hashmap_reset(info->map); /* this table is safe to use again */ flowtab_clean(info); /* unlock this table, has the effect of being free for use again */ mutex_unlock(&info->read_mutex); module_put(THIS_MODULE); return 0; }
/** * Create a hashmap for storing data on the fly. * * @param n_pairs number of entries in the hashmap * @param key_size size of the key of a pair * @param value_size size of the value of a pair * @return pointer to the hashmap wrapper */ struct pna_hashmap *hashmap_create(uint32_t n_pairs, uint32_t key_size, uint32_t value_size) { int i; struct pna_hashmap *map; /* find a free hashmap */ for (i = 0; i < PNA_NHASHMAPS; i++) { map = &hashmaps[i]; if (map->n_pairs == 0) break; } if (i == PNA_NHASHMAPS) { pna_error("Error all hashmaps are in use"); return NULL; } map->n_pairs = n_pairs; map->key_size = key_size; map->value_size = value_size; /* need at least 4 buckets */ map->n_buckets = 4; while (8*map->n_buckets <= map->n_pairs) { map->n_buckets <<= 1; } map->bkt_mask = map->n_buckets - 1; map->kvx_mask = (8*map->n_buckets) - 1; map->fp_mask = ~(map->kvx_mask); if (NULL == (map->buckets = (bkt_t *)malloc(BKTS_BYTES(map)))) { pna_error("Error could not allocate memory for buckets"); return NULL; } if (NULL == (map->pairs = (char *)malloc(PAIRS_BYTES(map)))) { pna_error("Error could not allocate memory for pairs"); return NULL; } map->next_idx = 0; /* XXX remove debug */ //printf("buckets for %d * %d * %d [* %d, %d]\n", 2, map->n_buckets, // BKT_SIZE, sizeof(*map->buckets), sizeof(**map->buckets)); //printf("buckets@0x%llx (%d)\n", map->buckets, BKTS_BYTES(map)); //printf("pairs@0x%llx (%d)\n", map->pairs, PAIRS_BYTES(map)); //printf("n_pairs: %d\n", map->n_pairs); //printf("n_buckets: %d (0x%08x)\n", map->n_buckets, map->bkt_mask); hashmap_reset(map); return map; }
/** * Destroy a hashmap from the system * @param *map hashmap to destroy */ void hashmap_destroy(struct pna_hashmap *map) { hashmap_reset(map); free(map->buckets); free(map->pairs); map->fp_mask = 0; map->kvx_mask = 0; map->bkt_mask = 0; map->n_buckets = 0; map->key_size = 0; map->value_size = 0; map->n_pairs = 0; }