/** * Reset all the pairs, buckets, and meta-data for a hashmap * @param *map hashmap to reset */ void hashmap_reset(struct pna_hashmap *map) { /* clear all buckets */ memset(map->buckets, 0, BKTS_BYTES(map)); /* clear all pairs */ memset(map->pairs, 0, PAIRS_BYTES(map)); /* reset next_idx */ map->next_idx = 0; }
/* initialization routine for flow monitoring */ int flowmon_init(void) { int i; struct flowtab_info *info; char table_str[PNA_MAX_STR]; struct proc_dir_entry *proc_node; struct flow_entry e; /* create the /proc base dir for pna tables */ proc_parent = proc_mkdir(PNA_PROCDIR, NULL); /* make memory for table meta-information */ flowtab_info = (struct flowtab_info *) vmalloc(pna_tables * sizeof(struct flowtab_info)); if (!flowtab_info) { pr_err("insufficient memory for flowtab_info\n"); flowmon_cleanup(); return -ENOMEM; } memset(flowtab_info, 0, pna_tables * sizeof(struct flowtab_info)); /* configure each table for use */ for (i = 0; i < pna_tables; i++) { info = &flowtab_info[i]; info->map = hashmap_create(pna_flow_entries, sizeof(e.key), sizeof(e.data)); if (!info->map) { pr_err("Could not allocate hashmap (%d/%d tables, %u sessions)\n", i, pna_tables, pna_flow_entries); flowmon_cleanup(); return -ENOMEM; } flowtab_clean(info); /* initialize the read_mutec */ mutex_init(&info->read_mutex); snprintf(table_str, PNA_MAX_STR, PNA_PROCFILE, i); strncpy(info->table_name, table_str, PNA_MAX_STR); proc_node = create_proc_entry(info->table_name, 0644, proc_parent); if (!proc_node) { pr_err("failed to make proc entry: %s\n", table_str); flowmon_cleanup(); return -ENOMEM; } proc_node->proc_fops = &flowtab_fops; proc_node->mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; proc_node->uid = 0; proc_node->gid = 0; proc_node->size = PAIRS_BYTES(info->map); } /* get packet arrival timestamps */ net_enable_timestamp(); 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; }