diff options
| author | Chas Williams <chas@cmf.nrl.navy.mil> | 2006-09-29 20:17:17 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-09-29 20:17:17 -0400 |
| commit | 6656e3c4c8e0c80f2d2bfece574876d269f64861 (patch) | |
| tree | b4470a2f0ffd372eb3886a6e344cd336ec430d03 | |
| parent | 33a9c2d4b758279c5077fc15d221b385a574ae0b (diff) | |
[ATM]: [lec] use refcnt to protect lec_arp_entries outside lock
Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/atm/lec.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c index c5d1f9e9a647..66c57c1091a8 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
| @@ -396,7 +396,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 396 | priv->stats.tx_dropped++; | 396 | priv->stats.tx_dropped++; |
| 397 | dev_kfree_skb(skb); | 397 | dev_kfree_skb(skb); |
| 398 | } | 398 | } |
| 399 | return 0; | 399 | goto out; |
| 400 | } | 400 | } |
| 401 | #if DUMP_PACKETS > 0 | 401 | #if DUMP_PACKETS > 0 |
| 402 | printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci); | 402 | printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci); |
| @@ -428,6 +428,9 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 428 | netif_wake_queue(dev); | 428 | netif_wake_queue(dev); |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | out: | ||
| 432 | if (entry) | ||
| 433 | lec_arp_put(entry); | ||
| 431 | dev->trans_start = jiffies; | 434 | dev->trans_start = jiffies; |
| 432 | return 0; | 435 | return 0; |
| 433 | } | 436 | } |
| @@ -1888,6 +1891,7 @@ static void lec_arp_check_expire(void *data) | |||
| 1888 | 1891 | ||
| 1889 | DPRINTK("lec_arp_check_expire %p\n", priv); | 1892 | DPRINTK("lec_arp_check_expire %p\n", priv); |
| 1890 | now = jiffies; | 1893 | now = jiffies; |
| 1894 | restart: | ||
| 1891 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 1895 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 1892 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 1896 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 1893 | hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { | 1897 | hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) { |
| @@ -1927,14 +1931,16 @@ static void lec_arp_check_expire(void *data) | |||
| 1927 | time_after_eq(now, entry->timestamp + | 1931 | time_after_eq(now, entry->timestamp + |
| 1928 | priv->path_switching_delay)) { | 1932 | priv->path_switching_delay)) { |
| 1929 | struct sk_buff *skb; | 1933 | struct sk_buff *skb; |
| 1934 | struct atm_vcc *vcc = entry->vcc; | ||
| 1930 | 1935 | ||
| 1931 | while ((skb = | 1936 | lec_arp_hold(entry); |
| 1932 | skb_dequeue(&entry->tx_wait)) != | 1937 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 1933 | NULL) | 1938 | while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) |
| 1934 | lec_send(entry->vcc, skb, | 1939 | lec_send(vcc, skb, entry->priv); |
| 1935 | entry->priv); | ||
| 1936 | entry->last_used = jiffies; | 1940 | entry->last_used = jiffies; |
| 1937 | entry->status = ESI_FORWARD_DIRECT; | 1941 | entry->status = ESI_FORWARD_DIRECT; |
| 1942 | lec_arp_put(entry); | ||
| 1943 | goto restart; | ||
| 1938 | } | 1944 | } |
| 1939 | } | 1945 | } |
| 1940 | } | 1946 | } |
| @@ -1977,6 +1983,7 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, | |||
| 1977 | if (entry->status == ESI_FORWARD_DIRECT) { | 1983 | if (entry->status == ESI_FORWARD_DIRECT) { |
| 1978 | /* Connection Ok */ | 1984 | /* Connection Ok */ |
| 1979 | entry->last_used = jiffies; | 1985 | entry->last_used = jiffies; |
| 1986 | lec_arp_hold(entry); | ||
| 1980 | *ret_entry = entry; | 1987 | *ret_entry = entry; |
| 1981 | found = entry->vcc; | 1988 | found = entry->vcc; |
| 1982 | goto out; | 1989 | goto out; |
| @@ -2007,6 +2014,7 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, | |||
| 2007 | * or BUS flood limit was reached for an entry which is | 2014 | * or BUS flood limit was reached for an entry which is |
| 2008 | * in ESI_ARP_PENDING or ESI_VC_PENDING state. | 2015 | * in ESI_ARP_PENDING or ESI_VC_PENDING state. |
| 2009 | */ | 2016 | */ |
| 2017 | lec_arp_hold(entry); | ||
| 2010 | *ret_entry = entry; | 2018 | *ret_entry = entry; |
| 2011 | DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, | 2019 | DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, |
| 2012 | entry->vcc); | 2020 | entry->vcc); |
| @@ -2335,18 +2343,24 @@ static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) | |||
| 2335 | int i; | 2343 | int i; |
| 2336 | 2344 | ||
| 2337 | DPRINTK("LEC:lec_flush_complete %lx\n", tran_id); | 2345 | DPRINTK("LEC:lec_flush_complete %lx\n", tran_id); |
| 2346 | restart: | ||
| 2338 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2347 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2339 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 2348 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 2340 | hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { | 2349 | hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) { |
| 2341 | if (entry->flush_tran_id == tran_id | 2350 | if (entry->flush_tran_id == tran_id |
| 2342 | && entry->status == ESI_FLUSH_PENDING) { | 2351 | && entry->status == ESI_FLUSH_PENDING) { |
| 2343 | struct sk_buff *skb; | 2352 | struct sk_buff *skb; |
| 2353 | struct atm_vcc *vcc = entry->vcc; | ||
| 2344 | 2354 | ||
| 2345 | while ((skb = | 2355 | lec_arp_hold(entry); |
| 2346 | skb_dequeue(&entry->tx_wait)) != NULL) | 2356 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2347 | lec_send(entry->vcc, skb, entry->priv); | 2357 | while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) |
| 2358 | lec_send(vcc, skb, entry->priv); | ||
| 2359 | entry->last_used = jiffies; | ||
| 2348 | entry->status = ESI_FORWARD_DIRECT; | 2360 | entry->status = ESI_FORWARD_DIRECT; |
| 2361 | lec_arp_put(entry); | ||
| 2349 | DPRINTK("LEC_ARP: Flushed\n"); | 2362 | DPRINTK("LEC_ARP: Flushed\n"); |
| 2363 | goto restart; | ||
| 2350 | } | 2364 | } |
| 2351 | } | 2365 | } |
| 2352 | } | 2366 | } |
