lkml.org 
[lkml]   [2001]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    "David S. Miller" wrote:
    >
    > Unified diffs only please... Thanks.

    Hrm, here's one with a -u option, this what you're looking for?


    --- ../../../linux/net/core/dev.c Mon Dec 11 14:29:35 2000
    +++ dev.c Sat Jan 6 14:14:10 2001
    @@ -1,4 +1,4 @@
    -/*
    +/* -*- linux-c -*-
    * NET3 Protocol independent device support routines.
    *
    * This program is free software; you can redistribute it and/or
    @@ -131,9 +132,17 @@
    * and the routines to invoke.
    *
    * Why 16. Because with 16 the only overlap we get on a hash of the
    - * low nibble of the protocol value is RARP/SNAP/X.25.
    + * low nibble of the protocol value is RARP/SNAP/X.25.
    + *
    + * NOTE: That is no longer true with the addition of VLAN tags. Not
    + * sure which should go first, but I bet it won't make much
    + * difference if we are running VLANs. The good news is that
    + * this protocol won't be in the list unless compiled in, so
    + * the average user (w/out VLANs) will not be adversly affected.
    + * --BLG
    *
    * 0800 IP
    + * 8100 802.1Q VLAN
    * 0001 802.3
    * 0002 AX.25
    * 0004 802.2
    @@ -178,6 +187,250 @@
    #endif


    +#define BENS_FAST_DEV_LOOKUP
    +#ifdef BENS_FAST_DEV_LOOKUP
    +/* Fash Device Lookup code. Should give much better than
    + * linear speed when looking for devices by idx or name.
    + * --Ben (greearb@candelatech.com)
    + */
    +#define FDL_HASH_LEN 256
    +
    +/* #define FDL_DEBUG */
    +
    +struct dev_hash_node {
    + struct net_device* dev;
    + struct dev_hash_node* next;
    +};
    +
    +struct dev_hash_node* fdl_name_base[FDL_HASH_LEN];/* hashed by name */
    +struct dev_hash_node* fdl_idx_base[FDL_HASH_LEN]; /* hashed by index */
    +int fdl_initialized_yet = 0;
    +
    +/* TODO: Make these inline methods */
    +/* Nice cheesy little hash method to be used on device-names (eth0, ppp0, etc) */
    +int fdl_calc_name_idx(const char* dev_name) {
    + int tmp = 0;
    + int i;
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "fdl_calc_name_idx, name: %s\n", dev_name);
    +#endif
    + for (i = 0; dev_name[i]; i++) {
    + tmp += (int)(dev_name[i]);
    + }
    + if (i > 3) {
    + tmp += (dev_name[i-2] * 10); /* might add a little spread to the hash */
    + tmp += (dev_name[i-3] * 100); /* might add a little spread to the hash */
    + }
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "fdl_calc_name_idx, rslt: %i\n", (int)(tmp % FDL_HASH_LEN));
    +#endif
    + return (tmp % FDL_HASH_LEN);
    +}
    +
    +int fdl_calc_index_idx(const int ifindex) {
    + return (ifindex % FDL_HASH_LEN);
    +}
    +
    +
    +/* Better have a lock on the dev_base before calling this... */
    +int __fdl_ensure_init(void) {
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_ensure_init, enter\n");
    +#endif
    + if (! fdl_initialized_yet) {
    + /* only do this once.. */
    + int i;
    + int idx = 0; /* into the hash table */
    + struct net_device* dev = dev_base;
    + struct dev_hash_node* dhn;
    +
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_ensure_init, doing real work...");
    +#endif
    +
    + fdl_initialized_yet = 1; /* it has been attempted at least... */
    +
    + for (i = 0; i<FDL_HASH_LEN; i++) {
    + fdl_name_base[i] = NULL;
    + fdl_idx_base[i] = NULL;
    + }
    +
    + /* add any current devices to the hash tables at this time. Note that
    + * this method must be called with locks on the dev_base acquired.
    + */
    + while (dev) {
    +
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_ensure_init, dev: %p dev: %s, idx: %i\n", dev, dev->name, idx);
    +#endif
    + /* first, take care of the hash-by-name */
    + idx = fdl_calc_name_idx(dev->name);
    + dhn = kmalloc(sizeof(struct dev_hash_node), GFP_ATOMIC);
    + if (dhn) {
    + dhn->dev = dev;
    + dhn->next = fdl_name_base[idx];
    + fdl_name_base[idx] = dhn;
    + }
    + else {
    + /* Nasty..couldn't get memory... */
    + return -ENOMEM;
    + }
    +
    + /* now, do the hash-by-idx */
    + idx = fdl_calc_index_idx(dev->ifindex);
    + dhn = kmalloc(sizeof(struct dev_hash_node), GFP_ATOMIC);
    + if (dhn) {
    + dhn->dev = dev;
    + dhn->next = fdl_idx_base[idx];
    + fdl_idx_base[idx] = dhn;
    + }
    + else {
    + /* Nasty..couldn't get memory... */
    + return -ENOMEM;
    + }
    +
    + dev = dev->next;
    + }
    + fdl_initialized_yet = 2; /* initialization actually worked */
    + }
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_ensure_init, end, fdl_initialized_yet: %i\n", fdl_initialized_yet);
    +#endif
    + if (fdl_initialized_yet == 2) {
    + return 0;
    + }
    + else {
    + return -1;
    + }
    +}/* fdl_ensure_init */
    +
    +
    +/* called from register_netdevice, assumes dev is locked, and that no one
    + * will be calling __find_dev_by_name before this exits.. etc.
    + */
    +int __fdl_register_netdevice(struct net_device* dev) {
    + if (__fdl_ensure_init() == 0) {
    + /* first, take care of the hash-by-name */
    + int idx = fdl_calc_name_idx(dev->name);
    + struct dev_hash_node* dhn = kmalloc(sizeof(struct dev_hash_node), GFP_ATOMIC);
    +
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_register_netdevice, dev: %p dev: %s, idx: %i", dev, dev->name, idx);
    +#endif
    +
    + if (dhn) {
    + dhn->dev = dev;
    + dhn->next = fdl_name_base[idx];
    + fdl_name_base[idx] = dhn;
    + }
    + else {
    + /* Nasty..couldn't get memory... */
    + /* Don't try to use these hash tables any more... */
    + fdl_initialized_yet = 1; /* tried, but failed */
    + return -ENOMEM;
    + }
    +
    + /* now, do the hash-by-idx */
    + idx = fdl_calc_index_idx(dev->ifindex);
    + dhn = kmalloc(sizeof(struct dev_hash_node), GFP_ATOMIC);
    +
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_register_netdevice, ifindex: %i, idx: %i", dev->ifindex, idx);
    +#endif
    +
    + if (dhn) {
    + dhn->dev = dev;
    + dhn->next = fdl_idx_base[idx];
    + fdl_idx_base[idx] = dhn;
    + }
    + else {
    + /* Nasty..couldn't get memory... */
    + /* Don't try to use these hash tables any more... */
    + fdl_initialized_yet = 1; /* tried, but failed */
    + return -ENOMEM;
    + }
    + }
    + return 0;
    +} /* fdl_register_netdevice */
    +
    +
    +/* called from register_netdevice, assumes dev is locked, and that no one
    + * will be calling __find_dev_by_name, etc. Returns 0 if found & removed one,
    + * returns -1 otherwise.
    + */
    +int __fdl_unregister_netdevice(struct net_device* dev) {
    + int retval = -1;
    + if (fdl_initialized_yet == 2) { /* If we've been initialized correctly... */
    + /* first, take care of the hash-by-name */
    + int idx = fdl_calc_name_idx(dev->name);
    + struct dev_hash_node* prev = fdl_name_base[idx];
    + struct dev_hash_node* cur = NULL;
    +
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__fdl_unregister_netdevice, dev: %p dev: %s, idx: %i", dev, dev->name, idx);
    +#endif
    +
    + if (prev) {
    + if (strcmp(dev->name, prev->dev->name) == 0) {
    + /* it's the first one... */
    + fdl_name_base[idx] = prev->next;
    + kfree(prev);
    + retval = 0;
    + }
    + else {
    + cur = prev->next;
    + while (cur) {
    + if (strcmp(dev->name, cur->dev->name) == 0) {
    + prev->next = cur->next;
    + kfree(cur);
    + retval = 0;
    + break;
    + }
    + else {
    + prev = cur;
    + cur = cur->next;
    + }
    + }
    + }
    + }
    +
    + /* Now, the hash-by-index */
    + idx = fdl_calc_index_idx(dev->ifindex);
    + prev = fdl_idx_base[idx];
    + cur = NULL;
    + if (prev) {
    + if (dev->ifindex == prev->dev->ifindex) {
    + /* it's the first one... */
    + fdl_idx_base[idx] = prev->next;
    + kfree(prev);
    + retval = 0;
    + }
    + else {
    + cur = prev->next;
    + while (cur) {
    + if (dev->ifindex == cur->dev->ifindex) {
    + prev->next = cur->next;
    + kfree(cur);
    + retval = 0;
    + break;
    + }
    + else {
    + prev = cur;
    + cur = cur->next;
    + }
    + }
    + }
    + }
    + }/* if we ensured init OK */
    + return retval;
    +} /* fdl_unregister_netdevice */
    +
    +
    +
    +#endif /* BENS_FAST_DEV_LOOKUP */
    +
    +
    +
    /******************************************************************************************

    Protocol management and registration routines
    @@ -396,7 +649,26 @@
    struct net_device *__dev_get_by_name(const char *name)
    {
    struct net_device *dev;
    -
    +
    +#ifdef BENS_FAST_DEV_LOOKUP
    + int idx = fdl_calc_name_idx(name);
    + struct dev_hash_node* dhn;
    + if (fdl_initialized_yet == 2) {
    +#ifdef FDL_DEBUG
    + printk(KERN_ERR "__dev_get_by_name, name: %s idx: %i\n", name, idx);
    +#endif
    + dhn = fdl_name_base[idx];
    + while (dhn) {
    + if (strcmp(dhn->dev->name, name) == 0) {
    + /* printk(KERN_ERR "__dev_get_by_name, found it: %p\n", dhn->dev); */
    + return dhn->dev;
    + }
    + dhn = dhn->next;
    + }
    + /* printk(KERN_ERR "__dev_get_by_name, didn't find it for name: %s\n", name); */
    + return NULL;
    + }
    +#endif
    for (dev = dev_base; dev != NULL; dev = dev->next) {
    if (strcmp(dev->name, name) == 0)
    return dev;
    @@ -472,6 +744,20 @@
    {
    struct net_device *dev;

    +#ifdef BENS_FAST_DEV_LOOKUP
    + int idx = fdl_calc_index_idx(ifindex);
    + struct dev_hash_node* dhn;
    + if (fdl_initialized_yet == 2) { /* have we gone through initialization before... */
    + dhn = fdl_idx_base[idx];
    + while (dhn) {
    + if (dhn->dev->ifindex == ifindex)
    + return dhn->dev;
    + dhn = dhn->next;
    + }
    + return NULL;
    + }
    +#endif
    +
    for (dev = dev_base; dev != NULL; dev = dev->next) {
    if (dev->ifindex == ifindex)
    return dev;
    @@ -549,15 +835,17 @@

    /*
    * If you need over 100 please also fix the algorithm...
    + * Increased it to deal with VLAN interfaces. It is unlikely
    + * that this many will ever be added, but it can't hurt! -BLG
    */
    - for (i = 0; i < 100; i++) {
    + for (i = 0; i < 8192; i++) {
    sprintf(buf,name,i);
    if (__dev_get_by_name(buf) == NULL) {
    strcpy(dev->name, buf);
    return i;
    }
    }
    - return -ENFILE; /* Over 100 of the things .. bail out! */
    + return -ENFILE; /* Over 8192 of the things .. bail out! */
    }

    /**
    @@ -2067,8 +2355,16 @@
    return -EBUSY;
    if (__dev_get_by_name(ifr->ifr_newname))
    return -EEXIST;
    +#ifdef BENS_FAST_DEV_LOOKUP
    + write_lock_bh(&dev_base_lock); /* gotta lock it to remove stuff */
    + __fdl_unregister_netdevice(dev); /* remove it from the hash.. */
    +#endif
    memcpy(dev->name, ifr->ifr_newname, IFNAMSIZ);
    dev->name[IFNAMSIZ-1] = 0;
    +#ifdef BENS_FAST_DEV_LOOKUP
    + __fdl_register_netdevice(dev);
    + write_unlock_bh(&dev_base_lock); /* gotta lock it to add stuff too */
    +#endif
    notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
    return 0;

    @@ -2342,6 +2638,12 @@
    }
    dev->next = NULL;
    write_lock_bh(&dev_base_lock);
    +#ifdef BENS_FAST_DEV_LOOKUP
    + /* Must do this before dp is set to dev, or it could be added twice, once
    + * on initialization based on dev_base, and once again after that...
    + */
    + __fdl_register_netdevice(dev);
    +#endif
    *dp = dev;
    dev_hold(dev);
    write_unlock_bh(&dev_base_lock);
    @@ -2396,6 +2698,12 @@
    dev->next = NULL;
    dev_init_scheduler(dev);
    write_lock_bh(&dev_base_lock);
    +#ifdef BENS_FAST_DEV_LOOKUP
    + /* Must do this before dp is set to dev, or it could be added twice, once
    + * on initialization based on dev_base, and once again after that...
    + */
    + __fdl_register_netdevice(dev);
    +#endif
    *dp = dev;
    dev_hold(dev);
    dev->deadbeaf = 0;
    @@ -2468,7 +2776,10 @@
    if (d == dev) {
    write_lock_bh(&dev_base_lock);
    *dp = d->next;
    - write_unlock_bh(&dev_base_lock);
    +#ifdef BENS_FAST_DEV_LOOKUP
    + __fdl_unregister_netdevice(dev);
    +#endif
    + write_unlock_bh(&dev_base_lock);
    break;
    }
    }

    --
    Ben Greear (greearb@candelatech.com) http://www.candelatech.com
    Author of ScryMUD: scry.wanfear.com 4444 (Released under GPL)
    http://scry.wanfear.com http://scry.wanfear.com/~greear
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 12:52    [W:0.043 / U:0.424 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site