{"action":"created","comment":{"url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/comments/30880188","id":30880188,"diff_hunk":"@@ -0,0 +1,502 @@\n+/*\n+ * evtdev.c\n+ *\n+ * Driver giving user-space access to the kernel's event channel.\n+ *\n+ * Copyright (c) 2015 Wei Liu <wei.liu2@citrix.com>\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ * 1. Redistributions of source code must retain the above copyright\n+ *    notice, this list of conditions and the following disclaimer.\n+ * 2. Redistributions in binary form must reproduce the above copyright\n+ *    notice, this list of conditions and the following disclaimer in the\n+ *    documentation and/or other materials provided with the distribution.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n+ * SUCH DAMAGE.\n+ */\n+\n+#include <sys/cdefs.h>\n+#include <sys/atomic.h>\n+\n+#include \"rumpxen_xendev.h\"\n+\n+#include <bmk-rumpuser/rumpuser.h>\n+#include <bmk-core/memalloc.h>\n+\n+#pragma GCC diagnostic ignored \"-Wcast-qual\"\n+/* mini-os/os.h has some bad casts */\n+#include <mini-os/events.h>\n+#include <mini-os/wait.h>\n+#pragma GCC diagnostic error \"-Wcast-qual\"\n+\n+/* For ioctl interface. */\n+#include \"xenio3.h\"\n+\n+/*----- data structures -----*/\n+#define EVTDEV_RING_SIZE 2048\n+#define EVTDEV_RING_MASK 2047\n+#define BYTES_PER_PORT   4\n+\n+/* protect against multiple writer (multiple events triggers at the\n+ * same time) there is only one reader, the worker thread.*/\n+static kmutex_t xenevt_ring_lock;\n+u_int xenevt_ring[EVTDEV_RING_SIZE];\n+u_int xenevt_ring_prod, xenevt_ring_cons;\n+\n+struct xenevt_dev_data {\n+\tu_int ring[EVTDEV_RING_SIZE];\n+\tu_int ring_cons;\n+\tu_int ring_prod;\n+#define EVTDEV_F_OVERFLOW 0x1 \t/* ring overflow */\n+\tu_int flags;\n+\n+\tkmutex_t lock;\n+\tkcondvar_t cv;\n+\tstruct selinfo selinfo; /* used by poll, see select(9) */\n+};\n+\n+/* Kernel event -> device instance mapping */\n+static kmutex_t devevent_lock;\n+static struct xenevt_dev_data *devevents[NR_EVENT_CHANNELS];\n+\n+/*----- helpers -----*/\n+#define WBITS (POLLOUT | POLLWRNORM)\n+#define RBITS (POLLIN  | POLLRDNORM)\n+\n+/* call with d->lock held */\n+static void queue(struct xenevt_dev_data *d, u_int port)\n+{\n+\tif (d->ring_cons == ((d->ring_prod + 1) & EVTDEV_RING_MASK)) {\n+\t\td->flags |= EVTDEV_RING_MASK;\n+\t\tprintf(\"evtdev: ring overflow port %d\\n\", port);\n+\t} else {\n+\t\td->ring[d->ring_prod] = port;\n+\t\tmembar_producer();\n+\t\td->ring_prod = (d->ring_prod + 1) & EVTDEV_RING_MASK;\n+\t}\n+\t/* notify */\n+\tcv_signal(&d->cv);\n+\tselnotify(&d->selinfo, RBITS, NOTE_SUBMIT);\n+}\n+\n+static void rump_evtdev_callback(u_int port)\n+{\n+\tmutex_enter(&xenevt_ring_lock);\n+\n+\tif (xenevt_ring_cons == ((xenevt_ring_prod + 1) & EVTDEV_RING_MASK)) {\n+\t\tminios_printk(\"xenevt driver ring overflowed!\\n\");\n+\t} else {\n+\t\txenevt_ring[xenevt_ring_prod] = port;\n+\t\tmembar_producer();\n+\t\txenevt_ring_prod = (xenevt_ring_prod + 1) & EVTDEV_RING_MASK;\n+\t}\n+\n+\tmutex_exit(&xenevt_ring_lock);\n+\n+\tminios_wake_up(&minios_events_waitq);\n+}\n+\n+static void xenevt_thread_func(void *ign)\n+{\n+\tu_int prod = xenevt_ring_prod;\n+\tu_int cons;\n+\n+\t/* give us a rump kernel context */\n+\trumpuser__hyp.hyp_schedule();\n+\trumpuser__hyp.hyp_lwproc_newlwp(0);\n+\trumpuser__hyp.hyp_unschedule();\n+\n+\tfor (;;) {\n+\t\tminios_wait_event(minios_events_waitq, xenevt_ring_prod != prod);\n+\t\tprod = xenevt_ring_prod;\n+\t\tcons = xenevt_ring_cons;\n+\n+\t\tmembar_sync();\n+\n+\t\twhile (cons != prod) {\n+\t\t\tu_int port = xenevt_ring[cons];\n+\t\t\tstruct xenevt_dev_data *d;\n+\n+\t\t\tKASSERT(port < NR_EVENT_CHANNELS);","path":"platform/xen/rumpxendev/evtdev.c","position":132,"original_position":132,"commit_id":"6fb10a6dee7eb172fcc1d944e22a98f05fb6d01d","original_commit_id":"6fb10a6dee7eb172fcc1d944e22a98f05fb6d01d","user":{"login":"liuw","id":138514,"avatar_url":"https://avatars.githubusercontent.com/u/138514?v=3","gravatar_id":"","url":"https://api.github.com/users/liuw","html_url":"https://github.com/liuw","followers_url":"https://api.github.com/users/liuw/followers","following_url":"https://api.github.com/users/liuw/following{/other_user}","gists_url":"https://api.github.com/users/liuw/gists{/gist_id}","starred_url":"https://api.github.com/users/liuw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liuw/subscriptions","organizations_url":"https://api.github.com/users/liuw/orgs","repos_url":"https://api.github.com/users/liuw/repos","events_url":"https://api.github.com/users/liuw/events{/privacy}","received_events_url":"https://api.github.com/users/liuw/received_events","type":"User","site_admin":false},"body":"I think this is OK. This is internal invariant -- port is queued by mini-os not user space, and we expect it to be less than NR_EVENT_CHANNELS.","created_at":"2015-05-22T09:13:49Z","updated_at":"2015-05-22T09:13:49Z","html_url":"https://github.com/rumpkernel/rumprun/pull/18#discussion_r30880188","pull_request_url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18","_links":{"self":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/comments/30880188"},"html":{"href":"https://github.com/rumpkernel/rumprun/pull/18#discussion_r30880188"},"pull_request":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18"}}},"pull_request":{"url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18","id":35959988,"html_url":"https://github.com/rumpkernel/rumprun/pull/18","diff_url":"https://github.com/rumpkernel/rumprun/pull/18.diff","patch_url":"https://github.com/rumpkernel/rumprun/pull/18.patch","issue_url":"https://api.github.com/repos/rumpkernel/rumprun/issues/18","number":18,"state":"open","locked":false,"title":"xen: introduce xenevt device","user":{"login":"liuw","id":138514,"avatar_url":"https://avatars.githubusercontent.com/u/138514?v=3","gravatar_id":"","url":"https://api.github.com/users/liuw","html_url":"https://github.com/liuw","followers_url":"https://api.github.com/users/liuw/followers","following_url":"https://api.github.com/users/liuw/following{/other_user}","gists_url":"https://api.github.com/users/liuw/gists{/gist_id}","starred_url":"https://api.github.com/users/liuw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liuw/subscriptions","organizations_url":"https://api.github.com/users/liuw/orgs","repos_url":"https://api.github.com/users/liuw/repos","events_url":"https://api.github.com/users/liuw/events{/privacy}","received_events_url":"https://api.github.com/users/liuw/received_events","type":"User","site_admin":false},"body":"Expose a userspace event channel device so that applications can use\r\nXen's event channel machinery.\r\n\r\nSigned-off-by: Wei Liu <liuw@liuw.name>","created_at":"2015-05-21T17:54:06Z","updated_at":"2015-05-22T09:13:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e817a5ee2b7a827294ae07252b329089169e86f9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18/commits","review_comments_url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18/comments","review_comment_url":"https://api.github.com/repos/rumpkernel/rumprun/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rumpkernel/rumprun/issues/18/comments","statuses_url":"https://api.github.com/repos/rumpkernel/rumprun/statuses/6fb10a6dee7eb172fcc1d944e22a98f05fb6d01d","head":{"label":"liuw:wip.xenevt-3","ref":"wip.xenevt-3","sha":"6fb10a6dee7eb172fcc1d944e22a98f05fb6d01d","user":{"login":"liuw","id":138514,"avatar_url":"https://avatars.githubusercontent.com/u/138514?v=3","gravatar_id":"","url":"https://api.github.com/users/liuw","html_url":"https://github.com/liuw","followers_url":"https://api.github.com/users/liuw/followers","following_url":"https://api.github.com/users/liuw/following{/other_user}","gists_url":"https://api.github.com/users/liuw/gists{/gist_id}","starred_url":"https://api.github.com/users/liuw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liuw/subscriptions","organizations_url":"https://api.github.com/users/liuw/orgs","repos_url":"https://api.github.com/users/liuw/repos","events_url":"https://api.github.com/users/liuw/events{/privacy}","received_events_url":"https://api.github.com/users/liuw/received_events","type":"User","site_admin":false},"repo":{"id":31963582,"name":"rumprun","full_name":"liuw/rumprun","owner":{"login":"liuw","id":138514,"avatar_url":"https://avatars.githubusercontent.com/u/138514?v=3","gravatar_id":"","url":"https://api.github.com/users/liuw","html_url":"https://github.com/liuw","followers_url":"https://api.github.com/users/liuw/followers","following_url":"https://api.github.com/users/liuw/following{/other_user}","gists_url":"https://api.github.com/users/liuw/gists{/gist_id}","starred_url":"https://api.github.com/users/liuw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liuw/subscriptions","organizations_url":"https://api.github.com/users/liuw/orgs","repos_url":"https://api.github.com/users/liuw/repos","events_url":"https://api.github.com/users/liuw/events{/privacy}","received_events_url":"https://api.github.com/users/liuw/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/liuw/rumprun","description":"The rumprun software stack for various platforms","fork":true,"url":"https://api.github.com/repos/liuw/rumprun","forks_url":"https://api.github.com/repos/liuw/rumprun/forks","keys_url":"https://api.github.com/repos/liuw/rumprun/keys{/key_id}","collaborators_url":"https://api.github.com/repos/liuw/rumprun/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/liuw/rumprun/teams","hooks_url":"https://api.github.com/repos/liuw/rumprun/hooks","issue_events_url":"https://api.github.com/repos/liuw/rumprun/issues/events{/number}","events_url":"https://api.github.com/repos/liuw/rumprun/events","assignees_url":"https://api.github.com/repos/liuw/rumprun/assignees{/user}","branches_url":"https://api.github.com/repos/liuw/rumprun/branches{/branch}","tags_url":"https://api.github.com/repos/liuw/rumprun/tags","blobs_url":"https://api.github.com/repos/liuw/rumprun/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/liuw/rumprun/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/liuw/rumprun/git/refs{/sha}","trees_url":"https://api.github.com/repos/liuw/rumprun/git/trees{/sha}","statuses_url":"https://api.github.com/repos/liuw/rumprun/statuses/{sha}","languages_url":"https://api.github.com/repos/liuw/rumprun/languages","stargazers_url":"https://api.github.com/repos/liuw/rumprun/stargazers","contributors_url":"https://api.github.com/repos/liuw/rumprun/contributors","subscribers_url":"https://api.github.com/repos/liuw/rumprun/subscribers","subscription_url":"https://api.github.com/repos/liuw/rumprun/subscription","commits_url":"https://api.github.com/repos/liuw/rumprun/commits{/sha}","git_commits_url":"https://api.github.com/repos/liuw/rumprun/git/commits{/sha}","comments_url":"https://api.github.com/repos/liuw/rumprun/comments{/number}","issue_comment_url":"https://api.github.com/repos/liuw/rumprun/issues/comments{/number}","contents_url":"https://api.github.com/repos/liuw/rumprun/contents/{+path}","compare_url":"https://api.github.com/repos/liuw/rumprun/compare/{base}...{head}","merges_url":"https://api.github.com/repos/liuw/rumprun/merges","archive_url":"https://api.github.com/repos/liuw/rumprun/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/liuw/rumprun/downloads","issues_url":"https://api.github.com/repos/liuw/rumprun/issues{/number}","pulls_url":"https://api.github.com/repos/liuw/rumprun/pulls{/number}","milestones_url":"https://api.github.com/repos/liuw/rumprun/milestones{/number}","notifications_url":"https://api.github.com/repos/liuw/rumprun/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/liuw/rumprun/labels{/name}","releases_url":"https://api.github.com/repos/liuw/rumprun/releases{/id}","created_at":"2015-03-10T14:58:23Z","updated_at":"2015-03-10T14:58:25Z","pushed_at":"2015-05-21T17:52:30Z","git_url":"git://github.com/liuw/rumprun.git","ssh_url":"git@github.com:liuw/rumprun.git","clone_url":"https://github.com/liuw/rumprun.git","svn_url":"https://github.com/liuw/rumprun","homepage":"","size":2401,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"rumpkernel:master","ref":"master","sha":"bb8216a550d101c75846abcc3569fe084f75cb1e","user":{"login":"rumpkernel","id":6481016,"avatar_url":"https://avatars.githubusercontent.com/u/6481016?v=3","gravatar_id":"","url":"https://api.github.com/users/rumpkernel","html_url":"https://github.com/rumpkernel","followers_url":"https://api.github.com/users/rumpkernel/followers","following_url":"https://api.github.com/users/rumpkernel/following{/other_user}","gists_url":"https://api.github.com/users/rumpkernel/gists{/gist_id}","starred_url":"https://api.github.com/users/rumpkernel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rumpkernel/subscriptions","organizations_url":"https://api.github.com/users/rumpkernel/orgs","repos_url":"https://api.github.com/users/rumpkernel/repos","events_url":"https://api.github.com/users/rumpkernel/events{/privacy}","received_events_url":"https://api.github.com/users/rumpkernel/received_events","type":"Organization","site_admin":false},"repo":{"id":31077135,"name":"rumprun","full_name":"rumpkernel/rumprun","owner":{"login":"rumpkernel","id":6481016,"avatar_url":"https://avatars.githubusercontent.com/u/6481016?v=3","gravatar_id":"","url":"https://api.github.com/users/rumpkernel","html_url":"https://github.com/rumpkernel","followers_url":"https://api.github.com/users/rumpkernel/followers","following_url":"https://api.github.com/users/rumpkernel/following{/other_user}","gists_url":"https://api.github.com/users/rumpkernel/gists{/gist_id}","starred_url":"https://api.github.com/users/rumpkernel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rumpkernel/subscriptions","organizations_url":"https://api.github.com/users/rumpkernel/orgs","repos_url":"https://api.github.com/users/rumpkernel/repos","events_url":"https://api.github.com/users/rumpkernel/events{/privacy}","received_events_url":"https://api.github.com/users/rumpkernel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rumpkernel/rumprun","description":"The rumprun unikernel and toolchain for various platforms","fork":false,"url":"https://api.github.com/repos/rumpkernel/rumprun","forks_url":"https://api.github.com/repos/rumpkernel/rumprun/forks","keys_url":"https://api.github.com/repos/rumpkernel/rumprun/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rumpkernel/rumprun/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rumpkernel/rumprun/teams","hooks_url":"https://api.github.com/repos/rumpkernel/rumprun/hooks","issue_events_url":"https://api.github.com/repos/rumpkernel/rumprun/issues/events{/number}","events_url":"https://api.github.com/repos/rumpkernel/rumprun/events","assignees_url":"https://api.github.com/repos/rumpkernel/rumprun/assignees{/user}","branches_url":"https://api.github.com/repos/rumpkernel/rumprun/branches{/branch}","tags_url":"https://api.github.com/repos/rumpkernel/rumprun/tags","blobs_url":"https://api.github.com/repos/rumpkernel/rumprun/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rumpkernel/rumprun/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rumpkernel/rumprun/git/refs{/sha}","trees_url":"https://api.github.com/repos/rumpkernel/rumprun/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rumpkernel/rumprun/statuses/{sha}","languages_url":"https://api.github.com/repos/rumpkernel/rumprun/languages","stargazers_url":"https://api.github.com/repos/rumpkernel/rumprun/stargazers","contributors_url":"https://api.github.com/repos/rumpkernel/rumprun/contributors","subscribers_url":"https://api.github.com/repos/rumpkernel/rumprun/subscribers","subscription_url":"https://api.github.com/repos/rumpkernel/rumprun/subscription","commits_url":"https://api.github.com/repos/rumpkernel/rumprun/commits{/sha}","git_commits_url":"https://api.github.com/repos/rumpkernel/rumprun/git/commits{/sha}","comments_url":"https://api.github.com/repos/rumpkernel/rumprun/comments{/number}","issue_comment_url":"https://api.github.com/repos/rumpkernel/rumprun/issues/comments{/number}","contents_url":"https://api.github.com/repos/rumpkernel/rumprun/contents/{+path}","compare_url":"https://api.github.com/repos/rumpkernel/rumprun/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rumpkernel/rumprun/merges","archive_url":"https://api.github.com/repos/rumpkernel/rumprun/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rumpkernel/rumprun/downloads","issues_url":"https://api.github.com/repos/rumpkernel/rumprun/issues{/number}","pulls_url":"https://api.github.com/repos/rumpkernel/rumprun/pulls{/number}","milestones_url":"https://api.github.com/repos/rumpkernel/rumprun/milestones{/number}","notifications_url":"https://api.github.com/repos/rumpkernel/rumprun/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rumpkernel/rumprun/labels{/name}","releases_url":"https://api.github.com/repos/rumpkernel/rumprun/releases{/id}","created_at":"2015-02-20T17:55:46Z","updated_at":"2015-05-12T09:34:01Z","pushed_at":"2015-05-21T17:54:06Z","git_url":"git://github.com/rumpkernel/rumprun.git","ssh_url":"git@github.com:rumpkernel/rumprun.git","clone_url":"https://github.com/rumpkernel/rumprun.git","svn_url":"https://github.com/rumpkernel/rumprun","homepage":"","size":3314,"stargazers_count":15,"watchers_count":15,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":7,"forks":7,"open_issues":7,"watchers":15,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18"},"html":{"href":"https://github.com/rumpkernel/rumprun/pull/18"},"issue":{"href":"https://api.github.com/repos/rumpkernel/rumprun/issues/18"},"comments":{"href":"https://api.github.com/repos/rumpkernel/rumprun/issues/18/comments"},"review_comments":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18/comments"},"review_comment":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rumpkernel/rumprun/pulls/18/commits"},"statuses":{"href":"https://api.github.com/repos/rumpkernel/rumprun/statuses/6fb10a6dee7eb172fcc1d944e22a98f05fb6d01d"}}}}