Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ATM]: [lec] add reference counting to lec_arp entries

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

authored by

Chas Williams and committed by
David S. Miller
33a9c2d4 987e46bd

+29 -14
+28 -14
net/atm/lec.c
··· 107 107 struct sk_buff *skb)); 108 108 static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc); 109 109 110 + /* must be done under lec_arp_lock */ 111 + static inline void lec_arp_hold(struct lec_arp_table *entry) 112 + { 113 + atomic_inc(&entry->usage); 114 + } 115 + 116 + static inline void lec_arp_put(struct lec_arp_table *entry) 117 + { 118 + if (atomic_dec_and_test(&entry->usage)) 119 + kfree(entry); 120 + } 121 + 122 + 110 123 static struct lane2_ops lane2_ops = { 111 124 lane2_resolve, /* resolve, spec 3.1.3 */ 112 125 lane2_associate_req, /* associate_req, spec 3.1.4 */ ··· 808 795 entry = lec_arp_find(priv, src); 809 796 if (entry && entry->vcc != vcc) { 810 797 lec_arp_remove(priv, entry); 811 - kfree(entry); 798 + lec_arp_put(entry); 812 799 } 813 800 } 814 801 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); ··· 1739 1726 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 1740 1727 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { 1741 1728 lec_arp_remove(priv, entry); 1742 - kfree(entry); 1729 + lec_arp_put(entry); 1743 1730 } 1744 1731 INIT_HLIST_HEAD(&priv->lec_arp_tables[i]); 1745 1732 } ··· 1748 1735 del_timer_sync(&entry->timer); 1749 1736 lec_arp_clear_vccs(entry); 1750 1737 hlist_del(&entry->next); 1751 - kfree(entry); 1738 + lec_arp_put(entry); 1752 1739 } 1753 1740 INIT_HLIST_HEAD(&priv->lec_arp_empty_ones); 1754 1741 ··· 1756 1743 del_timer_sync(&entry->timer); 1757 1744 lec_arp_clear_vccs(entry); 1758 1745 hlist_del(&entry->next); 1759 - kfree(entry); 1746 + lec_arp_put(entry); 1760 1747 } 1761 1748 INIT_HLIST_HEAD(&priv->lec_no_forward); 1762 1749 ··· 1764 1751 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ 1765 1752 lec_arp_clear_vccs(entry); 1766 1753 hlist_del(&entry->next); 1767 - kfree(entry); 1754 + lec_arp_put(entry); 1768 1755 } 1769 1756 INIT_HLIST_HEAD(&priv->mcast_fwds); 1770 1757 priv->mcast_vcc = NULL; ··· 1812 1799 to_return->last_used = jiffies; 1813 1800 to_return->priv = priv; 1814 1801 skb_queue_head_init(&to_return->tx_wait); 1802 + atomic_set(&to_return->usage, 1); 1815 1803 return to_return; 1816 1804 } 1817 1805 ··· 1857 1843 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 1858 1844 1859 1845 lec_arp_clear_vccs(to_remove); 1860 - kfree(to_remove); 1846 + lec_arp_put(to_remove); 1861 1847 } 1862 1848 1863 1849 /* ··· 1905 1891 /* Remove entry */ 1906 1892 DPRINTK("LEC:Entry timed out\n"); 1907 1893 lec_arp_remove(priv, entry); 1908 - kfree(entry); 1894 + lec_arp_put(entry); 1909 1895 } else { 1910 1896 /* Something else */ 1911 1897 if ((entry->status == ESI_VC_PENDING || ··· 2059 2045 && (permanent || 2060 2046 !(entry->flags & LEC_PERMANENT_FLAG))) { 2061 2047 lec_arp_remove(priv, entry); 2062 - kfree(entry); 2048 + lec_arp_put(entry); 2063 2049 } 2064 2050 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 2065 2051 return 0; ··· 2108 2094 tmp->old_push = entry->old_push; 2109 2095 tmp->last_used = jiffies; 2110 2096 del_timer(&entry->timer); 2111 - kfree(entry); 2097 + lec_arp_put(entry); 2112 2098 entry = tmp; 2113 2099 } else { 2114 2100 entry->status = ESI_FORWARD_DIRECT; ··· 2428 2414 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { 2429 2415 if (vcc == entry->vcc) { 2430 2416 lec_arp_remove(priv, entry); 2431 - kfree(entry); 2417 + lec_arp_put(entry); 2432 2418 if (priv->mcast_vcc == vcc) { 2433 2419 priv->mcast_vcc = NULL; 2434 2420 } ··· 2441 2427 lec_arp_clear_vccs(entry); 2442 2428 del_timer(&entry->timer); 2443 2429 hlist_del(&entry->next); 2444 - kfree(entry); 2430 + lec_arp_put(entry); 2445 2431 } 2446 2432 } 2447 2433 ··· 2450 2436 lec_arp_clear_vccs(entry); 2451 2437 del_timer(&entry->timer); 2452 2438 hlist_del(&entry->next); 2453 - kfree(entry); 2439 + lec_arp_put(entry); 2454 2440 } 2455 2441 } 2456 2442 ··· 2459 2445 lec_arp_clear_vccs(entry); 2460 2446 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ 2461 2447 hlist_del(&entry->next); 2462 - kfree(entry); 2448 + lec_arp_put(entry); 2463 2449 } 2464 2450 } 2465 2451 ··· 2495 2481 /* We might have got an entry */ 2496 2482 if ((tmp = lec_arp_find(priv, src))) { 2497 2483 lec_arp_remove(priv, tmp); 2498 - kfree(tmp); 2484 + lec_arp_put(tmp); 2499 2485 } 2500 2486 hlist_del(&entry->next); 2501 2487 lec_arp_add(priv, entry);
+1
net/atm/lec_arpc.h
··· 47 47 * the length of the tlvs array 48 48 */ 49 49 struct sk_buff_head tx_wait; /* wait queue for outgoing packets */ 50 + atomic_t usage; /* usage count */ 50 51 }; 51 52 52 53 /*