From babcda74e9d96bb58fd9c6c5112dbdbff169e695 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 3 Nov 2008 21:11:17 -0800 Subject: drivers/net: Kill now superfluous ->last_rx stores. The generic packet receive code takes care of setting netdev->last_rx when necessary, for the sake of the bonding ARP monitor. Drivers need not do it any more. Some cases had to be skipped over because the drivers were making use of the ->last_rx value themselves. Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 7e857e9..274d495 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1684,7 +1684,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) skb->protocol = htons(npindex_to_ethertype[npi]); skb_reset_mac_header(skb); netif_rx(skb); - ppp->dev->last_rx = jiffies; } } return; -- cgit v1.1 From 52256cfc9f81cd8713e00a0713e68347bbffba5a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 19 Nov 2008 22:22:30 -0800 Subject: ppp: convert to net_device_ops Convert this driver to network device ops. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 274d495..c1e57c0 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -971,8 +971,13 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; } +static const struct net_device_ops ppp_netdev_ops = { + .ndo_do_ioctl = ppp_net_ioctl, +}; + static void ppp_setup(struct net_device *dev) { + dev->netdev_ops = &ppp_netdev_ops; dev->hard_header_len = PPP_HDRLEN; dev->mtu = PPP_MTU; dev->addr_len = 0; @@ -2436,7 +2441,6 @@ ppp_create_interface(int unit, int *retp) dev->priv = ppp; dev->hard_start_xmit = ppp_start_xmit; - dev->do_ioctl = ppp_net_ioctl; ret = -EEXIST; mutex_lock(&all_ppp_mutex); -- cgit v1.1 From c8019bf3aff653cceb64f66489fc299ee5957b57 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 20 Nov 2008 04:24:17 -0800 Subject: netdevice ppp: Convert directly reference of netdev->priv 1. Use netdev_priv(dev) to replace dev->priv. 2. Alloc netdev's private data by alloc_netdev(). Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c1e57c0..bad99e8 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -886,7 +886,7 @@ out_chrdev: static int ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct ppp *ppp = (struct ppp *) dev->priv; + struct ppp *ppp = netdev_priv(dev); int npi, proto; unsigned char *pp; @@ -931,7 +931,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) static int ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct ppp *ppp = dev->priv; + struct ppp *ppp = netdev_priv(dev); int err = -EFAULT; void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data; struct ppp_stats stats; @@ -2418,13 +2418,12 @@ ppp_create_interface(int unit, int *retp) int ret = -ENOMEM; int i; - ppp = kzalloc(sizeof(struct ppp), GFP_KERNEL); - if (!ppp) - goto out; - dev = alloc_netdev(0, "", ppp_setup); + dev = alloc_netdev(sizeof(struct ppp), "", ppp_setup); if (!dev) goto out1; + ppp = netdev_priv(dev); + ppp->dev = dev; ppp->mru = PPP_MRU; init_ppp_file(&ppp->file, INTERFACE); ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */ @@ -2437,8 +2436,6 @@ ppp_create_interface(int unit, int *retp) ppp->minseq = -1; skb_queue_head_init(&ppp->mrq); #endif /* CONFIG_PPP_MULTILINK */ - ppp->dev = dev; - dev->priv = ppp; dev->hard_start_xmit = ppp_start_xmit; @@ -2476,8 +2473,6 @@ out2: mutex_unlock(&all_ppp_mutex); free_netdev(dev); out1: - kfree(ppp); -out: *retp = ret; return NULL; } -- cgit v1.1 From 008298231abbeb91bc7be9e8b078607b816d1a4a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 20 Nov 2008 20:14:53 -0800 Subject: netdev: add more functions to netdevice ops This patch moves neigh_setup and hard_start_xmit into the network device ops structure. For bisection, fix all the previously converted drivers as well. Bonding driver took the biggest hit on this. Added a prefetch of the hard_start_xmit in the fast path to try and reduce any impact this would have. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index bad99e8..1b15a08 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -972,7 +972,8 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } static const struct net_device_ops ppp_netdev_ops = { - .ndo_do_ioctl = ppp_net_ioctl, + .ndo_start_xmit = ppp_start_xmit, + .ndo_do_ioctl = ppp_net_ioctl, }; static void ppp_setup(struct net_device *dev) @@ -2437,8 +2438,6 @@ ppp_create_interface(int unit, int *retp) skb_queue_head_init(&ppp->mrq); #endif /* CONFIG_PPP_MULTILINK */ - dev->hard_start_xmit = ppp_start_xmit; - ret = -EEXIST; mutex_lock(&all_ppp_mutex); if (unit < 0) -- cgit v1.1 From 7a95d267fb62cd6b80ef73be0592bbbe1dbd5df7 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 17 Dec 2008 00:34:06 -0800 Subject: net: ppp_generic - use idr technique instead of cardmaps Use idr technique instead of own implemented cardmaps. It saves us a number of lines and gives an ability to use library functions. Signed-off-by: Cyrill Gorcunov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 183 ++++++++++++---------------------------------- 1 file changed, 48 insertions(+), 135 deletions(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1b15a08..3ee7830 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -172,35 +173,13 @@ struct channel { */ /* - * A cardmap represents a mapping from unsigned integers to pointers, - * and provides a fast "find lowest unused number" operation. - * It uses a broad (32-way) tree with a bitmap at each level. - * It is designed to be space-efficient for small numbers of entries - * and time-efficient for large numbers of entries. - */ -#define CARDMAP_ORDER 5 -#define CARDMAP_WIDTH (1U << CARDMAP_ORDER) -#define CARDMAP_MASK (CARDMAP_WIDTH - 1) - -struct cardmap { - int shift; - unsigned long inuse; - struct cardmap *parent; - void *ptr[CARDMAP_WIDTH]; -}; -static void *cardmap_get(struct cardmap *map, unsigned int nr); -static int cardmap_set(struct cardmap **map, unsigned int nr, void *ptr); -static unsigned int cardmap_find_first_free(struct cardmap *map); -static void cardmap_destroy(struct cardmap **map); - -/* * all_ppp_mutex protects the all_ppp_units mapping. * It also ensures that finding a ppp unit in the all_ppp_units map * and updating its file.refcnt field is atomic. */ static DEFINE_MUTEX(all_ppp_mutex); -static struct cardmap *all_ppp_units; static atomic_t ppp_unit_count = ATOMIC_INIT(0); +static struct idr ppp_units_idr; /* * all_channels_lock protects all_channels and last_channel_index, @@ -269,6 +248,9 @@ static struct channel *ppp_find_channel(int unit); static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); +static int unit_get(struct idr *p, void *ptr); +static void unit_put(struct idr *p, int n); +static void *unit_find(struct idr *p, int n); static struct class *ppp_class; @@ -870,6 +852,8 @@ static int __init ppp_init(void) "ppp"); } + idr_init(&ppp_units_idr); + out: if (err) printk(KERN_ERR "failed to register PPP device (%d)\n", err); @@ -2440,10 +2424,22 @@ ppp_create_interface(int unit, int *retp) ret = -EEXIST; mutex_lock(&all_ppp_mutex); - if (unit < 0) - unit = cardmap_find_first_free(all_ppp_units); - else if (cardmap_get(all_ppp_units, unit) != NULL) - goto out2; /* unit already exists */ + + if (unit < 0) { + unit = unit_get(&ppp_units_idr, ppp); + if (unit < 0) { + *retp = unit; + goto out2; + } + } else { + if (unit_find(&ppp_units_idr, unit)) + goto out2; /* unit already exists */ + else { + /* darn, someone is cheatting us? */ + *retp = -EINVAL; + goto out2; + } + } /* Initialize the new ppp unit */ ppp->file.index = unit; @@ -2451,23 +2447,18 @@ ppp_create_interface(int unit, int *retp) ret = register_netdev(dev); if (ret != 0) { + unit_put(&ppp_units_idr, unit); printk(KERN_ERR "PPP: couldn't register device %s (%d)\n", dev->name, ret); goto out2; } atomic_inc(&ppp_unit_count); - ret = cardmap_set(&all_ppp_units, unit, ppp); - if (ret != 0) - goto out3; - mutex_unlock(&all_ppp_mutex); + *retp = 0; return ppp; -out3: - atomic_dec(&ppp_unit_count); - unregister_netdev(dev); out2: mutex_unlock(&all_ppp_mutex); free_netdev(dev); @@ -2507,7 +2498,7 @@ static void ppp_shutdown_interface(struct ppp *ppp) unregister_netdev(dev); free_netdev(dev); } - cardmap_set(&all_ppp_units, ppp->file.index, NULL); + unit_put(&ppp_units_idr, ppp->file.index); ppp->file.dead = 1; ppp->owner = NULL; wake_up_interruptible(&ppp->file.rwait); @@ -2561,7 +2552,7 @@ static void ppp_destroy_interface(struct ppp *ppp) static struct ppp * ppp_find_unit(int unit) { - return cardmap_get(all_ppp_units, unit); + return unit_find(&ppp_units_idr, unit); } /* @@ -2679,123 +2670,45 @@ static void __exit ppp_cleanup(void) /* should never happen */ if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) printk(KERN_ERR "PPP: removing module but units remain!\n"); - cardmap_destroy(&all_ppp_units); unregister_chrdev(PPP_MAJOR, "ppp"); device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); class_destroy(ppp_class); + idr_destroy(&ppp_units_idr); } /* - * Cardmap implementation. + * Units handling. Caller must protect concurrent access + * by holding all_ppp_mutex */ -static void *cardmap_get(struct cardmap *map, unsigned int nr) + +/* get new free unit number and associate pointer with it */ +static int unit_get(struct idr *p, void *ptr) { - struct cardmap *p; - int i; + int unit, err; - for (p = map; p != NULL; ) { - if ((i = nr >> p->shift) >= CARDMAP_WIDTH) - return NULL; - if (p->shift == 0) - return p->ptr[i]; - nr &= ~(CARDMAP_MASK << p->shift); - p = p->ptr[i]; +again: + if (idr_pre_get(p, GFP_KERNEL) == 0) { + printk(KERN_ERR "Out of memory expanding drawable idr\n"); + return -ENOMEM; } - return NULL; -} -static int cardmap_set(struct cardmap **pmap, unsigned int nr, void *ptr) -{ - struct cardmap *p; - int i; + err = idr_get_new_above(p, ptr, 0, &unit); + if (err == -EAGAIN) + goto again; - p = *pmap; - if (p == NULL || (nr >> p->shift) >= CARDMAP_WIDTH) { - do { - /* need a new top level */ - struct cardmap *np = kzalloc(sizeof(*np), GFP_KERNEL); - if (!np) - goto enomem; - np->ptr[0] = p; - if (p != NULL) { - np->shift = p->shift + CARDMAP_ORDER; - p->parent = np; - } else - np->shift = 0; - p = np; - } while ((nr >> p->shift) >= CARDMAP_WIDTH); - *pmap = p; - } - while (p->shift > 0) { - i = (nr >> p->shift) & CARDMAP_MASK; - if (p->ptr[i] == NULL) { - struct cardmap *np = kzalloc(sizeof(*np), GFP_KERNEL); - if (!np) - goto enomem; - np->shift = p->shift - CARDMAP_ORDER; - np->parent = p; - p->ptr[i] = np; - } - if (ptr == NULL) - clear_bit(i, &p->inuse); - p = p->ptr[i]; - } - i = nr & CARDMAP_MASK; - p->ptr[i] = ptr; - if (ptr != NULL) - set_bit(i, &p->inuse); - else - clear_bit(i, &p->inuse); - return 0; - enomem: - return -ENOMEM; + return unit; } -static unsigned int cardmap_find_first_free(struct cardmap *map) +/* put unit number back to a pool */ +static void unit_put(struct idr *p, int n) { - struct cardmap *p; - unsigned int nr = 0; - int i; - - if ((p = map) == NULL) - return 0; - for (;;) { - i = find_first_zero_bit(&p->inuse, CARDMAP_WIDTH); - if (i >= CARDMAP_WIDTH) { - if (p->parent == NULL) - return CARDMAP_WIDTH << p->shift; - p = p->parent; - i = (nr >> p->shift) & CARDMAP_MASK; - set_bit(i, &p->inuse); - continue; - } - nr = (nr & (~CARDMAP_MASK << p->shift)) | (i << p->shift); - if (p->shift == 0 || p->ptr[i] == NULL) - return nr; - p = p->ptr[i]; - } + idr_remove(p, n); } -static void cardmap_destroy(struct cardmap **pmap) +/* get pointer associated with the number */ +static void *unit_find(struct idr *p, int n) { - struct cardmap *p, *np; - int i; - - for (p = *pmap; p != NULL; p = np) { - if (p->shift != 0) { - for (i = 0; i < CARDMAP_WIDTH; ++i) - if (p->ptr[i] != NULL) - break; - if (i < CARDMAP_WIDTH) { - np = p->ptr[i]; - p->ptr[i] = NULL; - continue; - } - } - np = p->parent; - kfree(p); - } - *pmap = NULL; + return idr_find(p, n); } /* Module/initialization stuff */ -- cgit v1.1 From ab5024ab23b78c86a0a1425defcdde48710fe449 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 18 Dec 2008 22:59:32 -0800 Subject: net: ppp_generic - use DEFINE_IDR for static initialization We could use DEFINE_IDR for statically allocated idr that allow us to save a few lines of code. And spell fix. Signed-off-by: Cyrill Gorcunov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net/ppp_generic.c') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3ee7830..c832d60 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -179,7 +179,7 @@ struct channel { */ static DEFINE_MUTEX(all_ppp_mutex); static atomic_t ppp_unit_count = ATOMIC_INIT(0); -static struct idr ppp_units_idr; +static DEFINE_IDR(ppp_units_idr); /* * all_channels_lock protects all_channels and last_channel_index, @@ -852,8 +852,6 @@ static int __init ppp_init(void) "ppp"); } - idr_init(&ppp_units_idr); - out: if (err) printk(KERN_ERR "failed to register PPP device (%d)\n", err); @@ -2435,7 +2433,7 @@ ppp_create_interface(int unit, int *retp) if (unit_find(&ppp_units_idr, unit)) goto out2; /* unit already exists */ else { - /* darn, someone is cheatting us? */ + /* darn, someone is cheating us? */ *retp = -EINVAL; goto out2; } -- cgit v1.1