[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1290432836.2811.44.camel@edumazet-laptop>
Date: Mon, 22 Nov 2010 14:33:56 +0100
From: Eric Dumazet <eric.dumazet@...il.com>
To: Tom Herbert <therbert@...gle.com>
Cc: davem@...emloft.net, netdev@...r.kernel.org
Subject: Re: [PATCH 2/2 v7] xps: Transmit Packet Steering
Le dimanche 21 novembre 2010 à 15:17 -0800, Tom Herbert a écrit :
...
> +
> +static DEFINE_MUTEX(xps_map_mutex);
> +
> +static ssize_t store_xps_map(struct netdev_queue *queue,
> + struct netdev_queue_attribute *attribute,
> + const char *buf, size_t len)
> +{
> + struct net_device *dev = queue->dev;
> + cpumask_var_t mask;
> + int err, i, cpu, pos, map_len, alloc_len, need_set;
> + unsigned long index;
> + struct xps_map *map, *new_map;
> + struct xps_dev_maps *dev_maps, *new_dev_maps;
> + int nonempty = 0;
> +
> + if (!capable(CAP_NET_ADMIN))
> + return -EPERM;
> +
> + if (!alloc_cpumask_var(&mask, GFP_KERNEL))
> + return -ENOMEM;
> +
> + index = get_netdev_queue_index(queue);
> +
> + err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
> + if (err) {
> + free_cpumask_var(mask);
> + return err;
> + }
> +
> + new_dev_maps = kzalloc(max_t(unsigned,
> + XPS_DEV_MAPS_SIZE, L1_CACHE_BYTES), GFP_KERNEL);
> + if (!new_dev_maps) {
> + free_cpumask_var(mask);
> + return -ENOMEM;
> + }
> +
> + mutex_lock(&xps_map_mutex);
> +
> + dev_maps = dev->xps_maps;
> +
> + for_each_possible_cpu(cpu) {
> + new_map = map = dev_maps ? dev_maps->cpu_map[cpu] : NULL;
> +
> + if (map) {
> + for (pos = 0; pos < map->len; pos++)
> + if (map->queues[pos] == index)
> + break;
> + map_len = map->len;
> + alloc_len = map->alloc_len;
> + } else
> + pos = map_len = alloc_len = 0;
> +
> + need_set = cpu_isset(cpu, *mask) && cpu_online(cpu);
> +
> + if (need_set && pos >= map_len) {
> + /* Need to add queue to this CPU's map */
> + if (map_len >= alloc_len) {
> + alloc_len = alloc_len ?
> + 2 * alloc_len : XPS_MIN_MAP_ALLOC;
> + new_map = kzalloc(XPS_MAP_SIZE(alloc_len),
> + GFP_KERNEL);
kzalloc_node(size, GFP_KERNEL, cpu_to_node(cpu))
to get memory close to the cpu ?
> + if (!new_map)
> + goto error;
> + new_map->alloc_len = alloc_len;
> + for (i = 0; i < map_len; i++)
> + new_map->queues[i] = map->queues[i];
> + new_map->len = map_len;
> + }
> + new_map->queues[new_map->len++] = index;
> + } else if (!need_set && pos < map_len) {
> + /* Need to remove queue from this CPU's map */
> + if (map_len > 1)
> + new_map->queues[pos] =
> + new_map->queues[--new_map->len];
> + else
> + new_map = NULL;
> + }
> + new_dev_maps->cpu_map[cpu] = new_map;
> + }
> +
> + /* Cleanup old maps */
> + for_each_possible_cpu(cpu) {
> + map = dev_maps ? dev_maps->cpu_map[cpu] : NULL;
> + if (map && new_dev_maps->cpu_map[cpu] != map)
> + call_rcu(&map->rcu, xps_map_release);
> + if (new_dev_maps->cpu_map[cpu])
> + nonempty = 1;
> + }
> +
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists