Chris Leech <[email protected]> wrote:
>
There seems to be a small race here.
> +static void net_dma_rebalance(void)
> +{
> + unsigned int cpu, i, n;
> + struct dma_chan *chan;
> +
> + lock_cpu_hotplug();
> +
> + if (net_dma_count == 0) {
> + for_each_online_cpu(cpu)
> + rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL);
> + unlock_cpu_hotplug();
> + return;
> + }
If some other CPU does netdev_dma_event(DMA_RESOURCE_REMOVED) now
> + i = 0;
> + cpu = first_cpu(cpu_online_map);
> +
> + rcu_read_lock();
> + list_for_each_entry(chan, &net_dma_client->channels, client_node) {
> + n = ((num_online_cpus() / net_dma_count)
> + + (i < (num_online_cpus() % net_dma_count) ? 1 : 0));
This will get a divide-by-zero.
> + while(n) {
> + per_cpu(softnet_data.net_dma, cpu) = chan;
> + cpu = next_cpu(cpu, cpu_online_map);
> + n--;
> + }
> + i++;
> + }
> + rcu_read_unlock();
> +
> + unlock_cpu_hotplug();
> +}
> +
> +/**
> + * netdev_dma_event - event callback for the net_dma_client
> + * @client: should always be net_dma_client
> + * @chan:
> + * @event:
> + */
> +static void netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
> + enum dma_event event)
> +{
> + switch (event) {
> + case DMA_RESOURCE_ADDED:
> + net_dma_count++;
> + net_dma_rebalance();
> + break;
> + case DMA_RESOURCE_REMOVED:
> + net_dma_count--;
> + net_dma_rebalance();
> + break;
> + default:
> + break;
> + }
> +}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]