1/* 2 * Equalizer Load-balancer for serial network interfaces. 3 * 4 * (c) Copyright 1995 Simon "Guru Aleph-Null" Janes 5 * NCM: Network and Communications Management, Inc. 6 * 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 * The author may be reached as simon@ncm.com, or C/O 12 * NCM 13 * Attn: Simon Janes 14 * 6803 Whittier Ave 15 * McLean VA 22101 16 * Phone: 1-703-847-0040 ext 103 17 */ 18 19/* 20 * Sources: 21 * skeleton.c by Donald Becker. 22 * Inspirations: 23 * The Harried and Overworked Alan Cox 24 * Conspiracies: 25 * The Alan Cox and Mike McLagan plot to get someone else to do the code, 26 * which turned out to be me. 27 */ 28 29/* 30 * $Log: eql.c,v $ 31 * Revision 1.1.1.1 2008/10/15 03:26:36 james26_jang 32 * Initial. 33 * 34 * Revision 1.1.1.1 2008/07/21 09:15:06 james26_jang 35 * New UI, New QoS, New wireless driver(4.151.10.29), ipmonitor. 36 * 37 * Revision 1.1 2008/07/17 12:33:03 james26_jang 38 * *** empty log message *** 39 * 40 * Revision 1.1.1.1 2007/02/15 12:11:33 jiahao 41 * initial update 42 * 43 * Revision 1.1.1.1 2007/01/25 12:51:55 jiahao_jhou 44 * 45 * 46 * Revision 1.1.1.1 2003/02/03 22:37:46 mhuang 47 * LINUX_2_4 branch snapshot from linux-mips.org CVS 48 * 49 * Revision 1.2 1996/04/11 17:51:52 guru 50 * Added one-line eql_remove_slave patch. 51 * 52 * Revision 1.1 1996/04/11 17:44:17 guru 53 * Initial revision 54 * 55 * Revision 3.13 1996/01/21 15:17:18 alan 56 * tx_queue_len changes. 57 * reformatted. 58 * 59 * Revision 3.12 1995/03/22 21:07:51 anarchy 60 * Added capable() checks on configuration. 61 * Moved header file. 62 * 63 * Revision 3.11 1995/01/19 23:14:31 guru 64 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 65 * (priority_Bps) + bytes_queued * 8; 66 * 67 * Revision 3.10 1995/01/19 23:07:53 guru 68 * back to 69 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 70 * (priority_Bps) + bytes_queued; 71 * 72 * Revision 3.9 1995/01/19 22:38:20 guru 73 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 74 * (priority_Bps) + bytes_queued * 4; 75 * 76 * Revision 3.8 1995/01/19 22:30:55 guru 77 * slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 78 * (priority_Bps) + bytes_queued * 2; 79 * 80 * Revision 3.7 1995/01/19 21:52:35 guru 81 * printk's trimmed out. 82 * 83 * Revision 3.6 1995/01/19 21:49:56 guru 84 * This is working pretty well. I gained 1 K/s in speed.. now it's just 85 * robustness and printk's to be diked out. 86 * 87 * Revision 3.5 1995/01/18 22:29:59 guru 88 * still crashes the kernel when the lock_wait thing is woken up. 89 * 90 * Revision 3.4 1995/01/18 21:59:47 guru 91 * Broken set-bit locking snapshot 92 * 93 * Revision 3.3 1995/01/17 22:09:18 guru 94 * infinite sleep in a lock somewhere.. 95 * 96 * Revision 3.2 1995/01/15 16:46:06 guru 97 * Log trimmed of non-pertinent 1.x branch messages 98 * 99 * Revision 3.1 1995/01/15 14:41:45 guru 100 * New Scheduler and timer stuff... 101 * 102 * Revision 1.15 1995/01/15 14:29:02 guru 103 * Will make 1.14 (now 1.15) the 3.0 branch, and the 1.12 the 2.0 branch, the one 104 * with the dumber scheduler 105 * 106 * Revision 1.14 1995/01/15 02:37:08 guru 107 * shock.. the kept-new-versions could have zonked working 108 * stuff.. shudder 109 * 110 * Revision 1.13 1995/01/15 02:36:31 guru 111 * big changes 112 * 113 * scheduler was torn out and replaced with something smarter 114 * 115 * global names not prefixed with eql_ were renamed to protect 116 * against namespace collisions 117 * 118 * a few more abstract interfaces were added to facilitate any 119 * potential change of datastructure. the driver is still using 120 * a linked list of slaves. going to a heap would be a bit of 121 * an overkill. 122 * 123 * this compiles fine with no warnings. 124 * 125 * the locking mechanism and timer stuff must be written however, 126 * this version will not work otherwise 127 * 128 */ 129 130#include <linux/module.h> 131#include <linux/kernel.h> 132#include <linux/init.h> 133#include <linux/timer.h> 134#include <linux/netdevice.h> 135 136#include <linux/if.h> 137#include <linux/if_arp.h> 138#include <linux/if_eql.h> 139 140#include <asm/uaccess.h> 141 142static char version[] __initdata = 143 "Equalizer1996: $Revision: 1.1.1.1 $ $Date: 2008/10/15 03:26:36 $ Simon Janes (simon@ncm.com)\n"; 144 145#ifndef EQL_DEBUG 146/* #undef EQL_DEBUG -* print nothing at all, not even a boot-banner */ 147/* #define EQL_DEBUG 1 -* print only the boot-banner */ 148/* #define EQL_DEBUG 5 -* print major function entries */ 149/* #define EQL_DEBUG 20 -* print subfunction entries */ 150/* #define EQL_DEBUG 50 -* print utility entries */ 151/* #define EQL_DEBUG 100 -* print voluminous function entries */ 152#define EQL_DEBUG 1 153#endif 154static unsigned int eql_debug = EQL_DEBUG; 155 156static int eql_init(struct net_device *dev); /* */ 157static int eql_open(struct net_device *dev); /* */ 158static int eql_close(struct net_device *dev); /* */ 159static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* */ 160static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev); /* */ 161 162static struct net_device_stats *eql_get_stats(struct net_device *dev); /* */ 163 164/* ioctl() handlers 165 ---------------- */ 166static int eql_enslave(struct net_device *dev, slaving_request_t *srq); /* */ 167static int eql_emancipate(struct net_device *dev, slaving_request_t *srq); /* */ 168 169static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ 170static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ 171 172static int eql_g_master_cfg(struct net_device *dev, master_config_t *mc); /* */ 173static int eql_s_master_cfg(struct net_device *dev, master_config_t *mc); /* */ 174 175static inline int eql_is_slave(struct net_device *dev); /* */ 176static inline int eql_is_master(struct net_device *dev); /* */ 177 178static slave_t *eql_new_slave(void); /* */ 179static void eql_delete_slave(slave_t *slave); /* */ 180 181/* static long eql_slave_priority(slave_t *slave); -* */ 182static inline int eql_number_slaves(slave_queue_t *queue); /* */ 183 184static inline int eql_is_empty(slave_queue_t *queue); /* */ 185static inline int eql_is_full(slave_queue_t *queue); /* */ 186 187static slave_queue_t *eql_new_slave_queue(struct net_device *dev); /* */ 188static void eql_delete_slave_queue(slave_queue_t *queue); /* */ 189 190static int eql_insert_slave(slave_queue_t *queue, slave_t *slave); /* */ 191static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave); /* */ 192 193/* static int eql_insert_slave_dev(slave_queue_t *queue, struct net_device *dev); -* */ 194static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ 195 196static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue); /* */ 197static inline slave_t *eql_best_slave(slave_queue_t *queue); /* */ 198static inline slave_t *eql_first_slave(slave_queue_t *queue); /* */ 199static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave); /* */ 200 201static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave); /* */ 202static inline void eql_schedule_slaves(slave_queue_t *queue); /* */ 203 204static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ 205 206/* static inline eql_lock_slave_queue(slave_queue_t *queue); -* */ 207/* static inline eql_unlock_slave_queue(slave_queue_t *queue); -* */ 208 209static void eql_timer(unsigned long param); /* */ 210 211/* struct net_device * interface functions 212 --------------------------------------------------------- 213 */ 214 215static int __init eql_init(struct net_device *dev) 216{ 217 static unsigned version_printed; 218 /* static unsigned num_masters = 0; */ 219 equalizer_t *eql = 0; 220 221 SET_MODULE_OWNER(dev); 222 223 if ( version_printed++ == 0 && eql_debug > 0) 224 printk(version); 225 /* 226 * Initialize the device structure. 227 */ 228 dev->priv = kmalloc (sizeof (equalizer_t), GFP_KERNEL); 229 if (dev->priv == NULL) 230 return -ENOMEM; 231 memset (dev->priv, 0, sizeof (equalizer_t)); 232 eql = (equalizer_t *) dev->priv; 233 234 eql->stats = kmalloc (sizeof (struct net_device_stats), GFP_KERNEL); 235 if (eql->stats == NULL) 236 { 237 kfree(dev->priv); 238 dev->priv = NULL; 239 return -ENOMEM; 240 } 241 memset (eql->stats, 0, sizeof (struct net_device_stats)); 242 243 init_timer (&eql->timer); 244 eql->timer.data = (unsigned long) dev->priv; 245 eql->timer.expires = jiffies+EQL_DEFAULT_RESCHED_IVAL; 246 eql->timer.function = &eql_timer; 247 eql->timer_on = 0; 248 249 dev->open = eql_open; 250 dev->stop = eql_close; 251 dev->do_ioctl = eql_ioctl; 252 dev->hard_start_xmit = eql_slave_xmit; 253 dev->get_stats = eql_get_stats; 254 255 /* 256 * Fill in the fields of the device structure with 257 * eql-generic values. 258 */ 259 260 /* 261 * Now we undo some of the things that eth_setup does 262 * that we don't like 263 */ 264 265 dev->mtu = EQL_DEFAULT_MTU; /* set to 576 in eql.h */ 266 dev->flags = IFF_MASTER; 267 268 dev->type = ARPHRD_SLIP; 269 dev->tx_queue_len = 5; /* Hands them off fast */ 270 271 return 0; 272} 273 274static int eql_open(struct net_device *dev) 275{ 276 equalizer_t *eql = (equalizer_t *) dev->priv; 277 slave_queue_t *new_queue; 278 279#ifdef EQL_DEBUG 280 if (eql_debug >= 5) 281 printk ("%s: open\n", dev->name); 282#endif 283 284 printk ("%s: remember to turn off Van-Jacobson compression on your slave devices.\n", dev->name); 285 286 new_queue = eql_new_slave_queue (dev); 287 288 if (new_queue != 0) 289 { 290 new_queue->master_dev = dev; 291 eql->queue = new_queue; 292 eql->queue->lock = 0; 293 eql->min_slaves = 1; 294 eql->max_slaves = EQL_DEFAULT_MAX_SLAVES; /* 4 usually... */ 295 296 printk ("%s: adding timer\n", dev->name); 297 eql->timer_on = 1; 298 add_timer (&eql->timer); 299 300 return 0; 301 } 302 return -ENOMEM; 303} 304 305 306static int eql_close(struct net_device *dev) 307{ 308 equalizer_t *eql = (equalizer_t *) dev->priv; 309 310#ifdef EQL_DEBUG 311 if ( eql_debug >= 5) 312 printk ("%s: close\n", dev->name); 313#endif 314 /* 315 * The timer has to be stopped first before we start hacking away 316 * at the data structure it scans every so often... 317 */ 318 319#ifdef EQL_DEBUG 320 printk ("%s: stopping timer\n", dev->name); 321#endif 322 eql->timer_on = 0; 323 del_timer (&eql->timer); 324 325 eql_delete_slave_queue (eql->queue); 326 327 return 0; 328} 329 330 331static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 332{ 333 if(cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG && 334 !capable(CAP_NET_ADMIN)) 335 return -EPERM; 336 switch (cmd) 337 { 338 case EQL_ENSLAVE: 339 return eql_enslave (dev, (slaving_request_t *) ifr->ifr_data); 340 case EQL_EMANCIPATE: 341 return eql_emancipate (dev, (slaving_request_t *) ifr->ifr_data); 342 case EQL_GETSLAVECFG: 343 return eql_g_slave_cfg (dev, (slave_config_t *) ifr->ifr_data); 344 case EQL_SETSLAVECFG: 345 return eql_s_slave_cfg (dev, (slave_config_t *) ifr->ifr_data); 346 case EQL_GETMASTRCFG: 347 return eql_g_master_cfg (dev, (master_config_t *) ifr->ifr_data); 348 case EQL_SETMASTRCFG: 349 return eql_s_master_cfg (dev, (master_config_t *) ifr->ifr_data); 350 default: 351 return -EOPNOTSUPP; 352 } 353} 354 355 356static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) 357{ 358 equalizer_t *eql = (equalizer_t *) dev->priv; 359 struct net_device *slave_dev = 0; 360 slave_t *slave; 361 362 if (skb == NULL) 363 return 0; 364 365 eql_schedule_slaves (eql->queue); 366 367 slave = eql_best_slave (eql->queue); 368 slave_dev = slave ? slave->dev : 0; 369 370 if ( slave_dev != 0 ) 371 { 372#ifdef EQL_DEBUG 373 if (eql_debug >= 100) 374 printk ("%s: %d slaves xmitng %d B %s\n", 375 dev->name, eql_number_slaves (eql->queue), skb->len, 376 slave_dev->name); 377#endif 378 skb->dev = slave_dev; 379 skb->priority = 1; 380 slave->bytes_queued += skb->len; 381 dev_queue_xmit (skb); 382 eql->stats->tx_packets++; 383 } 384 else 385 { 386 /* 387 * The alternative for this is the return 1 and have 388 * dev_queue_xmit just queue it up on the eql's queue. 389 */ 390 391 eql->stats->tx_dropped++; 392 dev_kfree_skb(skb); 393 } 394 return 0; 395} 396 397 398static struct net_device_stats * eql_get_stats(struct net_device *dev) 399{ 400 equalizer_t *eql = (equalizer_t *) dev->priv; 401 return eql->stats; 402} 403 404/* 405 * Private ioctl functions 406 */ 407 408static int eql_enslave(struct net_device *dev, slaving_request_t *srqp) 409{ 410 struct net_device *master_dev; 411 struct net_device *slave_dev; 412 slaving_request_t srq; 413 414 if (copy_from_user(&srq, srqp, sizeof (slaving_request_t))) 415 { 416#ifdef EQL_DEBUG 417 if (eql_debug >= 20) 418 printk ("EQL enslave: error detected by copy_from_user\n"); 419#endif 420 return -EFAULT; 421 } 422 423#ifdef EQL_DEBUG 424 if (eql_debug >= 20) 425 printk ("%s: enslave '%s' %ld bps\n", dev->name, 426 srq.slave_name, srq.priority); 427#endif 428 master_dev = dev; /* for "clarity" */ 429 slave_dev = __dev_get_by_name (srq.slave_name); 430 431 if (master_dev != 0 && slave_dev != 0) 432 { 433 if ((master_dev->flags & IFF_UP) == IFF_UP) 434 { 435 /*slave is not a master & not already a slave:*/ 436 if (! eql_is_master (slave_dev) && 437 ! eql_is_slave (slave_dev) ) 438 { 439 slave_t *s = eql_new_slave (); 440 equalizer_t *eql = 441 (equalizer_t *) master_dev->priv; 442 if (!s) 443 return -ENOMEM; 444 s->dev = slave_dev; 445 s->priority = srq.priority; 446 s->priority_bps = srq.priority; 447 s->priority_Bps = srq.priority / 8; 448 slave_dev->flags |= IFF_SLAVE; 449 eql_insert_slave (eql->queue, s); 450 return 0; 451 } 452#ifdef EQL_DEBUG 453 else if (eql_debug >= 20) 454 printk ("EQL enslave: slave is master or slave is already slave\n"); 455#endif 456 } 457#ifdef EQL_DEBUG 458 else if (eql_debug >= 20) 459 printk ("EQL enslave: master device not up!\n"); 460#endif 461 } 462#ifdef EQL_DEBUG 463 else if (eql_debug >= 20) 464 printk ("EQL enslave: master or slave are NULL"); 465#endif 466 return -EINVAL; 467} 468 469static int eql_emancipate(struct net_device *dev, slaving_request_t *srqp) 470{ 471 struct net_device *master_dev; 472 struct net_device *slave_dev; 473 slaving_request_t srq; 474 475 if (copy_from_user(&srq, srqp, sizeof (slaving_request_t))) 476 return -EFAULT; 477 478#ifdef EQL_DEBUG 479 if (eql_debug >= 20) 480 printk ("%s: emancipate `%s`\n", dev->name, srq.slave_name); 481#endif 482 master_dev = dev; /* for "clarity" */ 483 slave_dev = __dev_get_by_name (srq.slave_name); 484 485 if ( eql_is_slave (slave_dev) ) /* really is a slave */ 486 { 487 equalizer_t *eql = (equalizer_t *) master_dev->priv; 488 slave_dev->flags = slave_dev->flags & ~IFF_SLAVE; 489 eql_remove_slave_dev (eql->queue, slave_dev); 490 return 0; 491 } 492 return -EINVAL; 493} 494 495 496static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp) 497{ 498 slave_t *slave; 499 equalizer_t *eql; 500 struct net_device *slave_dev; 501 slave_config_t sc; 502 503 if (copy_from_user (&sc, scp, sizeof (slave_config_t))) 504 return -EFAULT; 505 506#ifdef EQL_DEBUG 507 if (eql_debug >= 20) 508 printk ("%s: get config for slave `%s'\n", dev->name, sc.slave_name); 509#endif 510 eql = (equalizer_t *) dev->priv; 511 slave_dev = __dev_get_by_name (sc.slave_name); 512 513 if ( eql_is_slave (slave_dev) ) 514 { 515 slave = eql_find_slave_dev (eql->queue, slave_dev); 516 if (slave != 0) 517 { 518 sc.priority = slave->priority; 519 if (copy_to_user (scp, &sc, sizeof (slave_config_t))) 520 return -EFAULT; 521 return 0; 522 } 523 } 524 return -EINVAL; 525} 526 527 528static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp) 529{ 530 slave_t *slave; 531 equalizer_t *eql; 532 struct net_device *slave_dev; 533 slave_config_t sc; 534 535 if (copy_from_user (&sc, scp, sizeof (slave_config_t))) 536 return -EFAULT; 537 538#ifdef EQL_DEBUG 539 if (eql_debug >= 20) 540 printk ("%s: set config for slave `%s'\n", dev->name, sc.slave_name); 541#endif 542 543 544 eql = (equalizer_t *) dev->priv; 545 slave_dev = __dev_get_by_name (sc.slave_name); 546 547 if ( eql_is_slave (slave_dev) ) 548 { 549 slave = eql_find_slave_dev (eql->queue, slave_dev); 550 if (slave != 0) 551 { 552 slave->priority = sc.priority; 553 slave->priority_bps = sc.priority; 554 slave->priority_Bps = sc.priority / 8; 555 return 0; 556 } 557 } 558 return -EINVAL; 559} 560 561 562static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp) 563{ 564 equalizer_t *eql; 565 master_config_t mc; 566 567#if EQL_DEBUG 568 if (eql_debug >= 20) 569 printk ("%s: get master config\n", dev->name); 570#endif 571 572 if ( eql_is_master (dev) ) 573 { 574 eql = (equalizer_t *) dev->priv; 575 mc.max_slaves = eql->max_slaves; 576 mc.min_slaves = eql->min_slaves; 577 if (copy_to_user (mcp, &mc, sizeof (master_config_t))) 578 return -EFAULT; 579 return 0; 580 } 581 return -EINVAL; 582} 583 584 585static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp) 586{ 587 equalizer_t *eql; 588 master_config_t mc; 589 590 if (copy_from_user (&mc, mcp, sizeof (master_config_t))) 591 return -EFAULT; 592#if EQL_DEBUG 593 if (eql_debug >= 20) 594 printk ("%s: set master config\n", dev->name); 595#endif 596 if ( eql_is_master (dev) ) 597 { 598 eql = (equalizer_t *) dev->priv; 599 eql->max_slaves = mc.max_slaves; 600 eql->min_slaves = mc.min_slaves; 601 return 0; 602 } 603 return -EINVAL; 604} 605 606/* 607 * Private device support functions 608 */ 609 610static inline int eql_is_slave(struct net_device *dev) 611{ 612 if (dev) 613 { 614 if ((dev->flags & IFF_SLAVE) == IFF_SLAVE) 615 return 1; 616 } 617 return 0; 618} 619 620 621static inline int eql_is_master(struct net_device *dev) 622{ 623 if (dev) 624 { 625 if ((dev->flags & IFF_MASTER) == IFF_MASTER) 626 return 1; 627 } 628 return 0; 629} 630 631 632static slave_t *eql_new_slave(void) 633{ 634 slave_t *slave; 635 636 slave = (slave_t *) kmalloc (sizeof (slave_t), GFP_KERNEL); 637 if (slave) 638 memset(slave, 0, sizeof (slave_t)); 639 return slave; 640} 641 642 643static void eql_delete_slave(slave_t *slave) 644{ 645 kfree (slave); 646} 647 648 649#if 0 /* not currently used, will be used 650 when we really use a priority queue */ 651static long slave_Bps(slave_t *slave) 652{ 653 return (slave->priority_Bps); 654} 655 656static long slave_bps(slave_t *slave) 657{ 658 return (slave->priority_bps); 659} 660 661#endif 662 663static inline int eql_number_slaves(slave_queue_t *queue) 664{ 665 return queue->num_slaves; 666} 667 668static inline int eql_is_empty(slave_queue_t *queue) 669{ 670 if (eql_number_slaves (queue) == 0) 671 return 1; 672 return 0; 673} 674 675static inline int eql_is_full(slave_queue_t *queue) 676{ 677 equalizer_t *eql = (equalizer_t *) queue->master_dev->priv; 678 679 if (eql_number_slaves (queue) == eql->max_slaves) 680 return 1; 681 return 0; 682} 683 684static slave_queue_t *eql_new_slave_queue(struct net_device *dev) 685{ 686 slave_queue_t *queue; 687 slave_t *head_slave; 688 slave_t *tail_slave; 689 690 queue = (slave_queue_t *) kmalloc (sizeof (slave_queue_t), GFP_KERNEL); 691 if (!queue) 692 goto err_out; 693 694 head_slave = eql_new_slave (); 695 if (!head_slave) 696 goto err_out_queue; 697 698 tail_slave = eql_new_slave (); 699 if (!tail_slave) 700 goto err_out_hs; 701 702 memset (queue, 0, sizeof (slave_queue_t)); 703 704 head_slave->next = tail_slave; 705 tail_slave->next = 0; 706 queue->head = head_slave; 707 queue->num_slaves = 0; 708 queue->master_dev = dev; 709 return queue; 710 711err_out_hs: 712 kfree (head_slave); 713err_out_queue: 714 kfree (queue); 715err_out: 716 return NULL; 717} 718 719 720static void eql_delete_slave_queue(slave_queue_t *queue) 721{ 722 slave_t *zapped; 723 /* 724 * This should only be called when there isn't a 725 * timer running that scans the data periodically.. 726 * dev_close stops the timer... 727 */ 728 729 while ( ! eql_is_empty (queue) ) 730 { 731 zapped = eql_remove_slave (queue, queue->head->next); 732 eql_delete_slave (zapped); 733 } 734 kfree (queue->head->next); 735 kfree (queue->head); 736 kfree (queue); 737} 738 739static int eql_insert_slave(slave_queue_t *queue, slave_t *slave) 740{ 741 unsigned long flags; 742 743 save_flags(flags); 744 cli (); 745 746 if ( ! eql_is_full (queue) ) 747 { 748 slave_t *duplicate_slave = 0; 749 duplicate_slave = eql_find_slave_dev (queue, slave->dev); 750 if (duplicate_slave != 0) 751 { 752/* printk ("%s: found a duplicate, killing it and replacing\n", 753 queue->master_dev->name); */ 754 eql_delete_slave (eql_remove_slave (queue, duplicate_slave)); 755 } 756 slave->next = queue->head->next; 757 queue->head->next = slave; 758 queue->num_slaves++; 759 restore_flags(flags); 760 return 0; 761 } 762 restore_flags(flags); 763 return 1; 764} 765 766 767static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave) 768{ 769 slave_t *prev; 770 slave_t *curr; 771 unsigned long flags; 772 773 save_flags(flags); 774 cli (); 775 776 prev = queue->head; 777 curr = queue->head->next; 778 while (curr != slave && 779 curr->dev != 0 ) 780 { 781/* printk ("%s: remove_slave; searching...\n", queue->master_dev->name); */ 782 prev = curr; 783 curr = curr->next; 784 } 785 786 if (curr == slave) 787 { 788 prev->next = curr->next; 789 queue->num_slaves--; 790 curr->dev->flags = curr->dev->flags & ~IFF_SLAVE; 791 restore_flags(flags); 792 return curr; 793 } 794 restore_flags(flags); 795 return 0; /* not found */ 796} 797 798 799static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev) 800{ 801 slave_t *prev; 802 slave_t *curr; 803 slave_t *target; 804 805 target = eql_find_slave_dev (queue, dev); 806 807 if (target != 0) 808 { 809 unsigned long flags; 810 811 save_flags(flags); 812 cli (); 813 prev = queue->head; 814 curr = prev->next; 815 while (curr != target) 816 { 817 prev = curr; 818 curr = curr->next; 819 } 820 prev->next = curr->next; 821 queue->num_slaves--; 822 restore_flags(flags); 823 eql_delete_slave (curr); 824 return 0; 825 } 826 return 1; 827} 828 829 830static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue) 831{ 832 if (queue->best_slave != 0) 833 { 834 if (queue->best_slave->dev != 0) 835 return queue->best_slave->dev; 836 else 837 return 0; 838 } 839 else 840 return 0; 841} 842 843 844static inline slave_t *eql_best_slave(slave_queue_t *queue) 845{ 846 return queue->best_slave; 847} 848 849static inline void eql_schedule_slaves(slave_queue_t *queue) 850{ 851 struct net_device *master_dev = queue->master_dev; 852 slave_t *best_slave = 0; 853 slave_t *slave_corpse = 0; 854 855#ifdef EQL_DEBUG 856 if (eql_debug >= 100) 857 printk ("%s: schedule %d slaves\n", 858 master_dev->name, eql_number_slaves (queue)); 859#endif 860 if ( eql_is_empty (queue) ) 861 { 862 /* 863 * No slaves to play with 864 */ 865 eql_set_best_slave (queue, (slave_t *) 0); 866 return; 867 } 868 else 869 { 870 /* 871 * Make a pass to set the best slave 872 */ 873 unsigned long best_load = (unsigned long) ULONG_MAX; 874 slave_t *slave = 0; 875 unsigned long flags; 876 int i; 877 878 save_flags(flags); 879 cli (); 880 for (i = 1, slave = eql_first_slave (queue); 881 i <= eql_number_slaves (queue); 882 i++, slave = eql_next_slave (queue, slave)) 883 { 884 /* 885 * Go through the slave list once, updating best_slave 886 * whenever a new best_load is found, whenever a dead 887 * slave is found, it is marked to be pulled out of the 888 * queue 889 */ 890 891 unsigned long slave_load; 892 unsigned long bytes_queued; 893 unsigned long priority_Bps; 894 895 if (slave != 0) 896 { 897 bytes_queued = slave->bytes_queued; 898 priority_Bps = slave->priority_Bps; 899 if ( slave->dev != 0) 900 { 901 if ((slave->dev->flags & IFF_UP) == IFF_UP ) 902 { 903 slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - 904 (priority_Bps) + bytes_queued * 8; 905 906 if (slave_load < best_load) 907 { 908 best_load = slave_load; 909 best_slave = slave; 910 } 911 } 912 else /* we found a dead slave */ 913 { 914 /* 915 * We only bury one slave at a time, if more than 916 * one slave dies, we will bury him on the next 917 * reschedule. slaves don't die all at once that 918 * much anyway 919 */ 920 slave_corpse = slave; 921 } 922 } 923 } 924 } /* for */ 925 restore_flags(flags); 926 eql_set_best_slave (queue, best_slave); 927 } /* else */ 928 if (slave_corpse != 0) 929 { 930 printk ("eql: scheduler found dead slave, burying...\n"); 931 eql_delete_slave (eql_remove_slave (queue, slave_corpse)); 932 } 933 return; 934} 935 936 937static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev) 938{ 939 slave_t *slave = 0; 940 slave = eql_first_slave(queue); 941 942 while (slave != 0 && slave->dev != dev && slave != 0) 943 { 944 slave = slave->next; 945 } 946 return slave; 947} 948 949 950static inline slave_t *eql_first_slave(slave_queue_t *queue) 951{ 952 return queue->head->next; 953} 954 955 956static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave) 957{ 958 return slave->next; 959} 960 961static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave) 962{ 963 queue->best_slave = slave; 964} 965 966static void eql_timer(unsigned long param) 967{ 968 equalizer_t *eql = (equalizer_t *) param; 969 slave_t *slave; 970 slave_t *slave_corpse = 0; 971 int i; 972 unsigned long flags; 973 974 if ( ! eql_is_empty (eql->queue) ) 975 { 976 save_flags(flags); 977 cli (); 978 for (i = 1, slave = eql_first_slave (eql->queue); 979 i <= eql_number_slaves (eql->queue); 980 i++, slave = eql_next_slave (eql->queue, slave)) 981 { 982 if (slave != 0) 983 { 984 if ((slave->dev->flags & IFF_UP) == IFF_UP ) 985 { 986 slave->bytes_queued -= slave->priority_Bps; 987 if (slave->bytes_queued < 0) 988 slave->bytes_queued = 0; 989 } 990 else 991 slave_corpse = slave; 992 } 993 } 994 restore_flags(flags); 995 if (slave_corpse != 0) 996 { 997 printk ("eql: timer found dead slave, burying...\n"); 998 eql_delete_slave (eql_remove_slave (eql->queue, slave_corpse)); 999 } 1000 } 1001 1002 if (eql->timer_on != 0) 1003 { 1004 eql->timer.expires = jiffies+EQL_DEFAULT_RESCHED_IVAL; 1005 add_timer (&eql->timer); 1006 } 1007} 1008 1009static struct net_device dev_eql; 1010 1011static int __init eql_init_module(void) 1012{ 1013 strcpy(dev_eql.name, "eql"); 1014 dev_eql.init = eql_init; 1015 if (register_netdev(&dev_eql) != 0) { 1016 printk("eql: register_netdev() returned non-zero.\n"); 1017 return -EIO; 1018 } 1019 return 0; 1020} 1021 1022static void __exit eql_cleanup_module(void) 1023{ 1024 kfree(((equalizer_t *)dev_eql.priv)->stats ); 1025 kfree(dev_eql.priv); 1026 unregister_netdev(&dev_eql); 1027} 1028 1029module_init(eql_init_module); 1030module_exit(eql_cleanup_module); 1031MODULE_LICENSE("GPL"); 1032 1033/* 1034 * Local Variables: 1035 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c eql.c" 1036 * version-control: t 1037 * kept-new-versions: 20 1038 * End: 1039 */ 1040