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