[RFC][1/2] remove atm_find_ci(); convert vcc_sklist to hash
From: chas williams <hidden>
Date: 2003-10-08 12:46:58
# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1435 -> 1.1436 # drivers/atm/he.c 1.28 -> 1.29 # drivers/atm/eni.c 1.29 -> 1.30 # net/atm/proc.c 1.34 -> 1.35 # drivers/atm/atmtcp.c 1.25 -> 1.26 # net/atm/signaling.c 1.24 -> 1.25 # include/linux/atmdev.h 1.37 -> 1.38 # drivers/atm/fore200e.c 1.26 -> 1.27 # net/atm/common.c 1.59 -> 1.60 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/10/08 chas@relax.cmf.nrl.navy.mil 1.1436 # [ATM]: convert vcc list to hash # -------------------------------------------- # diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
--- a/drivers/atm/atmtcp.c Wed Oct 8 08:29:48 2003
+++ b/drivers/atm/atmtcp.c Wed Oct 8 08:29:48 2003@@ -158,6 +158,7 @@ struct atm_vcc *vcc; struct hlist_node *node; struct sock *s; + int i; if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD; if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
@@ -166,14 +167,18 @@ if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 || ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL; read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - vcc = atm_sk(s); - if (vcc->dev != dev) - continue; - if ((vcc->vpi >> ci.vpi_bits) || - (vcc->vci >> ci.vci_bits)) { - read_unlock(&vcc_sklist_lock); - return -EBUSY; + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; + + sk_for_each(s, node, head) { + vcc = atm_sk(s); + if (vcc->dev != dev) + continue; + if ((vcc->vpi >> ci.vpi_bits) || + (vcc->vci >> ci.vci_bits)) { + read_unlock(&vcc_sklist_lock); + return -EBUSY; + } } } read_unlock(&vcc_sklist_lock);
@@ -244,6 +249,7 @@ struct sock *s; struct hlist_node *node; struct atm_vcc *walk; + int i; atmtcp_dev = (struct atm_dev *) vcc->dev_data; dev_data = PRIV(atmtcp_dev);
@@ -254,11 +260,15 @@ shutdown_atm_dev(atmtcp_dev); vcc->dev_data = NULL; read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - walk = atm_sk(s); - if (walk->dev != atmtcp_dev) - continue; - wake_up(walk->sk->sk_sleep); + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; + + sk_for_each(s, node, head) { + walk = atm_sk(s); + if (walk->dev != atmtcp_dev) + continue; + wake_up(walk->sk->sk_sleep); + } } read_unlock(&vcc_sklist_lock); }
@@ -272,7 +282,7 @@ struct hlist_node *node; struct atm_vcc *out_vcc = NULL; struct sk_buff *new_skb; - int result = 0; + int i, result = 0; if (!skb->len) return 0; dev = vcc->dev_data;
@@ -283,14 +293,18 @@ goto done; } read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - out_vcc = atm_sk(s); - if (out_vcc->dev != dev) - continue; - if (out_vcc->vpi == ntohs(hdr->vpi) && - out_vcc->vci == ntohs(hdr->vci) && - out_vcc->qos.rxtp.traffic_class != ATM_NONE) - break; + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; + + sk_for_each(s, node, head) { + out_vcc = atm_sk(s); + if (out_vcc->dev != dev) + continue; + if (out_vcc->vpi == ntohs(hdr->vpi) && + out_vcc->vci == ntohs(hdr->vci) && + out_vcc->qos.rxtp.traffic_class != ATM_NONE) + break; + } } read_unlock(&vcc_sklist_lock); if (!out_vcc) {
diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c
--- a/drivers/atm/eni.c Wed Oct 8 08:29:48 2003
+++ b/drivers/atm/eni.c Wed Oct 8 08:29:48 2003@@ -2147,30 +2147,34 @@ skb_queue_len(&tx->backlog)); } read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - struct eni_vcc *eni_vcc; - int length; + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; - vcc = atm_sk(s); - if (vcc->dev != dev) - continue; - eni_vcc = ENI_VCC(vcc); - if (--left) continue; - length = sprintf(page,"vcc %4d: ",vcc->vci); - if (eni_vcc->rx) { - length += sprintf(page+length,"0x%06lx-0x%06lx " - "(%6ld bytes)", - eni_vcc->recv-eni_dev->ram, - eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1, - eni_vcc->words*4); - if (eni_vcc->tx) length += sprintf(page+length,", "); + sk_for_each(s, node, head) { + struct eni_vcc *eni_vcc; + int length; + + vcc = atm_sk(s); + if (vcc->dev != dev) + continue; + eni_vcc = ENI_VCC(vcc); + if (--left) continue; + length = sprintf(page,"vcc %4d: ",vcc->vci); + if (eni_vcc->rx) { + length += sprintf(page+length,"0x%06lx-0x%06lx " + "(%6ld bytes)", + eni_vcc->recv-eni_dev->ram, + eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1, + eni_vcc->words*4); + if (eni_vcc->tx) length += sprintf(page+length,", "); + } + if (eni_vcc->tx) + length += sprintf(page+length,"tx[%d], txing %d bytes", + eni_vcc->tx->index,eni_vcc->txing); + page[length] = '\n'; + read_unlock(&vcc_sklist_lock); + return length+1; } - if (eni_vcc->tx) - length += sprintf(page+length,"tx[%d], txing %d bytes", - eni_vcc->tx->index,eni_vcc->txing); - page[length] = '\n'; - read_unlock(&vcc_sklist_lock); - return length+1; } read_unlock(&vcc_sklist_lock); for (i = 0; i < eni_dev->free_len; i++) {
diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
--- a/drivers/atm/fore200e.c Wed Oct 8 08:29:48 2003
+++ b/drivers/atm/fore200e.c Wed Oct 8 08:29:48 2003@@ -1071,14 +1071,16 @@ struct sock *s; struct atm_vcc* vcc; struct hlist_node *node; + int i; read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { + + sk_for_each(s, node, &vcc_hash[rpd->atm_header.vci & (VCC_HTABLE_SIZE-1)]) { vcc = atm_sk(s); if (vcc->dev != fore200e->atm_dev) - continue; + continue; if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) { - read_unlock(&vcc_sklist_lock); + read_unlock(&vcc_sklist_lock); return vcc; } }
@@ -2606,7 +2608,7 @@ struct sock *s; struct hlist_node *node; struct fore200e* fore200e = FORE200E_DEV(dev); - int len, left = *pos; + int i, len, left = *pos; if (!left--) {
@@ -2852,15 +2854,18 @@ " VCCs:\n address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n"); read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - vcc = atm_sk(s); + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; - if (vcc->dev != fore200e->atm_dev) + sk_for_each(s, node, head) { + vcc = atm_sk(s); + + if (vcc->dev != fore200e->atm_dev) continue; - fore200e_vcc = FORE200E_VCC(vcc); + fore200e_vcc = FORE200E_VCC(vcc); - len += sprintf(page + len, + len += sprintf(page + len, " %x\t%d.%d:%d\t\t(%d/%d)\t(%d/%d)\n", (u32)(unsigned long)vcc, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
@@ -2869,6 +2874,7 @@ fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu, fore200e_vcc->rx_max_pdu ); + } } read_unlock(&vcc_sklist_lock);
diff -Nru a/drivers/atm/he.c b/drivers/atm/he.c
--- a/drivers/atm/he.c Wed Oct 8 08:29:48 2003
+++ b/drivers/atm/he.c Wed Oct 8 08:29:48 2003@@ -328,6 +328,7 @@ static __inline__ struct atm_vcc* __find_vcc(struct he_dev *he_dev, unsigned cid) { + struct hlist_head *head; struct atm_vcc *vcc; struct hlist_node *node; struct sock *s;
@@ -336,8 +337,9 @@ vpi = cid >> he_dev->vcibits; vci = cid & ((1 << he_dev->vcibits) - 1); + head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)]; - sk_for_each(s, node, &vcc_sklist) { + sk_for_each(s, node, head) { vcc = atm_sk(s); if (vcc->dev == he_dev->atm_dev && vcc->vci == vci && vcc->vpi == vpi &&
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h Wed Oct 8 08:29:48 2003
+++ b/include/linux/atmdev.h Wed Oct 8 08:29:48 2003@@ -380,7 +380,9 @@ unsigned long atm_options; /* ATM layer options */ }; -extern struct hlist_head vcc_sklist; +#define VCC_HTABLE_SIZE 32 + +extern struct hlist_head vcc_hash[VCC_HTABLE_SIZE]; extern rwlock_t vcc_sklist_lock; #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c Wed Oct 8 08:29:48 2003
+++ b/net/atm/common.c Wed Oct 8 08:29:48 2003@@ -38,13 +38,16 @@ #define DPRINTK(format,args...) #endif - -HLIST_HEAD(vcc_sklist); +struct hlist_head vcc_hash[VCC_HTABLE_SIZE]; rwlock_t vcc_sklist_lock = RW_LOCK_UNLOCKED; void __vcc_insert_socket(struct sock *sk) { - sk_add_node(sk, &vcc_sklist); + struct atm_vcc *vcc = atm_sk(sk); + struct hlist_head *head = &vcc_hash[vcc->vci & + (VCC_HTABLE_SIZE - 1)]; + sk->sk_hashent = vcc->vci & (VCC_HTABLE_SIZE - 1); + sk_add_node(sk, head); } void vcc_insert_socket(struct sock *sk)
@@ -80,7 +83,7 @@ } -EXPORT_SYMBOL(vcc_sklist); +EXPORT_SYMBOL(vcc_hash); EXPORT_SYMBOL(vcc_sklist_lock); EXPORT_SYMBOL(vcc_insert_socket); EXPORT_SYMBOL(vcc_remove_socket);
@@ -250,11 +253,13 @@ static int check_ci(struct atm_vcc *vcc, short vpi, int vci) { + struct hlist_head *head = &vcc_hash[vci & + (VCC_HTABLE_SIZE - 1)]; struct hlist_node *node; struct sock *s; struct atm_vcc *walk; - sk_for_each(s, node, &vcc_sklist) { + sk_for_each(s, node, head) { walk = atm_sk(s); if (walk->dev != vcc->dev) continue;
diff -Nru a/net/atm/proc.c b/net/atm/proc.c
--- a/net/atm/proc.c Wed Oct 8 08:29:48 2003
+++ b/net/atm/proc.c Wed Oct 8 08:29:48 2003@@ -64,6 +64,7 @@ } struct vcc_state { + int bucket; struct sock *sk; int family; };
@@ -75,19 +76,30 @@ return !family || (vcc->sk->sk_family == family); } -static int __vcc_walk(struct sock **sock, int family, loff_t l) +static int __vcc_walk(struct sock **sock, int family, int *bucket, loff_t l) { struct sock *sk = *sock; if (sk == (void *)1) { - sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist); + for (*bucket = 0; *bucket < VCC_HTABLE_SIZE; ++*bucket) { + struct hlist_head *head = &vcc_hash[*bucket]; + + sk = hlist_empty(head) ? NULL : __sk_head(head); + if (sk) + break; + } l--; } +try_again: for (; sk; sk = sk_next(sk)) { l -= compare_family(sk, family); if (l < 0) goto out; } + if (!sk && ++*bucket < VCC_HTABLE_SIZE) { + sk = sk_head(&vcc_hash[*bucket]); + goto try_again; + } sk = (void *)1; out: *sock = sk;
@@ -96,7 +108,7 @@ static inline void *vcc_walk(struct vcc_state *state, loff_t l) { - return __vcc_walk(&state->sk, state->family, l) ? + return __vcc_walk(&state->sk, state->family, &state->bucket, l) ? state : NULL; }
@@ -207,9 +219,10 @@ default: seq_printf(seq, "%3d", vcc->sk->sk_family); } - seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d\n", vcc->flags, vcc->sk->sk_err, + seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d [%d] 0x%x\n", vcc->flags, vcc->sk->sk_err, atomic_read(&vcc->sk->sk_wmem_alloc),vcc->sk->sk_sndbuf, - atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf); + atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf, + atomic_read(&vcc->sk->sk_refcnt), vcc->sk->sk_hashent); } static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c Wed Oct 8 08:29:48 2003
+++ b/net/atm/signaling.c Wed Oct 8 08:29:48 2003@@ -216,6 +216,7 @@ { struct hlist_node *node; struct sock *s; + int i; DPRINTK("sigd_close\n"); sigd = NULL;
@@ -224,11 +225,15 @@ skb_queue_purge(&vcc->sk->sk_receive_queue); read_lock(&vcc_sklist_lock); - sk_for_each(s, node, &vcc_sklist) { - struct atm_vcc *vcc = atm_sk(s); + for(i = 0; i < VCC_HTABLE_SIZE; ++i) { + struct hlist_head *head = &vcc_hash[i]; - if (vcc->dev) - purge_vcc(vcc); + sk_for_each(s, node, head) { + struct atm_vcc *vcc = atm_sk(s); + + if (vcc->dev) + purge_vcc(vcc); + } } read_unlock(&vcc_sklist_lock); }