📄 eql.c
字号:
if (err) return err; copy_to_user (scp, &sc, sizeof (slave_config_t)); return 0; } } return -EINVAL;}static int eql_s_slave_cfg(struct device *dev, slave_config_t *scp){ slave_t *slave; equalizer_t *eql; struct device *slave_dev; slave_config_t sc; int err; err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t)); if (err) return err;#ifdef EQL_DEBUG if (eql_debug >= 20) printk ("%s: set config for slave `%s'\n", dev->name, sc.slave_name);#endif copy_from_user (&sc, scp, sizeof (slave_config_t)); eql = (equalizer_t *) dev->priv; slave_dev = dev_get (sc.slave_name); if ( eql_is_slave (slave_dev) ) { slave = eql_find_slave_dev (eql->queue, slave_dev); if (slave != 0) { slave->priority = sc.priority; slave->priority_bps = sc.priority; slave->priority_Bps = sc.priority / 8; return 0; } } return -EINVAL;}static int eql_g_master_cfg(struct device *dev, master_config_t *mcp){ equalizer_t *eql; master_config_t mc;#if EQL_DEBUG if (eql_debug >= 20) printk ("%s: get master config\n", dev->name);#endif if ( eql_is_master (dev) ) { int err; err = verify_area(VERIFY_WRITE, (void *)mcp, sizeof (master_config_t)); if (err) return err; eql = (equalizer_t *) dev->priv; mc.max_slaves = eql->max_slaves; mc.min_slaves = eql->min_slaves; copy_to_user (mcp, &mc, sizeof (master_config_t)); return 0; } return -EINVAL;}static int eql_s_master_cfg(struct device *dev, master_config_t *mcp){ equalizer_t *eql; master_config_t mc; int err; err = verify_area(VERIFY_READ, (void *)mcp, sizeof (master_config_t)); if (err) return err;#if EQL_DEBUG if (eql_debug >= 20) printk ("%s: set master config\n", dev->name);#endif copy_from_user (&mc, mcp, sizeof (master_config_t)); if ( eql_is_master (dev) ) { eql = (equalizer_t *) dev->priv; eql->max_slaves = mc.max_slaves; eql->min_slaves = mc.min_slaves; return 0; } return -EINVAL;}/* * Private device support functions */static inline int eql_is_slave(struct device *dev){ if (dev) { if ((dev->flags & IFF_SLAVE) == IFF_SLAVE) return 1; } return 0;}static inline int eql_is_master(struct device *dev){ if (dev) { if ((dev->flags & IFF_MASTER) == IFF_MASTER) return 1; } return 0;}static slave_t *eql_new_slave(void){ slave_t *slave; slave = (slave_t *) kmalloc (sizeof (slave_t), GFP_KERNEL); if (slave) { memset(slave, 0, sizeof (slave_t)); return slave; } return 0;}static void eql_delete_slave(slave_t *slave){ kfree (slave);}#if 0 /* not currently used, will be used when we really use a priority queue */static long slave_Bps(slave_t *slave){ return (slave->priority_Bps);}static long slave_bps(slave_t *slave){ return (slave->priority_bps);}#endifstatic inline int eql_number_slaves(slave_queue_t *queue){ return queue->num_slaves;}static inline int eql_is_empty(slave_queue_t *queue){ if (eql_number_slaves (queue) == 0) return 1; return 0;}static inline int eql_is_full(slave_queue_t *queue){ equalizer_t *eql = (equalizer_t *) queue->master_dev->priv; if (eql_number_slaves (queue) == eql->max_slaves) return 1; return 0;}static slave_queue_t *eql_new_slave_queue(struct device *dev){ slave_queue_t *queue; slave_t *head_slave; slave_t *tail_slave; queue = (slave_queue_t *) kmalloc (sizeof (slave_queue_t), GFP_KERNEL); if (queue == NULL) return 0; memset (queue, 0, sizeof (slave_queue_t)); head_slave = eql_new_slave (); tail_slave = eql_new_slave (); if ( head_slave != 0 && tail_slave != 0 ) { head_slave->next = tail_slave; tail_slave->next = 0; queue->head = head_slave; queue->num_slaves = 0; queue->master_dev = dev; } else { if (head_slave) kfree(head_slave); if (tail_slave) kfree(tail_slave); kfree (queue); return 0; } return queue;}static void eql_delete_slave_queue(slave_queue_t *queue){ slave_t *zapped; /* * This should only be called when there isn't a * timer running that scans the data periodically.. * dev_close stops the timer... */ while ( ! eql_is_empty (queue) ) { zapped = eql_remove_slave (queue, queue->head->next); eql_delete_slave (zapped); } kfree (queue->head->next); kfree (queue->head); kfree (queue);}static int eql_insert_slave(slave_queue_t *queue, slave_t *slave){ cli (); if ( ! eql_is_full (queue) ) { slave_t *duplicate_slave = 0; duplicate_slave = eql_find_slave_dev (queue, slave->dev); if (duplicate_slave != 0) {/* printk ("%s: found a duplicate, killing it and replacing\n", queue->master_dev->name); */ eql_delete_slave (eql_remove_slave (queue, duplicate_slave)); } slave->next = queue->head->next; queue->head->next = slave; queue->num_slaves++; sti (); return 0; } sti (); return 1;}static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave){ slave_t *prev; slave_t *curr; cli (); prev = queue->head; curr = queue->head->next; while (curr != slave && curr->dev != 0 ) {/* printk ("%s: remove_slave; searching...\n", queue->master_dev->name); */ prev = curr; curr = curr->next; } if (curr == slave) { prev->next = curr->next; queue->num_slaves--; curr->dev->flags = curr->dev->flags & ~IFF_SLAVE; sti(); return curr; } sti (); return 0; /* not found */}static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev){ slave_t *prev; slave_t *curr; slave_t *target; target = eql_find_slave_dev (queue, dev); if (target != 0) { cli (); prev = queue->head; curr = prev->next; while (curr != target) { prev = curr; curr = curr->next; } prev->next = curr->next; queue->num_slaves--; sti (); eql_delete_slave (curr); return 0; } return 1;}static inline struct device *eql_best_slave_dev(slave_queue_t *queue){ if (queue->best_slave != 0) { if (queue->best_slave->dev != 0) return queue->best_slave->dev; else return 0; } else return 0;}static inline slave_t *eql_best_slave(slave_queue_t *queue){ return queue->best_slave;}static inline void eql_schedule_slaves(slave_queue_t *queue){ struct device *master_dev = queue->master_dev; slave_t *best_slave = 0; slave_t *slave_corpse = 0;#ifdef EQL_DEBUG if (eql_debug >= 100) printk ("%s: schedule %d slaves\n", master_dev->name, eql_number_slaves (queue));#endif if ( eql_is_empty (queue) ) { /* * No slaves to play with */ eql_set_best_slave (queue, (slave_t *) 0); return; } else { /* * Make a pass to set the best slave */ unsigned long best_load = (unsigned long) ULONG_MAX; slave_t *slave = 0; int i; cli (); for (i = 1, slave = eql_first_slave (queue); i <= eql_number_slaves (queue); i++, slave = eql_next_slave (queue, slave)) { /* * Go through the slave list once, updating best_slave * whenever a new best_load is found, whenever a dead * slave is found, it is marked to be pulled out of the * queue */ unsigned long slave_load; unsigned long bytes_queued; unsigned long priority_Bps; if (slave != 0) { bytes_queued = slave->bytes_queued; priority_Bps = slave->priority_Bps; if ( slave->dev != 0) { if ((slave->dev->flags & IFF_UP) == IFF_UP ) { slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - (priority_Bps) + bytes_queued * 8; if (slave_load < best_load) { best_load = slave_load; best_slave = slave; } } else /* we found a dead slave */ { /* * We only bury one slave at a time, if more than * one slave dies, we will bury him on the next * reschedule. slaves don't die all at once that * much anyway */ slave_corpse = slave; } } } } /* for */ sti (); eql_set_best_slave (queue, best_slave); } /* else */ if (slave_corpse != 0) { printk ("eql: scheduler found dead slave, burying...\n"); eql_delete_slave (eql_remove_slave (queue, slave_corpse)); } return;}static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct device *dev){ slave_t *slave = 0; slave = eql_first_slave(queue); while (slave != 0 && slave->dev != dev && slave != 0) {#if 0 if (slave->dev != 0) printk ("eql: find_slave_dev; looked at '%s'...\n", slave->dev->name); else printk ("eql: find_slave_dev; looked at nothing...\n");#endif slave = slave->next; } return slave;}static inline slave_t *eql_first_slave(slave_queue_t *queue){ return queue->head->next;}static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave){ return slave->next;}static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave){ queue->best_slave = slave;}static void eql_timer(unsigned long param){ equalizer_t *eql = (equalizer_t *) param; slave_t *slave; slave_t *slave_corpse = 0; int i; if ( ! eql_is_empty (eql->queue) ) { cli (); for (i = 1, slave = eql_first_slave (eql->queue); i <= eql_number_slaves (eql->queue); i++, slave = eql_next_slave (eql->queue, slave)) { if (slave != 0) { if ((slave->dev->flags & IFF_UP) == IFF_UP ) { slave->bytes_queued -= slave->priority_Bps; if (slave->bytes_queued < 0) slave->bytes_queued = 0; } else slave_corpse = slave; } } sti (); if (slave_corpse != 0) { printk ("eql: timer found dead slave, burying...\n"); eql_delete_slave (eql_remove_slave (eql->queue, slave_corpse)); } } if (eql->timer_on != 0) { eql->timer.expires = jiffies+EQL_DEFAULT_RESCHED_IVAL; add_timer (&eql->timer); }}#ifdef MODULEstatic struct device dev_eql = { "eql", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, eql_init };int init_module(void){ if (register_netdev(&dev_eql) != 0) { printk("eql: register_netdev() returned non-zero.\n"); return -EIO; } return 0;}void cleanup_module(void){ unregister_netdev(&dev_eql);}#endif /* MODULE *//* * Local Variables: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c eql.c" * version-control: t * kept-new-versions: 20 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -