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 netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html