[Click] About queues scheduling
Roberto Riggio
roberto.riggio at create-net.org
Sun May 15 11:06:19 EDT 2011
Il 14/05/2011 06:26, Eddie Kohler ha scritto:
> If this works as I expect, you should see something like the
> following, with _iters_per_os == 2:
>
> push
> pull
> pull
> pull
> push
> pull
> pull
> pull
Yes, it works as described.
>
> Nevertheless, though, adding BURST to KernelTun would help even more.
I'm attaching a patch that adds support for the BURST param. It defaults
to 1
so the current behavior should not be affected.
>
> Any comments on if this helps?
With both patches the queue remains backlogged as I was expecting. Thanks.
> E
--
diff -urN -x .git -x diffserv -x wing -x secaggr -x click-align.cc -x
availablechannels.cc -x availablechannels.hh -x devinfo.cc -x devinfo.hh
click.upstream/elements/userlevel/kerneltun.cc
click/elements/userlevel/kerneltun.cc
--- click.upstream/elements/userlevel/kerneltun.cc 2011-05-10
10:22:19.915121002 +0200
+++ click/elements/userlevel/kerneltun.cc 2011-05-10
21:13:08.943966002 +0200
@@ -94,10 +94,12 @@
_adjust_headroom = false;
_headroom += (4 - _headroom % 4) % 4; // default 4/0 alignment
_mtu_out = DEFAULT_MTU;
+ _burst = 1;
if (Args(conf, this, errh)
.read_mp("ADDR", IPPrefixArg(), _near, _mask)
.read_p("GATEWAY", _gw)
.read("TAP", _tap)
+ .read("BURST", _burst)
.read("HEADROOM", _headroom).read_status(_adjust_headroom)
.read("ETHER", _macaddr)
.read("IGNORE_QUEUE_OVERFLOWS", _ignore_q_errs)
@@ -504,65 +506,75 @@
{
if (fd != _fd)
return;
- WritablePacket *p = Packet::make(_headroom, 0, _mtu_in, 0);
- if (!p) {
- click_chatter("out of memory!");
- return;
- }
- int cc = read(_fd, p->data(), _mtu_in);
- if (cc > 0) {
- p->take(_mtu_in - cc);
- bool ok = false;
-
- if (_tap) {
- if (_type == LINUX_UNIVERSAL)
- // 2-byte padding, 2-byte Ethernet type, then Ethernet header
- p->pull(4);
- else if (_type == LINUX_ETHERTAP)
- // 2-byte padding, then Ethernet header
- p->pull(2);
- ok = true;
- } else if (_type == LINUX_UNIVERSAL) {
- // 2-byte padding followed by an Ethernet type
- uint16_t etype = *(uint16_t *)(p->data() + 2);
- p->pull(4);
- if (etype != htons(ETHERTYPE_IP) && etype != htons(ETHERTYPE_IP6))
- checked_output_push(1, p->clone());
- else
- ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
- } else if (_type == BSD_TUN) {
- // 4-byte address family followed by IP header
- int af = ntohl(*(unsigned *)p->data());
- p->pull(4);
- if (af != AF_INET && af != AF_INET6) {
- click_chatter("KernelTun(%s): don't know AF %d",
_dev_name.c_str(), af);
- checked_output_push(1, p->clone());
- } else
- ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
- } else if (_type == OSX_TUN || _type == NETBSD_TUN) {
- ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
- } else { /* _type == LINUX_ETHERTAP */
- // 2-byte padding followed by a mostly-useless Ethernet header
- uint16_t etype = *(uint16_t *)(p->data() + 14);
- p->pull(16);
- if (etype != htons(ETHERTYPE_IP) && etype != htons(ETHERTYPE_IP6))
- checked_output_push(1, p->clone());
- else
- ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
- }
+ for (unsigned i = 0; i < _burst; i++) {
- if (ok) {
- p->timestamp_anno().assign_now();
- output(0).push(p);
- } else
- checked_output_push(1, p);
-
- } else {
- if (!_ignore_q_errs || !_printed_read_err || (errno != ENOBUFS)) {
- _printed_read_err = true;
- perror("KernelTun read");
- }
+ WritablePacket *p = Packet::make(_headroom, 0, _mtu_in, 0);
+ if (!p) {
+ click_chatter("out of memory!");
+ return;
+ }
+
+ int cc = read(_fd, p->data(), _mtu_in);
+
+ if ((cc == -1) && errno == EAGAIN) {
+ p->kill();
+ break;
+ }
+
+ if (cc > 0) {
+ p->take(_mtu_in - cc);
+ bool ok = false;
+
+ if (_tap) {
+ if (_type == LINUX_UNIVERSAL)
+ // 2-byte padding, 2-byte Ethernet type, then Ethernet header
+ p->pull(4);
+ else if (_type == LINUX_ETHERTAP)
+ // 2-byte padding, then Ethernet header
+ p->pull(2);
+ ok = true;
+ } else if (_type == LINUX_UNIVERSAL) {
+ // 2-byte padding followed by an Ethernet type
+ uint16_t etype = *(uint16_t *)(p->data() + 2);
+ p->pull(4);
+ if (etype != htons(ETHERTYPE_IP) && etype !=
htons(ETHERTYPE_IP6))
+ checked_output_push(1, p->clone());
+ else
+ ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+ } else if (_type == BSD_TUN) {
+ // 4-byte address family followed by IP header
+ int af = ntohl(*(unsigned *)p->data());
+ p->pull(4);
+ if (af != AF_INET && af != AF_INET6) {
+ click_chatter("KernelTun(%s): don't know AF %d",
_dev_name.c_str(), af);
+ checked_output_push(1, p->clone());
+ } else
+ ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+ } else if (_type == OSX_TUN || _type == NETBSD_TUN) {
+ ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+ } else { /* _type == LINUX_ETHERTAP */
+ // 2-byte padding followed by a mostly-useless Ethernet header
+ uint16_t etype = *(uint16_t *)(p->data() + 14);
+ p->pull(16);
+ if (etype != htons(ETHERTYPE_IP) && etype !=
htons(ETHERTYPE_IP6))
+ checked_output_push(1, p->clone());
+ else
+ ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+ }
+
+ if (ok) {
+ p->timestamp_anno().assign_now();
+ output(0).push(p);
+ } else
+ checked_output_push(1, p);
+
+ } else {
+ if (!_ignore_q_errs || !_printed_read_err || (errno != ENOBUFS)) {
+ _printed_read_err = true;
+ perror("KernelTun read");
+ }
+ }
}
}
diff -urN -x .git -x diffserv -x wing -x secaggr -x click-align.cc -x
availablechannels.cc -x availablechannels.hh -x devinfo.cc -x devinfo.hh
click.upstream/elements/userlevel/kerneltun.hh
click/elements/userlevel/kerneltun.hh
--- click.upstream/elements/userlevel/kerneltun.hh 2011-05-10
10:22:19.915121002 +0200
+++ click/elements/userlevel/kerneltun.hh 2011-04-27
16:41:19.551880001 +0200
@@ -129,6 +129,7 @@
enum Type { LINUX_UNIVERSAL, LINUX_ETHERTAP, BSD_TUN, BSD_TAP,
OSX_TUN,
NETBSD_TUN, NETBSD_TAP };
+ unsigned _burst;
int _fd;
int _mtu_in;
int _mtu_out;
More information about the click
mailing list