Linux认证辅导:Linux内核中流量控制(4)Linux认证考试
文章作者 100test 发表时间 2009:11:11 16:18:33
来源 100Test.Com百考试题网
4. 基本操作各种流控算法是通过流控操作结构实现,然后这些操作结构登记到内核的流控链表,在使用时可为网卡构造新的流控结构,将该结构和某种流控操作结构挂钩,这样就实现网卡采用某种策略发送数据进行流控,所有操作在用户空间都可通过tc程序设置。
4.1 Qdisc的一些基本操作4.1.1 分配新的流控结构/* net/sched/sch_generic.c */ // 分配新的Qdisc结构, Qdisc的操作结构由函数参数指定struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
{
void *p.
struct Qdisc *sch.
unsigned int size.
int err = -ENOBUFS.
/* ensure that the Qdisc and the private data are 32-byte aligned */
// Qdisc空间按32字节对齐
size = QDISC_ALIGN(sizeof(*sch)).
//增加私有数据空间
size = ops->.priv_size (QDISC_ALIGNTO - 1).
p = kzalloc(size, GFP_KERNEL).
if (!p)
goto errout.
//确保从缓冲区中的sch到缓冲区结束点空间是32字节对齐的
sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p).
//填充字节的数量
sch->.padded = (char *) sch - (char *) p.
// ------------------------------------
// |________|___________________________|
// ^ ^ ^
// | pad | |
// p sch
// 初始化链表, 将用于挂接到dev的Qdisc链表
INIT_LIST_HEAD(&.sch->.list).
//初始化数据包链表
skb_queue_head_init(&.sch->.q).
// Qdisc结构参数
sch->.ops = ops.
sch->.enqueue = ops->.enqueue.
sch->.dequeue = ops->.dequeue.
sch->.dev = dev.
//网卡使用计数增加
dev_hold(dev).
sch->.stats_lock = &.dev->.queue_lock.
atomic_set(&.sch->.refcnt, 1).
return sch.
errout:
return ERR_PTR(-err).
}
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
{
struct Qdisc *sch.
//分配Qdisc结构
sch = qdisc_alloc(dev, ops).
if (IS_ERR(sch))
goto errout.
// 如果没有初始化函数或者初始化成功, 返回Qdisc结构if (!ops->.init || ops->.init(sch, NULL) == 0)
return sch.
// 初始化失败, 释放Qdisc
qdisc_destroy(sch).
errout:
return NULL.
}
/* Under dev->.queue_lock and BH! */
//调用Qdisc操作函数中的reset函数
void qdisc_reset(struct Qdisc *qdisc)
{
struct Qdisc_ops *ops = qdisc->.ops.
if (ops->.reset)
ops->.reset(qdisc).
}
/* this is the rcu callback function to clean up a qdisc when there
* are no further references to it */
//真正释放Qdisc缓冲区