Commit d0732f649f090b31f976a9ce59a38e1191077909

Authored by Chas Williams
Committed by David S. Miller
1 parent 1c9d3e72a7

[ATM]: [lec] convert lec_arp_table to hlist

Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 170 additions and 282 deletions Side-by-side Diff

... ... @@ -806,7 +806,7 @@
806 806 dev_kfree_skb(skb);
807 807 return;
808 808 }
809   - if (priv->lec_arp_empty_ones) {
  809 + if (!hlist_empty(&priv->lec_arp_empty_ones)) {
810 810 lec_arp_check_empties(priv, vcc, skb);
811 811 }
812 812 skb->dev = dev;
813 813  
814 814  
815 815  
816 816  
817 817  
818 818  
... ... @@ -998,29 +998,32 @@
998 998 struct lec_state {
999 999 unsigned long flags;
1000 1000 struct lec_priv *locked;
1001   - struct lec_arp_table *entry;
  1001 + struct hlist_node *node;
1002 1002 struct net_device *dev;
1003 1003 int itf;
1004 1004 int arp_table;
1005 1005 int misc_table;
1006 1006 };
1007 1007  
1008   -static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
  1008 +static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
1009 1009 loff_t *l)
1010 1010 {
1011   - struct lec_arp_table *e = state->entry;
  1011 + struct hlist_node *e = state->node;
  1012 + struct lec_arp_table *tmp;
1012 1013  
1013 1014 if (!e)
1014   - e = tbl;
  1015 + e = tbl->first;
1015 1016 if (e == (void *)1) {
1016   - e = tbl;
  1017 + e = tbl->first;
1017 1018 --*l;
1018 1019 }
1019   - for (; e; e = e->next) {
  1020 +
  1021 + hlist_for_each_entry_from(tmp, e, next) {
1020 1022 if (--*l < 0)
1021 1023 break;
1022 1024 }
1023   - state->entry = e;
  1025 + state->node = e;
  1026 +
1024 1027 return (*l < 0) ? state : NULL;
1025 1028 }
1026 1029  
... ... @@ -1031,7 +1034,7 @@
1031 1034 int p;
1032 1035  
1033 1036 for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
1034   - v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
  1037 + v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
1035 1038 if (v)
1036 1039 break;
1037 1040 }
... ... @@ -1042,10 +1045,10 @@
1042 1045 static void *lec_misc_walk(struct lec_state *state, loff_t *l,
1043 1046 struct lec_priv *priv)
1044 1047 {
1045   - struct lec_arp_table *lec_misc_tables[] = {
1046   - priv->lec_arp_empty_ones,
1047   - priv->lec_no_forward,
1048   - priv->mcast_fwds
  1048 + struct hlist_head *lec_misc_tables[] = {
  1049 + &priv->lec_arp_empty_ones,
  1050 + &priv->lec_no_forward,
  1051 + &priv->mcast_fwds
1049 1052 };
1050 1053 void *v = NULL;
1051 1054 int q;
... ... @@ -1112,7 +1115,7 @@
1112 1115 state->locked = NULL;
1113 1116 state->arp_table = 0;
1114 1117 state->misc_table = 0;
1115   - state->entry = (void *)1;
  1118 + state->node = (void *)1;
1116 1119  
1117 1120 return *pos ? lec_get_idx(state, *pos) : (void *)1;
1118 1121 }
1119 1122  
... ... @@ -1148,9 +1151,10 @@
1148 1151 else {
1149 1152 struct lec_state *state = seq->private;
1150 1153 struct net_device *dev = state->dev;
  1154 + struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next);
1151 1155  
1152 1156 seq_printf(seq, "%s ", dev->name);
1153   - lec_info(seq, state->entry);
  1157 + lec_info(seq, entry);
1154 1158 }
1155 1159 return 0;
1156 1160 }
1157 1161  
... ... @@ -1455,8 +1459,11 @@
1455 1459 unsigned short i;
1456 1460  
1457 1461 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1458   - priv->lec_arp_tables[i] = NULL;
  1462 + INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1459 1463 }
  1464 + INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
  1465 + INIT_HLIST_HEAD(&priv->lec_no_forward);
  1466 + INIT_HLIST_HEAD(&priv->mcast_fwds);
1460 1467 spin_lock_init(&priv->lec_arp_lock);
1461 1468 init_timer(&priv->lec_arp_timer);
1462 1469 priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
... ... @@ -1479,7 +1486,7 @@
1479 1486 vcc->user_back = NULL;
1480 1487 vcc->push = entry->old_push;
1481 1488 vcc_release_async(vcc, -EPIPE);
1482   - vcc = NULL;
  1489 + entry->vcc = NULL;
1483 1490 }
1484 1491 if (entry->recv_vcc) {
1485 1492 entry->recv_vcc->push = entry->old_recv_push;
1486 1493  
1487 1494  
1488 1495  
1489 1496  
... ... @@ -1493,27 +1500,17 @@
1493 1500 * LANE2: Add to the end of the list to satisfy 8.1.13
1494 1501 */
1495 1502 static inline void
1496   -lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
  1503 +lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
1497 1504 {
1498   - unsigned short place;
1499   - struct lec_arp_table *tmp;
  1505 + struct hlist_head *tmp;
1500 1506  
1501   - place = HASH(to_add->mac_addr[ETH_ALEN - 1]);
1502   - tmp = priv->lec_arp_tables[place];
1503   - to_add->next = NULL;
1504   - if (tmp == NULL)
1505   - priv->lec_arp_tables[place] = to_add;
  1507 + tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
  1508 + hlist_add_head(&entry->next, tmp);
1506 1509  
1507   - else { /* add to the end */
1508   - while (tmp->next)
1509   - tmp = tmp->next;
1510   - tmp->next = to_add;
1511   - }
1512   -
1513 1510 DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1514   - 0xff & to_add->mac_addr[0], 0xff & to_add->mac_addr[1],
1515   - 0xff & to_add->mac_addr[2], 0xff & to_add->mac_addr[3],
1516   - 0xff & to_add->mac_addr[4], 0xff & to_add->mac_addr[5]);
  1511 + 0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1],
  1512 + 0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3],
  1513 + 0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]);
1517 1514 }
1518 1515  
1519 1516 /*
1520 1517  
1521 1518  
1522 1519  
... ... @@ -1522,40 +1519,26 @@
1522 1519 static int
1523 1520 lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
1524 1521 {
1525   - unsigned short place;
1526   - struct lec_arp_table *tmp;
1527   - int remove_vcc = 1;
  1522 + struct hlist_node *node;
  1523 + struct lec_arp_table *entry;
  1524 + int i, remove_vcc = 1;
1528 1525  
1529 1526 if (!to_remove) {
1530 1527 return -1;
1531 1528 }
1532   - place = HASH(to_remove->mac_addr[ETH_ALEN - 1]);
1533   - tmp = priv->lec_arp_tables[place];
1534   - if (tmp == to_remove) {
1535   - priv->lec_arp_tables[place] = tmp->next;
1536   - } else {
1537   - while (tmp && tmp->next != to_remove) {
1538   - tmp = tmp->next;
1539   - }
1540   - if (!tmp) { /* Entry was not found */
1541   - return -1;
1542   - }
1543   - }
1544   - tmp->next = to_remove->next;
  1529 +
  1530 + hlist_del(&to_remove->next);
1545 1531 del_timer(&to_remove->timer);
1546 1532  
1547   - /* If this is the only MAC connected to this VCC, also tear down
1548   - the VCC */
  1533 + /* If this is the only MAC connected to this VCC, also tear down the VCC */
1549 1534 if (to_remove->status >= ESI_FLUSH_PENDING) {
1550 1535 /*
1551 1536 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
1552 1537 */
1553   - for (place = 0; place < LEC_ARP_TABLE_SIZE; place++) {
1554   - for (tmp = priv->lec_arp_tables[place]; tmp != NULL;
1555   - tmp = tmp->next) {
1556   - if (memcmp
1557   - (tmp->atm_addr, to_remove->atm_addr,
1558   - ATM_ESA_LEN) == 0) {
  1538 + for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
  1539 + hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
  1540 + if (memcmp(to_remove->atm_addr,
  1541 + entry->atm_addr, ATM_ESA_LEN) == 0) {
1559 1542 remove_vcc = 0;
1560 1543 break;
1561 1544 }
1562 1545  
1563 1546  
1564 1547  
... ... @@ -1591,28 +1574,19 @@
1591 1574 return "<UNKNOWN>";
1592 1575 }
1593 1576 }
1594   -#endif
1595 1577  
1596 1578 static void dump_arp_table(struct lec_priv *priv)
1597 1579 {
1598   -#if DEBUG_ARP_TABLE
1599   - int i, j, offset;
  1580 + struct hlist_node *node;
1600 1581 struct lec_arp_table *rulla;
1601   - char buf[1024];
1602   - struct lec_arp_table **lec_arp_tables =
1603   - (struct lec_arp_table **)priv->lec_arp_tables;
1604   - struct lec_arp_table *lec_arp_empty_ones =
1605   - (struct lec_arp_table *)priv->lec_arp_empty_ones;
1606   - struct lec_arp_table *lec_no_forward =
1607   - (struct lec_arp_table *)priv->lec_no_forward;
1608   - struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
  1582 + char buf[256];
  1583 + int i, j, offset;
1609 1584  
1610 1585 printk("Dump %p:\n", priv);
1611 1586 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1612   - rulla = lec_arp_tables[i];
1613   - offset = 0;
1614   - offset += sprintf(buf, "%d: %p\n", i, rulla);
1615   - while (rulla) {
  1587 + hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) {
  1588 + offset = 0;
  1589 + offset += sprintf(buf, "%d: %p\n", i, rulla);
1616 1590 offset += sprintf(buf + offset, "Mac:");
1617 1591 for (j = 0; j < ETH_ALEN; j++) {
1618 1592 offset += sprintf(buf + offset,
1619 1593  
1620 1594  
1621 1595  
... ... @@ -1639,15 +1613,13 @@
1639 1613 "Flags:%x, Packets_flooded:%x, Status: %s ",
1640 1614 rulla->flags, rulla->packets_flooded,
1641 1615 get_status_string(rulla->status));
1642   - offset += sprintf(buf + offset, "->%p\n", rulla->next);
1643   - rulla = rulla->next;
  1616 + printk("%s\n", buf);
1644 1617 }
1645   - printk("%s", buf);
1646 1618 }
1647   - rulla = lec_no_forward;
1648   - if (rulla)
  1619 +
  1620 + if (!hlist_empty(&priv->lec_no_forward))
1649 1621 printk("No forward\n");
1650   - while (rulla) {
  1622 + hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) {
1651 1623 offset = 0;
1652 1624 offset += sprintf(buf + offset, "Mac:");
1653 1625 for (j = 0; j < ETH_ALEN; j++) {
1654 1626  
1655 1627  
... ... @@ -1671,14 +1643,12 @@
1671 1643 "Flags:%x, Packets_flooded:%x, Status: %s ",
1672 1644 rulla->flags, rulla->packets_flooded,
1673 1645 get_status_string(rulla->status));
1674   - offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next);
1675   - rulla = rulla->next;
1676   - printk("%s", buf);
  1646 + printk("%s\n", buf);
1677 1647 }
1678   - rulla = lec_arp_empty_ones;
1679   - if (rulla)
  1648 +
  1649 + if (!hlist_empty(&priv->lec_arp_empty_ones))
1680 1650 printk("Empty ones\n");
1681   - while (rulla) {
  1651 + hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) {
1682 1652 offset = 0;
1683 1653 offset += sprintf(buf + offset, "Mac:");
1684 1654 for (j = 0; j < ETH_ALEN; j++) {
1685 1655  
1686 1656  
... ... @@ -1702,15 +1672,12 @@
1702 1672 "Flags:%x, Packets_flooded:%x, Status: %s ",
1703 1673 rulla->flags, rulla->packets_flooded,
1704 1674 get_status_string(rulla->status));
1705   - offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next);
1706   - rulla = rulla->next;
1707 1675 printk("%s", buf);
1708 1676 }
1709 1677  
1710   - rulla = mcast_fwds;
1711   - if (rulla)
  1678 + if (!hlist_empty(&priv->mcast_fwds))
1712 1679 printk("Multicast Forward VCCs\n");
1713   - while (rulla) {
  1680 + hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) {
1714 1681 offset = 0;
1715 1682 offset += sprintf(buf + offset, "Mac:");
1716 1683 for (j = 0; j < ETH_ALEN; j++) {
1717 1684  
1718 1685  
... ... @@ -1734,13 +1701,13 @@
1734 1701 "Flags:%x, Packets_flooded:%x, Status: %s ",
1735 1702 rulla->flags, rulla->packets_flooded,
1736 1703 get_status_string(rulla->status));
1737   - offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next);
1738   - rulla = rulla->next;
1739   - printk("%s", buf);
  1704 + printk("%s\n", buf);
1740 1705 }
1741 1706  
1742   -#endif
1743 1707 }
  1708 +#else
  1709 +#define dump_arp_table(priv) do { } while (0)
  1710 +#endif
1744 1711  
1745 1712 /*
1746 1713 * Destruction of arp-cache
... ... @@ -1748,7 +1715,8 @@
1748 1715 static void lec_arp_destroy(struct lec_priv *priv)
1749 1716 {
1750 1717 unsigned long flags;
1751   - struct lec_arp_table *entry, *next;
  1718 + struct hlist_node *node, *next;
  1719 + struct lec_arp_table *entry;
1752 1720 int i;
1753 1721  
1754 1722 del_timer_sync(&priv->lec_arp_timer);
1755 1723  
1756 1724  
1757 1725  
1758 1726  
1759 1727  
1760 1728  
1761 1729  
1762 1730  
1763 1731  
1764 1732  
1765 1733  
1766 1734  
... ... @@ -1759,43 +1727,37 @@
1759 1727  
1760 1728 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1761 1729 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1762   - for (entry = priv->lec_arp_tables[i]; entry != NULL;
1763   - entry = next) {
1764   - next = entry->next;
  1730 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1765 1731 lec_arp_remove(priv, entry);
1766 1732 kfree(entry);
1767 1733 }
  1734 + INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1768 1735 }
1769   - entry = priv->lec_arp_empty_ones;
1770   - while (entry) {
1771   - next = entry->next;
  1736 +
  1737 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
1772 1738 del_timer_sync(&entry->timer);
1773 1739 lec_arp_clear_vccs(entry);
  1740 + hlist_del(&entry->next);
1774 1741 kfree(entry);
1775   - entry = next;
1776 1742 }
1777   - priv->lec_arp_empty_ones = NULL;
1778   - entry = priv->lec_no_forward;
1779   - while (entry) {
1780   - next = entry->next;
  1743 + INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
  1744 +
  1745 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
1781 1746 del_timer_sync(&entry->timer);
1782 1747 lec_arp_clear_vccs(entry);
  1748 + hlist_del(&entry->next);
1783 1749 kfree(entry);
1784   - entry = next;
1785 1750 }
1786   - priv->lec_no_forward = NULL;
1787   - entry = priv->mcast_fwds;
1788   - while (entry) {
1789   - next = entry->next;
  1751 + INIT_HLIST_HEAD(&priv->lec_no_forward);
  1752 +
  1753 + hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
1790 1754 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
1791 1755 lec_arp_clear_vccs(entry);
  1756 + hlist_del(&entry->next);
1792 1757 kfree(entry);
1793   - entry = next;
1794 1758 }
1795   - priv->mcast_fwds = NULL;
  1759 + INIT_HLIST_HEAD(&priv->mcast_fwds);
1796 1760 priv->mcast_vcc = NULL;
1797   - memset(priv->lec_arp_tables, 0,
1798   - sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
1799 1761 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1800 1762 }
1801 1763  
1802 1764  
1803 1765  
1804 1766  
... ... @@ -1805,20 +1767,19 @@
1805 1767 static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
1806 1768 unsigned char *mac_addr)
1807 1769 {
1808   - unsigned short place;
1809   - struct lec_arp_table *to_return;
  1770 + struct hlist_node *node;
  1771 + struct hlist_head *head;
  1772 + struct lec_arp_table *entry;
1810 1773  
1811 1774 DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1812 1775 mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff,
1813 1776 mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff);
1814   - place = HASH(mac_addr[ETH_ALEN - 1]);
1815 1777  
1816   - to_return = priv->lec_arp_tables[place];
1817   - while (to_return) {
1818   - if (!compare_ether_addr(mac_addr, to_return->mac_addr)) {
1819   - return to_return;
  1778 + head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
  1779 + hlist_for_each_entry(entry, node, head, next) {
  1780 + if (!compare_ether_addr(mac_addr, entry->mac_addr)) {
  1781 + return entry;
1820 1782 }
1821   - to_return = to_return->next;
1822 1783 }
1823 1784 return NULL;
1824 1785 }
... ... @@ -1834,6 +1795,7 @@
1834 1795 return NULL;
1835 1796 }
1836 1797 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
  1798 + INIT_HLIST_NODE(&to_return->next);
1837 1799 init_timer(&to_return->timer);
1838 1800 to_return->timer.function = lec_arp_expire_arp;
1839 1801 to_return->timer.data = (unsigned long)to_return;
... ... @@ -1871,7 +1833,6 @@
1871 1833 unsigned long flags;
1872 1834 struct lec_arp_table *to_remove = (struct lec_arp_table *)data;
1873 1835 struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
1874   - struct lec_arp_table *entry = NULL;
1875 1836  
1876 1837 del_timer(&to_remove->timer);
1877 1838  
1878 1839  
... ... @@ -1879,30 +1840,9 @@
1879 1840 to_remove, priv,
1880 1841 to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
1881 1842 to_remove->vcc ? to_remove->recv_vcc->vci : 0);
1882   - DPRINTK("eo:%p nf:%p\n", priv->lec_arp_empty_ones,
1883   - priv->lec_no_forward);
1884 1843  
1885 1844 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1886   - if (to_remove == priv->lec_arp_empty_ones)
1887   - priv->lec_arp_empty_ones = to_remove->next;
1888   - else {
1889   - entry = priv->lec_arp_empty_ones;
1890   - while (entry && entry->next != to_remove)
1891   - entry = entry->next;
1892   - if (entry)
1893   - entry->next = to_remove->next;
1894   - }
1895   - if (!entry) {
1896   - if (to_remove == priv->lec_no_forward) {
1897   - priv->lec_no_forward = to_remove->next;
1898   - } else {
1899   - entry = priv->lec_no_forward;
1900   - while (entry && entry->next != to_remove)
1901   - entry = entry->next;
1902   - if (entry)
1903   - entry->next = to_remove->next;
1904   - }
1905   - }
  1845 + hlist_del(&to_remove->next);
1906 1846 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1907 1847  
1908 1848 lec_arp_clear_vccs(to_remove);
1909 1849  
1910 1850  
... ... @@ -1929,18 +1869,17 @@
1929 1869 {
1930 1870 unsigned long flags;
1931 1871 struct lec_priv *priv = (struct lec_priv *)data;
1932   - struct lec_arp_table *entry, *next;
  1872 + struct hlist_node *node, *next;
  1873 + struct lec_arp_table *entry;
1933 1874 unsigned long now;
1934 1875 unsigned long time_to_check;
1935 1876 int i;
1936 1877  
1937 1878 DPRINTK("lec_arp_check_expire %p\n", priv);
1938   - DPRINTK("expire: eo:%p nf:%p\n", priv->lec_arp_empty_ones,
1939   - priv->lec_no_forward);
1940 1879 now = jiffies;
1941 1880 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1942 1881 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1943   - for (entry = priv->lec_arp_tables[i]; entry != NULL;) {
  1882 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1944 1883 if ((entry->flags) & LEC_REMOTE_FLAG &&
1945 1884 priv->topology_change)
1946 1885 time_to_check = priv->forward_delay_time;
1947 1886  
... ... @@ -1954,10 +1893,8 @@
1954 1893 && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */
1955 1894 /* Remove entry */
1956 1895 DPRINTK("LEC:Entry timed out\n");
1957   - next = entry->next;
1958 1896 lec_arp_remove(priv, entry);
1959 1897 kfree(entry);
1960   - entry = next;
1961 1898 } else {
1962 1899 /* Something else */
1963 1900 if ((entry->status == ESI_VC_PENDING ||
... ... @@ -1988,7 +1925,6 @@
1988 1925 entry->last_used = jiffies;
1989 1926 entry->status = ESI_FORWARD_DIRECT;
1990 1927 }
1991   - entry = entry->next;
1992 1928 }
1993 1929 }
1994 1930 }
1995 1931  
... ... @@ -2100,15 +2036,14 @@
2100 2036 unsigned long permanent)
2101 2037 {
2102 2038 unsigned long flags;
2103   - struct lec_arp_table *entry, *next;
  2039 + struct hlist_node *node, *next;
  2040 + struct lec_arp_table *entry;
2104 2041 int i;
2105 2042  
2106 2043 DPRINTK("lec_addr_delete\n");
2107 2044 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2108 2045 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2109   - for (entry = priv->lec_arp_tables[i]; entry != NULL;
2110   - entry = next) {
2111   - next = entry->next;
  2046 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2112 2047 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
2113 2048 && (permanent ||
2114 2049 !(entry->flags & LEC_PERMANENT_FLAG))) {
... ... @@ -2132,6 +2067,7 @@
2132 2067 unsigned int targetless_le_arp)
2133 2068 {
2134 2069 unsigned long flags;
  2070 + struct hlist_node *node, *next;
2135 2071 struct lec_arp_table *entry, *tmp;
2136 2072 int i;
2137 2073  
2138 2074  
2139 2075  
2140 2076  
... ... @@ -2147,50 +2083,39 @@
2147 2083 * LANE2: ignore targetless LE_ARPs for which
2148 2084 * we have no entry in the cache. 7.1.30
2149 2085 */
2150   - if (priv->lec_arp_empty_ones) {
2151   - entry = priv->lec_arp_empty_ones;
2152   - if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
2153   - priv->lec_arp_empty_ones = entry->next;
2154   - } else {
2155   - while (entry->next && memcmp(entry->next->atm_addr,
2156   - atm_addr, ATM_ESA_LEN))
2157   - entry = entry->next;
2158   - if (entry->next) {
2159   - tmp = entry;
2160   - entry = entry->next;
2161   - tmp->next = entry->next;
2162   - } else
2163   - entry = NULL;
2164   -
2165   - }
2166   - if (entry) {
2167   - del_timer(&entry->timer);
2168   - tmp = lec_arp_find(priv, mac_addr);
2169   - if (tmp) {
2170   - del_timer(&tmp->timer);
2171   - tmp->status = ESI_FORWARD_DIRECT;
2172   - memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
2173   - tmp->vcc = entry->vcc;
2174   - tmp->old_push = entry->old_push;
2175   - tmp->last_used = jiffies;
  2086 + if (!hlist_empty(&priv->lec_arp_empty_ones)) {
  2087 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
  2088 + if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
  2089 + hlist_del(&entry->next);
2176 2090 del_timer(&entry->timer);
2177   - kfree(entry);
2178   - entry = tmp;
2179   - } else {
2180   - entry->status = ESI_FORWARD_DIRECT;
2181   - memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
2182   - entry->last_used = jiffies;
2183   - lec_arp_add(priv, entry);
  2091 + tmp = lec_arp_find(priv, mac_addr);
  2092 + if (tmp) {
  2093 + del_timer(&tmp->timer);
  2094 + tmp->status = ESI_FORWARD_DIRECT;
  2095 + memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
  2096 + tmp->vcc = entry->vcc;
  2097 + tmp->old_push = entry->old_push;
  2098 + tmp->last_used = jiffies;
  2099 + del_timer(&entry->timer);
  2100 + kfree(entry);
  2101 + entry = tmp;
  2102 + } else {
  2103 + entry->status = ESI_FORWARD_DIRECT;
  2104 + memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
  2105 + entry->last_used = jiffies;
  2106 + lec_arp_add(priv, entry);
  2107 + }
  2108 + if (remoteflag)
  2109 + entry->flags |= LEC_REMOTE_FLAG;
  2110 + else
  2111 + entry->flags &= ~LEC_REMOTE_FLAG;
  2112 + DPRINTK("After update\n");
  2113 + dump_arp_table(priv);
  2114 + goto out;
2184 2115 }
2185   - if (remoteflag)
2186   - entry->flags |= LEC_REMOTE_FLAG;
2187   - else
2188   - entry->flags &= ~LEC_REMOTE_FLAG;
2189   - DPRINTK("After update\n");
2190   - dump_arp_table(priv);
2191   - goto out;
2192 2116 }
2193 2117 }
  2118 +
2194 2119 entry = lec_arp_find(priv, mac_addr);
2195 2120 if (!entry) {
2196 2121 entry = make_entry(priv, mac_addr);
... ... @@ -2203,7 +2128,7 @@
2203 2128 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
2204 2129 del_timer(&entry->timer);
2205 2130 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2206   - for (tmp = priv->lec_arp_tables[i]; tmp; tmp = tmp->next) {
  2131 + hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) {
2207 2132 if (entry != tmp &&
2208 2133 !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
2209 2134 /* Vcc to this host exists */
... ... @@ -2226,8 +2151,7 @@
2226 2151 entry->flags &= ~LEC_REMOTE_FLAG;
2227 2152 if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
2228 2153 entry->status = ESI_VC_PENDING;
2229   - send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr,
2230   - NULL);
  2154 + send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
2231 2155 }
2232 2156 DPRINTK("After update2\n");
2233 2157 dump_arp_table(priv);
... ... @@ -2244,6 +2168,7 @@
2244 2168 void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
2245 2169 {
2246 2170 unsigned long flags;
  2171 + struct hlist_node *node;
2247 2172 struct lec_arp_table *entry;
2248 2173 int i, found_entry = 0;
2249 2174  
... ... @@ -2269,8 +2194,7 @@
2269 2194 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2270 2195 entry->recv_vcc = vcc;
2271 2196 entry->old_recv_push = old_push;
2272   - entry->next = priv->mcast_fwds;
2273   - priv->mcast_fwds = entry;
  2197 + hlist_add_head(&entry->next, &priv->mcast_fwds);
2274 2198 goto out;
2275 2199 } else if (ioc_data->receive == 1) {
2276 2200 /*
2277 2201  
... ... @@ -2300,9 +2224,8 @@
2300 2224 entry->status = ESI_UNKNOWN;
2301 2225 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2302 2226 entry->timer.function = lec_arp_expire_vcc;
  2227 + hlist_add_head(&entry->next, &priv->lec_no_forward);
2303 2228 add_timer(&entry->timer);
2304   - entry->next = priv->lec_no_forward;
2305   - priv->lec_no_forward = entry;
2306 2229 dump_arp_table(priv);
2307 2230 goto out;
2308 2231 }
... ... @@ -2320,8 +2243,7 @@
2320 2243 ioc_data->atm_addr[16], ioc_data->atm_addr[17],
2321 2244 ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
2322 2245 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2323   - for (entry = priv->lec_arp_tables[i]; entry;
2324   - entry = entry->next) {
  2246 + hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2325 2247 if (memcmp
2326 2248 (ioc_data->atm_addr, entry->atm_addr,
2327 2249 ATM_ESA_LEN) == 0) {
... ... @@ -2384,8 +2306,7 @@
2384 2306 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2385 2307 memset(entry->mac_addr, 0, ETH_ALEN);
2386 2308 entry->status = ESI_UNKNOWN;
2387   - entry->next = priv->lec_arp_empty_ones;
2388   - priv->lec_arp_empty_ones = entry;
  2309 + hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
2389 2310 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2390 2311 entry->timer.function = lec_arp_expire_vcc;
2391 2312 add_timer(&entry->timer);
2392 2313  
... ... @@ -2398,14 +2319,14 @@
2398 2319 static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
2399 2320 {
2400 2321 unsigned long flags;
  2322 + struct hlist_node *node;
2401 2323 struct lec_arp_table *entry;
2402 2324 int i;
2403 2325  
2404 2326 DPRINTK("LEC:lec_flush_complete %lx\n", tran_id);
2405 2327 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2406 2328 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2407   - for (entry = priv->lec_arp_tables[i]; entry;
2408   - entry = entry->next) {
  2329 + hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2409 2330 if (entry->flush_tran_id == tran_id
2410 2331 && entry->status == ESI_FLUSH_PENDING) {
2411 2332 struct sk_buff *skb;
2412 2333  
2413 2334  
2414 2335  
... ... @@ -2427,19 +2348,19 @@
2427 2348 unsigned char *atm_addr, unsigned long tran_id)
2428 2349 {
2429 2350 unsigned long flags;
  2351 + struct hlist_node *node;
2430 2352 struct lec_arp_table *entry;
2431 2353 int i;
2432 2354  
2433 2355 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2434 2356 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
2435   - for (entry = priv->lec_arp_tables[i]; entry;
2436   - entry = entry->next)
  2357 + hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2437 2358 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
2438 2359 entry->flush_tran_id = tran_id;
2439   - DPRINTK
2440   - ("Set flush transaction id to %lx for %p\n",
2441   - tran_id, entry);
  2360 + DPRINTK("Set flush transaction id to %lx for %p\n",
  2361 + tran_id, entry);
2442 2362 }
  2363 + }
2443 2364 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2444 2365 }
2445 2366  
2446 2367  
2447 2368  
2448 2369  
... ... @@ -2483,15 +2404,17 @@
2483 2404 static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2484 2405 {
2485 2406 unsigned long flags;
2486   - struct lec_arp_table *entry, *next;
  2407 + struct hlist_node *node, *next;
  2408 + struct lec_arp_table *entry;
2487 2409 int i;
2488 2410  
2489 2411 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
2490 2412 dump_arp_table(priv);
  2413 +
2491 2414 spin_lock_irqsave(&priv->lec_arp_lock, flags);
  2415 +
2492 2416 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2493   - for (entry = priv->lec_arp_tables[i]; entry; entry = next) {
2494   - next = entry->next;
  2417 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2495 2418 if (vcc == entry->vcc) {
2496 2419 lec_arp_remove(priv, entry);
2497 2420 kfree(entry);
2498 2421  
2499 2422  
2500 2423  
2501 2424  
2502 2425  
2503 2426  
2504 2427  
2505 2428  
2506 2429  
2507 2430  
2508 2431  
... ... @@ -2502,49 +2425,31 @@
2502 2425 }
2503 2426 }
2504 2427  
2505   - entry = priv->lec_arp_empty_ones;
2506   - priv->lec_arp_empty_ones = NULL;
2507   - while (entry != NULL) {
2508   - next = entry->next;
2509   - if (entry->vcc == vcc) { /* leave it out from the list */
  2428 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
  2429 + if (entry->vcc == vcc) {
2510 2430 lec_arp_clear_vccs(entry);
2511 2431 del_timer(&entry->timer);
  2432 + hlist_del(&entry->next);
2512 2433 kfree(entry);
2513   - } else { /* put it back to the list */
2514   - entry->next = priv->lec_arp_empty_ones;
2515   - priv->lec_arp_empty_ones = entry;
2516 2434 }
2517   - entry = next;
2518 2435 }
2519 2436  
2520   - entry = priv->lec_no_forward;
2521   - priv->lec_no_forward = NULL;
2522   - while (entry != NULL) {
2523   - next = entry->next;
  2437 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
2524 2438 if (entry->recv_vcc == vcc) {
2525 2439 lec_arp_clear_vccs(entry);
2526 2440 del_timer(&entry->timer);
  2441 + hlist_del(&entry->next);
2527 2442 kfree(entry);
2528   - } else {
2529   - entry->next = priv->lec_no_forward;
2530   - priv->lec_no_forward = entry;
2531 2443 }
2532   - entry = next;
2533 2444 }
2534 2445  
2535   - entry = priv->mcast_fwds;
2536   - priv->mcast_fwds = NULL;
2537   - while (entry != NULL) {
2538   - next = entry->next;
  2446 + hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
2539 2447 if (entry->recv_vcc == vcc) {
2540 2448 lec_arp_clear_vccs(entry);
2541 2449 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
  2450 + hlist_del(&entry->next);
2542 2451 kfree(entry);
2543   - } else {
2544   - entry->next = priv->mcast_fwds;
2545   - priv->mcast_fwds = entry;
2546 2452 }
2547   - entry = next;
2548 2453 }
2549 2454  
2550 2455 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
... ... @@ -2556,7 +2461,8 @@
2556 2461 struct atm_vcc *vcc, struct sk_buff *skb)
2557 2462 {
2558 2463 unsigned long flags;
2559   - struct lec_arp_table *entry, *prev;
  2464 + struct hlist_node *node, *next;
  2465 + struct lec_arp_table *entry, *tmp;
2560 2466 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
2561 2467 unsigned char *src;
2562 2468 #ifdef CONFIG_TR
2563 2469  
2564 2470  
... ... @@ -2569,41 +2475,23 @@
2569 2475 src = hdr->h_source;
2570 2476  
2571 2477 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2572   - entry = priv->lec_arp_empty_ones;
2573   - if (vcc == entry->vcc) {
2574   - del_timer(&entry->timer);
2575   - memcpy(entry->mac_addr, src, ETH_ALEN);
2576   - entry->status = ESI_FORWARD_DIRECT;
2577   - entry->last_used = jiffies;
2578   - priv->lec_arp_empty_ones = entry->next;
2579   - /* We might have got an entry */
2580   - if ((prev = lec_arp_find(priv, src))) {
2581   - lec_arp_remove(priv, prev);
2582   - kfree(prev);
  2478 + hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
  2479 + if (vcc == entry->vcc) {
  2480 + del_timer(&entry->timer);
  2481 + memcpy(entry->mac_addr, src, ETH_ALEN);
  2482 + entry->status = ESI_FORWARD_DIRECT;
  2483 + entry->last_used = jiffies;
  2484 + /* We might have got an entry */
  2485 + if ((tmp = lec_arp_find(priv, src))) {
  2486 + lec_arp_remove(priv, tmp);
  2487 + kfree(tmp);
  2488 + }
  2489 + hlist_del(&entry->next);
  2490 + lec_arp_add(priv, entry);
  2491 + goto out;
2583 2492 }
2584   - lec_arp_add(priv, entry);
2585   - goto out;
2586 2493 }
2587   - prev = entry;
2588   - entry = entry->next;
2589   - while (entry && entry->vcc != vcc) {
2590   - prev = entry;
2591   - entry = entry->next;
2592   - }
2593   - if (!entry) {
2594   - DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2595   - goto out;
2596   - }
2597   - del_timer(&entry->timer);
2598   - memcpy(entry->mac_addr, src, ETH_ALEN);
2599   - entry->status = ESI_FORWARD_DIRECT;
2600   - entry->last_used = jiffies;
2601   - prev->next = entry->next;
2602   - if ((prev = lec_arp_find(priv, src))) {
2603   - lec_arp_remove(priv, prev);
2604   - kfree(prev);
2605   - }
2606   - lec_arp_add(priv, entry);
  2494 + DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2607 2495 out:
2608 2496 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2609 2497 }
... ... @@ -72,18 +72,18 @@
72 72 struct lec_priv {
73 73 struct net_device_stats stats;
74 74 unsigned short lecid; /* Lecid of this client */
75   - struct lec_arp_table *lec_arp_empty_ones;
  75 + struct hlist_head lec_arp_empty_ones;
76 76 /* Used for storing VCC's that don't have a MAC address attached yet */
77   - struct lec_arp_table *lec_arp_tables[LEC_ARP_TABLE_SIZE];
  77 + struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE];
78 78 /* Actual LE ARP table */
79   - struct lec_arp_table *lec_no_forward;
  79 + struct hlist_head lec_no_forward;
80 80 /*
81 81 * Used for storing VCC's (and forward packets from) which are to
82 82 * age out by not using them to forward packets.
83 83 * This is because to some LE clients there will be 2 VCCs. Only
84 84 * one of them gets used.
85 85 */
86   - struct lec_arp_table *mcast_fwds;
  86 + struct hlist_head mcast_fwds;
87 87 /*
88 88 * With LANEv2 it is possible that BUS (or a special multicast server)
89 89 * establishes multiple Multicast Forward VCCs to us. This list
... ... @@ -11,7 +11,7 @@
11 11 #include <linux/atmlec.h>
12 12  
13 13 struct lec_arp_table {
14   - struct lec_arp_table *next; /* Linked entry list */
  14 + struct hlist_node next; /* Linked entry list */
15 15 unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */
16 16 unsigned char mac_addr[ETH_ALEN]; /* Mac address */
17 17 int is_rdesc; /* Mac address is a route descriptor */