aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netdevice.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-01 14:35:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-01 14:35:16 -0400
commit9a5467fd600669cda488771dac3e951034fe2b08 (patch)
tree20c3c73ff3571e525193aca20d3602161b4e90be /include/linux/netdevice.h
parent676056132425ac425d7215cdaa8bd25582e07966 (diff)
parent00b1304c4ca81dd893973cc620b87a5c3ff3f660 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (46 commits) tcp: MD5: Fix IPv6 signatures skbuff: add missing kernel-doc for do_not_encrypt net/ipv4/route.c: fix build error tcp: MD5: Fix MD5 signatures on certain ACK packets ipv6: Fix ip6_xmit to send fragments if ipfragok is true ipvs: Move userspace definitions to include/linux/ip_vs.h netdev: Fix lockdep warnings in multiqueue configurations. netfilter: xt_hashlimit: fix race between htable_destroy and htable_gc netfilter: ipt_recent: fix race between recent_mt_destroy and proc manipulations netfilter: nf_conntrack_tcp: decrease timeouts while data in unacknowledged irda: replace __FUNCTION__ with __func__ nsc-ircc: default to dongle type 9 on IBM hardware bluetooth: add quirks for a few hci_usb devices hysdn: remove the packed attribute from PofTimStamp_tag isdn: use the common ascii hex helpers tg3: adapt tg3 to use reworked PCI PM code atm: fix direct casts of pointers to u32 in the InterPhase driver atm: fix const assignment/discard warnings in the ATM networking driver net: use the common ascii hex helpers random32: seeding improvement ...
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r--include/linux/netdevice.h86
1 files changed, 55 insertions, 31 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b4d056ceab96..ee583f642a9f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -440,6 +440,7 @@ static inline void napi_synchronize(const struct napi_struct *n)
440enum netdev_queue_state_t 440enum netdev_queue_state_t
441{ 441{
442 __QUEUE_STATE_XOFF, 442 __QUEUE_STATE_XOFF,
443 __QUEUE_STATE_FROZEN,
443}; 444};
444 445
445struct netdev_queue { 446struct netdev_queue {
@@ -636,7 +637,7 @@ struct net_device
636 unsigned int real_num_tx_queues; 637 unsigned int real_num_tx_queues;
637 638
638 unsigned long tx_queue_len; /* Max frames per queue allowed */ 639 unsigned long tx_queue_len; /* Max frames per queue allowed */
639 640 spinlock_t tx_global_lock;
640/* 641/*
641 * One part is mostly used on xmit path (device) 642 * One part is mostly used on xmit path (device)
642 */ 643 */
@@ -1099,6 +1100,11 @@ static inline int netif_queue_stopped(const struct net_device *dev)
1099 return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0)); 1100 return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0));
1100} 1101}
1101 1102
1103static inline int netif_tx_queue_frozen(const struct netdev_queue *dev_queue)
1104{
1105 return test_bit(__QUEUE_STATE_FROZEN, &dev_queue->state);
1106}
1107
1102/** 1108/**
1103 * netif_running - test if up 1109 * netif_running - test if up
1104 * @dev: network device 1110 * @dev: network device
@@ -1475,6 +1481,26 @@ static inline void __netif_tx_lock_bh(struct netdev_queue *txq)
1475 txq->xmit_lock_owner = smp_processor_id(); 1481 txq->xmit_lock_owner = smp_processor_id();
1476} 1482}
1477 1483
1484static inline int __netif_tx_trylock(struct netdev_queue *txq)
1485{
1486 int ok = spin_trylock(&txq->_xmit_lock);
1487 if (likely(ok))
1488 txq->xmit_lock_owner = smp_processor_id();
1489 return ok;
1490}
1491
1492static inline void __netif_tx_unlock(struct netdev_queue *txq)
1493{
1494 txq->xmit_lock_owner = -1;
1495 spin_unlock(&txq->_xmit_lock);
1496}
1497
1498static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
1499{
1500 txq->xmit_lock_owner = -1;
1501 spin_unlock_bh(&txq->_xmit_lock);
1502}
1503
1478/** 1504/**
1479 * netif_tx_lock - grab network device transmit lock 1505 * netif_tx_lock - grab network device transmit lock
1480 * @dev: network device 1506 * @dev: network device
@@ -1484,12 +1510,23 @@ static inline void __netif_tx_lock_bh(struct netdev_queue *txq)
1484 */ 1510 */
1485static inline void netif_tx_lock(struct net_device *dev) 1511static inline void netif_tx_lock(struct net_device *dev)
1486{ 1512{
1487 int cpu = smp_processor_id();
1488 unsigned int i; 1513 unsigned int i;
1514 int cpu;
1489 1515
1516 spin_lock(&dev->tx_global_lock);
1517 cpu = smp_processor_id();
1490 for (i = 0; i < dev->num_tx_queues; i++) { 1518 for (i = 0; i < dev->num_tx_queues; i++) {
1491 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 1519 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
1520
1521 /* We are the only thread of execution doing a
1522 * freeze, but we have to grab the _xmit_lock in
1523 * order to synchronize with threads which are in
1524 * the ->hard_start_xmit() handler and already
1525 * checked the frozen bit.
1526 */
1492 __netif_tx_lock(txq, cpu); 1527 __netif_tx_lock(txq, cpu);
1528 set_bit(__QUEUE_STATE_FROZEN, &txq->state);
1529 __netif_tx_unlock(txq);
1493 } 1530 }
1494} 1531}
1495 1532
@@ -1499,40 +1536,22 @@ static inline void netif_tx_lock_bh(struct net_device *dev)
1499 netif_tx_lock(dev); 1536 netif_tx_lock(dev);
1500} 1537}
1501 1538
1502static inline int __netif_tx_trylock(struct netdev_queue *txq)
1503{
1504 int ok = spin_trylock(&txq->_xmit_lock);
1505 if (likely(ok))
1506 txq->xmit_lock_owner = smp_processor_id();
1507 return ok;
1508}
1509
1510static inline int netif_tx_trylock(struct net_device *dev)
1511{
1512 return __netif_tx_trylock(netdev_get_tx_queue(dev, 0));
1513}
1514
1515static inline void __netif_tx_unlock(struct netdev_queue *txq)
1516{
1517 txq->xmit_lock_owner = -1;
1518 spin_unlock(&txq->_xmit_lock);
1519}
1520
1521static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
1522{
1523 txq->xmit_lock_owner = -1;
1524 spin_unlock_bh(&txq->_xmit_lock);
1525}
1526
1527static inline void netif_tx_unlock(struct net_device *dev) 1539static inline void netif_tx_unlock(struct net_device *dev)
1528{ 1540{
1529 unsigned int i; 1541 unsigned int i;
1530 1542
1531 for (i = 0; i < dev->num_tx_queues; i++) { 1543 for (i = 0; i < dev->num_tx_queues; i++) {
1532 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 1544 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
1533 __netif_tx_unlock(txq);
1534 }
1535 1545
1546 /* No need to grab the _xmit_lock here. If the
1547 * queue is not stopped for another reason, we
1548 * force a schedule.
1549 */
1550 clear_bit(__QUEUE_STATE_FROZEN, &txq->state);
1551 if (!test_bit(__QUEUE_STATE_XOFF, &txq->state))
1552 __netif_schedule(txq->qdisc);
1553 }
1554 spin_unlock(&dev->tx_global_lock);
1536} 1555}
1537 1556
1538static inline void netif_tx_unlock_bh(struct net_device *dev) 1557static inline void netif_tx_unlock_bh(struct net_device *dev)
@@ -1556,13 +1575,18 @@ static inline void netif_tx_unlock_bh(struct net_device *dev)
1556static inline void netif_tx_disable(struct net_device *dev) 1575static inline void netif_tx_disable(struct net_device *dev)
1557{ 1576{
1558 unsigned int i; 1577 unsigned int i;
1578 int cpu;
1559 1579
1560 netif_tx_lock_bh(dev); 1580 local_bh_disable();
1581 cpu = smp_processor_id();
1561 for (i = 0; i < dev->num_tx_queues; i++) { 1582 for (i = 0; i < dev->num_tx_queues; i++) {
1562 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 1583 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
1584
1585 __netif_tx_lock(txq, cpu);
1563 netif_tx_stop_queue(txq); 1586 netif_tx_stop_queue(txq);
1587 __netif_tx_unlock(txq);
1564 } 1588 }
1565 netif_tx_unlock_bh(dev); 1589 local_bh_enable();
1566} 1590}
1567 1591
1568static inline void netif_addr_lock(struct net_device *dev) 1592static inline void netif_addr_lock(struct net_device *dev)