{"action":"opened","number":184,"pull_request":{"url":"https://api.github.com/repos/lkl/linux/pulls/184","id":79667719,"html_url":"https://github.com/lkl/linux/pull/184","diff_url":"https://github.com/lkl/linux/pull/184.diff","patch_url":"https://github.com/lkl/linux/pull/184.patch","issue_url":"https://api.github.com/repos/lkl/linux/issues/184","number":184,"state":"open","locked":false,"title":"lkl: Add offload (TSO4, CSUM) support to LKL device, #2 of 2","user":{"login":"hkchu","id":18743165,"avatar_url":"https://avatars.githubusercontent.com/u/18743165?v=3","gravatar_id":"","url":"https://api.github.com/users/hkchu","html_url":"https://github.com/hkchu","followers_url":"https://api.github.com/users/hkchu/followers","following_url":"https://api.github.com/users/hkchu/following{/other_user}","gists_url":"https://api.github.com/users/hkchu/gists{/gist_id}","starred_url":"https://api.github.com/users/hkchu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hkchu/subscriptions","organizations_url":"https://api.github.com/users/hkchu/orgs","repos_url":"https://api.github.com/users/hkchu/repos","events_url":"https://api.github.com/users/hkchu/events{/privacy}","received_events_url":"https://api.github.com/users/hkchu/received_events","type":"User","site_admin":false},"body":"The patch adds offload support to LKL's virtio device. It focuses\r\non the main offload features including TSO4 and CSUM, for both \"HOST\"\r\n(for the TX direction) and \"GUEST\" (for the RX direction). The\r\nremaining, less used ones can be added easily later. It also supports\r\na special \"mergeable RX buffer\" mode (VIRTIO_NET_F_MRG_RXBUF) that\r\nallows RX memory to be used more efficiently.\r\n\r\nThe patch builds on top of a previous patch to\r\n\r\n1) support much longer sg lists when TSO/LRO is enabled. The patch\r\ncaps the size to MAX_SKB_FRAGS plus two for headers. MAX_SKB_FRAGS\r\nallows the support of skb's max \"frags\" but not the less used\r\n\"frag_list\". Note that although only the tap device backend has been\r\nmodified to support iovec directly, other device such as raw socket\r\ncan be adapted easily too.\r\n\r\n2) all the remaining code to support the proper use of vring_desc/\r\nvring_avail/vring_used for large segments. Most of the complexity\r\nlies in the support of \"mergeable RX buffer\" mode. Note that the patch\r\nchanges the default descriptor ring size (QUEUE_DEPTH) from 32 to 128.\r\nWithout a larger ring in VIRTIO_NET_F_MRG_RXBUF mode, there often\r\naren't enough descrptors (upto MAX_SKB_FRAGS+2) to support an incoming\r\nlarge segment. But for some reason the 128 descrptor ring size often\r\nresults in a small amount of TCP sprurious retransmissions when in the\r\n\"big_packets\" mode for a single TCP_STREAM run.\r\n\r\nWith the offload support thruput performnace gets a big boost as shown\r\nbelow. In my original development branch that is two months old, the\r\nthruput gain is even bigger (>> 15Gbps). What has changed in between\r\ncausing some loss in the perf gain has yet to be determined.\r\n\r\nNote that the perf test result below also includes brief descriptions\r\nof what each feature flag means in the context of the test environment\r\ninvolving both virtio_net and tuntap.\r\n\r\n----------------------------\r\nTODO: figure out why my dev branch gives 18Gbps while the latest\r\nbranch only produces < 7Gbps.\r\n\r\n----------------------------\r\nPerformance tests:\r\n\r\nAll the tests below use netperf/netserver with one side running on top\r\nof LKL in the hijack mode while the other side running on top of the\r\nhost kernel stack. A tap device is used to connect the two ends.\r\n\r\nLKL_HIJACK_OFFLOAD is used to enable the desired offload features.\r\nE.g., to test the \"mergeable RX buffer\" + \"guest csum\" features,\r\nsimply do \"export LKL_HIJACK_OFFLOAD=0x8002\"\r\n\r\n1) netperf running on top of LKL talks to netserver running on top of\r\nhost kernel through tuntap:\r\n\r\n1.1. baseline (no offload enabled so csum is done in s/w and max pkt\r\nsize = 1500):\r\n\r\nNote that in this setup csum will be computed twice for each pkt,\r\nfirst to generate a valid csum to deposit into the csum field of the\r\nTCP header when a TCP segment is created by the LKL stack, then by\r\nthe host kernel stack when performing csum validation on a newly\r\narrived pkt.\r\n\r\nthruput: 1.3Gbps\r\n\r\n1.2. VIRTIO_NET_F_CSUM enabled\r\n\r\nThis flag from the virtio_net device will cause the LKL stack to skip\r\ncomputing the csum in the TCP header. pkts will carry vnet_hdr with the\r\nflag \"VIRTIO_NET_HDR_F_NEEDS_CSUM\" and various other fields\r\n(\"csum_start\", \"csum_offset\") initialized. When they are injected into\r\ntuntap, the latter will cause skb->ip_summed to be set to\r\nCHECKSUM_PARTIAL. When such skb is received by the host TCP stack,\r\nsince CHECKSUM_PARTIAL == CHECKSUM_UNNECESSARY | CHECKSUM_COMPLETE,\r\nit will cause the host stack to skip csum validation. In other words\r\nall csum computation is skipped in this setup.\r\n\r\nthruput: 1.9Gbps\r\n\r\n1.3. VIRTIO_NET_F_CSUM plus VIRTIO_NET_F_HOST_TSO4\r\n\r\nThis enables TSO on the virtion_net driver, which will cause the LKL\r\nTCP stack to send down large (upto 64KB) segments. Note that\r\nVIRTIO_NET_F_HOST_TSO4 has a dependency on VIRTIO_NET_F_CSUM. In other\r\nwords VIRTIO_NET_F_HOST_TSO4 flag will be ignored unless\r\nVIRTIO_NET_F_CSUM is also enabled.\r\n\r\nthruput: 3.2Gbps\r\n\r\n1.4. like the above but employs the largest TSO size as possible\r\n\r\nTSO size is capped by the size of IP datagram at 64KB. In real life\r\n(and especially for LKL) the size is somewhat correlated with the\r\nsize of write buffer used by the socket app to send data down.\r\nNetperf uses 16KB buffer by default, which will result in a large\r\nsegment of 11 MTU size pkts plus a fragment of 456 bytes given the\r\ndefault MSS of 1448 bytes.\r\n\r\nTo maximize the benefit of TSO, I set the netperf write buffer size\r\nto 65160, which is equivalent to 45 full segments. This results in\r\n2X improvement in the thruput. (With bits from my older lkl branch\r\nthruput zoomed past 18Gbps.)\r\n\r\nthruput: 6.5Gbps\r\n\r\n2) netserver runs on top of LKL while netperf runs on top of tuntap\r\nover the host kernel.\r\n\r\n2.1. baseline\r\nNo large segment nor csum offload. Csum calculation is done twice on\r\neach pkt of upto 1500B in size, first inside of the host kernel stack,\r\nthen by csum validation in the LKL stack when receiving a TCP pkt.\r\n\r\nthruput: 3.8Gbps\r\n\r\n2.2. Enable VIRTIO_NET_F_GUEST_CSUM device feature\r\n\r\nVIRTIO_NET_F_GUEST_CSUM will cause the LKL virtio device code in the\r\npatch above to enable \"TUN_F_CSUM\" offload feature on the tuntap\r\ndevice. It will also set VIRTIO_NET_HDR_F_DATA_VALID flag in the\r\nvnet_hdr of every pkt received from the tap device. This will cause\r\nthe LKL stack to skip csum validation hence no csum calculation is\r\ndone for the whole path.\r\n\r\nthruput: 4.0Gbps\r\n\r\n2.3. Enable VIRTIO_NET_F_GUEST_TSO4\r\n\r\nThe above flag on the virtio_net device will cause tuntap \"offload\" to\r\nbe enabled. Specifically TUN_F_TSO4 flag will be set. Since TUN_F_TSO4\r\nrequires TUN_F_CSUM (i.e., TUN_F_TSO4 flag will be ignored by tuntap\r\nunless TUN_F_CSUM is also on), the patch will enable both on the\r\nsubsequent TUNSETOFFLOAD ioctl() call to the tuntap device.\r\n\r\nThese tuntap flags will be translated to NETIF_F_HW_CSUM and\r\nNETIF_F_TSO device features respectively, and will cause the host\r\nkernel stack to emit upto 64KB size TCP segments with an unfilled csum\r\nfield in the header. When these pkts egress from the tuntap device,\r\ntheir virnet_hdr will carry \"VIRTIO_NET_HDR_F_NEEDS_CSUM\" flag with\r\n\"csum_start\" and \"csum_offset\" correctly initialized. The\r\nVIRTIO_NET_HDR_F_NEEDS_CSUM flag will invoke some minimal validation\r\nin the virtio_net driver and skb->ip_summed set to CHECKSUM_PARTIAL.\r\nThe latter will cause the LKL stack to skip csum validation if the\r\nTCP segment is terminated locally.\r\n\r\nAlso the \"VIRTIO_NET_F_GUEST_TSO4\" device feature will cause the\r\nbig_packets\" mode in the virtio_net driver to be enabled. LKL virtio\r\ndevice code from this patch will handle the \"avail\" slots posted by\r\nthe driver correctly.\r\n\r\nthruput: 6.5Gbps\r\n\r\n2.4. Enable VIRTIO_NET_F_GUEST_CSUM + VIRTIO_NET_F_GUEST_TSO4\r\n\r\nThis is similar to the above except that with the\r\nVIRTIO_NET_F_GUEST_CSUM flag, LKL device will override the vnet_hdr\r\nflag to LKL_VIRTIO_NET_HDR_F_DATA_VALID, directing the LKL stack to\r\nskip csum validation.\r\n\r\nthruput: 6.7Gbps\r\n\r\n2.5. Enable VIRTIO_NET_F_GUEST_CSUM + VIRTIO_NET_F_MRG_RXBUF\r\n\r\nThis enables the \"mergeable RX buffer\" mode. On my old bits it produced\r\nmuch higher thruput > 16Gbps that's not there in the latest bits.\r\n\r\nthruput: 6.8Gbps\r\n\r\nSigned-off-by: H.K. Jerry Chu <hkchu@google.com>","created_at":"2016-08-02T02:35:56Z","updated_at":"2016-08-02T02:35:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/lkl/linux/pulls/184/commits","review_comments_url":"https://api.github.com/repos/lkl/linux/pulls/184/comments","review_comment_url":"https://api.github.com/repos/lkl/linux/pulls/comments{/number}","comments_url":"https://api.github.com/repos/lkl/linux/issues/184/comments","statuses_url":"https://api.github.com/repos/lkl/linux/statuses/96cd50e3b43780701c1b91d43bb8c53b1f0f0d59","head":{"label":"hkchu:offload","ref":"offload","sha":"96cd50e3b43780701c1b91d43bb8c53b1f0f0d59","user":{"login":"hkchu","id":18743165,"avatar_url":"https://avatars.githubusercontent.com/u/18743165?v=3","gravatar_id":"","url":"https://api.github.com/users/hkchu","html_url":"https://github.com/hkchu","followers_url":"https://api.github.com/users/hkchu/followers","following_url":"https://api.github.com/users/hkchu/following{/other_user}","gists_url":"https://api.github.com/users/hkchu/gists{/gist_id}","starred_url":"https://api.github.com/users/hkchu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hkchu/subscriptions","organizations_url":"https://api.github.com/users/hkchu/orgs","repos_url":"https://api.github.com/users/hkchu/repos","events_url":"https://api.github.com/users/hkchu/events{/privacy}","received_events_url":"https://api.github.com/users/hkchu/received_events","type":"User","site_admin":false},"repo":{"id":64185118,"name":"linux","full_name":"hkchu/linux","owner":{"login":"hkchu","id":18743165,"avatar_url":"https://avatars.githubusercontent.com/u/18743165?v=3","gravatar_id":"","url":"https://api.github.com/users/hkchu","html_url":"https://github.com/hkchu","followers_url":"https://api.github.com/users/hkchu/followers","following_url":"https://api.github.com/users/hkchu/following{/other_user}","gists_url":"https://api.github.com/users/hkchu/gists{/gist_id}","starred_url":"https://api.github.com/users/hkchu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hkchu/subscriptions","organizations_url":"https://api.github.com/users/hkchu/orgs","repos_url":"https://api.github.com/users/hkchu/repos","events_url":"https://api.github.com/users/hkchu/events{/privacy}","received_events_url":"https://api.github.com/users/hkchu/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/hkchu/linux","description":"Linux kernel source tree","fork":true,"url":"https://api.github.com/repos/hkchu/linux","forks_url":"https://api.github.com/repos/hkchu/linux/forks","keys_url":"https://api.github.com/repos/hkchu/linux/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hkchu/linux/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hkchu/linux/teams","hooks_url":"https://api.github.com/repos/hkchu/linux/hooks","issue_events_url":"https://api.github.com/repos/hkchu/linux/issues/events{/number}","events_url":"https://api.github.com/repos/hkchu/linux/events","assignees_url":"https://api.github.com/repos/hkchu/linux/assignees{/user}","branches_url":"https://api.github.com/repos/hkchu/linux/branches{/branch}","tags_url":"https://api.github.com/repos/hkchu/linux/tags","blobs_url":"https://api.github.com/repos/hkchu/linux/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hkchu/linux/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hkchu/linux/git/refs{/sha}","trees_url":"https://api.github.com/repos/hkchu/linux/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hkchu/linux/statuses/{sha}","languages_url":"https://api.github.com/repos/hkchu/linux/languages","stargazers_url":"https://api.github.com/repos/hkchu/linux/stargazers","contributors_url":"https://api.github.com/repos/hkchu/linux/contributors","subscribers_url":"https://api.github.com/repos/hkchu/linux/subscribers","subscription_url":"https://api.github.com/repos/hkchu/linux/subscription","commits_url":"https://api.github.com/repos/hkchu/linux/commits{/sha}","git_commits_url":"https://api.github.com/repos/hkchu/linux/git/commits{/sha}","comments_url":"https://api.github.com/repos/hkchu/linux/comments{/number}","issue_comment_url":"https://api.github.com/repos/hkchu/linux/issues/comments{/number}","contents_url":"https://api.github.com/repos/hkchu/linux/contents/{+path}","compare_url":"https://api.github.com/repos/hkchu/linux/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hkchu/linux/merges","archive_url":"https://api.github.com/repos/hkchu/linux/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hkchu/linux/downloads","issues_url":"https://api.github.com/repos/hkchu/linux/issues{/number}","pulls_url":"https://api.github.com/repos/hkchu/linux/pulls{/number}","milestones_url":"https://api.github.com/repos/hkchu/linux/milestones{/number}","notifications_url":"https://api.github.com/repos/hkchu/linux/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hkchu/linux/labels{/name}","releases_url":"https://api.github.com/repos/hkchu/linux/releases{/id}","deployments_url":"https://api.github.com/repos/hkchu/linux/deployments","created_at":"2016-07-26T02:59:13Z","updated_at":"2016-07-26T03:08:01Z","pushed_at":"2016-08-02T02:33:12Z","git_url":"git://github.com/hkchu/linux.git","ssh_url":"git@github.com:hkchu/linux.git","clone_url":"https://github.com/hkchu/linux.git","svn_url":"https://github.com/hkchu/linux","homepage":"","size":1570772,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"lkl:master","ref":"master","sha":"59c55ff6c4eba6958bfc33196a292777fc2466c6","user":{"login":"lkl","id":247191,"avatar_url":"https://avatars.githubusercontent.com/u/247191?v=3","gravatar_id":"","url":"https://api.github.com/users/lkl","html_url":"https://github.com/lkl","followers_url":"https://api.github.com/users/lkl/followers","following_url":"https://api.github.com/users/lkl/following{/other_user}","gists_url":"https://api.github.com/users/lkl/gists{/gist_id}","starred_url":"https://api.github.com/users/lkl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lkl/subscriptions","organizations_url":"https://api.github.com/users/lkl/orgs","repos_url":"https://api.github.com/users/lkl/repos","events_url":"https://api.github.com/users/lkl/events{/privacy}","received_events_url":"https://api.github.com/users/lkl/received_events","type":"Organization","site_admin":false},"repo":{"id":45491718,"name":"linux","full_name":"lkl/linux","owner":{"login":"lkl","id":247191,"avatar_url":"https://avatars.githubusercontent.com/u/247191?v=3","gravatar_id":"","url":"https://api.github.com/users/lkl","html_url":"https://github.com/lkl","followers_url":"https://api.github.com/users/lkl/followers","following_url":"https://api.github.com/users/lkl/following{/other_user}","gists_url":"https://api.github.com/users/lkl/gists{/gist_id}","starred_url":"https://api.github.com/users/lkl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lkl/subscriptions","organizations_url":"https://api.github.com/users/lkl/orgs","repos_url":"https://api.github.com/users/lkl/repos","events_url":"https://api.github.com/users/lkl/events{/privacy}","received_events_url":"https://api.github.com/users/lkl/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/lkl/linux","description":"Linux kernel source tree","fork":true,"url":"https://api.github.com/repos/lkl/linux","forks_url":"https://api.github.com/repos/lkl/linux/forks","keys_url":"https://api.github.com/repos/lkl/linux/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lkl/linux/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lkl/linux/teams","hooks_url":"https://api.github.com/repos/lkl/linux/hooks","issue_events_url":"https://api.github.com/repos/lkl/linux/issues/events{/number}","events_url":"https://api.github.com/repos/lkl/linux/events","assignees_url":"https://api.github.com/repos/lkl/linux/assignees{/user}","branches_url":"https://api.github.com/repos/lkl/linux/branches{/branch}","tags_url":"https://api.github.com/repos/lkl/linux/tags","blobs_url":"https://api.github.com/repos/lkl/linux/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lkl/linux/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lkl/linux/git/refs{/sha}","trees_url":"https://api.github.com/repos/lkl/linux/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lkl/linux/statuses/{sha}","languages_url":"https://api.github.com/repos/lkl/linux/languages","stargazers_url":"https://api.github.com/repos/lkl/linux/stargazers","contributors_url":"https://api.github.com/repos/lkl/linux/contributors","subscribers_url":"https://api.github.com/repos/lkl/linux/subscribers","subscription_url":"https://api.github.com/repos/lkl/linux/subscription","commits_url":"https://api.github.com/repos/lkl/linux/commits{/sha}","git_commits_url":"https://api.github.com/repos/lkl/linux/git/commits{/sha}","comments_url":"https://api.github.com/repos/lkl/linux/comments{/number}","issue_comment_url":"https://api.github.com/repos/lkl/linux/issues/comments{/number}","contents_url":"https://api.github.com/repos/lkl/linux/contents/{+path}","compare_url":"https://api.github.com/repos/lkl/linux/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lkl/linux/merges","archive_url":"https://api.github.com/repos/lkl/linux/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lkl/linux/downloads","issues_url":"https://api.github.com/repos/lkl/linux/issues{/number}","pulls_url":"https://api.github.com/repos/lkl/linux/pulls{/number}","milestones_url":"https://api.github.com/repos/lkl/linux/milestones{/number}","notifications_url":"https://api.github.com/repos/lkl/linux/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lkl/linux/labels{/name}","releases_url":"https://api.github.com/repos/lkl/linux/releases{/id}","deployments_url":"https://api.github.com/repos/lkl/linux/deployments","created_at":"2015-11-03T19:53:35Z","updated_at":"2016-07-26T10:06:19Z","pushed_at":"2016-08-01T08:43:36Z","git_url":"git://github.com/lkl/linux.git","ssh_url":"git@github.com:lkl/linux.git","clone_url":"https://github.com/lkl/linux.git","svn_url":"https://github.com/lkl/linux","homepage":"","size":1571070,"stargazers_count":141,"watchers_count":141,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":23,"mirror_url":null,"open_issues_count":30,"forks":23,"open_issues":30,"watchers":141,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lkl/linux/pulls/184"},"html":{"href":"https://github.com/lkl/linux/pull/184"},"issue":{"href":"https://api.github.com/repos/lkl/linux/issues/184"},"comments":{"href":"https://api.github.com/repos/lkl/linux/issues/184/comments"},"review_comments":{"href":"https://api.github.com/repos/lkl/linux/pulls/184/comments"},"review_comment":{"href":"https://api.github.com/repos/lkl/linux/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/lkl/linux/pulls/184/commits"},"statuses":{"href":"https://api.github.com/repos/lkl/linux/statuses/96cd50e3b43780701c1b91d43bb8c53b1f0f0d59"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":1,"additions":173,"deletions":47,"changed_files":4}}
{"actor":{"display_login":"hkchu"}}