aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/Makefile1
-rw-r--r--net/core/dev.c185
-rw-r--r--net/core/dev_mcast.c28
-rw-r--r--net/core/ethtool.c9
-rw-r--r--net/core/netpoll.c9
-rw-r--r--net/core/pktgen.c4
-rw-r--r--net/core/skbuff.c10
-rw-r--r--net/core/sock.c6
-rw-r--r--net/core/user_dma.c131
9 files changed, 278 insertions, 105 deletions
diff --git a/net/core/Makefile b/net/core/Makefile
index 79fe12cced27..e9bd2467d5a9 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_NET_DIVERT) += dv.o
16obj-$(CONFIG_NET_PKTGEN) += pktgen.o 16obj-$(CONFIG_NET_PKTGEN) += pktgen.o
17obj-$(CONFIG_WIRELESS_EXT) += wireless.o 17obj-$(CONFIG_WIRELESS_EXT) += wireless.o
18obj-$(CONFIG_NETPOLL) += netpoll.o 18obj-$(CONFIG_NETPOLL) += netpoll.o
19obj-$(CONFIG_NET_DMA) += user_dma.o
diff --git a/net/core/dev.c b/net/core/dev.c
index 4fba549caf29..ab39fe17cb58 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -115,6 +115,7 @@
115#include <net/iw_handler.h> 115#include <net/iw_handler.h>
116#include <asm/current.h> 116#include <asm/current.h>
117#include <linux/audit.h> 117#include <linux/audit.h>
118#include <linux/dmaengine.h>
118 119
119/* 120/*
120 * The list of packet types we will receive (as opposed to discard) 121 * The list of packet types we will receive (as opposed to discard)
@@ -148,6 +149,12 @@ static DEFINE_SPINLOCK(ptype_lock);
148static struct list_head ptype_base[16]; /* 16 way hashed list */ 149static struct list_head ptype_base[16]; /* 16 way hashed list */
149static struct list_head ptype_all; /* Taps */ 150static struct list_head ptype_all; /* Taps */
150 151
152#ifdef CONFIG_NET_DMA
153static struct dma_client *net_dma_client;
154static unsigned int net_dma_count;
155static spinlock_t net_dma_event_lock;
156#endif
157
151/* 158/*
152 * The @dev_base list is protected by @dev_base_lock and the rtnl 159 * The @dev_base list is protected by @dev_base_lock and the rtnl
153 * semaphore. 160 * semaphore.
@@ -1215,75 +1222,15 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
1215#define illegal_highdma(dev, skb) (0) 1222#define illegal_highdma(dev, skb) (0)
1216#endif 1223#endif
1217 1224
1218/* Keep head the same: replace data */
1219int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
1220{
1221 unsigned int size;
1222 u8 *data;
1223 long offset;
1224 struct skb_shared_info *ninfo;
1225 int headerlen = skb->data - skb->head;
1226 int expand = (skb->tail + skb->data_len) - skb->end;
1227
1228 if (skb_shared(skb))
1229 BUG();
1230
1231 if (expand <= 0)
1232 expand = 0;
1233
1234 size = skb->end - skb->head + expand;
1235 size = SKB_DATA_ALIGN(size);
1236 data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
1237 if (!data)
1238 return -ENOMEM;
1239
1240 /* Copy entire thing */
1241 if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
1242 BUG();
1243
1244 /* Set up shinfo */
1245 ninfo = (struct skb_shared_info*)(data + size);
1246 atomic_set(&ninfo->dataref, 1);
1247 ninfo->tso_size = skb_shinfo(skb)->tso_size;
1248 ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
1249 ninfo->nr_frags = 0;
1250 ninfo->frag_list = NULL;
1251
1252 /* Offset between the two in bytes */
1253 offset = data - skb->head;
1254
1255 /* Free old data. */
1256 skb_release_data(skb);
1257
1258 skb->head = data;
1259 skb->end = data + size;
1260
1261 /* Set up new pointers */
1262 skb->h.raw += offset;
1263 skb->nh.raw += offset;
1264 skb->mac.raw += offset;
1265 skb->tail += offset;
1266 skb->data += offset;
1267
1268 /* We are no longer a clone, even if we were. */
1269 skb->cloned = 0;
1270
1271 skb->tail += skb->data_len;
1272 skb->data_len = 0;
1273 return 0;
1274}
1275
1276#define HARD_TX_LOCK(dev, cpu) { \ 1225#define HARD_TX_LOCK(dev, cpu) { \
1277 if ((dev->features & NETIF_F_LLTX) == 0) { \ 1226 if ((dev->features & NETIF_F_LLTX) == 0) { \
1278 spin_lock(&dev->xmit_lock); \ 1227 netif_tx_lock(dev); \
1279 dev->xmit_lock_owner = cpu; \
1280 } \ 1228 } \
1281} 1229}
1282 1230
1283#define HARD_TX_UNLOCK(dev) { \ 1231#define HARD_TX_UNLOCK(dev) { \
1284 if ((dev->features & NETIF_F_LLTX) == 0) { \ 1232 if ((dev->features & NETIF_F_LLTX) == 0) { \
1285 dev->xmit_lock_owner = -1; \ 1233 netif_tx_unlock(dev); \
1286 spin_unlock(&dev->xmit_lock); \
1287 } \ 1234 } \
1288} 1235}
1289 1236
@@ -1321,7 +1268,7 @@ int dev_queue_xmit(struct sk_buff *skb)
1321 1268
1322 if (skb_shinfo(skb)->frag_list && 1269 if (skb_shinfo(skb)->frag_list &&
1323 !(dev->features & NETIF_F_FRAGLIST) && 1270 !(dev->features & NETIF_F_FRAGLIST) &&
1324 __skb_linearize(skb, GFP_ATOMIC)) 1271 __skb_linearize(skb))
1325 goto out_kfree_skb; 1272 goto out_kfree_skb;
1326 1273
1327 /* Fragmented skb is linearized if device does not support SG, 1274 /* Fragmented skb is linearized if device does not support SG,
@@ -1330,14 +1277,14 @@ int dev_queue_xmit(struct sk_buff *skb)
1330 */ 1277 */
1331 if (skb_shinfo(skb)->nr_frags && 1278 if (skb_shinfo(skb)->nr_frags &&
1332 (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && 1279 (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
1333 __skb_linearize(skb, GFP_ATOMIC)) 1280 __skb_linearize(skb))
1334 goto out_kfree_skb; 1281 goto out_kfree_skb;
1335 1282
1336 /* If packet is not checksummed and device does not support 1283 /* If packet is not checksummed and device does not support
1337 * checksumming for this protocol, complete checksumming here. 1284 * checksumming for this protocol, complete checksumming here.
1338 */ 1285 */
1339 if (skb->ip_summed == CHECKSUM_HW && 1286 if (skb->ip_summed == CHECKSUM_HW &&
1340 (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) && 1287 (!(dev->features & NETIF_F_GEN_CSUM) &&
1341 (!(dev->features & NETIF_F_IP_CSUM) || 1288 (!(dev->features & NETIF_F_IP_CSUM) ||
1342 skb->protocol != htons(ETH_P_IP)))) 1289 skb->protocol != htons(ETH_P_IP))))
1343 if (skb_checksum_help(skb, 0)) 1290 if (skb_checksum_help(skb, 0))
@@ -1382,8 +1329,8 @@ int dev_queue_xmit(struct sk_buff *skb)
1382 /* The device has no queue. Common case for software devices: 1329 /* The device has no queue. Common case for software devices:
1383 loopback, all the sorts of tunnels... 1330 loopback, all the sorts of tunnels...
1384 1331
1385 Really, it is unlikely that xmit_lock protection is necessary here. 1332 Really, it is unlikely that netif_tx_lock protection is necessary
1386 (f.e. loopback and IP tunnels are clean ignoring statistics 1333 here. (f.e. loopback and IP tunnels are clean ignoring statistics
1387 counters.) 1334 counters.)
1388 However, it is possible, that they rely on protection 1335 However, it is possible, that they rely on protection
1389 made by us here. 1336 made by us here.
@@ -1846,6 +1793,19 @@ static void net_rx_action(struct softirq_action *h)
1846 } 1793 }
1847 } 1794 }
1848out: 1795out:
1796#ifdef CONFIG_NET_DMA
1797 /*
1798 * There may not be any more sk_buffs coming right now, so push
1799 * any pending DMA copies to hardware
1800 */
1801 if (net_dma_client) {
1802 struct dma_chan *chan;
1803 rcu_read_lock();
1804 list_for_each_entry_rcu(chan, &net_dma_client->channels, client_node)
1805 dma_async_memcpy_issue_pending(chan);
1806 rcu_read_unlock();
1807 }
1808#endif
1849 local_irq_enable(); 1809 local_irq_enable();
1850 return; 1810 return;
1851 1811
@@ -2785,7 +2745,7 @@ int register_netdevice(struct net_device *dev)
2785 BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); 2745 BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
2786 2746
2787 spin_lock_init(&dev->queue_lock); 2747 spin_lock_init(&dev->queue_lock);
2788 spin_lock_init(&dev->xmit_lock); 2748 spin_lock_init(&dev->_xmit_lock);
2789 dev->xmit_lock_owner = -1; 2749 dev->xmit_lock_owner = -1;
2790#ifdef CONFIG_NET_CLS_ACT 2750#ifdef CONFIG_NET_CLS_ACT
2791 spin_lock_init(&dev->ingress_lock); 2751 spin_lock_init(&dev->ingress_lock);
@@ -2829,9 +2789,7 @@ int register_netdevice(struct net_device *dev)
2829 2789
2830 /* Fix illegal SG+CSUM combinations. */ 2790 /* Fix illegal SG+CSUM combinations. */
2831 if ((dev->features & NETIF_F_SG) && 2791 if ((dev->features & NETIF_F_SG) &&
2832 !(dev->features & (NETIF_F_IP_CSUM | 2792 !(dev->features & NETIF_F_ALL_CSUM)) {
2833 NETIF_F_NO_CSUM |
2834 NETIF_F_HW_CSUM))) {
2835 printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", 2793 printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
2836 dev->name); 2794 dev->name);
2837 dev->features &= ~NETIF_F_SG; 2795 dev->features &= ~NETIF_F_SG;
@@ -3300,6 +3258,88 @@ static int dev_cpu_callback(struct notifier_block *nfb,
3300} 3258}
3301#endif /* CONFIG_HOTPLUG_CPU */ 3259#endif /* CONFIG_HOTPLUG_CPU */
3302 3260
3261#ifdef CONFIG_NET_DMA
3262/**
3263 * net_dma_rebalance -
3264 * This is called when the number of channels allocated to the net_dma_client
3265 * changes. The net_dma_client tries to have one DMA channel per CPU.
3266 */
3267static void net_dma_rebalance(void)
3268{
3269 unsigned int cpu, i, n;
3270 struct dma_chan *chan;
3271
3272 lock_cpu_hotplug();
3273
3274 if (net_dma_count == 0) {
3275 for_each_online_cpu(cpu)
3276 rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL);
3277 unlock_cpu_hotplug();
3278 return;
3279 }
3280
3281 i = 0;
3282 cpu = first_cpu(cpu_online_map);
3283
3284 rcu_read_lock();
3285 list_for_each_entry(chan, &net_dma_client->channels, client_node) {
3286 n = ((num_online_cpus() / net_dma_count)
3287 + (i < (num_online_cpus() % net_dma_count) ? 1 : 0));
3288
3289 while(n) {
3290 per_cpu(softnet_data.net_dma, cpu) = chan;
3291 cpu = next_cpu(cpu, cpu_online_map);
3292 n--;
3293 }
3294 i++;
3295 }
3296 rcu_read_unlock();
3297
3298 unlock_cpu_hotplug();
3299}
3300
3301/**
3302 * netdev_dma_event - event callback for the net_dma_client
3303 * @client: should always be net_dma_client
3304 * @chan:
3305 * @event:
3306 */
3307static void netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
3308 enum dma_event event)
3309{
3310 spin_lock(&net_dma_event_lock);
3311 switch (event) {
3312 case DMA_RESOURCE_ADDED:
3313 net_dma_count++;
3314 net_dma_rebalance();
3315 break;
3316 case DMA_RESOURCE_REMOVED:
3317 net_dma_count--;
3318 net_dma_rebalance();
3319 break;
3320 default:
3321 break;
3322 }
3323 spin_unlock(&net_dma_event_lock);
3324}
3325
3326/**
3327 * netdev_dma_regiser - register the networking subsystem as a DMA client
3328 */
3329static int __init netdev_dma_register(void)
3330{
3331 spin_lock_init(&net_dma_event_lock);
3332 net_dma_client = dma_async_client_register(netdev_dma_event);
3333 if (net_dma_client == NULL)
3334 return -ENOMEM;
3335
3336 dma_async_client_chan_request(net_dma_client, num_online_cpus());
3337 return 0;
3338}
3339
3340#else
3341static int __init netdev_dma_register(void) { return -ENODEV; }
3342#endif /* CONFIG_NET_DMA */
3303 3343
3304/* 3344/*
3305 * Initialize the DEV module. At boot time this walks the device list and 3345 * Initialize the DEV module. At boot time this walks the device list and
@@ -3353,6 +3393,8 @@ static int __init net_dev_init(void)
3353 atomic_set(&queue->backlog_dev.refcnt, 1); 3393 atomic_set(&queue->backlog_dev.refcnt, 1);
3354 } 3394 }
3355 3395
3396 netdev_dma_register();
3397
3356 dev_boot_phase = 0; 3398 dev_boot_phase = 0;
3357 3399
3358 open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); 3400 open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
@@ -3371,7 +3413,6 @@ subsys_initcall(net_dev_init);
3371EXPORT_SYMBOL(__dev_get_by_index); 3413EXPORT_SYMBOL(__dev_get_by_index);
3372EXPORT_SYMBOL(__dev_get_by_name); 3414EXPORT_SYMBOL(__dev_get_by_name);
3373EXPORT_SYMBOL(__dev_remove_pack); 3415EXPORT_SYMBOL(__dev_remove_pack);
3374EXPORT_SYMBOL(__skb_linearize);
3375EXPORT_SYMBOL(dev_valid_name); 3416EXPORT_SYMBOL(dev_valid_name);
3376EXPORT_SYMBOL(dev_add_pack); 3417EXPORT_SYMBOL(dev_add_pack);
3377EXPORT_SYMBOL(dev_alloc_name); 3418EXPORT_SYMBOL(dev_alloc_name);
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 05d60850840e..c57d887da2ef 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -62,7 +62,7 @@
62 * Device mc lists are changed by bh at least if IPv6 is enabled, 62 * Device mc lists are changed by bh at least if IPv6 is enabled,
63 * so that it must be bh protected. 63 * so that it must be bh protected.
64 * 64 *
65 * We block accesses to device mc filters with dev->xmit_lock. 65 * We block accesses to device mc filters with netif_tx_lock.
66 */ 66 */
67 67
68/* 68/*
@@ -93,9 +93,9 @@ static void __dev_mc_upload(struct net_device *dev)
93 93
94void dev_mc_upload(struct net_device *dev) 94void dev_mc_upload(struct net_device *dev)
95{ 95{
96 spin_lock_bh(&dev->xmit_lock); 96 netif_tx_lock_bh(dev);
97 __dev_mc_upload(dev); 97 __dev_mc_upload(dev);
98 spin_unlock_bh(&dev->xmit_lock); 98 netif_tx_unlock_bh(dev);
99} 99}
100 100
101/* 101/*
@@ -107,7 +107,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
107 int err = 0; 107 int err = 0;
108 struct dev_mc_list *dmi, **dmip; 108 struct dev_mc_list *dmi, **dmip;
109 109
110 spin_lock_bh(&dev->xmit_lock); 110 netif_tx_lock_bh(dev);
111 111
112 for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { 112 for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
113 /* 113 /*
@@ -139,13 +139,13 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
139 */ 139 */
140 __dev_mc_upload(dev); 140 __dev_mc_upload(dev);
141 141
142 spin_unlock_bh(&dev->xmit_lock); 142 netif_tx_unlock_bh(dev);
143 return 0; 143 return 0;
144 } 144 }
145 } 145 }
146 err = -ENOENT; 146 err = -ENOENT;
147done: 147done:
148 spin_unlock_bh(&dev->xmit_lock); 148 netif_tx_unlock_bh(dev);
149 return err; 149 return err;
150} 150}
151 151
@@ -160,7 +160,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
160 160
161 dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC); 161 dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
162 162
163 spin_lock_bh(&dev->xmit_lock); 163 netif_tx_lock_bh(dev);
164 for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { 164 for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
165 if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && 165 if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
166 dmi->dmi_addrlen == alen) { 166 dmi->dmi_addrlen == alen) {
@@ -176,7 +176,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
176 } 176 }
177 177
178 if ((dmi = dmi1) == NULL) { 178 if ((dmi = dmi1) == NULL) {
179 spin_unlock_bh(&dev->xmit_lock); 179 netif_tx_unlock_bh(dev);
180 return -ENOMEM; 180 return -ENOMEM;
181 } 181 }
182 memcpy(dmi->dmi_addr, addr, alen); 182 memcpy(dmi->dmi_addr, addr, alen);
@@ -189,11 +189,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
189 189
190 __dev_mc_upload(dev); 190 __dev_mc_upload(dev);
191 191
192 spin_unlock_bh(&dev->xmit_lock); 192 netif_tx_unlock_bh(dev);
193 return 0; 193 return 0;
194 194
195done: 195done:
196 spin_unlock_bh(&dev->xmit_lock); 196 netif_tx_unlock_bh(dev);
197 kfree(dmi1); 197 kfree(dmi1);
198 return err; 198 return err;
199} 199}
@@ -204,7 +204,7 @@ done:
204 204
205void dev_mc_discard(struct net_device *dev) 205void dev_mc_discard(struct net_device *dev)
206{ 206{
207 spin_lock_bh(&dev->xmit_lock); 207 netif_tx_lock_bh(dev);
208 208
209 while (dev->mc_list != NULL) { 209 while (dev->mc_list != NULL) {
210 struct dev_mc_list *tmp = dev->mc_list; 210 struct dev_mc_list *tmp = dev->mc_list;
@@ -215,7 +215,7 @@ void dev_mc_discard(struct net_device *dev)
215 } 215 }
216 dev->mc_count = 0; 216 dev->mc_count = 0;
217 217
218 spin_unlock_bh(&dev->xmit_lock); 218 netif_tx_unlock_bh(dev);
219} 219}
220 220
221#ifdef CONFIG_PROC_FS 221#ifdef CONFIG_PROC_FS
@@ -250,7 +250,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
250 struct dev_mc_list *m; 250 struct dev_mc_list *m;
251 struct net_device *dev = v; 251 struct net_device *dev = v;
252 252
253 spin_lock_bh(&dev->xmit_lock); 253 netif_tx_lock_bh(dev);
254 for (m = dev->mc_list; m; m = m->next) { 254 for (m = dev->mc_list; m; m = m->next) {
255 int i; 255 int i;
256 256
@@ -262,7 +262,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
262 262
263 seq_putc(seq, '\n'); 263 seq_putc(seq, '\n');
264 } 264 }
265 spin_unlock_bh(&dev->xmit_lock); 265 netif_tx_unlock_bh(dev);
266 return 0; 266 return 0;
267} 267}
268 268
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index e6f76106a99b..33ce7ed6afc6 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_device *dev)
30 30
31u32 ethtool_op_get_tx_csum(struct net_device *dev) 31u32 ethtool_op_get_tx_csum(struct net_device *dev)
32{ 32{
33 return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0; 33 return (dev->features & NETIF_F_ALL_CSUM) != 0;
34} 34}
35 35
36int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 36int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
@@ -551,9 +551,7 @@ static int ethtool_set_sg(struct net_device *dev, char __user *useraddr)
551 return -EFAULT; 551 return -EFAULT;
552 552
553 if (edata.data && 553 if (edata.data &&
554 !(dev->features & (NETIF_F_IP_CSUM | 554 !(dev->features & NETIF_F_ALL_CSUM))
555 NETIF_F_NO_CSUM |
556 NETIF_F_HW_CSUM)))
557 return -EINVAL; 555 return -EINVAL;
558 556
559 return __ethtool_set_sg(dev, edata.data); 557 return __ethtool_set_sg(dev, edata.data);
@@ -591,7 +589,7 @@ static int ethtool_set_tso(struct net_device *dev, char __user *useraddr)
591 589
592static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr) 590static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
593{ 591{
594 struct ethtool_value edata = { ETHTOOL_GTSO }; 592 struct ethtool_value edata = { ETHTOOL_GUFO };
595 593
596 if (!dev->ethtool_ops->get_ufo) 594 if (!dev->ethtool_ops->get_ufo)
597 return -EOPNOTSUPP; 595 return -EOPNOTSUPP;
@@ -600,6 +598,7 @@ static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
600 return -EFAULT; 598 return -EFAULT;
601 return 0; 599 return 0;
602} 600}
601
603static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) 602static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
604{ 603{
605 struct ethtool_value edata; 604 struct ethtool_value edata;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index e8e05cebd95a..9cb781830380 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
273 273
274 do { 274 do {
275 npinfo->tries--; 275 npinfo->tries--;
276 spin_lock(&np->dev->xmit_lock); 276 netif_tx_lock(np->dev);
277 np->dev->xmit_lock_owner = smp_processor_id();
278 277
279 /* 278 /*
280 * network drivers do not expect to be called if the queue is 279 * network drivers do not expect to be called if the queue is
281 * stopped. 280 * stopped.
282 */ 281 */
283 if (netif_queue_stopped(np->dev)) { 282 if (netif_queue_stopped(np->dev)) {
284 np->dev->xmit_lock_owner = -1; 283 netif_tx_unlock(np->dev);
285 spin_unlock(&np->dev->xmit_lock);
286 netpoll_poll(np); 284 netpoll_poll(np);
287 udelay(50); 285 udelay(50);
288 continue; 286 continue;
289 } 287 }
290 288
291 status = np->dev->hard_start_xmit(skb, np->dev); 289 status = np->dev->hard_start_xmit(skb, np->dev);
292 np->dev->xmit_lock_owner = -1; 290 netif_tx_unlock(np->dev);
293 spin_unlock(&np->dev->xmit_lock);
294 291
295 /* success */ 292 /* success */
296 if(!status) { 293 if(!status) {
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index c23e9c06ee23..67ed14ddabd2 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2897,7 +2897,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
2897 } 2897 }
2898 } 2898 }
2899 2899
2900 spin_lock_bh(&odev->xmit_lock); 2900 netif_tx_lock_bh(odev);
2901 if (!netif_queue_stopped(odev)) { 2901 if (!netif_queue_stopped(odev)) {
2902 2902
2903 atomic_inc(&(pkt_dev->skb->users)); 2903 atomic_inc(&(pkt_dev->skb->users));
@@ -2942,7 +2942,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
2942 pkt_dev->next_tx_ns = 0; 2942 pkt_dev->next_tx_ns = 0;
2943 } 2943 }
2944 2944
2945 spin_unlock_bh(&odev->xmit_lock); 2945 netif_tx_unlock_bh(odev);
2946 2946
2947 /* If pkt_dev->count is zero, then run forever */ 2947 /* If pkt_dev->count is zero, then run forever */
2948 if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) { 2948 if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index fb3770f9c094..bb7210f4005e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -464,7 +464,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
464 n->tc_verd = CLR_TC_MUNGED(n->tc_verd); 464 n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
465 C(input_dev); 465 C(input_dev);
466#endif 466#endif
467 467 skb_copy_secmark(n, skb);
468#endif 468#endif
469 C(truesize); 469 C(truesize);
470 atomic_set(&n->users, 1); 470 atomic_set(&n->users, 1);
@@ -526,6 +526,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
526#endif 526#endif
527 new->tc_index = old->tc_index; 527 new->tc_index = old->tc_index;
528#endif 528#endif
529 skb_copy_secmark(new, old);
529 atomic_set(&new->users, 1); 530 atomic_set(&new->users, 1);
530 skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; 531 skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
531 skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; 532 skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
@@ -800,12 +801,10 @@ struct sk_buff *skb_pad(struct sk_buff *skb, int pad)
800 return nskb; 801 return nskb;
801} 802}
802 803
803/* Trims skb to length len. It can change skb pointers, if "realloc" is 1. 804/* Trims skb to length len. It can change skb pointers.
804 * If realloc==0 and trimming is impossible without change of data,
805 * it is BUG().
806 */ 805 */
807 806
808int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc) 807int ___pskb_trim(struct sk_buff *skb, unsigned int len)
809{ 808{
810 int offset = skb_headlen(skb); 809 int offset = skb_headlen(skb);
811 int nfrags = skb_shinfo(skb)->nr_frags; 810 int nfrags = skb_shinfo(skb)->nr_frags;
@@ -815,7 +814,6 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc)
815 int end = offset + skb_shinfo(skb)->frags[i].size; 814 int end = offset + skb_shinfo(skb)->frags[i].size;
816 if (end > len) { 815 if (end > len) {
817 if (skb_cloned(skb)) { 816 if (skb_cloned(skb)) {
818 BUG_ON(!realloc);
819 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 817 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
820 return -ENOMEM; 818 return -ENOMEM;
821 } 819 }
diff --git a/net/core/sock.c b/net/core/sock.c
index ed2afdb9ea2d..5d820c376653 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -832,6 +832,9 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
832 atomic_set(&newsk->sk_omem_alloc, 0); 832 atomic_set(&newsk->sk_omem_alloc, 0);
833 skb_queue_head_init(&newsk->sk_receive_queue); 833 skb_queue_head_init(&newsk->sk_receive_queue);
834 skb_queue_head_init(&newsk->sk_write_queue); 834 skb_queue_head_init(&newsk->sk_write_queue);
835#ifdef CONFIG_NET_DMA
836 skb_queue_head_init(&newsk->sk_async_wait_queue);
837#endif
835 838
836 rwlock_init(&newsk->sk_dst_lock); 839 rwlock_init(&newsk->sk_dst_lock);
837 rwlock_init(&newsk->sk_callback_lock); 840 rwlock_init(&newsk->sk_callback_lock);
@@ -1383,6 +1386,9 @@ void sock_init_data(struct socket *sock, struct sock *sk)
1383 skb_queue_head_init(&sk->sk_receive_queue); 1386 skb_queue_head_init(&sk->sk_receive_queue);
1384 skb_queue_head_init(&sk->sk_write_queue); 1387 skb_queue_head_init(&sk->sk_write_queue);
1385 skb_queue_head_init(&sk->sk_error_queue); 1388 skb_queue_head_init(&sk->sk_error_queue);
1389#ifdef CONFIG_NET_DMA
1390 skb_queue_head_init(&sk->sk_async_wait_queue);
1391#endif
1386 1392
1387 sk->sk_send_head = NULL; 1393 sk->sk_send_head = NULL;
1388 1394
diff --git a/net/core/user_dma.c b/net/core/user_dma.c
new file mode 100644
index 000000000000..b7c98dbcdb81
--- /dev/null
+++ b/net/core/user_dma.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
3 * Portions based on net/core/datagram.c and copyrighted by their authors.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59
17 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * The full GNU General Public License is included in this distribution in the
20 * file called COPYING.
21 */
22
23/*
24 * This code allows the net stack to make use of a DMA engine for
25 * skb to iovec copies.
26 */
27
28#include <linux/dmaengine.h>
29#include <linux/socket.h>
30#include <linux/rtnetlink.h> /* for BUG_TRAP */
31#include <net/tcp.h>
32
33#define NET_DMA_DEFAULT_COPYBREAK 4096
34
35int sysctl_tcp_dma_copybreak = NET_DMA_DEFAULT_COPYBREAK;
36
37/**
38 * dma_skb_copy_datagram_iovec - Copy a datagram to an iovec.
39 * @skb - buffer to copy
40 * @offset - offset in the buffer to start copying from
41 * @iovec - io vector to copy to
42 * @len - amount of data to copy from buffer to iovec
43 * @pinned_list - locked iovec buffer data
44 *
45 * Note: the iovec is modified during the copy.
46 */
47int dma_skb_copy_datagram_iovec(struct dma_chan *chan,
48 struct sk_buff *skb, int offset, struct iovec *to,
49 size_t len, struct dma_pinned_list *pinned_list)
50{
51 int start = skb_headlen(skb);
52 int i, copy = start - offset;
53 dma_cookie_t cookie = 0;
54
55 /* Copy header. */
56 if (copy > 0) {
57 if (copy > len)
58 copy = len;
59 cookie = dma_memcpy_to_iovec(chan, to, pinned_list,
60 skb->data + offset, copy);
61 if (cookie < 0)
62 goto fault;
63 len -= copy;
64 if (len == 0)
65 goto end;
66 offset += copy;
67 }
68
69 /* Copy paged appendix. Hmm... why does this look so complicated? */
70 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
71 int end;
72
73 BUG_TRAP(start <= offset + len);
74
75 end = start + skb_shinfo(skb)->frags[i].size;
76 copy = end - offset;
77 if ((copy = end - offset) > 0) {
78 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
79 struct page *page = frag->page;
80
81 if (copy > len)
82 copy = len;
83
84 cookie = dma_memcpy_pg_to_iovec(chan, to, pinned_list, page,
85 frag->page_offset + offset - start, copy);
86 if (cookie < 0)
87 goto fault;
88 len -= copy;
89 if (len == 0)
90 goto end;
91 offset += copy;
92 }
93 start = end;
94 }
95
96 if (skb_shinfo(skb)->frag_list) {
97 struct sk_buff *list = skb_shinfo(skb)->frag_list;
98
99 for (; list; list = list->next) {
100 int end;
101
102 BUG_TRAP(start <= offset + len);
103
104 end = start + list->len;
105 copy = end - offset;
106 if (copy > 0) {
107 if (copy > len)
108 copy = len;
109 cookie = dma_skb_copy_datagram_iovec(chan, list,
110 offset - start, to, copy,
111 pinned_list);
112 if (cookie < 0)
113 goto fault;
114 len -= copy;
115 if (len == 0)
116 goto end;
117 offset += copy;
118 }
119 start = end;
120 }
121 }
122
123end:
124 if (!len) {
125 skb->dma_cookie = cookie;
126 return cookie;
127 }
128
129fault:
130 return -EFAULT;
131}