[Click] About queues scheduling

Eddie Kohler kohler at cs.ucla.edu
Tue May 17 11:41:46 EDT 2011


Hi Roberto,

Thanks for this!  I applied my own version of it, which included a check that 
errno!=EAGAIN to avoid unnecessary error messages.

Eddie


On 5/15/11 8:06 AM, Roberto Riggio wrote:
> 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