From owner-svn-src-stable-10@freebsd.org Sun Oct 9 19:58:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9E295C0B2E6; Sun, 9 Oct 2016 19:58:28 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6136E822; Sun, 9 Oct 2016 19:58:28 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u99JwRTm086763; Sun, 9 Oct 2016 19:58:27 GMT (envelope-from pfg@FreeBSD.org) Received: (from pfg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u99JwRJ5086759; Sun, 9 Oct 2016 19:58:27 GMT (envelope-from pfg@FreeBSD.org) Message-Id: <201610091958.u99JwRJ5086759@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pfg set sender to pfg@FreeBSD.org using -f From: "Pedro F. Giffuni" Date: Sun, 9 Oct 2016 19:58:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306910 - stable/10/usr.sbin/fifolog/lib X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 09 Oct 2016 19:58:28 -0000 Author: pfg Date: Sun Oct 9 19:58:27 2016 New Revision: 306910 URL: https://svnweb.freebsd.org/changeset/base/306910 Log: MFC r305812: fifolog(1): invert order of calloc(3) arguments. The second argument to calloc(3) should be the size, make it so. While here be a little bit more cautious in fifolog_reader_open() to protect in the unlikely event of an overflowed allocation. Modified: stable/10/usr.sbin/fifolog/lib/fifolog_create.c stable/10/usr.sbin/fifolog/lib/fifolog_reader.c stable/10/usr.sbin/fifolog/lib/fifolog_write_poll.c stable/10/usr.sbin/fifolog/lib/miniobj.h Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.sbin/fifolog/lib/fifolog_create.c ============================================================================== --- stable/10/usr.sbin/fifolog/lib/fifolog_create.c Sun Oct 9 19:57:20 2016 (r306909) +++ stable/10/usr.sbin/fifolog/lib/fifolog_create.c Sun Oct 9 19:58:27 2016 (r306910) @@ -97,7 +97,7 @@ fifolog_create(const char *fn, off_t siz if (S_ISREG(st.st_mode) && ftruncate(fd, size) < 0) return ("Could not ftrunc"); - buf = calloc(recsize, 1); + buf = calloc(1, recsize); if (buf == NULL) return ("Could not malloc"); Modified: stable/10/usr.sbin/fifolog/lib/fifolog_reader.c ============================================================================== --- stable/10/usr.sbin/fifolog/lib/fifolog_reader.c Sun Oct 9 19:57:20 2016 (r306909) +++ stable/10/usr.sbin/fifolog/lib/fifolog_reader.c Sun Oct 9 19:58:27 2016 (r306910) @@ -67,10 +67,10 @@ fifolog_reader_open(const char *fname) if (retval != NULL) err(1, "%s", retval); - fr->olen = fr->ff->recsize * 16; - fr->obuf = calloc(fr->olen, 1); + fr->obuf = calloc(16, fr->ff->recsize); if (fr->obuf == NULL) err(1, "Cannot malloc"); + fr->olen = fr->ff->recsize * 16; i = inflateInit(fr->ff->zs); assert(i == Z_OK); Modified: stable/10/usr.sbin/fifolog/lib/fifolog_write_poll.c ============================================================================== --- stable/10/usr.sbin/fifolog/lib/fifolog_write_poll.c Sun Oct 9 19:57:20 2016 (r306909) +++ stable/10/usr.sbin/fifolog/lib/fifolog_write_poll.c Sun Oct 9 19:58:27 2016 (r306910) @@ -45,7 +45,7 @@ static int fifolog_write_gzip(struct fifolog_writer *f, time_t now); #define ALLOC(ptr, size) do { \ - (*(ptr)) = calloc(size, 1); \ + (*(ptr)) = calloc(1, size); \ assert(*(ptr) != NULL); \ } while (0) Modified: stable/10/usr.sbin/fifolog/lib/miniobj.h ============================================================================== --- stable/10/usr.sbin/fifolog/lib/miniobj.h Sun Oct 9 19:57:20 2016 (r306909) +++ stable/10/usr.sbin/fifolog/lib/miniobj.h Sun Oct 9 19:58:27 2016 (r306910) @@ -28,7 +28,7 @@ #define ALLOC_OBJ(to, type_magic) \ do { \ - (to) = calloc(sizeof *(to), 1); \ + (to) = calloc(1, sizeof *(to)); \ if ((to) != NULL) \ (to)->magic = (type_magic); \ } while (0) From owner-svn-src-stable-10@freebsd.org Sun Oct 9 20:13:54 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B8245C0B6DF; Sun, 9 Oct 2016 20:13:54 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 874F1338; Sun, 9 Oct 2016 20:13:54 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u99KDrjT094227; Sun, 9 Oct 2016 20:13:53 GMT (envelope-from pfg@FreeBSD.org) Received: (from pfg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u99KDrE2094226; Sun, 9 Oct 2016 20:13:53 GMT (envelope-from pfg@FreeBSD.org) Message-Id: <201610092013.u99KDrE2094226@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pfg set sender to pfg@FreeBSD.org using -f From: "Pedro F. Giffuni" Date: Sun, 9 Oct 2016 20:13:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306914 - stable/10/usr.bin/patch X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 09 Oct 2016 20:13:54 -0000 Author: pfg Date: Sun Oct 9 20:13:53 2016 New Revision: 306914 URL: https://svnweb.freebsd.org/changeset/base/306914 Log: MFC r306560, r306561: patch(1): make some macros look boolean. Minor cleanup inspired by a new patch(1) variant in schily tools. For reference: https://sourceforge.net/p/schillix-on/ Modified: stable/10/usr.bin/patch/common.h Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.bin/patch/common.h ============================================================================== --- stable/10/usr.bin/patch/common.h Sun Oct 9 20:12:58 2016 (r306913) +++ stable/10/usr.bin/patch/common.h Sun Oct 9 20:13:53 2016 (r306914) @@ -53,10 +53,9 @@ /* handy definitions */ -#define strNE(s1,s2) (strcmp(s1, s2)) -#define strEQ(s1,s2) (!strcmp(s1, s2)) -#define strnNE(s1,s2,l) (strncmp(s1, s2, l)) -#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l)) +#define strEQ(s1,s2) (strcmp(s1, s2) == 0) +#define strnNE(s1,s2,l) (strncmp(s1, s2, l) != 0) +#define strnEQ(s1,s2,l) (strncmp(s1, s2, l) == 0) /* typedefs */ From owner-svn-src-stable-10@freebsd.org Sun Oct 9 21:28:57 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CA0D3C0B0B6; Sun, 9 Oct 2016 21:28:57 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 90BBAA96; Sun, 9 Oct 2016 21:28:57 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u99LSuvV021308; Sun, 9 Oct 2016 21:28:56 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u99LSuJj021307; Sun, 9 Oct 2016 21:28:56 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201610092128.u99LSuJj021307@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Sun, 9 Oct 2016 21:28:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306924 - stable/10/etc/rc.d X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 09 Oct 2016 21:28:57 -0000 Author: jilles Date: Sun Oct 9 21:28:56 2016 New Revision: 306924 URL: https://svnweb.freebsd.org/changeset/base/306924 Log: MFC r297314: rc.d: Make msgs a proper rc.d script. PR: 207149 Reported by: Jonathan de Boyne Pollard Modified: stable/10/etc/rc.d/msgs Directory Properties: stable/10/ (props changed) Modified: stable/10/etc/rc.d/msgs ============================================================================== --- stable/10/etc/rc.d/msgs Sun Oct 9 21:05:19 2016 (r306923) +++ stable/10/etc/rc.d/msgs Sun Oct 9 21:28:56 2016 (r306924) @@ -6,8 +6,20 @@ # PROVIDE: msgs # REQUIRE: LOGIN -# Make a bounds file for msgs(1) if there isn't one already -# -if [ -d /var/msgs -a ! -f /var/msgs/bounds -a ! -L /var/msgs/bounds ]; then - echo 0 > /var/msgs/bounds -fi +. /etc/rc.subr + +name="msgs" +start_cmd="msgs_start" +stop_cmd=":" + +msgs_start() +{ + # Make a bounds file for msgs(1) if there isn't one already + # + if [ -d /var/msgs -a ! -f /var/msgs/bounds -a ! -L /var/msgs/bounds ]; then + echo 0 > /var/msgs/bounds + fi +} + +load_rc_config $name +run_rc_command "$1" From owner-svn-src-stable-10@freebsd.org Sun Oct 9 21:35:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B2114C0B208; Sun, 9 Oct 2016 21:35:13 +0000 (UTC) (envelope-from jch@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8196CE64; Sun, 9 Oct 2016 21:35:13 +0000 (UTC) (envelope-from jch@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u99LZCm6024907; Sun, 9 Oct 2016 21:35:12 GMT (envelope-from jch@FreeBSD.org) Received: (from jch@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u99LZCTR024906; Sun, 9 Oct 2016 21:35:12 GMT (envelope-from jch@FreeBSD.org) Message-Id: <201610092135.u99LZCTR024906@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jch set sender to jch@FreeBSD.org using -f From: Julien Charbon Date: Sun, 9 Oct 2016 21:35:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306925 - stable/10/sys/netinet X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 09 Oct 2016 21:35:13 -0000 Author: jch Date: Sun Oct 9 21:35:12 2016 New Revision: 306925 URL: https://svnweb.freebsd.org/changeset/base/306925 Log: MFC r306443: Fix an issue with accept_filter introduced with r261242: As a side effect of r261242 when using accept_filter the first call to soisconnected() is done earlier in tcp_input() instead of tcp_do_segment() context. Restore the expected behaviour. Note: This call to soisconnected() seems to be extraneous in all cases (with or without accept_filter). Will be addressed in a separate commit. PR: 212920 Reported by: Alexey Tested by: Alexey, jch Sponsored by: Verisign, Inc. Modified: stable/10/sys/netinet/tcp_syncache.c Modified: stable/10/sys/netinet/tcp_syncache.c ============================================================================== --- stable/10/sys/netinet/tcp_syncache.c Sun Oct 9 21:28:56 2016 (r306924) +++ stable/10/sys/netinet/tcp_syncache.c Sun Oct 9 21:35:12 2016 (r306925) @@ -922,7 +922,9 @@ syncache_socket(struct syncache *sc, str INP_WUNLOCK(inp); - soisconnected(so); + if ((so->so_options & SO_ACCEPTFILTER) == 0) { + soisconnected(so); + } TCPSTAT_INC(tcps_accepts); return (so); From owner-svn-src-stable-10@freebsd.org Mon Oct 10 04:57:34 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D0890C0B360; Mon, 10 Oct 2016 04:57:34 +0000 (UTC) (envelope-from julian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A01D62B; Mon, 10 Oct 2016 04:57:34 +0000 (UTC) (envelope-from julian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9A4vXAM092951; Mon, 10 Oct 2016 04:57:33 GMT (envelope-from julian@FreeBSD.org) Received: (from julian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9A4vXlI092950; Mon, 10 Oct 2016 04:57:33 GMT (envelope-from julian@FreeBSD.org) Message-Id: <201610100457.u9A4vXlI092950@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: julian set sender to julian@FreeBSD.org using -f From: Julian Elischer Date: Mon, 10 Oct 2016 04:57:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306935 - stable/10/sys/kern X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 04:57:34 -0000 Author: julian Date: Mon Oct 10 04:57:33 2016 New Revision: 306935 URL: https://svnweb.freebsd.org/changeset/base/306935 Log: While the thread is sleeping in taskqueue_drain_all() it is posible that the queue entry it is looking at is removed from the queue, but we make no effort to account for this. when we wake up we need to check it's still there. PR: 209580 Sponsored by: Panzura inc Differential Revision: D8160 Modified: stable/10/sys/kern/subr_taskqueue.c Modified: stable/10/sys/kern/subr_taskqueue.c ============================================================================== --- stable/10/sys/kern/subr_taskqueue.c Mon Oct 10 04:53:15 2016 (r306934) +++ stable/10/sys/kern/subr_taskqueue.c Mon Oct 10 04:57:33 2016 (r306935) @@ -454,9 +454,26 @@ taskqueue_drain_all(struct taskqueue *qu TQ_LOCK(queue); task = STAILQ_LAST(&queue->tq_queue, task, ta_link); - if (task != NULL) - while (task->ta_pending != 0) - TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0); + while (task != NULL && task->ta_pending != 0) { + struct task *oldtask; + TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0); + /* + * While we were asleeep the last entry may have been freed. + * We need to check if it's still even in the queue. + * Not perfect, but it's better than referencing bad memory. + * first guess is the current 'end of queue' but if a new + * item has been added we need to take the expensive path + * Better fix in 11. + */ + oldtask = task; + if (oldtask != + (task = STAILQ_LAST(&queue->tq_queue, task, ta_link))) { + STAILQ_FOREACH(task, &queue->tq_queue, ta_link) { + if (task == oldtask) + break; + } + } + } taskqueue_drain_running(queue); KASSERT(STAILQ_EMPTY(&queue->tq_queue), ("taskqueue queue is not empty after draining")); From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:25:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 563FEC0B1B3; Mon, 10 Oct 2016 11:25:13 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 17AD3CCD; Mon, 10 Oct 2016 11:25:13 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABPCnR040649; Mon, 10 Oct 2016 11:25:12 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABPCAT040647; Mon, 10 Oct 2016 11:25:12 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201610101125.u9ABPCAT040647@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 10 Oct 2016 11:25:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306947 - in stable/10: share/man/man9 sys/kern X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:25:13 -0000 Author: hselasky Date: Mon Oct 10 11:25:11 2016 New Revision: 306947 URL: https://svnweb.freebsd.org/changeset/base/306947 Log: MFC r306441 and r306634: While draining a timeout task prevent the taskqueue_enqueue_timeout() function from restarting the timer. Commonly taskqueue_enqueue_timeout() is called from within the task function itself without any checks for teardown. Then it can happen the timer stays active after the return of taskqueue_drain_timeout(), because the timeout and task is drained separately. This patch factors out the teardown flag into the timeout task itself, allowing existing code to stay as-is instead of applying a teardown flag to each and every of the timeout task consumers. Add assert to taskqueue_drain_timeout() which prevents parallel execution on the same timeout task. Update manual page documenting the return value of taskqueue_enqueue_timeout(). Differential Revision: https://reviews.freebsd.org/D8012 Reviewed by: kib, trasz Modified: stable/10/share/man/man9/taskqueue.9 stable/10/sys/kern/subr_taskqueue.c Directory Properties: stable/10/ (props changed) Modified: stable/10/share/man/man9/taskqueue.9 ============================================================================== --- stable/10/share/man/man9/taskqueue.9 Mon Oct 10 11:22:11 2016 (r306946) +++ stable/10/share/man/man9/taskqueue.9 Mon Oct 10 11:25:11 2016 (r306947) @@ -221,6 +221,8 @@ Otherwise, the task is scheduled for enq after the absolute value of .Va ticks is passed. +This function returns -1 if the task is being drained. +Otherwise, the number of pending calls is returned. .Pp The .Fn taskqueue_cancel Modified: stable/10/sys/kern/subr_taskqueue.c ============================================================================== --- stable/10/sys/kern/subr_taskqueue.c Mon Oct 10 11:22:11 2016 (r306946) +++ stable/10/sys/kern/subr_taskqueue.c Mon Oct 10 11:25:11 2016 (r306947) @@ -75,6 +75,7 @@ struct taskqueue { #define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2) #define DT_CALLOUT_ARMED (1 << 0) +#define DT_DRAIN_IN_PROGRESS (1 << 1) #define TQ_LOCK(tq) \ do { \ @@ -279,7 +280,11 @@ taskqueue_enqueue_timeout(struct taskque KASSERT(!queue->tq_spin, ("Timeout for spin-queue")); timeout_task->q = queue; res = timeout_task->t.ta_pending; - if (ticks == 0) { + if (timeout_task->f & DT_DRAIN_IN_PROGRESS) { + /* Do nothing */ + TQ_UNLOCK(queue); + res = -1; + } else if (ticks == 0) { taskqueue_enqueue_locked(queue, &timeout_task->t); /* The lock is released inside. */ } else { @@ -485,8 +490,24 @@ taskqueue_drain_timeout(struct taskqueue struct timeout_task *timeout_task) { + /* + * Set flag to prevent timer from re-starting during drain: + */ + TQ_LOCK(queue); + KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0, + ("Drain already in progress")); + timeout_task->f |= DT_DRAIN_IN_PROGRESS; + TQ_UNLOCK(queue); + callout_drain(&timeout_task->c); taskqueue_drain(queue, &timeout_task->t); + + /* + * Clear flag to allow timer to re-start: + */ + TQ_LOCK(queue); + timeout_task->f &= ~DT_DRAIN_IN_PROGRESS; + TQ_UNLOCK(queue); } static void From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:34:52 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9FD8BC0B796; Mon, 10 Oct 2016 11:34:52 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 54AF2A7D; Mon, 10 Oct 2016 11:34:52 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABYp0d044451; Mon, 10 Oct 2016 11:34:51 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABYpAk044450; Mon, 10 Oct 2016 11:34:51 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201610101134.u9ABYpAk044450@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 10 Oct 2016 11:34:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306950 - stable/10/sys/ofed/include/linux X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:34:52 -0000 Author: hselasky Date: Mon Oct 10 11:34:51 2016 New Revision: 306950 URL: https://svnweb.freebsd.org/changeset/base/306950 Log: MFC r306451: The IORESOURCE_XXX defines should resemble a bitmask while SYS_RES_XXX are not bitmasks. Fix return value of pci_resource_flags() to reflect this change. Sponsored by: Mellanox Technologies Modified: stable/10/sys/ofed/include/linux/pci.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/ofed/include/linux/pci.h ============================================================================== --- stable/10/sys/ofed/include/linux/pci.h Mon Oct 10 11:30:35 2016 (r306949) +++ stable/10/sys/ofed/include/linux/pci.h Mon Oct 10 11:34:51 2016 (r306950) @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -115,9 +115,9 @@ struct pci_device_id { #define PCI_EXP_TYPE_RC_EC PCIEM_TYPE_ROOT_EC /* Root Complex Event Collector */ -#define IORESOURCE_MEM SYS_RES_MEMORY -#define IORESOURCE_IO SYS_RES_IOPORT -#define IORESOURCE_IRQ SYS_RES_IRQ +#define IORESOURCE_MEM (1 << SYS_RES_MEMORY) +#define IORESOURCE_IO (1 << SYS_RES_IOPORT) +#define IORESOURCE_IRQ (1 << SYS_RES_IRQ) struct pci_dev; @@ -213,17 +213,28 @@ pci_resource_len(struct pci_dev *pdev, i return rle->count; } +static inline int +pci_resource_type(struct pci_dev *pdev, int bar) +{ + struct resource_list_entry *rle; + + if ((rle = _pci_get_bar(pdev, bar)) == NULL) + return (-1); + return (rle->type); +} + /* * All drivers just seem to want to inspect the type not flags. */ static inline int pci_resource_flags(struct pci_dev *pdev, int bar) { - struct resource_list_entry *rle; + int type; - if ((rle = _pci_get_bar(pdev, bar)) == NULL) + type = pci_resource_type(pdev, bar); + if (type < 0) return (0); - return rle->type; + return (1 << type); } static inline const char * @@ -283,8 +294,8 @@ pci_request_region(struct pci_dev *pdev, int rid; int type; - type = pci_resource_flags(pdev, bar); - if (type == 0) + type = pci_resource_type(pdev, bar); + if (type < 0) return (-ENODEV); rid = PCIR_BAR(bar); if (bus_alloc_resource_any(pdev->dev.bsddev, type, &rid, From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:40:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B708DC0BB7A; Mon, 10 Oct 2016 11:40:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 881C4207; Mon, 10 Oct 2016 11:40:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABeqx1044860; Mon, 10 Oct 2016 11:40:52 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABeqIU044859; Mon, 10 Oct 2016 11:40:52 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201610101140.u9ABeqIU044859@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 10 Oct 2016 11:40:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306953 - stable/10/sys/dev/mlx5/mlx5_en X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:40:53 -0000 Author: hselasky Date: Mon Oct 10 11:40:52 2016 New Revision: 306953 URL: https://svnweb.freebsd.org/changeset/base/306953 Log: MFC r306453: Set hardware stats flag to avoid double counting the number of incoming bytes. Found by: Ben RUBSON Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c ============================================================================== --- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Oct 10 11:38:55 2016 (r306952) +++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Oct 10 11:40:52 2016 (r306953) @@ -2909,6 +2909,7 @@ mlx5e_create_ifp(struct mlx5_core_dev *m ifp->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU; ifp->if_capabilities |= IFCAP_LRO; ifp->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO; + ifp->if_capabilities |= IFCAP_HWSTATS; /* set TSO limits so that we don't have to drop TX packets */ ifp->if_hw_tsomax = MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:43:56 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B268AC0BD7A; Mon, 10 Oct 2016 11:43:56 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 83A75B71; Mon, 10 Oct 2016 11:43:56 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABhtuW048853; Mon, 10 Oct 2016 11:43:55 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABhtFj048852; Mon, 10 Oct 2016 11:43:55 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201610101143.u9ABhtFj048852@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 10 Oct 2016 11:43:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306955 - stable/10/sys/ofed/drivers/net/mlx4 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:43:56 -0000 Author: hselasky Date: Mon Oct 10 11:43:55 2016 New Revision: 306955 URL: https://svnweb.freebsd.org/changeset/base/306955 Log: MFC r306454: Set hardware stats flag to avoid double counting the number of incoming bytes. Found by: Ben RUBSON Sponsored by: Mellanox Technologies Modified: stable/10/sys/ofed/drivers/net/mlx4/en_netdev.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/ofed/drivers/net/mlx4/en_netdev.c ============================================================================== --- stable/10/sys/ofed/drivers/net/mlx4/en_netdev.c Mon Oct 10 11:42:25 2016 (r306954) +++ stable/10/sys/ofed/drivers/net/mlx4/en_netdev.c Mon Oct 10 11:43:55 2016 (r306955) @@ -2166,6 +2166,7 @@ int mlx4_en_init_netdev(struct mlx4_en_d dev->if_capabilities |= IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER; dev->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU; dev->if_capabilities |= IFCAP_LRO; + dev->if_capabilities |= IFCAP_HWSTATS; if (mdev->LSO_support) dev->if_capabilities |= IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTSO; From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:47:30 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B32B7C0BF45; Mon, 10 Oct 2016 11:47:30 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8AAA3FD3; Mon, 10 Oct 2016 11:47:30 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABlTa4049139; Mon, 10 Oct 2016 11:47:29 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABlTW1049137; Mon, 10 Oct 2016 11:47:29 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201610101147.u9ABlTW1049137@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 10 Oct 2016 11:47:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306957 - in stable/10/sys/dev/usb: . serial X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:47:30 -0000 Author: hselasky Date: Mon Oct 10 11:47:29 2016 New Revision: 306957 URL: https://svnweb.freebsd.org/changeset/base/306957 Log: MFC r306478: Add new USB ID. While at it remove some whitespaces. Submitted by: Jose Luis Duran PR: 213110 Modified: stable/10/sys/dev/usb/serial/u3g.c stable/10/sys/dev/usb/usbdevs Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/usb/serial/u3g.c ============================================================================== --- stable/10/sys/dev/usb/serial/u3g.c Mon Oct 10 11:46:08 2016 (r306956) +++ stable/10/sys/dev/usb/serial/u3g.c Mon Oct 10 11:47:29 2016 (r306957) @@ -525,6 +525,7 @@ static const STRUCT_USB_HOST_ID u3g_devs U3G_DEV(SIERRA, MC5728, 0), U3G_DEV(SIERRA, MC7354, 0), U3G_DEV(SIERRA, MC7355, 0), + U3G_DEV(SIERRA, MC7430, 0), U3G_DEV(SIERRA, MC8700, 0), U3G_DEV(SIERRA, MC8755, 0), U3G_DEV(SIERRA, MC8755_2, 0), @@ -628,7 +629,7 @@ u3g_sael_m460_init(struct usb_device *ud static const uint8_t setup[][24] = { { 0x41, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x41, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + { 0x41, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xc1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02 }, @@ -640,7 +641,7 @@ u3g_sael_m460_init(struct usb_device *ud { 0x41, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 }, { 0x41, 0x19, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x13 }, - { 0x41, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + { 0x41, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00 }, { 0x41, 0x12, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -650,7 +651,7 @@ u3g_sael_m460_init(struct usb_device *ud { 0x41, 0x19, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x13 }, { 0x41, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00 }, { 0x41, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 }, }; @@ -684,7 +685,7 @@ u3g_sael_m460_init(struct usb_device *ud DPRINTFN(0, "too small buffer\n"); continue; } - err = usbd_do_request(udev, NULL, &req, + err = usbd_do_request(udev, NULL, &req, __DECONST(uint8_t *, &setup[n][8])); } if (err) { @@ -859,7 +860,7 @@ u3g_attach(device_t dev) } /* copy in USB config */ - for (n = 0; n != U3G_N_TRANSFER; n++) + for (n = 0; n != U3G_N_TRANSFER; n++) u3g_config_tmp[n] = u3g_config[n]; device_set_usb_desc(dev); Modified: stable/10/sys/dev/usb/usbdevs ============================================================================== --- stable/10/sys/dev/usb/usbdevs Mon Oct 10 11:46:08 2016 (r306956) +++ stable/10/sys/dev/usb/usbdevs Mon Oct 10 11:47:29 2016 (r306957) @@ -4079,6 +4079,7 @@ product SIERRA E6893 0x6893 E6893 product SIERRA MC8700 0x68A3 MC8700 product SIERRA MC7354 0x68C0 MC7354 product SIERRA MC7355 0x9041 MC7355 +product SIERRA MC7430 0x9071 Sierra Wireless MC7430 Qualcomm Snapdragon X7 LTE-A product SIERRA AC313U 0x68aa Sierra Wireless AirCard 313U product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer From owner-svn-src-stable-10@freebsd.org Mon Oct 10 11:53:55 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 469EDC0B3CB; Mon, 10 Oct 2016 11:53:55 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 182A4BBF; Mon, 10 Oct 2016 11:53:55 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9ABrsMD052917; Mon, 10 Oct 2016 11:53:54 GMT (envelope-from tijl@FreeBSD.org) Received: (from tijl@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9ABrsb0052916; Mon, 10 Oct 2016 11:53:54 GMT (envelope-from tijl@FreeBSD.org) Message-Id: <201610101153.u9ABrsb0052916@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tijl set sender to tijl@FreeBSD.org using -f From: Tijl Coosemans Date: Mon, 10 Oct 2016 11:53:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306961 - stable/10/sys/i386/i386 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 11:53:55 -0000 Author: tijl Date: Mon Oct 10 11:53:54 2016 New Revision: 306961 URL: https://svnweb.freebsd.org/changeset/base/306961 Log: MFC: r306318 Allocate a zeroed LDT. Failing to do this might result in the LDT appearing to run out of free descriptors because of random junk in the descriptor's 'sd_type' field. http://lists.freebsd.org/pipermail/freebsd-amd64/2014-May/016088.html PR: 212639 Submitted by: wheelcomplex@gmail.com Modified: stable/10/sys/i386/i386/sys_machdep.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/i386/i386/sys_machdep.c ============================================================================== --- stable/10/sys/i386/i386/sys_machdep.c Mon Oct 10 11:51:47 2016 (r306960) +++ stable/10/sys/i386/i386/sys_machdep.c Mon Oct 10 11:53:54 2016 (r306961) @@ -509,7 +509,7 @@ user_ldt_alloc(struct mdproc *mdp, int l new_ldt->ldt_len = len = NEW_MAX_LD(len); new_ldt->ldt_base = (caddr_t)kmem_malloc(kernel_arena, - len * sizeof(union descriptor), M_WAITOK); + len * sizeof(union descriptor), M_WAITOK | M_ZERO); new_ldt->ldt_refcnt = 1; new_ldt->ldt_active = 0; From owner-svn-src-stable-10@freebsd.org Mon Oct 10 15:44:44 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2075EC0C07F; Mon, 10 Oct 2016 15:44:44 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E32F4275; Mon, 10 Oct 2016 15:44:43 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AFihgX042778; Mon, 10 Oct 2016 15:44:43 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AFihDm042777; Mon, 10 Oct 2016 15:44:43 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101544.u9AFihDm042777@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 15:44:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306968 - stable/10/bin/chio X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 15:44:44 -0000 Author: sevan (doc committer) Date: Mon Oct 10 15:44:42 2016 New Revision: 306968 URL: https://svnweb.freebsd.org/changeset/base/306968 Log: MFC r306584: Move the description of CHANGER variable to ENVIRONMENT section rather than in the DESCRIPTION section. From OpenBSD src/bin/chio/chio.1 r1.23 PR: 212158 Approved by: bjk Obtained from: OpenBSD Differential Revision: https://reviews.freebsd.org/D8117 Modified: stable/10/bin/chio/chio.1 Directory Properties: stable/10/ (props changed) Modified: stable/10/bin/chio/chio.1 ============================================================================== --- stable/10/bin/chio/chio.1 Mon Oct 10 15:42:50 2016 (r306967) +++ stable/10/bin/chio/chio.1 Mon Oct 10 15:44:42 2016 (r306968) @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 14, 1998 +.Dd October 2, 2016 .Dt CHIO 1 .Os .Sh NAME @@ -61,10 +61,6 @@ rather than the default device .Pa /dev/ch0 . .El .Pp -The default changer may be overridden by setting the environment variable -.Ev CHANGER -to the desired changer device. -.Pp A medium changer apparatus is made up of .Em elements . There are five element types: @@ -267,6 +263,12 @@ Element supports passing media (exportin .It INENAB Element supports receiving media (importing) from an outside human operator. .El +.Sh ENVIRONMENT +.Bl -tag -width CHANGER +.It Ev CHANGER +The default changer may be overridden by setting this environmental +variable to the desired changer device. +.El .Sh FILES .Bl -tag -width /dev/ch0 -compact .It Pa /dev/ch0 From owner-svn-src-stable-10@freebsd.org Mon Oct 10 15:48:41 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7EE26C0C195; Mon, 10 Oct 2016 15:48:41 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4B04E9B7; Mon, 10 Oct 2016 15:48:41 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AFmeqe043102; Mon, 10 Oct 2016 15:48:40 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AFmeuo043101; Mon, 10 Oct 2016 15:48:40 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101548.u9AFmeuo043101@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 15:48:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306971 - stable/10/bin/chio X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 15:48:41 -0000 Author: sevan (doc committer) Date: Mon Oct 10 15:48:40 2016 New Revision: 306971 URL: https://svnweb.freebsd.org/changeset/base/306971 Log: MFC r306714: Document where chio(1) originated from & which version of FreeBSD first included it. PR: 211776 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8104 Modified: stable/10/bin/chio/chio.1 Directory Properties: stable/10/ (props changed) Modified: stable/10/bin/chio/chio.1 ============================================================================== --- stable/10/bin/chio/chio.1 Mon Oct 10 15:47:39 2016 (r306970) +++ stable/10/bin/chio/chio.1 Mon Oct 10 15:48:40 2016 (r306971) @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 2, 2016 +.Dd October 5, 2016 .Dt CHIO 1 .Os .Sh NAME @@ -289,6 +289,14 @@ Configure the changer to use picker 2 (t .Sh SEE ALSO .Xr mt 1 , .Xr mount 8 +.Sh HISTORY +A +.Nm +utility appeared in +.Nx 1.3 . +.Nm +first appeared in +.Fx 2.2 . .Sh AUTHORS .An -nosplit The From owner-svn-src-stable-10@freebsd.org Mon Oct 10 15:54:33 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CA486C0C49C; Mon, 10 Oct 2016 15:54:33 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9BAB81F4; Mon, 10 Oct 2016 15:54:33 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AFsWIY046968; Mon, 10 Oct 2016 15:54:32 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AFsWUl046967; Mon, 10 Oct 2016 15:54:32 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101554.u9AFsWUl046967@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 15:54:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306974 - stable/10/bin/ed X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 15:54:33 -0000 Author: sevan (doc committer) Date: Mon Oct 10 15:54:32 2016 New Revision: 306974 URL: https://svnweb.freebsd.org/changeset/base/306974 Log: MFC r306581: Use .At macro instead of specifying AT&T UNIX literaly. PR: 212034 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8114 Modified: stable/10/bin/ed/ed.1 Directory Properties: stable/10/ (props changed) Modified: stable/10/bin/ed/ed.1 ============================================================================== --- stable/10/bin/ed/ed.1 Mon Oct 10 15:53:56 2016 (r306973) +++ stable/10/bin/ed/ed.1 Mon Oct 10 15:54:32 2016 (r306974) @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd July 3, 2004 +.Dd October 2, 2016 .Dt ED 1 .Os .Sh NAME @@ -998,7 +998,7 @@ per line overhead: 4 ints An .Nm command appeared in -Version 1 AT&T UNIX. +.At v1 . .Sh BUGS The .Nm From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:07:24 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5A93FC0C8FD; Mon, 10 Oct 2016 16:07:24 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2C203FCE; Mon, 10 Oct 2016 16:07:24 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AG7N7t051222; Mon, 10 Oct 2016 16:07:23 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AG7N9b051221; Mon, 10 Oct 2016 16:07:23 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101607.u9AG7N9b051221@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:07:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306976 - stable/10/bin/chmod X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:07:24 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:07:23 2016 New Revision: 306976 URL: https://svnweb.freebsd.org/changeset/base/306976 Log: MFC r306582: "POSIX doesn't specify -h." - r1.27 from NetBSD http://man.openbsd.org/?query=chmod&apropos=0&sec=0&arch=default&manpath=POSIX-2013 PR: 212337 Approved by: bcr (mentor) Obtained from: NetBSD Differential Revision: https://reviews.freebsd.org/D8118 Modified: stable/10/bin/chmod/chmod.c Directory Properties: stable/10/ (props changed) Modified: stable/10/bin/chmod/chmod.c ============================================================================== --- stable/10/bin/chmod/chmod.c Mon Oct 10 16:06:55 2016 (r306975) +++ stable/10/bin/chmod/chmod.c Mon Oct 10 16:07:23 2016 (r306976) @@ -91,12 +91,11 @@ main(int argc, char *argv[]) break; case 'h': /* - * In System V (and probably POSIX.2) the -h option - * causes chmod to change the mode of the symbolic - * link. 4.4BSD's symbolic links didn't have modes, - * so it was an undocumented noop. In FreeBSD 3.0, - * lchmod(2) is introduced and this option does real - * work. + * In System V the -h option causes chmod to change + * the mode of the symbolic link. 4.4BSD's symbolic + * links didn't have modes, so it was an undocumented + * noop. In FreeBSD 3.0, lchmod(2) is introduced and + * this option does real work. */ hflag = 1; break; From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:11:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F407DC0CB04; Mon, 10 Oct 2016 16:11:52 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C58F696F; Mon, 10 Oct 2016 16:11:52 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGBpLw055116; Mon, 10 Oct 2016 16:11:51 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGBp3W055115; Mon, 10 Oct 2016 16:11:51 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101611.u9AGBp3W055115@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:11:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306979 - stable/10/sbin/ccdconfig X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:11:53 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:11:51 2016 New Revision: 306979 URL: https://svnweb.freebsd.org/changeset/base/306979 Log: MFC r306598 ccdconfig first appeared in NetBSD 1.1 From NetBSD man page, confirmed with repo tags in CVS [1] (there was also no 1.0a release according to [2]) [1] http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/ccdconfig/ccdconfig.c [2] http://netbsd.org/releases/formal.html#history PR: 212437 Approved by: bcr (mentor) Obtained from: NetBSD Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/ccdconfig/ccdconfig.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/ccdconfig/ccdconfig.8 ============================================================================== --- stable/10/sbin/ccdconfig/ccdconfig.8 Mon Oct 10 16:11:02 2016 (r306978) +++ stable/10/sbin/ccdconfig/ccdconfig.8 Mon Oct 10 16:11:51 2016 (r306979) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 1, 2013 +.Dd October 3, 2016 .Dt CCDCONFIG 8 .Os .Sh NAME @@ -159,7 +159,7 @@ It reads as a two disk stripe of da4 and to a two disk stripe of da6 and da7. The last example is a simple mirror. -The 2nd slice of /dev/da8 is mirrored with the 3rd slice of /dev/da9 +The second slice of /dev/da8 is mirrored with the third slice of /dev/da9 and assigned to ccd0. .Bd -literal # ccdconfig ccd0 64 none /dev/da0s1 /dev/da1s1 /dev/da2s1 /dev/da3s1 @@ -246,7 +246,7 @@ and The .Nm utility first appeared in -.Nx 1.0a . +.Nx 1.1 . .Sh BUGS The initial disklabel returned by .Xr ccd 4 From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:14:01 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 608B8C0CB96; Mon, 10 Oct 2016 16:14:01 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2C91DB95; Mon, 10 Oct 2016 16:14:01 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGE0LE055258; Mon, 10 Oct 2016 16:14:00 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGE0PT055257; Mon, 10 Oct 2016 16:14:00 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101614.u9AGE0PT055257@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:14:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306980 - stable/10/sbin/dump X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:14:01 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:14:00 2016 New Revision: 306980 URL: https://svnweb.freebsd.org/changeset/base/306980 Log: MFC r306600: dump(8) first appeared in V4 UNIX http://minnie.tuhs.org/cgi-bin/utree.pl?file=V4/man/man8 PR: 212444 Approved by: bcr (mentor) Obtained from: TUHS Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/dump/dump.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/dump/dump.8 ============================================================================== --- stable/10/sbin/dump/dump.8 Mon Oct 10 16:11:51 2016 (r306979) +++ stable/10/sbin/dump/dump.8 Mon Oct 10 16:14:00 2016 (r306980) @@ -29,7 +29,7 @@ .\" @(#)dump.8 8.3 (Berkeley) 5/1/95 .\" $FreeBSD$ .\" -.Dd February 24, 2006 +.Dd October 3, 2016 .Dt DUMP 8 .Os .Sh NAME @@ -514,7 +514,7 @@ Many, and verbose. A .Nm utility appeared in -.At v6 . +.At v4 . .Sh BUGS Fewer than 32 read errors on the file system are ignored, though all errors will generate a warning message. From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:17:16 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0552EC0CD30; Mon, 10 Oct 2016 16:17:16 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CAB9B185; Mon, 10 Oct 2016 16:17:15 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGHEXA055940; Mon, 10 Oct 2016 16:17:14 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGHE9J055939; Mon, 10 Oct 2016 16:17:14 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101617.u9AGHE9J055939@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:17:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306983 - stable/10/sbin/dumpon X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:17:16 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:17:14 2016 New Revision: 306983 URL: https://svnweb.freebsd.org/changeset/base/306983 Log: MFC r306601: dumpon(8) appears to be present in FreeBSD 2.0.5, despite initial import of man page listed FreeBSD 2.1. PR: 212445 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/dumpon/dumpon.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/dumpon/dumpon.8 ============================================================================== --- stable/10/sbin/dumpon/dumpon.8 Mon Oct 10 16:16:26 2016 (r306982) +++ stable/10/sbin/dumpon/dumpon.8 Mon Oct 10 16:17:14 2016 (r306983) @@ -28,7 +28,7 @@ .\" From: @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd October 8, 2014 +.Dd October 3, 2016 .Dt DUMPON 8 .Os .Sh NAME @@ -154,7 +154,7 @@ boot-time system configuration The .Nm utility appeared in -.Fx 2.1 . +.Fx 2.0.5 . .Sh BUGS Because the file system layer is already dead by the time a crash dump is taken, it is not possible to send crash dumps directly to a file. From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:21:35 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5523BC0CE19; Mon, 10 Oct 2016 16:21:35 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2334D86F; Mon, 10 Oct 2016 16:21:35 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGLYTX056962; Mon, 10 Oct 2016 16:21:34 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGLYrf056961; Mon, 10 Oct 2016 16:21:34 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101621.u9AGLYrf056961@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:21:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306984 - stable/10/sbin/fsck_msdosfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:21:35 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:21:34 2016 New Revision: 306984 URL: https://svnweb.freebsd.org/changeset/base/306984 Log: MFC r306602: Mention the version of NetBSD the utility originated from. PR: 212476 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/fsck_msdosfs/fsck_msdosfs.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/fsck_msdosfs/fsck_msdosfs.8 ============================================================================== --- stable/10/sbin/fsck_msdosfs/fsck_msdosfs.8 Mon Oct 10 16:17:14 2016 (r306983) +++ stable/10/sbin/fsck_msdosfs/fsck_msdosfs.8 Mon Oct 10 16:21:34 2016 (r306984) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 4, 2009 +.Dd October 3, 2016 .Dt FSCK_MSDOSFS 8 .Os .Sh NAME @@ -114,7 +114,10 @@ as the answer to all operator questions. .Sh HISTORY The .Nm -utility first appeared in +utility appeared in +.Nx 1.2 . +.Nm +first appeared in .Fx 4.4 . .Sh BUGS The From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:25:06 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BF9E2C0B14F; Mon, 10 Oct 2016 16:25:06 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8E89215D; Mon, 10 Oct 2016 16:25:06 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGP5Km060287; Mon, 10 Oct 2016 16:25:05 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGP56R060286; Mon, 10 Oct 2016 16:25:05 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101625.u9AGP56R060286@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:25:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306987 - stable/10/sbin/fsdb X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:25:06 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:25:05 2016 New Revision: 306987 URL: https://svnweb.freebsd.org/changeset/base/306987 Log: MFC r306603: Document which version of BSD first showed up in and add the version info for NetBSD & FreeBSD. PR: 212477 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/fsdb/fsdb.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/fsdb/fsdb.8 ============================================================================== --- stable/10/sbin/fsdb/fsdb.8 Mon Oct 10 16:24:05 2016 (r306986) +++ stable/10/sbin/fsdb/fsdb.8 Mon Oct 10 16:25:05 2016 (r306987) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 24, 2006 +.Dd October 3, 2016 .Dt FSDB 8 .Os .Sh NAME @@ -239,19 +239,20 @@ Exit the program. .Sh HISTORY The .Nm -utility uses the source code for +utility appeared in +.Bx 4.3 Tahoe . +It used the source code for .Xr fsck 8 to implement most of the file system manipulation code. The remainder of .Nm -first appeared in -.Nx , +appeared in +.Nx 1.1 written by .An John T. Kohl . -.Pp -.An Peter Wemm -ported it to -.Fx . +It first appeared in +.Fx 2.1.5 +ported by Peter Wemm. .Sh BUGS Manipulation of ``short'' symlinks has no effect. In particular, one should not From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:26:39 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4E3E0C0B1DC; Mon, 10 Oct 2016 16:26:39 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1D55032B; Mon, 10 Oct 2016 16:26:39 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGQcO0060401; Mon, 10 Oct 2016 16:26:38 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGQcHQ060400; Mon, 10 Oct 2016 16:26:38 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101626.u9AGQcHQ060400@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:26:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306988 - stable/10/sbin/gbde X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:26:39 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:26:38 2016 New Revision: 306988 URL: https://svnweb.freebsd.org/changeset/base/306988 Log: MFC r306604: gbde first appeared in FreeBSD 5.0 PR: 212478 Approved by: brc (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/gbde/gbde.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/gbde/gbde.8 ============================================================================== --- stable/10/sbin/gbde/gbde.8 Mon Oct 10 16:25:05 2016 (r306987) +++ stable/10/sbin/gbde/gbde.8 Mon Oct 10 16:26:38 2016 (r306988) @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 27, 2014 +.Dd October 3, 2016 .Dt GBDE 8 .Os .Sh NAME @@ -249,6 +249,9 @@ under DARPA/SPAWAR contract N66001-01-C- .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Nm +first appeared in +.Fx 5.0 . .Sh AUTHORS .An "Poul-Henning Kamp" Aq phk@FreeBSD.org .Sh BUGS From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:30:02 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4CEBAC0B355; Mon, 10 Oct 2016 16:30:02 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1BF6DA18; Mon, 10 Oct 2016 16:30:02 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGU1DQ060749; Mon, 10 Oct 2016 16:30:01 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGU1C6060748; Mon, 10 Oct 2016 16:30:01 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101630.u9AGU1C6060748@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:30:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306991 - stable/10/sbin/init X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:30:02 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:30:01 2016 New Revision: 306991 URL: https://svnweb.freebsd.org/changeset/base/306991 Log: MFC r306605: init was there in UNIX from V1 http://minnie.tuhs.org/cgi-bin/utree.pl?file=V1/init.s PR: 212503 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/init/init.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/init/init.8 ============================================================================== --- stable/10/sbin/init/init.8 Mon Oct 10 16:29:14 2016 (r306990) +++ stable/10/sbin/init/init.8 Mon Oct 10 16:30:01 2016 (r306991) @@ -31,7 +31,7 @@ .\" @(#)init.8 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd July 24, 2015 +.Dd October 3, 2016 .Dt INIT 8 .Os .Sh NAME @@ -345,7 +345,7 @@ a persistent device error condition. An .Nm utility appeared in -.At v6 . +.At v1 . .Sh CAVEATS Systems without .Xr sysctl 8 From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:32:57 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2ACC3C0B54C; Mon, 10 Oct 2016 16:32:57 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id ED0B3F20; Mon, 10 Oct 2016 16:32:56 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGWuYe064284; Mon, 10 Oct 2016 16:32:56 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGWuxO064283; Mon, 10 Oct 2016 16:32:56 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101632.u9AGWuxO064283@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:32:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306992 - stable/10/sbin/mknod X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:32:57 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:32:55 2016 New Revision: 306992 URL: https://svnweb.freebsd.org/changeset/base/306992 Log: MFC r306606: mknod appeared in V4 UNIX http://minnie.tuhs.org/cgi-bin/utree.pl?file=V4/man/man8/mknod.8 PR: 212509 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/mknod/mknod.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/mknod/mknod.8 ============================================================================== --- stable/10/sbin/mknod/mknod.8 Mon Oct 10 16:30:01 2016 (r306991) +++ stable/10/sbin/mknod/mknod.8 Mon Oct 10 16:32:55 2016 (r306992) @@ -28,7 +28,7 @@ .\" @(#)mknod.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd January 31, 2010 +.Dd October 3, 2016 .Dt MKNOD 8 .Os .Sh NAME @@ -149,4 +149,4 @@ nodes cannot be used to access devices. A .Nm utility appeared in -.At v6 . +.At v4 . From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:36:15 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 490E7C0B846; Mon, 10 Oct 2016 16:36:15 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1ABA86A4; Mon, 10 Oct 2016 16:36:15 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGaELQ064655; Mon, 10 Oct 2016 16:36:14 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGaE70064654; Mon, 10 Oct 2016 16:36:14 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101636.u9AGaE70064654@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:36:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306995 - stable/10/sbin/mksnap_ffs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:36:15 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:36:14 2016 New Revision: 306995 URL: https://svnweb.freebsd.org/changeset/base/306995 Log: MFC r306607: mksnap_ffs appeared in FreeBSD 5.1. PR: 212510 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/mksnap_ffs/mksnap_ffs.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/mksnap_ffs/mksnap_ffs.8 ============================================================================== --- stable/10/sbin/mksnap_ffs/mksnap_ffs.8 Mon Oct 10 16:35:25 2016 (r306994) +++ stable/10/sbin/mksnap_ffs/mksnap_ffs.8 Mon Oct 10 16:36:14 2016 (r306995) @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 14, 2011 +.Dd October 3, 2016 .Dt MKSNAP_FFS 8 .Os .Sh NAME @@ -75,7 +75,7 @@ mount -o ro /dev/md0 /mnt/ The .Nm utility first appeared in -.Fx 5.0 . +.Fx 5.1 . .Sh CAVEATS The disk full situation is not handled gracefully and may lead to a system panic when no free blocks are found. From owner-svn-src-stable-10@freebsd.org Mon Oct 10 16:38:08 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 654BCC0B918; Mon, 10 Oct 2016 16:38:08 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3CE4C8B4; Mon, 10 Oct 2016 16:38:08 +0000 (UTC) (envelope-from sevan@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9AGc7jP064790; Mon, 10 Oct 2016 16:38:07 GMT (envelope-from sevan@FreeBSD.org) Received: (from sevan@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9AGc7f4064789; Mon, 10 Oct 2016 16:38:07 GMT (envelope-from sevan@FreeBSD.org) Message-Id: <201610101638.u9AGc7f4064789@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sevan set sender to sevan@FreeBSD.org using -f From: Sevan Janiyan Date: Mon, 10 Oct 2016 16:38:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r306996 - stable/10/sbin/mount_fusefs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2016 16:38:08 -0000 Author: sevan (doc committer) Date: Mon Oct 10 16:38:07 2016 New Revision: 306996 URL: https://svnweb.freebsd.org/changeset/base/306996 Log: MFC r306610: Note mount_fusefs appeared in FreeBSD 10. Move note regarding implementation to caveats. Address issued raised by Igor. PR: 212513 Approved by: bcr (mentor) Differential Revision: https://reviews.freebsd.org/D8105 Modified: stable/10/sbin/mount_fusefs/mount_fusefs.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/sbin/mount_fusefs/mount_fusefs.8 ============================================================================== --- stable/10/sbin/mount_fusefs/mount_fusefs.8 Mon Oct 10 16:36:14 2016 (r306995) +++ stable/10/sbin/mount_fusefs/mount_fusefs.8 Mon Oct 10 16:38:07 2016 (r306996) @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 11, 2012 +.Dd October 3, 2016 .Dt MOUNT_FUSEFS 8 .Os .Sh NAME @@ -52,7 +52,8 @@ .Sh DESCRIPTION Basic usage is to start a fuse daemon on the given .Ar special -file. In practice, the daemon is assigned a +file. +In practice, the daemon is assigned a .Ar special file automatically, which can then be indentified via .Xr fstat 1 . @@ -68,7 +69,8 @@ is appended to the list of arguments, .Nm will call the .Ar fuse_daemon -via that command. In that way the +via that command. +In that way the .Ar fuse_daemon will be instructed to attach itself to .Ar special . @@ -101,7 +103,8 @@ The options are as follows: .It Fl A , Ic --reject-allow_other Prohibit the .Cm allow_other -mount flag. Intended for use in scripts and the +mount flag. +Intended for use in scripts and the .Xr sudoers 5 file. .It Fl S , Ic --safe @@ -143,8 +146,8 @@ Only root can use this option Limit size of read requests to .Ar n .It Cm private -Refuse shared mounting of the daemon. This is the default behaviour, -to allow sharing, expicitly use +Refuse shared mounting of the daemon. +This is the default behaviour, to allow sharing, expicitly use .Fl o Cm noprivate .It Cm neglect_shares Do not refuse unmounting if there are secondary mounts @@ -155,11 +158,13 @@ Prefix absolute symlinks with the mountp .El .Pp Besides the above mount options, there is a set of pseudo-mount options which -are supported by the Fuse library. One can list these by passing +are supported by the Fuse library. +One can list these by passing .Fl h -to a Fuse daemon. Most of these options have effect only on the behaviour of -the daemon (that is, their scope is limited to userspace). However, -there are some which do require in-kernel support. +to a Fuse daemon. +Most of these options only have affect on the behavior of the daemon (that is, +their scope is limited to userspace). +However, there are some which do require in-kernel support. Currently the options supported by the kernel are: .Bl -tag -width indent .It Cm direct_io @@ -190,7 +195,7 @@ only if the filesystem daemon has the sa real gid) as the user. .Pp This is applied for Fuse mounts by default and only root can mount without -the strict access policy (ie. the +the strict access policy (i.e. the .Cm allow_other mount option). .Pp @@ -202,7 +207,7 @@ Users might opt to willingly relax stric are concerned) by doing their own secondary mount (See .Sx SHARED MOUNTS ) . .Sh SHARED MOUNTS -A Fuse daemon can be shared (ie. mounted multiple times). +A Fuse daemon can be shared (i.e. mounted multiple times). When doing the first (primary) mount, the spawner and the mounter of the daemon must have the same uid, or the mounter should be the superuser. .Pp @@ -213,9 +218,9 @@ The behaviour of a secondary mount is an links: they redirect all filesystem operations to the primary mount. .Pp Doing a secondary mount is like signing an agreement: by this action, the mounter -agrees that the Fuse daemon can trace her I/O activities. From then on -she is not banned from using the filesystem (either via her own mount or -via the primary mount), regardless whether +agrees that the Fuse daemon can trace her I/O activities. +From then on she is not banned from using the filesystem +(either via her own mount or via the primary mount), regardless whether .Cm allow_other is used or not. .Pp @@ -227,14 +232,15 @@ mount; e.g. System administrators might want to use a custom mount policy (ie., one going beyond the .Va vfs.usermount -sysctl). The primary tool for such purposes is +sysctl). +The primary tool for such purposes is .Xr sudo 8 . However, given that .Nm is capable of invoking an arbitrary program, one must be careful when doing this. .Nm -is designed in a way such that it makes that easy. For this purpose, -there are options which disable certain risky features (ie. +is designed in a way such that it makes that easy. +For this purpose, there are options which disable certain risky features (i.e. .Fl S and .Fl A ) , @@ -270,8 +276,8 @@ If set, .Nm will ignore uknown mount options. .It Ev MOUNT_FUSEFS_CALL_BY_LIB -Adjust behaviour to the needs of the FUSE library. Currently it effects -help output. +Adjust behavior to the needs of the FUSE library. +Currently it effects help output. .El .Pp Although the following variables do not have any effect on @@ -279,11 +285,13 @@ Although the following variables do not itself, they affect the behaviour of fuse daemons: .Bl -tag -width ".Ev FUSE_DEV_NAME" .It Ev FUSE_DEV_NAME -Device to attach. If not set, the multiplexer path +Device to attach. +If not set, the multiplexer path .Ar /dev/fuse is used. .It Ev FUSE_DEV_FD -File desciptor of an opened Fuse device to use. Overrides +File desciptor of an opened Fuse device to use. +Overrides .Ev FUSE_DEV_NAME . .It Ev FUSE_NO_MOUNT If set, the library will not attempt to mount the filesystem, even @@ -294,7 +302,8 @@ if a mountpoint argument is supplied. .It Pa /dev/fuse Fuse device with which the kernel and Fuse daemons can communicate. .It Pa /dev/fuse -The multiplexer path. An +The multiplexer path. +An .Xr open 2 performed on it automatically is passed to a free Fuse device by the kernel (which might be created just for this puprose). @@ -331,12 +340,19 @@ does not call any external utility and a .Xr sudo 8 .Sh HISTORY .Nm -appears as the part of the FreeBSD implementation of the Fuse userspace filesystem -framework (see http://fuse.sourceforge.net). This user interface is FreeBSD specific. +appeared in +.Fx 10.0 +as the part of the +.Fx +implementation of the Fuse userspace filesystem +framework (see http://fuse.sourceforge.net). .Sh CAVEATS -Secondary mounts should be unmounted via their device name. If an attempt is -made to be unmount them via their filesystem root path, the unmount request -will be forwarded to the primary mount path. +This user interface is +.Fx +specific. +Secondary mounts should be unmounted via their device name. +If an attempt is made to unmount them via their filesystem root path, +the unmount request will be forwarded to the primary mount path. In general, unmounting by device name is less error-prone than by mount path (although the latter will also work under normal circumstances). .Pp From owner-svn-src-stable-10@freebsd.org Tue Oct 11 02:26:00 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A07B4C0C832; Tue, 11 Oct 2016 02:26:00 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 595FC20D; Tue, 11 Oct 2016 02:26:00 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B2Px8n093444; Tue, 11 Oct 2016 02:25:59 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B2Px3r093443; Tue, 11 Oct 2016 02:25:59 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110225.u9B2Px3r093443@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 02:25:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307011 - stable/10/sys/ofed/include/linux X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 02:26:00 -0000 Author: sephe Date: Tue Oct 11 02:25:59 2016 New Revision: 307011 URL: https://svnweb.freebsd.org/changeset/base/307011 Log: MFC 306480 linuxkpi: Fix PCI BAR lazy allocation support. FreeBSD supports lazy allocation of PCI BAR, that is, when a device driver's attach method is invoked, even if the device's PCI BAR address wasn't initialized, the invocation of bus_alloc_resource_any() (the call chain: pci_alloc_resource() -> pci_alloc_multi_resource() -> pci_reserve_map() -> pci_write_bar()) would allocate a proper address for the PCI BAR and write this 'lazy allocated' address into the PCI BAR. This model works fine for native FreeBSD device drivers, but _not_ for device drivers shared with Linux (e.g. dev/mlx5/mlx5_core/mlx5_main.c and ofed/drivers/net/mlx4/main.c. Both of them use pci_request_regions(), which doesn't work properly with the PCI BAR lazy allocation, because pci_resource_type() -> _pci_get_rle() always returns NULL, so pci_request_regions() doesn't have the opportunity to invoke bus_alloc_resource_any(). We now use pci_find_bar() in pci_resource_type(), which is able to locate all available PCI BARs even if some of them will be lazy allocated. Submitted by: Dexuan Cui Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8071 Modified: stable/10/sys/ofed/include/linux/pci.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/ofed/include/linux/pci.h ============================================================================== --- stable/10/sys/ofed/include/linux/pci.h Tue Oct 11 02:08:09 2016 (r307010) +++ stable/10/sys/ofed/include/linux/pci.h Tue Oct 11 02:25:59 2016 (r307011) @@ -216,11 +216,16 @@ pci_resource_len(struct pci_dev *pdev, i static inline int pci_resource_type(struct pci_dev *pdev, int bar) { - struct resource_list_entry *rle; + struct pci_map *pm; - if ((rle = _pci_get_bar(pdev, bar)) == NULL) + pm = pci_find_bar(pdev->dev.bsddev, PCIR_BAR(bar)); + if (!pm) return (-1); - return (rle->type); + + if (PCI_BAR_IO(pm->pm_value)) + return (SYS_RES_IOPORT); + else + return (SYS_RES_MEMORY); } /* From owner-svn-src-stable-10@freebsd.org Tue Oct 11 05:44:39 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 01383C074DC; Tue, 11 Oct 2016 05:44:39 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 96A11380; Tue, 11 Oct 2016 05:44:38 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B5ibxQ068974; Tue, 11 Oct 2016 05:44:37 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B5ib1A068963; Tue, 11 Oct 2016 05:44:37 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110544.u9B5ib1A068963@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 05:44:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307014 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 05:44:39 -0000 Author: sephe Date: Tue Oct 11 05:44:36 2016 New Revision: 307014 URL: https://svnweb.freebsd.org/changeset/base/307014 Log: MFC 302540 hyperv/vmbus: Implement a new set of APIs for post message Hypercall And use this new APIs for Initial Contact post message Hypercall. More post message Hypercalls will be converted. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6830 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_connection.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h stable/10/sys/dev/hyperv/vmbus/hyperv_var.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 05:44:36 2016 (r307014) @@ -77,10 +77,6 @@ typedef uint8_t hv_bool_uint8_t; #define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) #define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) -#define HV_VMBUS_VERSION_INVALID -1 - -#define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1 - /* * Make maximum size of pipe payload of 16K */ @@ -537,20 +533,6 @@ typedef struct { uint32_t child_rel_id; } __packed hv_vmbus_channel_relid_released; -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t vmbus_version_requested; - uint32_t padding2; - uint64_t interrupt_page; - uint64_t monitor_page_1; - uint64_t monitor_page_2; -} __packed hv_vmbus_channel_initiate_contact; - -typedef struct { - hv_vmbus_channel_msg_header header; - hv_bool_uint8_t version_supported; -} __packed hv_vmbus_channel_version_response; - typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload; #define HW_MACADDR_LEN 6 Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 05:44:36 2016 (r307014) @@ -43,29 +43,30 @@ __FBSDID("$FreeBSD$"); * Internal functions */ -typedef void (*vmbus_msg_handler)(const hv_vmbus_channel_msg_header *msg); - typedef struct hv_vmbus_channel_msg_table_entry { hv_vmbus_channel_msg_type messageType; - vmbus_msg_handler messageHandler; + void (*messageHandler) + (struct vmbus_softc *sc, + const struct vmbus_message *msg); } hv_vmbus_channel_msg_table_entry; static void vmbus_channel_on_offer_internal(void *context); static void vmbus_channel_on_offer_rescind_internal(void *context); -static void vmbus_channel_on_offer(const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_open_result( - const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_offer_rescind( - const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_gpadl_created( - const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_gpadl_torndown( - const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_offers_delivered( - const hv_vmbus_channel_msg_header *hdr); -static void vmbus_channel_on_version_response( - const hv_vmbus_channel_msg_header *hdr); +static void vmbus_channel_on_offer(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_open_result(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_gpadl_created(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_gpadl_torndown(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_channel_on_version_response(struct vmbus_softc *, + const struct vmbus_message *); /** * Channel message dispatch table @@ -401,8 +402,11 @@ vmbus_channel_select_defcpu(struct hv_vm * object to process the offer synchronously */ static void -vmbus_channel_on_offer(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_offer(struct vmbus_softc *sc, const struct vmbus_message *msg) { + const hv_vmbus_channel_msg_header *hdr = + (const hv_vmbus_channel_msg_header *)msg->msg_data; + const hv_vmbus_channel_offer_channel *offer; hv_vmbus_channel_offer_channel *copied; @@ -479,8 +483,12 @@ vmbus_channel_on_offer_internal(void* co * synchronously */ static void -vmbus_channel_on_offer_rescind(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_offer_rescind(struct vmbus_softc *sc, + const struct vmbus_message *msg) { + const hv_vmbus_channel_msg_header *hdr = + (const hv_vmbus_channel_msg_header *)msg->msg_data; + const hv_vmbus_channel_rescind_offer *rescind; hv_vmbus_channel* channel; @@ -511,8 +519,8 @@ vmbus_channel_on_offer_rescind_internal( * @brief Invoked when all offers have been delivered. */ static void -vmbus_channel_on_offers_delivered( - const hv_vmbus_channel_msg_header *hdr __unused) +vmbus_channel_on_offers_delivered(struct vmbus_softc *sc __unused, + const struct vmbus_message *msg __unused) { mtx_lock(&vmbus_chwait_lock); @@ -529,8 +537,12 @@ vmbus_channel_on_offers_delivered( * response and signal the requesting thread. */ static void -vmbus_channel_on_open_result(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_open_result(struct vmbus_softc *sc, + const struct vmbus_message *msg) { + const hv_vmbus_channel_msg_header *hdr = + (const hv_vmbus_channel_msg_header *)msg->msg_data; + const hv_vmbus_channel_open_result *result; hv_vmbus_channel_msg_info* msg_info; hv_vmbus_channel_msg_header* requestHeader; @@ -571,8 +583,12 @@ vmbus_channel_on_open_result(const hv_vm * response and signal the requesting thread. */ static void -vmbus_channel_on_gpadl_created(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_gpadl_created(struct vmbus_softc *sc, + const struct vmbus_message *msg) { + const hv_vmbus_channel_msg_header *hdr = + (const hv_vmbus_channel_msg_header *)msg->msg_data; + const hv_vmbus_channel_gpadl_created *gpadl_created; hv_vmbus_channel_msg_info* msg_info; hv_vmbus_channel_msg_header* request_header; @@ -613,8 +629,12 @@ vmbus_channel_on_gpadl_created(const hv_ * response and signal the requesting thread */ static void -vmbus_channel_on_gpadl_torndown(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_gpadl_torndown(struct vmbus_softc *sc, + const struct vmbus_message *msg) { + const hv_vmbus_channel_msg_header *hdr = + (const hv_vmbus_channel_msg_header *)msg->msg_data; + const hv_vmbus_channel_gpadl_torndown *gpadl_torndown; hv_vmbus_channel_msg_info* msg_info; hv_vmbus_channel_msg_header* requestHeader; @@ -650,39 +670,11 @@ vmbus_channel_on_gpadl_torndown(const hv mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); } -/** - * @brief Version response handler. - * - * This is invoked when we received a response - * to our initiate contact request. Find the matching request, copy th - * response and signal the requesting thread. - */ static void -vmbus_channel_on_version_response(const hv_vmbus_channel_msg_header *hdr) +vmbus_channel_on_version_response(struct vmbus_softc *sc, + const struct vmbus_message *msg) { - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_header* requestHeader; - hv_vmbus_channel_initiate_contact* initiate; - const hv_vmbus_channel_version_response *versionResponse; - - versionResponse = (const hv_vmbus_channel_version_response *)hdr; - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, - msg_list_entry) { - requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg; - if (requestHeader->message_type - == HV_CHANNEL_MESSAGE_INITIATED_CONTACT) { - initiate = - (hv_vmbus_channel_initiate_contact*) requestHeader; - memcpy(&msg_info->response.version_response, - versionResponse, - sizeof(hv_vmbus_channel_version_response)); - sema_post(&msg_info->wait_sema); - } - } - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - + vmbus_msghc_wakeup(sc, msg); } /** @@ -868,5 +860,5 @@ vmbus_chan_msgproc(struct vmbus_softc *s entry = &g_channel_message_table[msg_type]; if (entry->messageHandler) - entry->messageHandler(hdr); + entry->messageHandler(sc, msg); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_connection.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 05:44:36 2016 (r307014) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -52,97 +53,7 @@ hv_vmbus_connection hv_vmbus_g_connectio { .connect_state = HV_DISCONNECTED, .next_gpadl_handle = 0xE1E10, }; -uint32_t hv_vmbus_protocal_version = HV_VMBUS_VERSION_WS2008; - -static uint32_t -hv_vmbus_get_next_version(uint32_t current_ver) -{ - switch (current_ver) { - case (HV_VMBUS_VERSION_WIN7): - return(HV_VMBUS_VERSION_WS2008); - - case (HV_VMBUS_VERSION_WIN8): - return(HV_VMBUS_VERSION_WIN7); - - case (HV_VMBUS_VERSION_WIN8_1): - return(HV_VMBUS_VERSION_WIN8); - - case (HV_VMBUS_VERSION_WS2008): - default: - return(HV_VMBUS_VERSION_INVALID); - } -} - -/** - * Negotiate the highest supported hypervisor version. - */ -static int -hv_vmbus_negotiate_version(struct vmbus_softc *sc, - hv_vmbus_channel_msg_info *msg_info, uint32_t version) -{ - int ret = 0; - hv_vmbus_channel_initiate_contact *msg; - - sema_init(&msg_info->wait_sema, 0, "Msg Info Sema"); - msg = (hv_vmbus_channel_initiate_contact*) msg_info->msg; - - msg->header.message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT; - msg->vmbus_version_requested = version; - - msg->interrupt_page = sc->vmbus_evtflags_dma.hv_paddr; - msg->monitor_page_1 = sc->vmbus_mnf1_dma.hv_paddr; - msg->monitor_page_2 = sc->vmbus_mnf2_dma.hv_paddr; - - /** - * Add to list before we send the request since we may receive the - * response before returning from this routine - */ - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - - TAILQ_INSERT_TAIL( - &hv_vmbus_g_connection.channel_msg_anchor, - msg_info, - msg_list_entry); - - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - ret = hv_vmbus_post_message( - msg, - sizeof(hv_vmbus_channel_initiate_contact)); - - if (ret != 0) { - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE( - &hv_vmbus_g_connection.channel_msg_anchor, - msg_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - return (ret); - } - - /** - * Wait for the connection response - */ - ret = sema_timedwait(&msg_info->wait_sema, 5 * hz); /* KYS 5 seconds */ - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE( - &hv_vmbus_g_connection.channel_msg_anchor, - msg_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - /** - * Check if successful - */ - if (msg_info->response.version_response.version_supported) { - hv_vmbus_g_connection.connect_state = HV_CONNECTED; - } else { - ret = ECONNREFUSED; - } - - return (ret); -} +uint32_t hv_vmbus_protocal_version; /** * Send a connect request on the partition service connection @@ -150,10 +61,6 @@ hv_vmbus_negotiate_version(struct vmbus_ int hv_vmbus_connect(struct vmbus_softc *sc) { - int ret = 0; - uint32_t version; - hv_vmbus_channel_msg_info* msg_info = NULL; - /** * Make sure we are not connecting or connected */ @@ -174,60 +81,12 @@ hv_vmbus_connect(struct vmbus_softc *sc) mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel", NULL, MTX_DEF); - msg_info = (hv_vmbus_channel_msg_info*) - malloc(sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_initiate_contact), - M_DEVBUF, M_WAITOK | M_ZERO); - hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); - /* - * Find the highest vmbus version number we can support. - */ - version = HV_VMBUS_VERSION_CURRENT; - - do { - ret = hv_vmbus_negotiate_version(sc, msg_info, version); - if (ret == EWOULDBLOCK) { - /* - * We timed out. - */ - goto cleanup; - } - - if (hv_vmbus_g_connection.connect_state == HV_CONNECTED) - break; - - version = hv_vmbus_get_next_version(version); - } while (version != HV_VMBUS_VERSION_INVALID); - - hv_vmbus_protocal_version = version; - if (bootverbose) - printf("VMBUS: Protocol Version: %d.%d\n", - version >> 16, version & 0xFFFF); - sema_destroy(&msg_info->wait_sema); - free(msg_info, M_DEVBUF); + hv_vmbus_g_connection.connect_state = HV_CONNECTED; return (0); - - /* - * Cleanup after failure! - */ - cleanup: - - hv_vmbus_g_connection.connect_state = HV_DISCONNECTED; - - mtx_destroy(&hv_vmbus_g_connection.channel_lock); - mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock); - - if (msg_info) { - sema_destroy(&msg_info->wait_sema); - free(msg_info, M_DEVBUF); - } - - free(hv_vmbus_g_connection.channels, M_DEVBUF); - return (ret); } /** @@ -333,7 +192,7 @@ int hv_vmbus_post_message(void *buffer, */ for (retries = 0; retries < 20; retries++) { ret = hv_vmbus_post_msg_via_msg_ipc(connId, - VMBUS_MSGTYPE_CHANNEL, buffer, bufferLen); + HYPERV_MSGTYPE_CHANNEL, buffer, bufferLen); if (ret == HV_STATUS_SUCCESS) return (0); Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 05:44:36 2016 (r307014) @@ -95,7 +95,6 @@ typedef union { hv_vmbus_channel_open_result open_result; hv_vmbus_channel_gpadl_torndown gpadl_torndown; hv_vmbus_channel_gpadl_created gpadl_created; - hv_vmbus_channel_version_response version_response; } hv_vmbus_channel_msg_response; /* Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 05:44:36 2016 (r307014) @@ -118,6 +118,13 @@ hv_vmbus_do_hypercall(uint64_t value, vo in_paddr, out_paddr); } +uint64_t +hypercall_post_message(bus_addr_t msg_paddr) +{ + return hypercall_md(hypercall_context.hc_addr, + HYPERCALL_POST_MESSAGE, msg_paddr, 0); +} + /** * @brief Post a message using the hypervisor message IPC. * (This involves a hypercall.) Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 05:44:36 2016 (r307014) @@ -29,6 +29,8 @@ #ifndef _HYPERV_REG_H_ #define _HYPERV_REG_H_ +#include + /* * Hyper-V Synthetic MSRs */ @@ -130,4 +132,41 @@ #define CPUID_LEAF_HV_LIMITS 0x40000005 #define CPUID_LEAF_HV_HWFEATURES 0x40000006 +/* + * Hyper-V message types + */ +#define HYPERV_MSGTYPE_NONE 0 +#define HYPERV_MSGTYPE_CHANNEL 1 +#define HYPERV_MSGTYPE_TIMER_EXPIRED 0x80000010 + +/* + * Hypercall status codes + */ +#define HYPERCALL_STATUS_SUCCESS 0x0000 + +/* + * Hypercall input values + */ +#define HYPERCALL_POST_MESSAGE 0x005c + +/* + * Hypercall input parameters + */ + +/* + * HYPERCALL_POST_MESSAGE + */ +#define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 +#define HYPERCALL_POSTMSGIN_SIZE 256 +#define HYPERCALL_POSTMSGIN_ALIGN 8 + +struct hypercall_postmsg_in { + uint32_t hc_connid; + uint32_t hc_rsvd; + uint32_t hc_msgtype; /* HYPERV_MSGTYPE_ */ + uint32_t hc_dsize; + uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; +} __packed; +CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); + #endif /* !_HYPERV_REG_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 05:44:36 2016 (r307014) @@ -29,6 +29,8 @@ #ifndef _HYPERV_VAR_H_ #define _HYPERV_VAR_H_ +#include + #ifndef NANOSEC #define NANOSEC 1000000000ULL #endif @@ -38,4 +40,6 @@ extern u_int hyperv_features; extern u_int hyperv_recommends; +uint64_t hypercall_post_message(bus_addr_t msg_paddr); + #endif /* !_HYPERV_VAR_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 05:44:36 2016 (r307014) @@ -69,10 +69,354 @@ __FBSDID("$FreeBSD$"); #include #include "acpi_if.h" +/* + * NOTE: DO NOT CHANGE THESE + */ +#define VMBUS_CONNID_MESSAGE 1 +#define VMBUS_CONNID_EVENT 2 + +struct vmbus_msghc { + struct hypercall_postmsg_in *mh_inprm; + struct hypercall_postmsg_in mh_inprm_save; + struct hyperv_dma mh_inprm_dma; + + struct vmbus_message *mh_resp; + struct vmbus_message mh_resp0; +}; + +struct vmbus_msghc_ctx { + struct vmbus_msghc *mhc_free; + struct mtx mhc_free_lock; + uint32_t mhc_flags; + + struct vmbus_msghc *mhc_active; + struct mtx mhc_active_lock; +}; + +#define VMBUS_MSGHC_CTXF_DESTROY 0x0001 + +static int vmbus_init(struct vmbus_softc *); +static int vmbus_init_contact(struct vmbus_softc *, + uint32_t); + +static struct vmbus_msghc_ctx *vmbus_msghc_ctx_create(bus_dma_tag_t); +static void vmbus_msghc_ctx_destroy( + struct vmbus_msghc_ctx *); +static void vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *); +static struct vmbus_msghc *vmbus_msghc_alloc(bus_dma_tag_t); +static void vmbus_msghc_free(struct vmbus_msghc *); +static struct vmbus_msghc *vmbus_msghc_get1(struct vmbus_msghc_ctx *, + uint32_t); + struct vmbus_softc *vmbus_sc; extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr); +static const uint32_t vmbus_version[] = { + HV_VMBUS_VERSION_WIN8_1, + HV_VMBUS_VERSION_WIN8, + HV_VMBUS_VERSION_WIN7, + HV_VMBUS_VERSION_WS2008 +}; + +static struct vmbus_msghc * +vmbus_msghc_alloc(bus_dma_tag_t parent_dtag) +{ + struct vmbus_msghc *mh; + + mh = malloc(sizeof(*mh), M_DEVBUF, M_WAITOK | M_ZERO); + + mh->mh_inprm = hyperv_dmamem_alloc(parent_dtag, + HYPERCALL_POSTMSGIN_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE, + &mh->mh_inprm_dma, BUS_DMA_WAITOK); + if (mh->mh_inprm == NULL) { + free(mh, M_DEVBUF); + return NULL; + } + return mh; +} + +static void +vmbus_msghc_free(struct vmbus_msghc *mh) +{ + hyperv_dmamem_free(&mh->mh_inprm_dma, mh->mh_inprm); + free(mh, M_DEVBUF); +} + +static void +vmbus_msghc_ctx_free(struct vmbus_msghc_ctx *mhc) +{ + KASSERT(mhc->mhc_active == NULL, ("still have active msg hypercall")); + KASSERT(mhc->mhc_free == NULL, ("still have hypercall msg")); + + mtx_destroy(&mhc->mhc_free_lock); + mtx_destroy(&mhc->mhc_active_lock); + free(mhc, M_DEVBUF); +} + +static struct vmbus_msghc_ctx * +vmbus_msghc_ctx_create(bus_dma_tag_t parent_dtag) +{ + struct vmbus_msghc_ctx *mhc; + + mhc = malloc(sizeof(*mhc), M_DEVBUF, M_WAITOK | M_ZERO); + mtx_init(&mhc->mhc_free_lock, "vmbus msghc free", NULL, MTX_DEF); + mtx_init(&mhc->mhc_active_lock, "vmbus msghc act", NULL, MTX_DEF); + + mhc->mhc_free = vmbus_msghc_alloc(parent_dtag); + if (mhc->mhc_free == NULL) { + vmbus_msghc_ctx_free(mhc); + return NULL; + } + return mhc; +} + +static struct vmbus_msghc * +vmbus_msghc_get1(struct vmbus_msghc_ctx *mhc, uint32_t dtor_flag) +{ + struct vmbus_msghc *mh; + + mtx_lock(&mhc->mhc_free_lock); + + while ((mhc->mhc_flags & dtor_flag) == 0 && mhc->mhc_free == NULL) { + mtx_sleep(&mhc->mhc_free, &mhc->mhc_free_lock, 0, + "gmsghc", 0); + } + if (mhc->mhc_flags & dtor_flag) { + /* Being destroyed */ + mh = NULL; + } else { + mh = mhc->mhc_free; + KASSERT(mh != NULL, ("no free hypercall msg")); + KASSERT(mh->mh_resp == NULL, + ("hypercall msg has pending response")); + mhc->mhc_free = NULL; + } + + mtx_unlock(&mhc->mhc_free_lock); + + return mh; +} + +struct vmbus_msghc * +vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize) +{ + struct hypercall_postmsg_in *inprm; + struct vmbus_msghc *mh; + + if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX) + return NULL; + + mh = vmbus_msghc_get1(sc->vmbus_msg_hc, VMBUS_MSGHC_CTXF_DESTROY); + if (mh == NULL) + return NULL; + + inprm = mh->mh_inprm; + memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE); + inprm->hc_connid = VMBUS_CONNID_MESSAGE; + inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL; + inprm->hc_dsize = dsize; + + return mh; +} + +void +vmbus_msghc_put(struct vmbus_softc *sc, struct vmbus_msghc *mh) +{ + struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc; + + KASSERT(mhc->mhc_active == NULL, ("msg hypercall is active")); + mh->mh_resp = NULL; + + mtx_lock(&mhc->mhc_free_lock); + KASSERT(mhc->mhc_free == NULL, ("has free hypercall msg")); + mhc->mhc_free = mh; + mtx_unlock(&mhc->mhc_free_lock); + wakeup(&mhc->mhc_free); +} + +void * +vmbus_msghc_dataptr(struct vmbus_msghc *mh) +{ + return mh->mh_inprm->hc_data; +} + +static void +vmbus_msghc_ctx_destroy(struct vmbus_msghc_ctx *mhc) +{ + struct vmbus_msghc *mh; + + mtx_lock(&mhc->mhc_free_lock); + mhc->mhc_flags |= VMBUS_MSGHC_CTXF_DESTROY; + mtx_unlock(&mhc->mhc_free_lock); + wakeup(&mhc->mhc_free); + + mh = vmbus_msghc_get1(mhc, 0); + if (mh == NULL) + panic("can't get msghc"); + + vmbus_msghc_free(mh); + vmbus_msghc_ctx_free(mhc); +} + +int +vmbus_msghc_exec_noresult(struct vmbus_msghc *mh) +{ + sbintime_t time = SBT_1MS; + int i; + + /* + * Save the input parameter so that we could restore the input + * parameter if the Hypercall failed. + * + * XXX + * Is this really necessary?! i.e. Will the Hypercall ever + * overwrite the input parameter? + */ + memcpy(&mh->mh_inprm_save, mh->mh_inprm, HYPERCALL_POSTMSGIN_SIZE); + + /* + * In order to cope with transient failures, e.g. insufficient + * resources on host side, we retry the post message Hypercall + * several times. 20 retries seem sufficient. + */ +#define HC_RETRY_MAX 20 + + for (i = 0; i < HC_RETRY_MAX; ++i) { + uint64_t status; + + status = hypercall_post_message(mh->mh_inprm_dma.hv_paddr); + if (status == HYPERCALL_STATUS_SUCCESS) + return 0; + + pause_sbt("hcpmsg", time, 0, C_HARDCLOCK); + if (time < SBT_1S * 2) + time *= 2; + + /* Restore input parameter and try again */ + memcpy(mh->mh_inprm, &mh->mh_inprm_save, + HYPERCALL_POSTMSGIN_SIZE); + } + +#undef HC_RETRY_MAX + + return EIO; +} + +int +vmbus_msghc_exec(struct vmbus_softc *sc, struct vmbus_msghc *mh) +{ + struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc; + int error; + + KASSERT(mh->mh_resp == NULL, ("hypercall msg has pending response")); + + mtx_lock(&mhc->mhc_active_lock); + KASSERT(mhc->mhc_active == NULL, ("pending active msg hypercall")); + mhc->mhc_active = mh; + mtx_unlock(&mhc->mhc_active_lock); + + error = vmbus_msghc_exec_noresult(mh); + if (error) { + mtx_lock(&mhc->mhc_active_lock); + KASSERT(mhc->mhc_active == mh, ("msghc mismatch")); + mhc->mhc_active = NULL; + mtx_unlock(&mhc->mhc_active_lock); + } + return error; +} + +const struct vmbus_message * +vmbus_msghc_wait_result(struct vmbus_softc *sc, struct vmbus_msghc *mh) +{ + struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc; + + mtx_lock(&mhc->mhc_active_lock); + + KASSERT(mhc->mhc_active == mh, ("msghc mismatch")); + while (mh->mh_resp == NULL) { + mtx_sleep(&mhc->mhc_active, &mhc->mhc_active_lock, 0, + "wmsghc", 0); + } + mhc->mhc_active = NULL; + + mtx_unlock(&mhc->mhc_active_lock); + + return mh->mh_resp; +} + +void +vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg) +{ + struct vmbus_msghc_ctx *mhc = sc->vmbus_msg_hc; + struct vmbus_msghc *mh; + + mtx_lock(&mhc->mhc_active_lock); + + mh = mhc->mhc_active; + KASSERT(mh != NULL, ("no pending msg hypercall")); + memcpy(&mh->mh_resp0, msg, sizeof(mh->mh_resp0)); + mh->mh_resp = &mh->mh_resp0; + + mtx_unlock(&mhc->mhc_active_lock); + wakeup(&mhc->mhc_active); +} + +static int +vmbus_init_contact(struct vmbus_softc *sc, uint32_t version) +{ + struct vmbus_chanmsg_init_contact *req; + const struct vmbus_chanmsg_version_resp *resp; + const struct vmbus_message *msg; + struct vmbus_msghc *mh; + int error, supp = 0; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) + return ENXIO; + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_INIT_CONTACT; + req->chm_ver = version; + req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr; + req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr; + req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr; + + error = vmbus_msghc_exec(sc, mh); + if (error) { + vmbus_msghc_put(sc, mh); + return error; + } + + msg = vmbus_msghc_wait_result(sc, mh); + resp = (const struct vmbus_chanmsg_version_resp *)msg->msg_data; + supp = resp->chm_supp; + + vmbus_msghc_put(sc, mh); + + return (supp ? 0 : EOPNOTSUPP); +} + +static int +vmbus_init(struct vmbus_softc *sc) +{ + int i; + + for (i = 0; i < nitems(vmbus_version); ++i) { + int error; + + error = vmbus_init_contact(sc, vmbus_version[i]); + if (!error) { + hv_vmbus_protocal_version = vmbus_version[i]; + device_printf(sc->vmbus_dev, "version %u.%u\n", + (hv_vmbus_protocal_version >> 16), + (hv_vmbus_protocal_version & 0xffff)); + return 0; + } + } + return ENXIO; +} + static void vmbus_msg_task(void *xsc, int pending __unused) { @@ -81,19 +425,19 @@ vmbus_msg_task(void *xsc, int pending __ msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE; for (;;) { - if (msg->msg_type == VMBUS_MSGTYPE_NONE) { + if (msg->msg_type == HYPERV_MSGTYPE_NONE) { /* No message */ break; - } else if (msg->msg_type == VMBUS_MSGTYPE_CHANNEL) { + } else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) { /* Channel message */ vmbus_chan_msgproc(sc, __DEVOLATILE(const struct vmbus_message *, msg)); } - msg->msg_type = VMBUS_MSGTYPE_NONE; + msg->msg_type = HYPERV_MSGTYPE_NONE; /* * Make sure the write to msg_type (i.e. set to - * VMBUS_MSGTYPE_NONE) happens before we read the + * HYPERV_MSGTYPE_NONE) happens before we read the * msg_flags and EOMing. Otherwise, the EOMing will * not deliver any more messages since there is no * empty slot @@ -127,14 +471,14 @@ vmbus_handle_intr1(struct vmbus_softc *s * TODO: move this to independent IDT vector. */ msg = msg_base + VMBUS_SINT_TIMER; - if (msg->msg_type == VMBUS_MSGTYPE_TIMER_EXPIRED) { - msg->msg_type = VMBUS_MSGTYPE_NONE; + if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) { + msg->msg_type = HYPERV_MSGTYPE_NONE; vmbus_et_intr(frame); /* * Make sure the write to msg_type (i.e. set to - * VMBUS_MSGTYPE_NONE) happens before we read the + * HYPERV_MSGTYPE_NONE) happens before we read the * msg_flags and EOMing. Otherwise, the EOMing will * not deliver any more messages since there is no * empty slot @@ -166,7 +510,7 @@ vmbus_handle_intr1(struct vmbus_softc *s * Check messages. Mainly management stuffs; ultra low rate. */ msg = msg_base + VMBUS_SINT_MESSAGE; - if (__predict_false(msg->msg_type != VMBUS_MSGTYPE_NONE)) { + if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) { taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu), VMBUS_PCPU_PTR(sc, message_task, cpu)); } @@ -700,6 +1044,16 @@ vmbus_bus_init(void) sc->vmbus_flags |= VMBUS_FLAG_ATTACHED; /* + * Create context for "post message" Hypercalls + */ + sc->vmbus_msg_hc = vmbus_msghc_ctx_create( + bus_get_dma_tag(sc->vmbus_dev)); + if (sc->vmbus_msg_hc == NULL) { + ret = ENXIO; + goto cleanup; + } + + /* * Allocate DMA stuffs. */ ret = vmbus_dma_alloc(sc); @@ -728,6 +1082,10 @@ vmbus_bus_init(void) if (ret != 0) goto cleanup; + ret = vmbus_init(sc); + if (ret != 0) + goto cleanup; + if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) sc->vmbus_event_proc = vmbus_event_proc_compat; @@ -745,6 +1103,10 @@ vmbus_bus_init(void) cleanup: vmbus_intr_teardown(sc); vmbus_dma_free(sc); + if (sc->vmbus_msg_hc != NULL) { + vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc); + sc->vmbus_msg_hc = NULL; + } return (ret); } @@ -812,6 +1174,11 @@ vmbus_detach(device_t dev) vmbus_intr_teardown(sc); vmbus_dma_free(sc); + if (sc->vmbus_msg_hc != NULL) { + vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc); + sc->vmbus_msg_hc = NULL; + } + return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 02:54:56 2016 (r307013) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 05:44:36 2016 (r307014) @@ -39,7 +39,7 @@ #define VMBUS_MSG_SIZE 256 struct vmbus_message { - uint32_t msg_type; /* VMBUS_MSGTYPE_ */ + uint32_t msg_type; /* HYPERV_MSGTYPE_ */ uint8_t msg_dsize; /* data size */ uint8_t msg_flags; /* VMBUS_MSGFLAG_ */ uint16_t msg_rsvd; @@ -48,10 +48,6 @@ struct vmbus_message { } __packed; CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE); -#define VMBUS_MSGTYPE_NONE 0 -#define VMBUS_MSGTYPE_CHANNEL 1 -#define VMBUS_MSGTYPE_TIMER_EXPIRED 0x80000010 - #define VMBUS_MSGFLAG_PENDING 0x01 /* @@ -81,4 +77,34 @@ CTASSERT(sizeof(struct vmbus_evtflags) = #define VMBUS_CHAN_MAX_COMPAT 256 #define VMBUS_CHAN_MAX (VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX) +/* + * Channel messages + * - Embedded in vmbus_message.msg_data, e.g. response. + * - Embedded in hypercall_postmsg_in.hc_data, e.g. request. + */ + +#define VMBUS_CHANMSG_TYPE_INIT_CONTACT 14 /* REQ */ +#define VMBUS_CHANMSG_TYPE_VERSION_RESP 15 /* RESP */ + +struct vmbus_chanmsg_hdr { + uint32_t chm_type; /* VMBUS_CHANMSG_TYPE_ */ + uint32_t chm_rsvd; +} __packed; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Tue Oct 11 05:47:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7D906C075C7; Tue, 11 Oct 2016 05:47:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 30E6678E; Tue, 11 Oct 2016 05:47:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B5lqTT069132; Tue, 11 Oct 2016 05:47:52 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B5lq85069131; Tue, 11 Oct 2016 05:47:52 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110547.u9B5lq85069131@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 05:47:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307015 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 05:47:53 -0000 Author: sephe Date: Tue Oct 11 05:47:52 2016 New Revision: 307015 URL: https://svnweb.freebsd.org/changeset/base/307015 Log: MFC 302544 hyperv/hn: Add tunable to allow tcp_lro_queue_mbuf() Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6841 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 05:44:36 2016 (r307014) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 05:47:52 2016 (r307015) @@ -299,6 +299,12 @@ static int hn_tx_swq_depth = 0; SYSCTL_INT(_hw_hn, OID_AUTO, tx_swq_depth, CTLFLAG_RDTUN, &hn_tx_swq_depth, 0, "Depth of IFQ or BUFRING"); +#if __FreeBSD_version >= 1100095 +static u_int hn_lro_mbufq_depth = 0; +SYSCTL_UINT(_hw_hn, OID_AUTO, lro_mbufq_depth, CTLFLAG_RDTUN, + &hn_lro_mbufq_depth, 0, "Depth of LRO mbuf queue"); +#endif + static u_int hn_cpu_index; /* @@ -1300,6 +1306,19 @@ hv_m_append(struct mbuf *m0, int len, c_ return (remainder == 0); } +#if defined(INET) || defined(INET6) +static __inline int +hn_lro_rx(struct lro_ctrl *lc, struct mbuf *m) +{ +#if __FreeBSD_version >= 1100095 + if (hn_lro_mbufq_depth) { + tcp_lro_queue_mbuf(lc, m); + return 0; + } +#endif + return tcp_lro_rx(lc, m, 0); +} +#endif /* * Called when we receive a data packet from the "wire" on the @@ -1505,7 +1524,7 @@ skip: if (lro->lro_cnt) { rxr->hn_lro_tried++; - if (tcp_lro_rx(lro, m_new, 0) == 0) { + if (hn_lro_rx(lro, m_new) == 0) { /* DONE! */ return 0; } @@ -2269,7 +2288,8 @@ hn_create_rx_data(struct hn_softc *sc, i */ #if defined(INET) || defined(INET6) #if __FreeBSD_version >= 1100095 - tcp_lro_init_args(&rxr->hn_lro, sc->hn_ifp, lroent_cnt, 0); + tcp_lro_init_args(&rxr->hn_lro, sc->hn_ifp, lroent_cnt, + hn_lro_mbufq_depth); #else tcp_lro_init(&rxr->hn_lro); rxr->hn_lro.ifp = sc->hn_ifp; From owner-svn-src-stable-10@freebsd.org Tue Oct 11 06:04:42 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 61A57C07D7B; Tue, 11 Oct 2016 06:04:42 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1420811B; Tue, 11 Oct 2016 06:04:42 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B64fo7076563; Tue, 11 Oct 2016 06:04:41 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B64e2D076555; Tue, 11 Oct 2016 06:04:40 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110604.u9B64e2D076555@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 06:04:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307016 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 06:04:42 -0000 Author: sephe Date: Tue Oct 11 06:04:40 2016 New Revision: 307016 URL: https://svnweb.freebsd.org/changeset/base/307016 Log: MFC 302543,302545,302547,302549,302554,302556,302557,302559,302606 302543 hyperv/vmbus: Use post message Hypercall APIs for channel request Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6831 302545 hyperv/vmbus: Function renaming. And pass vmbus_softc to vmbus_doattach() Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6842 302547 hyperv/vmbus: Explicitly assign channel message process array. While I'm here, remove the useless message type from message process array, which is not used and serves no purposes at all. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6858 302549 hyperv/vmbus: Add sysctl to expose vmbus version. Requested by: Hongxiong Xian Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6860 302554 hyperv/vmbus: Use post message Hypercall APIs for unload Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6861 302556 hyperv/vmbus: Create channel synchronously. The device probe/attach has been move to a different thread, so the reasons to create the channel asynchronously are no longer valid. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6862 302557 hyperv/vmbus: Save vmbus softc to channels. So that we don't need to access the global vmbus softc. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6863 302559 hyperv/vmbus: Embed channel detach task in channel itself. GC work queue stuffs. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6864 302606 hyperv/vmbus: Reorganize vmbus scan process. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6875 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_connection.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:04:40 2016 (r307016) @@ -713,6 +713,7 @@ typedef struct { typedef struct hv_vmbus_channel { TAILQ_ENTRY(hv_vmbus_channel) list_entry; struct hv_device* device; + struct vmbus_softc *vmbus_sc; hv_vmbus_channel_state state; hv_vmbus_channel_offer_channel offer_msg; /* @@ -808,6 +809,8 @@ typedef struct hv_vmbus_channel { void *hv_chan_priv1; void *hv_chan_priv2; void *hv_chan_priv3; + + struct task ch_detach_task; } hv_vmbus_channel; #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:04:40 2016 (r307016) @@ -67,7 +67,7 @@ static void vmbus_channel_set_event(hv_vmbus_channel *channel) { if (channel->offer_msg.monitor_allocated) { - struct vmbus_softc *sc = vmbus_get_softc(); + struct vmbus_softc *sc = channel->vmbus_sc; hv_vmbus_monitor_page *monitor_page; uint32_t chanid = channel->offer_msg.child_rel_id; @@ -205,7 +205,7 @@ hv_vmbus_channel_open( vmbus_on_channel_open(new_channel); - new_channel->rxq = VMBUS_PCPU_GET(vmbus_get_softc(), event_tq, + new_channel->rxq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, new_channel->target_cpu); TASK_INIT(&new_channel->channel_task, 0, VmbusProcessChannelEvent, new_channel); Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:04:40 2016 (r307016) @@ -39,19 +39,13 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * Internal functions - */ +typedef void (*vmbus_chanmsg_proc_t) + (struct vmbus_softc *, const struct vmbus_message *); -typedef struct hv_vmbus_channel_msg_table_entry { - hv_vmbus_channel_msg_type messageType; - void (*messageHandler) - (struct vmbus_softc *sc, - const struct vmbus_message *msg); -} hv_vmbus_channel_msg_table_entry; - -static void vmbus_channel_on_offer_internal(void *context); -static void vmbus_channel_on_offer_rescind_internal(void *context); +static struct hv_vmbus_channel *hv_vmbus_allocate_channel(struct vmbus_softc *); +static void vmbus_channel_on_offer_internal(struct vmbus_softc *, + const hv_vmbus_channel_offer_channel *offer); +static void vmbus_chan_detach_task(void *, int); static void vmbus_channel_on_offer(struct vmbus_softc *, const struct vmbus_message *); @@ -71,108 +65,38 @@ static void vmbus_channel_on_version_res /** * Channel message dispatch table */ -static const hv_vmbus_channel_msg_table_entry - g_channel_message_table[HV_CHANNEL_MESSAGE_COUNT] = { - { HV_CHANNEL_MESSAGE_INVALID, - NULL }, - { HV_CHANNEL_MESSAGE_OFFER_CHANNEL, - vmbus_channel_on_offer }, - { HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER, - vmbus_channel_on_offer_rescind }, - { HV_CHANNEL_MESSAGE_REQUEST_OFFERS, - NULL }, - { HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED, - vmbus_channel_on_offers_delivered }, - { HV_CHANNEL_MESSAGE_OPEN_CHANNEL, - NULL }, - { HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT, - vmbus_channel_on_open_result }, - { HV_CHANNEL_MESSAGE_CLOSE_CHANNEL, - NULL }, - { HV_CHANNEL_MESSAGEL_GPADL_HEADER, - NULL }, - { HV_CHANNEL_MESSAGE_GPADL_BODY, - NULL }, - { HV_CHANNEL_MESSAGE_GPADL_CREATED, - vmbus_channel_on_gpadl_created }, - { HV_CHANNEL_MESSAGE_GPADL_TEARDOWN, - NULL }, - { HV_CHANNEL_MESSAGE_GPADL_TORNDOWN, - vmbus_channel_on_gpadl_torndown }, - { HV_CHANNEL_MESSAGE_REL_ID_RELEASED, - NULL }, - { HV_CHANNEL_MESSAGE_INITIATED_CONTACT, - NULL }, - { HV_CHANNEL_MESSAGE_VERSION_RESPONSE, - vmbus_channel_on_version_response }, - { HV_CHANNEL_MESSAGE_UNLOAD, - NULL } +static const vmbus_chanmsg_proc_t +vmbus_chanmsg_process[HV_CHANNEL_MESSAGE_COUNT] = { + [HV_CHANNEL_MESSAGE_OFFER_CHANNEL] = + vmbus_channel_on_offer, + [HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER] = + vmbus_channel_on_offer_rescind, + [HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED] = + vmbus_channel_on_offers_delivered, + [HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT] = + vmbus_channel_on_open_result, + [HV_CHANNEL_MESSAGE_GPADL_CREATED] = + vmbus_channel_on_gpadl_created, + [HV_CHANNEL_MESSAGE_GPADL_TORNDOWN] = + vmbus_channel_on_gpadl_torndown, + [HV_CHANNEL_MESSAGE_VERSION_RESPONSE] = + vmbus_channel_on_version_response }; -typedef struct hv_work_item { - struct task work; - void (*callback)(void *); - void* context; -} hv_work_item; - -static struct mtx vmbus_chwait_lock; -MTX_SYSINIT(vmbus_chwait_lk, &vmbus_chwait_lock, "vmbus primarych wait lock", - MTX_DEF); -static uint32_t vmbus_chancnt; -static uint32_t vmbus_devcnt; - -#define VMBUS_CHANCNT_DONE 0x80000000 - -/** - * Implementation of the work abstraction. - */ -static void -work_item_callback(void *work, int pending) -{ - struct hv_work_item *w = (struct hv_work_item *)work; - - w->callback(w->context); - - free(w, M_DEVBUF); -} - -/** - * @brief Create work item - */ -static int -hv_queue_work_item( - void (*callback)(void *), void *context) -{ - struct hv_work_item *w = malloc(sizeof(struct hv_work_item), - M_DEVBUF, M_NOWAIT); - KASSERT(w != NULL, ("Error VMBUS: Failed to allocate WorkItem\n")); - if (w == NULL) - return (ENOMEM); - - w->callback = callback; - w->context = context; - - TASK_INIT(&w->work, 0, work_item_callback, w); - - return (taskqueue_enqueue(taskqueue_thread, &w->work)); -} - - /** * @brief Allocate and initialize a vmbus channel object */ -hv_vmbus_channel* -hv_vmbus_allocate_channel(void) +static struct hv_vmbus_channel * +hv_vmbus_allocate_channel(struct vmbus_softc *sc) { - hv_vmbus_channel* channel; + struct hv_vmbus_channel *channel; - channel = (hv_vmbus_channel*) malloc( - sizeof(hv_vmbus_channel), - M_DEVBUF, - M_WAITOK | M_ZERO); + channel = malloc(sizeof(*channel), M_DEVBUF, M_WAITOK | M_ZERO); + channel->vmbus_sc = sc; mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF); TAILQ_INIT(&channel->sc_list_anchor); + TASK_INIT(&channel->ch_detach_task, 0, vmbus_chan_detach_task, channel); return (channel); } @@ -195,7 +119,6 @@ static void vmbus_channel_process_offer(hv_vmbus_channel *new_channel) { hv_vmbus_channel* channel; - int ret; uint32_t relid; relid = new_channel->offer_msg.child_rel_id; @@ -300,19 +223,8 @@ vmbus_channel_process_offer(hv_vmbus_cha * binding which eventually invokes the device driver's AddDevice() * method. */ - ret = hv_vmbus_child_device_register(new_channel->device); - if (ret != 0) { - mtx_lock(&hv_vmbus_g_connection.channel_lock); - TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor, - new_channel, list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_lock); - hv_vmbus_free_vmbus_channel(new_channel); - } - - mtx_lock(&vmbus_chwait_lock); - vmbus_devcnt++; - mtx_unlock(&vmbus_chwait_lock); - wakeup(&vmbus_devcnt); + hv_vmbus_child_device_register(new_channel->vmbus_sc, + new_channel->device); } void @@ -327,7 +239,7 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch } chan->target_cpu = cpu; - chan->target_vcpu = VMBUS_PCPU_GET(vmbus_get_softc(), vcpuid, cpu); + chan->target_vcpu = VMBUS_PCPU_GET(chan->vmbus_sc, vcpuid, cpu); if (bootverbose) { printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", @@ -396,46 +308,28 @@ vmbus_channel_select_defcpu(struct hv_vm /** * @brief Handler for channel offers from Hyper-V/Azure * - * Handler for channel offers from vmbus in parent partition. We ignore - * all offers except network and storage offers. For each network and storage - * offers, we create a channel object and queue a work item to the channel - * object to process the offer synchronously + * Handler for channel offers from vmbus in parent partition. */ static void vmbus_channel_on_offer(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_header *hdr = - (const hv_vmbus_channel_msg_header *)msg->msg_data; - const hv_vmbus_channel_offer_channel *offer; - hv_vmbus_channel_offer_channel *copied; - offer = (const hv_vmbus_channel_offer_channel *)hdr; + /* New channel is offered by vmbus */ + vmbus_scan_newchan(sc); - // copy offer data - copied = malloc(sizeof(*copied), M_DEVBUF, M_NOWAIT); - if (copied == NULL) { - printf("fail to allocate memory\n"); - return; - } - - memcpy(copied, hdr, sizeof(*copied)); - hv_queue_work_item(vmbus_channel_on_offer_internal, copied); - - mtx_lock(&vmbus_chwait_lock); - if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0) - vmbus_chancnt++; - mtx_unlock(&vmbus_chwait_lock); + offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data; + vmbus_channel_on_offer_internal(sc, offer); } static void -vmbus_channel_on_offer_internal(void* context) +vmbus_channel_on_offer_internal(struct vmbus_softc *sc, + const hv_vmbus_channel_offer_channel *offer) { hv_vmbus_channel* new_channel; - hv_vmbus_channel_offer_channel* offer = (hv_vmbus_channel_offer_channel*)context; /* Allocate the channel object and save this offer */ - new_channel = hv_vmbus_allocate_channel(); + new_channel = hv_vmbus_allocate_channel(sc); /* * By default we setup state to enable batched @@ -472,45 +366,41 @@ vmbus_channel_on_offer_internal(void* co vmbus_channel_select_defcpu(new_channel); vmbus_channel_process_offer(new_channel); - - free(offer, M_DEVBUF); } /** * @brief Rescind offer handler. * * We queue a work item to process this offer - * synchronously + * synchronously. + * + * XXX pretty broken; need rework. */ static void vmbus_channel_on_offer_rescind(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_header *hdr = - (const hv_vmbus_channel_msg_header *)msg->msg_data; - const hv_vmbus_channel_rescind_offer *rescind; hv_vmbus_channel* channel; - rescind = (const hv_vmbus_channel_rescind_offer *)hdr; + rescind = (const hv_vmbus_channel_rescind_offer *)msg->msg_data; channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; if (channel == NULL) return; - - hv_queue_work_item(vmbus_channel_on_offer_rescind_internal, channel); hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; + + taskqueue_enqueue(taskqueue_thread, &channel->ch_detach_task); } static void -vmbus_channel_on_offer_rescind_internal(void *context) +vmbus_chan_detach_task(void *xchan, int pending __unused) { - hv_vmbus_channel* channel; + struct hv_vmbus_channel *chan = xchan; - channel = (hv_vmbus_channel*)context; - if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { + if (HV_VMBUS_CHAN_ISPRIMARY(chan)) { /* Only primary channel owns the hv_device */ - hv_vmbus_child_device_unregister(channel->device); + hv_vmbus_child_device_unregister(chan->device); } } @@ -519,14 +409,12 @@ vmbus_channel_on_offer_rescind_internal( * @brief Invoked when all offers have been delivered. */ static void -vmbus_channel_on_offers_delivered(struct vmbus_softc *sc __unused, +vmbus_channel_on_offers_delivered(struct vmbus_softc *sc, const struct vmbus_message *msg __unused) { - mtx_lock(&vmbus_chwait_lock); - vmbus_chancnt |= VMBUS_CHANCNT_DONE; - mtx_unlock(&vmbus_chwait_lock); - wakeup(&vmbus_chancnt); + /* No more new channels for the channel request. */ + vmbus_scan_done(sc); } /** @@ -678,36 +566,6 @@ vmbus_channel_on_version_response(struct } /** - * @brief Send a request to get all our pending offers. - */ -int -hv_vmbus_request_channel_offers(void) -{ - int ret; - hv_vmbus_channel_msg_header* msg; - hv_vmbus_channel_msg_info* msg_info; - - msg_info = (hv_vmbus_channel_msg_info *) - malloc(sizeof(hv_vmbus_channel_msg_info) - + sizeof(hv_vmbus_channel_msg_header), M_DEVBUF, M_NOWAIT); - - if (msg_info == NULL) { - if(bootverbose) - printf("Error VMBUS: malloc failed for Request Offers\n"); - return (ENOMEM); - } - - msg = (hv_vmbus_channel_msg_header*) msg_info->msg; - msg->message_type = HV_CHANNEL_MESSAGE_REQUEST_OFFERS; - - ret = hv_vmbus_post_message(msg, sizeof(hv_vmbus_channel_msg_header)); - - free(msg_info, M_DEVBUF); - - return (ret); -} - -/** * @brief Release channels that are unattached/unconnected (i.e., no drivers associated) */ void @@ -760,7 +618,7 @@ vmbus_select_outgoing_channel(struct hv_ return outgoing_channel; } - cur_vcpu = VMBUS_PCPU_GET(vmbus_get_softc(), vcpuid, smp_pro_id); + cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) { if (new_channel->state != HV_CHANNEL_OPENED_STATE){ @@ -789,21 +647,6 @@ vmbus_select_outgoing_channel(struct hv_ return(outgoing_channel); } -void -vmbus_scan(void) -{ - uint32_t chancnt; - - mtx_lock(&vmbus_chwait_lock); - while ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0) - mtx_sleep(&vmbus_chancnt, &vmbus_chwait_lock, 0, "waitch", 0); - chancnt = vmbus_chancnt & ~VMBUS_CHANCNT_DONE; - - while (vmbus_devcnt != chancnt) - mtx_sleep(&vmbus_devcnt, &vmbus_chwait_lock, 0, "waitdev", 0); - mtx_unlock(&vmbus_chwait_lock); -} - struct hv_vmbus_channel ** vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt) { @@ -845,20 +688,17 @@ vmbus_rel_subchan(struct hv_vmbus_channe void vmbus_chan_msgproc(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_table_entry *entry; - const hv_vmbus_channel_msg_header *hdr; - hv_vmbus_channel_msg_type msg_type; - - hdr = (const hv_vmbus_channel_msg_header *)msg->msg_data; - msg_type = hdr->message_type; + vmbus_chanmsg_proc_t msg_proc; + uint32_t msg_type; + msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type; if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) { device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", msg_type); return; } - entry = &g_channel_message_table[msg_type]; - if (entry->messageHandler) - entry->messageHandler(sc, msg); + msg_proc = vmbus_chanmsg_process[msg_type]; + if (msg_proc != NULL) + msg_proc(sc, msg); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_connection.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 06:04:40 2016 (r307016) @@ -95,19 +95,13 @@ hv_vmbus_connect(struct vmbus_softc *sc) int hv_vmbus_disconnect(void) { - int ret = 0; - hv_vmbus_channel_unload msg; - - msg.message_type = HV_CHANNEL_MESSAGE_UNLOAD; - - ret = hv_vmbus_post_message(&msg, sizeof(hv_vmbus_channel_unload)); mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock); free(hv_vmbus_g_connection.channels, M_DEVBUF); hv_vmbus_g_connection.connect_state = HV_DISCONNECTED; - return (ret); + return (0); } static __inline void @@ -213,7 +207,7 @@ int hv_vmbus_post_message(void *buffer, int hv_vmbus_set_event(hv_vmbus_channel *channel) { - struct vmbus_softc *sc = vmbus_get_softc(); + struct vmbus_softc *sc = channel->vmbus_sc; int ret = 0; uint32_t chanid = channel->offer_msg.child_rel_id; @@ -231,7 +225,7 @@ vmbus_on_channel_open(const struct hv_vm int flag_cnt; flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1; - flag_cnt_ptr = VMBUS_PCPU_PTR(vmbus_get_softc(), event_flags_cnt, + flag_cnt_ptr = VMBUS_PCPU_PTR(chan->vmbus_sc, event_flags_cnt, chan->target_cpu); for (;;) { Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:04:40 2016 (r307016) @@ -395,9 +395,7 @@ void hv_ring_buffer_read_begin( uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); -hv_vmbus_channel* hv_vmbus_allocate_channel(void); void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); -int hv_vmbus_request_channel_offers(void); void hv_vmbus_release_unattached_channels(void); uint16_t hv_vmbus_post_msg_via_msg_ipc( @@ -413,7 +411,9 @@ struct hv_device* hv_vmbus_child_device_ hv_guid device_instance, hv_vmbus_channel *channel); -int hv_vmbus_child_device_register( +struct vmbus_softc; + +void hv_vmbus_child_device_register(struct vmbus_softc *, struct hv_device *child_dev); int hv_vmbus_child_device_unregister( struct hv_device *child_dev); @@ -421,13 +421,9 @@ int hv_vmbus_child_device_unregister( /** * Connection interfaces */ -struct vmbus_softc; int hv_vmbus_connect(struct vmbus_softc *); int hv_vmbus_disconnect(void); int hv_vmbus_post_message(void *buffer, size_t buf_size); int hv_vmbus_set_event(hv_vmbus_channel *channel); -/* Wait for device creation */ -void vmbus_scan(void); - #endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:04:40 2016 (r307016) @@ -98,6 +98,13 @@ struct vmbus_msghc_ctx { static int vmbus_init(struct vmbus_softc *); static int vmbus_init_contact(struct vmbus_softc *, uint32_t); +static int vmbus_req_channels(struct vmbus_softc *sc); +static void vmbus_uninit(struct vmbus_softc *); +static int vmbus_scan(struct vmbus_softc *); +static void vmbus_scan_wait(struct vmbus_softc *); +static void vmbus_scan_newdev(struct vmbus_softc *); + +static int vmbus_sysctl_version(SYSCTL_HANDLER_ARGS); static struct vmbus_msghc_ctx *vmbus_msghc_ctx_create(bus_dma_tag_t); static void vmbus_msghc_ctx_destroy( @@ -418,6 +425,131 @@ vmbus_init(struct vmbus_softc *sc) } static void +vmbus_uninit(struct vmbus_softc *sc) +{ + struct vmbus_chanmsg_unload *req; + struct vmbus_msghc *mh; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for unload\n"); + return; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_UNLOAD; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, + "unload msg hypercall failed\n"); + } +} + +static int +vmbus_req_channels(struct vmbus_softc *sc) +{ + struct vmbus_chanmsg_channel_req *req; + struct vmbus_msghc *mh; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) + return ENXIO; + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHANNEL_REQ; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + return error; +} + +void +vmbus_scan_newchan(struct vmbus_softc *sc) +{ + mtx_lock(&sc->vmbus_scan_lock); + if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) + sc->vmbus_scan_chcnt++; + mtx_unlock(&sc->vmbus_scan_lock); +} + +void +vmbus_scan_done(struct vmbus_softc *sc) +{ + mtx_lock(&sc->vmbus_scan_lock); + sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE; + mtx_unlock(&sc->vmbus_scan_lock); + wakeup(&sc->vmbus_scan_chcnt); +} + +static void +vmbus_scan_newdev(struct vmbus_softc *sc) +{ + mtx_lock(&sc->vmbus_scan_lock); + sc->vmbus_scan_devcnt++; + mtx_unlock(&sc->vmbus_scan_lock); + wakeup(&sc->vmbus_scan_devcnt); +} + +static void +vmbus_scan_wait(struct vmbus_softc *sc) +{ + uint32_t chancnt; + + mtx_lock(&sc->vmbus_scan_lock); + while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) { + mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0, + "waitch", 0); + } + chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE; + + while (sc->vmbus_scan_devcnt != chancnt) { + mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0, + "waitdev", 0); + } + mtx_unlock(&sc->vmbus_scan_lock); +} + +static int +vmbus_scan(struct vmbus_softc *sc) +{ + int error; + + /* + * Start vmbus scanning. + */ + error = vmbus_req_channels(sc); + if (error) { + device_printf(sc->vmbus_dev, "channel request failed: %d\n", + error); + return error; + } + + /* + * Wait for all devices are added to vmbus. + */ + vmbus_scan_wait(sc); + + /* + * Identify, probe and attach. + */ + bus_generic_probe(sc->vmbus_dev); + bus_generic_attach(sc->vmbus_dev); + + if (bootverbose) { + device_printf(sc->vmbus_dev, "device scan, probe and attach " + "done\n"); + } + return 0; +} + +static void vmbus_msg_task(void *xsc, int pending __unused) { struct vmbus_softc *sc = xsc; @@ -972,12 +1104,13 @@ hv_vmbus_child_device_create(hv_guid typ return (child_dev); } -int -hv_vmbus_child_device_register(struct hv_device *child_dev) +void +hv_vmbus_child_device_register(struct vmbus_softc *sc, + struct hv_device *child_dev) { device_t child, parent; - parent = vmbus_get_device(); + parent = sc->vmbus_dev; if (bootverbose) { char name[HYPERV_GUID_STRLEN]; @@ -989,7 +1122,8 @@ hv_vmbus_child_device_register(struct hv child_dev->device = child; device_set_ivars(child, child_dev); - return (0); + /* New device was added to vmbus */ + vmbus_scan_newdev(sc); } int @@ -1007,6 +1141,17 @@ hv_vmbus_child_device_unregister(struct } static int +vmbus_sysctl_version(SYSCTL_HANDLER_ARGS) +{ + char verstr[16]; + + snprintf(verstr, sizeof(verstr), "%u.%u", + hv_vmbus_protocal_version >> 16, + hv_vmbus_protocal_version & 0xffff); + return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); +} + +static int vmbus_probe(device_t dev) { char *id[] = { "VMBUS", NULL }; @@ -1034,15 +1179,18 @@ vmbus_probe(device_t dev) * - retrieve the channel offers */ static int -vmbus_bus_init(void) +vmbus_doattach(struct vmbus_softc *sc) { - struct vmbus_softc *sc = vmbus_get_softc(); + struct sysctl_oid_list *child; + struct sysctl_ctx_list *ctx; int ret; if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED) return (0); sc->vmbus_flags |= VMBUS_FLAG_ATTACHED; + mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF); + /* * Create context for "post message" Hypercalls */ @@ -1092,11 +1240,15 @@ vmbus_bus_init(void) else sc->vmbus_event_proc = vmbus_event_proc; - hv_vmbus_request_channel_offers(); + ret = vmbus_scan(sc); + if (ret != 0) + goto cleanup; - vmbus_scan(); - bus_generic_attach(sc->vmbus_dev); - device_printf(sc->vmbus_dev, "device scan, probe and attach done\n"); + ctx = device_get_sysctl_ctx(sc->vmbus_dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev)); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, + vmbus_sysctl_version, "A", "vmbus version"); return (ret); @@ -1107,6 +1259,7 @@ cleanup: vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc); sc->vmbus_msg_hc = NULL; } + mtx_destroy(&sc->vmbus_scan_lock); return (ret); } @@ -1136,16 +1289,17 @@ vmbus_attach(device_t dev) * initialization directly. */ if (!cold) - vmbus_bus_init(); + vmbus_doattach(vmbus_sc); - bus_generic_probe(dev); return (0); } static void vmbus_sysinit(void *arg __unused) { - if (vm_guest != VM_GUEST_HV || vmbus_get_softc() == NULL) + struct vmbus_softc *sc = vmbus_get_softc(); + + if (vm_guest != VM_GUEST_HV || sc == NULL) return; /* @@ -1155,7 +1309,7 @@ vmbus_sysinit(void *arg __unused) * initialization directly. */ if (!cold) - vmbus_bus_init(); + vmbus_doattach(sc); } static int @@ -1164,6 +1318,8 @@ vmbus_detach(device_t dev) struct vmbus_softc *sc = device_get_softc(dev); hv_vmbus_release_unattached_channels(); + + vmbus_uninit(sc); hv_vmbus_disconnect(); if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) { @@ -1179,6 +1335,7 @@ vmbus_detach(device_t dev) sc->vmbus_msg_hc = NULL; } + mtx_destroy(&sc->vmbus_scan_lock); return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 06:04:40 2016 (r307016) @@ -83,8 +83,10 @@ CTASSERT(sizeof(struct vmbus_evtflags) = * - Embedded in hypercall_postmsg_in.hc_data, e.g. request. */ +#define VMBUS_CHANMSG_TYPE_CHANNEL_REQ 3 /* REQ */ #define VMBUS_CHANMSG_TYPE_INIT_CONTACT 14 /* REQ */ #define VMBUS_CHANMSG_TYPE_VERSION_RESP 15 /* RESP */ +#define VMBUS_CHANMSG_TYPE_UNLOAD 16 /* REQ */ struct vmbus_chanmsg_hdr { uint32_t chm_type; /* VMBUS_CHANMSG_TYPE_ */ @@ -107,4 +109,14 @@ struct vmbus_chanmsg_version_resp { uint8_t chm_supp; } __packed; +/* VMBUS_CHANMSG_TYPE_CHANNEL_REQ */ +struct vmbus_chanmsg_channel_req { + struct vmbus_chanmsg_hdr chm_hdr; +} __packed; + +/* VMBUS_CHANMSG_TYPE_UNLOAD */ +struct vmbus_chanmsg_unload { + struct vmbus_chanmsg_hdr chm_hdr; +} __packed; + #endif /* !_VMBUS_REG_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 05:47:52 2016 (r307015) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 06:04:40 2016 (r307016) @@ -83,6 +83,11 @@ struct vmbus_softc { void *vmbus_mnf1; /* monitored by VM, unused */ struct hyperv_dma vmbus_mnf1_dma; struct hyperv_dma vmbus_mnf2_dma; + + struct mtx vmbus_scan_lock; + uint32_t vmbus_scan_chcnt; +#define VMBUS_SCAN_CHCNT_DONE 0x80000000 + uint32_t vmbus_scan_devcnt; }; #define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */ @@ -128,4 +133,7 @@ const struct vmbus_message *vmbus_msghc_ struct vmbus_msghc *); void vmbus_msghc_wakeup(struct vmbus_softc *, const struct vmbus_message *); +void vmbus_scan_done(struct vmbus_softc *); +void vmbus_scan_newchan(struct vmbus_softc *); + #endif /* !_VMBUS_VAR_H_ */ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 06:19:08 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0D5E2C0C35C; Tue, 11 Oct 2016 06:19:08 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 97C7C8EB; Tue, 11 Oct 2016 06:19:07 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B6J62S080533; Tue, 11 Oct 2016 06:19:06 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B6J6NA080529; Tue, 11 Oct 2016 06:19:06 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110619.u9B6J6NA080529@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 06:19:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307017 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 06:19:08 -0000 Author: sephe Date: Tue Oct 11 06:19:06 2016 New Revision: 307017 URL: https://svnweb.freebsd.org/changeset/base/307017 Log: MFC 302607-302612 302607 hyperv/vmbus: Use post message Hypercall APIs for channel open Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6876 302608 hyperv/vmbus: Remove unnecessary check and unapplied comment Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6877 302609 hyperv/vmbus: Use post message Hypercall APIs for GPADL connect. This also fixes memory leakge if sub-connect messages are needed. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6878 302610 hyperv/vmbus: Use post message Hypercall APIs for channel close Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6906 302611 hyperv/vmbus: Use post message Hypercall APIs for GPA disconnect Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6912 302612 hyperv: Nuke unused stuffs Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6913 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_connection.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:04:40 2016 (r307016) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:19:06 2016 (r307017) @@ -179,8 +179,6 @@ typedef struct hv_vmbus_channel_offer { } __packed hv_vmbus_channel_offer; -typedef uint32_t hv_gpadl_handle; - typedef struct { uint16_t type; uint16_t data_offset8; @@ -352,14 +350,6 @@ typedef struct { } __packed hv_vmbus_channel_query_vmbus_version; /* - * VMBus Version Supported parameters - */ -typedef struct { - hv_vmbus_channel_msg_header header; - hv_bool_uint8_t version_supported; -} __packed hv_vmbus_channel_version_supported; - -/* * Channel Offer parameters */ typedef struct { @@ -397,171 +387,13 @@ typedef struct uint32_t child_rel_id; } __packed hv_vmbus_channel_rescind_offer; - -/* - * Request Offer -- no parameters, SynIC message contains the partition ID - * - * Set Snoop -- no parameters, SynIC message contains the partition ID - * - * Clear Snoop -- no parameters, SynIC message contains the partition ID - * - * All Offers Delivered -- no parameters, SynIC message contains the - * partition ID - * - * Flush Client -- no parameters, SynIC message contains the partition ID - */ - - -/* - * Open Channel parameters - */ -typedef struct -{ - hv_vmbus_channel_msg_header header; - - /* - * Identifies the specific VMBus channel that is being opened. - */ - uint32_t child_rel_id; - - /* - * ID making a particular open request at a channel offer unique. - */ - uint32_t open_id; - - /* - * GPADL for the channel's ring buffer. - */ - hv_gpadl_handle ring_buffer_gpadl_handle; - - /* - * Before win8, all incoming channel interrupts are only - * delivered on cpu 0. Setting this value to 0 would - * preserve the earlier behavior. - */ - uint32_t target_vcpu; - - /* - * The upstream ring buffer begins at offset zero in the memory described - * by ring_buffer_gpadl_handle. The downstream ring buffer follows it at - * this offset (in pages). - */ - uint32_t downstream_ring_buffer_page_offset; - - /* - * User-specific data to be passed along to the server endpoint. - */ - uint8_t user_data[HV_MAX_USER_DEFINED_BYTES]; - -} __packed hv_vmbus_channel_open_channel; - -typedef uint32_t hv_nt_status; - -/* - * Open Channel Result parameters - */ -typedef struct -{ - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; - uint32_t open_id; - hv_nt_status status; -} __packed hv_vmbus_channel_open_result; - -/* - * Close channel parameters - */ -typedef struct -{ - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; -} __packed hv_vmbus_channel_close_channel; - -/* - * Channel Message GPADL - */ -#define HV_GPADL_TYPE_RING_BUFFER 1 -#define HV_GPADL_TYPE_SERVER_SAVE_AREA 2 -#define HV_GPADL_TYPE_TRANSACTION 8 - -/* - * The number of PFNs in a GPADL message is defined by the number of pages - * that would be spanned by byte_count and byte_offset. If the implied number - * of PFNs won't fit in this packet, there will be a follow-up packet that - * contains more - */ - -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; - uint16_t range_buf_len; - uint16_t range_count; - hv_gpa_range range[0]; -} __packed hv_vmbus_channel_gpadl_header; - -/* - * This is the follow-up packet that contains more PFNs - */ -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t message_number; - uint32_t gpadl; - uint64_t pfn[0]; -} __packed hv_vmbus_channel_gpadl_body; - -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; - uint32_t creation_status; -} __packed hv_vmbus_channel_gpadl_created; - -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; -} __packed hv_vmbus_channel_gpadl_teardown; - -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t gpadl; -} __packed hv_vmbus_channel_gpadl_torndown; - typedef struct { hv_vmbus_channel_msg_header header; uint32_t child_rel_id; } __packed hv_vmbus_channel_relid_released; -typedef hv_vmbus_channel_msg_header hv_vmbus_channel_unload; - #define HW_MACADDR_LEN 6 -/* - * Fixme: Added to quiet "typeof" errors involving hv_vmbus.h when - * the including C file was compiled with "-std=c99". - */ -#ifndef typeof -#define typeof __typeof -#endif - -#ifndef NULL -#define NULL (void *)0 -#endif - -typedef void *hv_vmbus_handle; - -#ifndef CONTAINING_RECORD -#define CONTAINING_RECORD(address, type, field) ((type *)( \ - (uint8_t *)(address) - \ - (uint8_t *)(&((type *)0)->field))) -#endif /* CONTAINING_RECORD */ - - -#define container_of(ptr, type, member) ({ \ - __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - enum { HV_VMBUS_IVAR_TYPE, HV_VMBUS_IVAR_INSTANCE, Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:04:40 2016 (r307016) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:19:06 2016 (r307017) @@ -49,14 +49,6 @@ __FBSDID("$FreeBSD$"); #include #include -static int vmbus_channel_create_gpadl_header( - /* must be phys and virt contiguous*/ - void* contig_buffer, - /* page-size multiple */ - uint32_t size, - hv_vmbus_channel_msg_info** msg_info, - uint32_t* message_count); - static void vmbus_channel_set_event(hv_vmbus_channel* channel); static void VmbusProcessChannelEvent(void* channel, int pending); @@ -182,11 +174,21 @@ hv_vmbus_channel_open( hv_vmbus_pfn_channel_callback pfn_on_channel_callback, void* context) { - + struct vmbus_softc *sc = new_channel->vmbus_sc; + const struct vmbus_chanmsg_chopen_resp *resp; + const struct vmbus_message *msg; + struct vmbus_chanmsg_chopen *req; + struct vmbus_msghc *mh; + uint32_t status; int ret = 0; void *in, *out; - hv_vmbus_channel_open_channel* open_msg; - hv_vmbus_channel_msg_info* open_info; + + if (user_data_len > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { + device_printf(sc->vmbus_dev, + "invalid udata len %u for chan%u\n", + user_data_len, new_channel->offer_msg.child_rel_id); + return EINVAL; + } mtx_lock(&new_channel->sc_lock); if (new_channel->state == HV_CHANNEL_OPEN_STATE) { @@ -248,381 +250,231 @@ hv_vmbus_channel_open( send_ring_buffer_size + recv_ring_buffer_size, &new_channel->ring_buffer_gpadl_handle); - /** - * Create and init the channel open message + /* + * Open channel w/ the bufring GPADL on the target CPU. */ - open_info = (hv_vmbus_channel_msg_info*) malloc( - sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_open_channel), - M_DEVBUF, - M_NOWAIT); - KASSERT(open_info != NULL, - ("Error VMBUS: malloc failed to allocate Open Channel message!")); - - if (open_info == NULL) - return (ENOMEM); - - sema_init(&open_info->wait_sema, 0, "Open Info Sema"); - - open_msg = (hv_vmbus_channel_open_channel*) open_info->msg; - open_msg->header.message_type = HV_CHANNEL_MESSAGE_OPEN_CHANNEL; - open_msg->open_id = new_channel->offer_msg.child_rel_id; - open_msg->child_rel_id = new_channel->offer_msg.child_rel_id; - open_msg->ring_buffer_gpadl_handle = - new_channel->ring_buffer_gpadl_handle; - open_msg->downstream_ring_buffer_page_offset = send_ring_buffer_size - >> PAGE_SHIFT; - open_msg->target_vcpu = new_channel->target_vcpu; - + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chopen(chan%u)\n", + new_channel->offer_msg.child_rel_id); + return ENXIO; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; + req->chm_chanid = new_channel->offer_msg.child_rel_id; + req->chm_openid = new_channel->offer_msg.child_rel_id; + req->chm_gpadl = new_channel->ring_buffer_gpadl_handle; + req->chm_vcpuid = new_channel->target_vcpu; + req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; if (user_data_len) - memcpy(open_msg->user_data, user_data, user_data_len); - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_INSERT_TAIL( - &hv_vmbus_g_connection.channel_msg_anchor, - open_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - ret = hv_vmbus_post_message( - open_msg, sizeof(hv_vmbus_channel_open_channel)); + memcpy(req->chm_udata, user_data, user_data_len); - if (ret != 0) - goto cleanup; - - ret = sema_timedwait(&open_info->wait_sema, 5 * hz); /* KYS 5 seconds */ - - if (ret) { - if(bootverbose) - printf("VMBUS: channel <%p> open timeout.\n", new_channel); - goto cleanup; + ret = vmbus_msghc_exec(sc, mh); + if (ret != 0) { + device_printf(sc->vmbus_dev, + "chopen(chan%u) msg hypercall exec failed: %d\n", + new_channel->offer_msg.child_rel_id, ret); + vmbus_msghc_put(sc, mh); + return ret; } - if (open_info->response.open_result.status == 0) { - new_channel->state = HV_CHANNEL_OPENED_STATE; - if(bootverbose) - printf("VMBUS: channel <%p> open success.\n", new_channel); + msg = vmbus_msghc_wait_result(sc, mh); + resp = (const struct vmbus_chanmsg_chopen_resp *)msg->msg_data; + status = resp->chm_status; + + vmbus_msghc_put(sc, mh); + + if (status == 0) { + new_channel->state = HV_CHANNEL_OPENED_STATE; + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u opened\n", + new_channel->offer_msg.child_rel_id); + } } else { - if(bootverbose) - printf("Error VMBUS: channel <%p> open failed - %d!\n", - new_channel, open_info->response.open_result.status); + device_printf(sc->vmbus_dev, "failed to open chan%u\n", + new_channel->offer_msg.child_rel_id); + ret = ENXIO; } - - cleanup: - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE( - &hv_vmbus_g_connection.channel_msg_anchor, - open_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - sema_destroy(&open_info->wait_sema); - free(open_info, M_DEVBUF); - return (ret); } /** - * @brief Create a gpadl for the specified buffer - */ -static int -vmbus_channel_create_gpadl_header( - void* contig_buffer, - uint32_t size, /* page-size multiple */ - hv_vmbus_channel_msg_info** msg_info, - uint32_t* message_count) -{ - int i; - int page_count; - unsigned long long pfn; - uint32_t msg_size; - hv_vmbus_channel_gpadl_header* gpa_header; - hv_vmbus_channel_gpadl_body* gpadl_body; - hv_vmbus_channel_msg_info* msg_header; - hv_vmbus_channel_msg_info* msg_body; - - int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; - - page_count = size >> PAGE_SHIFT; - pfn = hv_get_phys_addr(contig_buffer) >> PAGE_SHIFT; - - /*do we need a gpadl body msg */ - pfnSize = HV_MAX_SIZE_CHANNEL_MESSAGE - - sizeof(hv_vmbus_channel_gpadl_header) - - sizeof(hv_gpa_range); - pfnCount = pfnSize / sizeof(uint64_t); - - if (page_count > pfnCount) { /* if(we need a gpadl body) */ - /* fill in the header */ - msg_size = sizeof(hv_vmbus_channel_msg_info) - + sizeof(hv_vmbus_channel_gpadl_header) - + sizeof(hv_gpa_range) - + pfnCount * sizeof(uint64_t); - msg_header = malloc(msg_size, M_DEVBUF, M_NOWAIT | M_ZERO); - KASSERT( - msg_header != NULL, - ("Error VMBUS: malloc failed to allocate Gpadl Message!")); - if (msg_header == NULL) - return (ENOMEM); - - TAILQ_INIT(&msg_header->sub_msg_list_anchor); - msg_header->message_size = msg_size; - - gpa_header = (hv_vmbus_channel_gpadl_header*) msg_header->msg; - gpa_header->range_count = 1; - gpa_header->range_buf_len = sizeof(hv_gpa_range) - + page_count * sizeof(uint64_t); - gpa_header->range[0].byte_offset = 0; - gpa_header->range[0].byte_count = size; - for (i = 0; i < pfnCount; i++) { - gpa_header->range[0].pfn_array[i] = pfn + i; - } - *msg_info = msg_header; - *message_count = 1; - - pfnSum = pfnCount; - pfnLeft = page_count - pfnCount; - - /* - * figure out how many pfns we can fit - */ - pfnSize = HV_MAX_SIZE_CHANNEL_MESSAGE - - sizeof(hv_vmbus_channel_gpadl_body); - pfnCount = pfnSize / sizeof(uint64_t); - - /* - * fill in the body - */ - while (pfnLeft) { - if (pfnLeft > pfnCount) { - pfnCurr = pfnCount; - } else { - pfnCurr = pfnLeft; - } - - msg_size = sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_gpadl_body) + - pfnCurr * sizeof(uint64_t); - msg_body = malloc(msg_size, M_DEVBUF, M_NOWAIT | M_ZERO); - KASSERT( - msg_body != NULL, - ("Error VMBUS: malloc failed to allocate Gpadl msg_body!")); - if (msg_body == NULL) - return (ENOMEM); - - msg_body->message_size = msg_size; - (*message_count)++; - gpadl_body = - (hv_vmbus_channel_gpadl_body*) msg_body->msg; - /* - * gpadl_body->gpadl = kbuffer; - */ - for (i = 0; i < pfnCurr; i++) { - gpadl_body->pfn[i] = pfn + pfnSum + i; - } - - TAILQ_INSERT_TAIL( - &msg_header->sub_msg_list_anchor, - msg_body, - msg_list_entry); - pfnSum += pfnCurr; - pfnLeft -= pfnCurr; - } - } else { /* else everything fits in a header */ - - msg_size = sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_gpadl_header) + - sizeof(hv_gpa_range) + - page_count * sizeof(uint64_t); - msg_header = malloc(msg_size, M_DEVBUF, M_NOWAIT | M_ZERO); - KASSERT( - msg_header != NULL, - ("Error VMBUS: malloc failed to allocate Gpadl Message!")); - if (msg_header == NULL) - return (ENOMEM); - - msg_header->message_size = msg_size; - - gpa_header = (hv_vmbus_channel_gpadl_header*) msg_header->msg; - gpa_header->range_count = 1; - gpa_header->range_buf_len = sizeof(hv_gpa_range) + - page_count * sizeof(uint64_t); - gpa_header->range[0].byte_offset = 0; - gpa_header->range[0].byte_count = size; - for (i = 0; i < page_count; i++) { - gpa_header->range[0].pfn_array[i] = pfn + i; - } - - *msg_info = msg_header; - *message_count = 1; - } - - return (0); -} - -/** * @brief Establish a GPADL for the specified buffer */ int -hv_vmbus_channel_establish_gpadl( - hv_vmbus_channel* channel, - void* contig_buffer, - uint32_t size, /* page-size multiple */ - uint32_t* gpadl_handle) - +hv_vmbus_channel_establish_gpadl(struct hv_vmbus_channel *channel, + void *contig_buffer, uint32_t size, uint32_t *gpadl0) { - int ret = 0; - hv_vmbus_channel_gpadl_header* gpadl_msg; - hv_vmbus_channel_gpadl_body* gpadl_body; - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_info* sub_msg_info; - uint32_t msg_count; - hv_vmbus_channel_msg_info* curr; - uint32_t next_gpadl_handle; - - next_gpadl_handle = atomic_fetchadd_int( - &hv_vmbus_g_connection.next_gpadl_handle, 1); - - ret = vmbus_channel_create_gpadl_header( - contig_buffer, size, &msg_info, &msg_count); + struct vmbus_softc *sc = channel->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_gpadl_conn *req; + const struct vmbus_message *msg; + size_t reqsz; + uint32_t gpadl, status; + int page_count, range_len, i, cnt, error; + uint64_t page_id, paddr; - if(ret != 0) { - /* - * XXX - * We can _not_ even revert the above incremental, - * if multiple GPADL establishments are running - * parallelly, decrement the global next_gpadl_handle - * is calling for _big_ trouble. A better solution - * is to have a 0-based GPADL id bitmap ... - */ - return ret; - } + /* + * Preliminary checks. + */ - sema_init(&msg_info->wait_sema, 0, "Open Info Sema"); - gpadl_msg = (hv_vmbus_channel_gpadl_header*) msg_info->msg; - gpadl_msg->header.message_type = HV_CHANNEL_MESSAGEL_GPADL_HEADER; - gpadl_msg->child_rel_id = channel->offer_msg.child_rel_id; - gpadl_msg->gpadl = next_gpadl_handle; - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_INSERT_TAIL( - &hv_vmbus_g_connection.channel_msg_anchor, - msg_info, - msg_list_entry); - - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - ret = hv_vmbus_post_message( - gpadl_msg, - msg_info->message_size - - (uint32_t) sizeof(hv_vmbus_channel_msg_info)); + KASSERT((size & PAGE_MASK) == 0, + ("invalid GPA size %u, not multiple page size", size)); + page_count = size >> PAGE_SHIFT; - if (ret != 0) - goto cleanup; + paddr = hv_get_phys_addr(contig_buffer); + KASSERT((paddr & PAGE_MASK) == 0, + ("GPA is not page aligned %jx", (uintmax_t)paddr)); + page_id = paddr >> PAGE_SHIFT; - if (msg_count > 1) { - TAILQ_FOREACH(curr, - &msg_info->sub_msg_list_anchor, msg_list_entry) { - sub_msg_info = curr; - gpadl_body = - (hv_vmbus_channel_gpadl_body*) sub_msg_info->msg; - - gpadl_body->header.message_type = - HV_CHANNEL_MESSAGE_GPADL_BODY; - gpadl_body->gpadl = next_gpadl_handle; - - ret = hv_vmbus_post_message( - gpadl_body, - sub_msg_info->message_size - - (uint32_t) sizeof(hv_vmbus_channel_msg_info)); - /* if (the post message failed) give up and clean up */ - if(ret != 0) - goto cleanup; - } + range_len = __offsetof(struct vmbus_gpa_range, gpa_page[page_count]); + /* + * We don't support multiple GPA ranges. + */ + if (range_len > UINT16_MAX) { + device_printf(sc->vmbus_dev, "GPA too large, %d pages\n", + page_count); + return EOPNOTSUPP; } - ret = sema_timedwait(&msg_info->wait_sema, 5 * hz); /* KYS 5 seconds*/ - if (ret != 0) - goto cleanup; - - *gpadl_handle = gpadl_msg->gpadl; - -cleanup: - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE(&hv_vmbus_g_connection.channel_msg_anchor, - msg_info, msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - sema_destroy(&msg_info->wait_sema); - free(msg_info, M_DEVBUF); + /* + * Allocate GPADL id. + */ + gpadl = atomic_fetchadd_int( + &hv_vmbus_g_connection.next_gpadl_handle, 1); + *gpadl0 = gpadl; - return (ret); + /* + * Connect this GPADL to the target channel. + * + * NOTE: + * Since each message can only hold small set of page + * addresses, several messages may be required to + * complete the connection. + */ + if (page_count > VMBUS_CHANMSG_GPADL_CONN_PGMAX) + cnt = VMBUS_CHANMSG_GPADL_CONN_PGMAX; + else + cnt = page_count; + page_count -= cnt; + + reqsz = __offsetof(struct vmbus_chanmsg_gpadl_conn, + chm_range.gpa_page[cnt]); + mh = vmbus_msghc_get(sc, reqsz); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for gpadl->chan%u\n", + channel->offer_msg.child_rel_id); + return EIO; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_CONN; + req->chm_chanid = channel->offer_msg.child_rel_id; + req->chm_gpadl = gpadl; + req->chm_range_len = range_len; + req->chm_range_cnt = 1; + req->chm_range.gpa_len = size; + req->chm_range.gpa_ofs = 0; + for (i = 0; i < cnt; ++i) + req->chm_range.gpa_page[i] = page_id++; + + error = vmbus_msghc_exec(sc, mh); + if (error) { + device_printf(sc->vmbus_dev, + "gpadl->chan%u msg hypercall exec failed: %d\n", + channel->offer_msg.child_rel_id, error); + vmbus_msghc_put(sc, mh); + return error; + } + + while (page_count > 0) { + struct vmbus_chanmsg_gpadl_subconn *subreq; + + if (page_count > VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX) + cnt = VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX; + else + cnt = page_count; + page_count -= cnt; + + reqsz = __offsetof(struct vmbus_chanmsg_gpadl_subconn, + chm_gpa_page[cnt]); + vmbus_msghc_reset(mh, reqsz); + + subreq = vmbus_msghc_dataptr(mh); + subreq->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_SUBCONN; + subreq->chm_gpadl = gpadl; + for (i = 0; i < cnt; ++i) + subreq->chm_gpa_page[i] = page_id++; + + vmbus_msghc_exec_noresult(mh); + } + KASSERT(page_count == 0, ("invalid page count %d", page_count)); + + msg = vmbus_msghc_wait_result(sc, mh); + status = ((const struct vmbus_chanmsg_gpadl_connresp *) + msg->msg_data)->chm_status; + + vmbus_msghc_put(sc, mh); + + if (status != 0) { + device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " + "status %u\n", channel->offer_msg.child_rel_id, status); + return EIO; + } + return 0; } -/** - * @brief Teardown the specified GPADL handle +/* + * Disconnect the GPA from the target channel */ int -hv_vmbus_channel_teardown_gpdal( - hv_vmbus_channel* channel, - uint32_t gpadl_handle) +hv_vmbus_channel_teardown_gpdal(struct hv_vmbus_channel *chan, uint32_t gpadl) { - int ret = 0; - hv_vmbus_channel_gpadl_teardown* msg; - hv_vmbus_channel_msg_info* info; - - info = (hv_vmbus_channel_msg_info *) - malloc( sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_gpadl_teardown), - M_DEVBUF, M_NOWAIT); - KASSERT(info != NULL, - ("Error VMBUS: malloc failed to allocate Gpadl Teardown Msg!")); - if (info == NULL) { - ret = ENOMEM; - goto cleanup; - } - - sema_init(&info->wait_sema, 0, "Open Info Sema"); - - msg = (hv_vmbus_channel_gpadl_teardown*) info->msg; - - msg->header.message_type = HV_CHANNEL_MESSAGE_GPADL_TEARDOWN; - msg->child_rel_id = channel->offer_msg.child_rel_id; - msg->gpadl = gpadl_handle; - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_msg_anchor, - info, msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - ret = hv_vmbus_post_message(msg, - sizeof(hv_vmbus_channel_gpadl_teardown)); - if (ret != 0) - goto cleanup; - - ret = sema_timedwait(&info->wait_sema, 5 * hz); /* KYS 5 seconds */ - -cleanup: - /* - * Received a torndown response - */ - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE(&hv_vmbus_g_connection.channel_msg_anchor, - info, msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - sema_destroy(&info->wait_sema); - free(info, M_DEVBUF); + struct vmbus_softc *sc = chan->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_gpadl_disconn *req; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for gpa x->chan%u\n", + chan->offer_msg.child_rel_id); + return EBUSY; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_DISCONN; + req->chm_chanid = chan->offer_msg.child_rel_id; + req->chm_gpadl = gpadl; + + error = vmbus_msghc_exec(sc, mh); + if (error) { + device_printf(sc->vmbus_dev, + "gpa x->chan%u msg hypercall exec failed: %d\n", + chan->offer_msg.child_rel_id, error); + vmbus_msghc_put(sc, mh); + return error; + } + + vmbus_msghc_wait_result(sc, mh); + /* Discard result; no useful information */ + vmbus_msghc_put(sc, mh); - return (ret); + return 0; } static void hv_vmbus_channel_close_internal(hv_vmbus_channel *channel) { - int ret = 0; + struct vmbus_softc *sc = channel->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_chclose *req; struct taskqueue *rxq = channel->rxq; - hv_vmbus_channel_close_channel* msg; - hv_vmbus_channel_msg_info* info; + int error; channel->state = HV_CHANNEL_OPEN_STATE; @@ -636,20 +488,31 @@ hv_vmbus_channel_close_internal(hv_vmbus /** * Send a closing message */ - info = (hv_vmbus_channel_msg_info *) - malloc( sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_close_channel), - M_DEVBUF, M_NOWAIT); - KASSERT(info != NULL, ("VMBUS: malloc failed hv_vmbus_channel_close!")); - if(info == NULL) - return; - - msg = (hv_vmbus_channel_close_channel*) info->msg; - msg->header.message_type = HV_CHANNEL_MESSAGE_CLOSE_CHANNEL; - msg->child_rel_id = channel->offer_msg.child_rel_id; - ret = hv_vmbus_post_message( - msg, sizeof(hv_vmbus_channel_close_channel)); + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chclose(chan%u)\n", + channel->offer_msg.child_rel_id); + return; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHCLOSE; + req->chm_chanid = channel->offer_msg.child_rel_id; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, + "chclose(chan%u) msg hypercall exec failed: %d\n", + channel->offer_msg.child_rel_id, error); + return; + } else if (bootverbose) { + device_printf(sc->vmbus_dev, "close chan%u\n", + channel->offer_msg.child_rel_id); + } /* Tear down the gpadl for the channel's ring buffer */ if (channel->ring_buffer_gpadl_handle) { @@ -665,8 +528,6 @@ hv_vmbus_channel_close_internal(hv_vmbus contigfree(channel->ring_buffer_pages, channel->ring_buffer_size, M_DEVBUF); - - free(info, M_DEVBUF); } /** @@ -988,23 +849,6 @@ VmbusProcessChannelEvent(void* context, hv_vmbus_channel* channel = (hv_vmbus_channel*)context; boolean_t is_batched_reading; - /** - * Find the channel based on this relid and invokes - * the channel callback to process the event - */ - - if (channel == NULL) { - return; - } - /** - * To deal with the race condition where we might - * receive a packet while the relevant driver is - * being unloaded, dispatch the callback while - * holding the channel lock. The unloading driver - * will acquire the same channel lock to set the - * callback to NULL. This closes the window. - */ - if (channel->on_channel_callback != NULL) { arg = channel->channel_callback_context; is_batched_reading = channel->batched_reading; Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:04:40 2016 (r307016) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:19:06 2016 (r307017) @@ -421,46 +421,13 @@ vmbus_channel_on_offers_delivered(struct * @brief Open result handler. * * This is invoked when we received a response - * to our channel open request. Find the matching request, copy the - * response and signal the requesting thread. + * to our channel open request. */ static void vmbus_channel_on_open_result(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_header *hdr = - (const hv_vmbus_channel_msg_header *)msg->msg_data; - - const hv_vmbus_channel_open_result *result; - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_header* requestHeader; - hv_vmbus_channel_open_channel* openMsg; - - result = (const hv_vmbus_channel_open_result *)hdr; - - /* - * Find the open msg, copy the result and signal/unblock the wait event - */ - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - - TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, - msg_list_entry) { - requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg; - - if (requestHeader->message_type == - HV_CHANNEL_MESSAGE_OPEN_CHANNEL) { - openMsg = (hv_vmbus_channel_open_channel*) msg_info->msg; - if (openMsg->child_rel_id == result->child_rel_id - && openMsg->open_id == result->open_id) { - memcpy(&msg_info->response.open_result, result, - sizeof(hv_vmbus_channel_open_result)); - sema_post(&msg_info->wait_sema); - break; - } - } - } - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - + vmbus_msghc_wakeup(sc, msg); } /** @@ -474,39 +441,7 @@ static void vmbus_channel_on_gpadl_created(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_header *hdr = - (const hv_vmbus_channel_msg_header *)msg->msg_data; - - const hv_vmbus_channel_gpadl_created *gpadl_created; - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_header* request_header; - hv_vmbus_channel_gpadl_header* gpadl_header; - - gpadl_created = (const hv_vmbus_channel_gpadl_created *)hdr; - - /* Find the establish msg, copy the result and signal/unblock - * the wait event - */ - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, - msg_list_entry) { - request_header = (hv_vmbus_channel_msg_header*) msg_info->msg; - if (request_header->message_type == - HV_CHANNEL_MESSAGEL_GPADL_HEADER) { - gpadl_header = - (hv_vmbus_channel_gpadl_header*) request_header; - - if ((gpadl_created->child_rel_id == gpadl_header->child_rel_id) - && (gpadl_created->gpadl == gpadl_header->gpadl)) { - memcpy(&msg_info->response.gpadl_created, - gpadl_created, - sizeof(hv_vmbus_channel_gpadl_created)); - sema_post(&msg_info->wait_sema); - break; - } - } - } - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); + vmbus_msghc_wakeup(sc, msg); } /** @@ -520,42 +455,7 @@ static void vmbus_channel_on_gpadl_torndown(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_msg_header *hdr = - (const hv_vmbus_channel_msg_header *)msg->msg_data; - - const hv_vmbus_channel_gpadl_torndown *gpadl_torndown; - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_header* requestHeader; - hv_vmbus_channel_gpadl_teardown* gpadlTeardown; - - gpadl_torndown = (const hv_vmbus_channel_gpadl_torndown *)hdr; - - /* - * Find the open msg, copy the result and signal/unblock the - * wait event. *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Tue Oct 11 06:35:31 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D1782C0C92F; Tue, 11 Oct 2016 06:35:31 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 980D317B; Tue, 11 Oct 2016 06:35:31 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B6ZUab088104; Tue, 11 Oct 2016 06:35:30 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B6ZTbO088089; Tue, 11 Oct 2016 06:35:29 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110635.u9B6ZTbO088089@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 06:35:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307018 - in stable/10/sys: conf dev/hyperv/include dev/hyperv/netvsc dev/hyperv/storvsc dev/hyperv/vmbus modules/hyperv/netvsc modules/hyperv/storvsc modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 06:35:31 -0000 Author: sephe Date: Tue Oct 11 06:35:29 2016 New Revision: 307018 URL: https://svnweb.freebsd.org/changeset/base/307018 Log: MFC 302617-302621,302623,302629-302631 302617 hyperv/vmbus: Flatten channel message response processing. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6914 302618 hyperv/vmbus: Avoid tx_evtflags setting code duplication. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6915 302619 hyperv/vmbus: Busdma-fy Hypercall signal event input parameter. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6916 302620 hyperv: Nuke unused stuffs Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6917 302621 hyperv/vmbus: Don't be oversmart in default cpu selection. Pin the channel to cpu0 by default. Drivers having special channel-cpu mapping requirement should call vmbus_channel_cpu_{set,rr}() themselves. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6918 302623 hyperv/vmbus: Minor renaming Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6919 302629 hyperv/vmbus: Rework vmbus version accessing. Instead of global variable, vmbus version is accessed through a vmbus DEVMETHOD now. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6953 302630 hyperv/vmbus: Move GPADL index into vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6954 302631 hyperv/vmbus: Move channel list to vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6956 Added: stable/10/sys/dev/hyperv/vmbus/vmbus_if.m - copied unchanged from r302629, head/sys/dev/hyperv/vmbus/vmbus_if.m Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_connection.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h stable/10/sys/dev/hyperv/vmbus/hyperv_var.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h stable/10/sys/modules/hyperv/netvsc/Makefile stable/10/sys/modules/hyperv/storvsc/Makefile stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/conf/files.amd64 Tue Oct 11 06:35:29 2016 (r307018) @@ -279,6 +279,7 @@ dev/hyperv/vmbus/hyperv.c optional hy dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/lindev/full.c optional lindev Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/conf/files.i386 Tue Oct 11 06:35:29 2016 (r307018) @@ -256,6 +256,7 @@ dev/hyperv/vmbus/hyperv.c optional hy dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv +dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/i386/vmbus_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:35:29 2016 (r307018) @@ -55,6 +55,7 @@ #include #include +#include typedef uint8_t hv_bool_uint8_t; @@ -72,10 +73,13 @@ typedef uint8_t hv_bool_uint8_t; * 2.4 -- Windows 8 * 3.0 -- Windows 8.1 */ -#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13)) -#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1)) -#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) -#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) +#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) +#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) +#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) +#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) + +#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) +#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) /* * Make maximum size of pipe payload of 16K @@ -528,22 +532,7 @@ typedef union { } __packed hv_vmbus_connection_id; -/* - * Definition of the hv_vmbus_signal_event hypercall input structure - */ -typedef struct { - hv_vmbus_connection_id connection_id; - uint16_t flag_number; - uint16_t rsvd_z; -} __packed hv_vmbus_input_signal_event; - -typedef struct { - uint64_t align8; - hv_vmbus_input_signal_event event; -} __packed hv_vmbus_input_signal_event_buffer; - typedef struct hv_vmbus_channel { - TAILQ_ENTRY(hv_vmbus_channel) list_entry; struct hv_device* device; struct vmbus_softc *vmbus_sc; hv_vmbus_channel_state state; @@ -589,14 +578,8 @@ typedef struct hv_vmbus_channel { boolean_t is_dedicated_interrupt; - /* - * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall. - */ - hv_vmbus_input_signal_event_buffer signal_event_buffer; - /* - * 8-bytes aligned of the buffer above - */ - hv_vmbus_input_signal_event *signal_event_param; + struct hypercall_sigevt_in *ch_sigevt; + struct hyperv_dma ch_sigevt_dma; /* * From Win8, this field specifies the target virtual process @@ -643,6 +626,7 @@ typedef struct hv_vmbus_channel { void *hv_chan_priv3; struct task ch_detach_task; + TAILQ_ENTRY(hv_vmbus_channel) ch_link; } hv_vmbus_channel; #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) @@ -726,6 +710,7 @@ int hv_vmbus_channel_teardown_gpdal( struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); void vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu); +void vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan); struct hv_vmbus_channel ** vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt); void vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt); @@ -741,5 +726,4 @@ hv_get_phys_addr(void *virt) return (ret); } -extern uint32_t hv_vmbus_protocal_version; #endif /* __HYPERV_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:35:29 2016 (r307018) @@ -116,9 +116,11 @@ __FBSDID("$FreeBSD$"); #include #include + #include "hv_net_vsc.h" #include "hv_rndis.h" #include "hv_rndis_filter.h" +#include "vmbus_if.h" #define hv_chan_rxr hv_chan_priv1 #define hv_chan_txr hv_chan_priv2 @@ -2425,8 +2427,10 @@ static int hn_create_tx_ring(struct hn_softc *sc, int id) { struct hn_tx_ring *txr = &sc->hn_tx_ring[id]; + device_t dev = sc->hn_dev; bus_dma_tag_t parent_dtag; int error, i; + uint32_t version; txr->hn_sc = sc; txr->hn_tx_idx = id; @@ -2465,10 +2469,18 @@ hn_create_tx_ring(struct hn_softc *sc, i } txr->hn_direct_tx_size = hn_direct_tx_size; - if (hv_vmbus_protocal_version >= HV_VMBUS_VERSION_WIN8_1) + version = VMBUS_GET_VERSION(device_get_parent(dev), dev); + if (version >= VMBUS_VERSION_WIN8_1) { txr->hn_csum_assist = HN_CSUM_ASSIST; - else + } else { txr->hn_csum_assist = HN_CSUM_ASSIST_WIN8; + if (id == 0) { + device_printf(dev, "bus version %u.%u, " + "no UDP checksum offloading\n", + VMBUS_VERSION_MAJOR(version), + VMBUS_VERSION_MINOR(version)); + } + } /* * Always schedule transmission instead of trying to do direct @@ -2476,7 +2488,7 @@ hn_create_tx_ring(struct hn_softc *sc, i */ txr->hn_sched_tx = 1; - parent_dtag = bus_get_dma_tag(sc->hn_dev); + parent_dtag = bus_get_dma_tag(dev); /* DMA tag for RNDIS messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ @@ -2493,7 +2505,7 @@ hn_create_tx_ring(struct hn_softc *sc, i NULL, /* lockfuncarg */ &txr->hn_tx_rndis_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create rndis dmatag\n"); + device_printf(dev, "failed to create rndis dmatag\n"); return error; } @@ -2512,7 +2524,7 @@ hn_create_tx_ring(struct hn_softc *sc, i NULL, /* lockfuncarg */ &txr->hn_tx_data_dtag); if (error) { - device_printf(sc->hn_dev, "failed to create data dmatag\n"); + device_printf(dev, "failed to create data dmatag\n"); return error; } @@ -2529,7 +2541,7 @@ hn_create_tx_ring(struct hn_softc *sc, i BUS_DMA_WAITOK | BUS_DMA_COHERENT, &txd->rndis_msg_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate rndis_msg, %d\n", i); return error; } @@ -2540,7 +2552,7 @@ hn_create_tx_ring(struct hn_softc *sc, i hyperv_dma_map_paddr, &txd->rndis_msg_paddr, BUS_DMA_NOWAIT); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to load rndis_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, txd->rndis_msg_dmap); @@ -2551,7 +2563,7 @@ hn_create_tx_ring(struct hn_softc *sc, i error = bus_dmamap_create(txr->hn_tx_data_dtag, 0, &txd->data_dmap); if (error) { - device_printf(sc->hn_dev, + device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); @@ -2579,7 +2591,7 @@ hn_create_tx_ring(struct hn_softc *sc, i * Create per TX ring sysctl tree: * dev.hn.UNIT.tx.RINGID */ - ctx = device_get_sysctl_ctx(sc->hn_dev); + ctx = device_get_sysctl_ctx(dev); child = SYSCTL_CHILDREN(sc->hn_tx_sysctl_tree); snprintf(name, sizeof(name), "%d", id); Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 06:35:29 2016 (r307018) @@ -72,7 +72,9 @@ __FBSDID("$FreeBSD$"); #include #include + #include "hv_vstorage.h" +#include "vmbus_if.h" #define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE) #define STORVSC_MAX_LUNS_PER_TARGET (64) @@ -361,6 +363,7 @@ storvsc_subchan_attach(struct hv_vmbus_c memset(&props, 0, sizeof(props)); + vmbus_channel_cpu_rr(new_channel); ret = hv_vmbus_channel_open(new_channel, sc->hs_drv_props->drv_ringbuffer_size, sc->hs_drv_props->drv_ringbuffer_size, @@ -464,6 +467,7 @@ hv_storvsc_channel_init(struct hv_device struct storvsc_softc *sc; uint16_t max_chans = 0; boolean_t support_multichannel = FALSE; + uint32_t version; max_chans = 0; support_multichannel = FALSE; @@ -588,8 +592,9 @@ hv_storvsc_channel_init(struct hv_device /* multi-channels feature is supported by WIN8 and above version */ max_chans = vstor_packet->u.chan_props.max_channel_cnt; - if ((hv_vmbus_protocal_version != HV_VMBUS_VERSION_WIN7) && - (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) && + version = VMBUS_GET_VERSION(device_get_parent(dev->device), + dev->device); + if (version != VMBUS_VERSION_WIN7 && version != VMBUS_VERSION_WS2008 && (vstor_packet->u.chan_props.flags & HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) { support_multichannel = TRUE; @@ -655,7 +660,7 @@ hv_storvsc_connect_vsp(struct hv_device /* * Open the channel */ - + vmbus_channel_cpu_rr(dev->channel); ret = hv_vmbus_channel_open( dev->channel, sc->hs_drv_props->drv_ringbuffer_size, Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:35:29 2016 (r307018) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -58,21 +59,21 @@ static void VmbusProcessChannelEvent(voi static void vmbus_channel_set_event(hv_vmbus_channel *channel) { + struct vmbus_softc *sc = channel->vmbus_sc; + uint32_t chanid = channel->offer_msg.child_rel_id; + + atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], + 1UL << (chanid & VMBUS_EVTFLAG_MASK)); + if (channel->offer_msg.monitor_allocated) { - struct vmbus_softc *sc = channel->vmbus_sc; hv_vmbus_monitor_page *monitor_page; - uint32_t chanid = channel->offer_msg.child_rel_id; - - atomic_set_long( - &sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], - 1UL << (chanid & VMBUS_EVTFLAG_MASK)); monitor_page = sc->vmbus_mnf2; synch_set_bit(channel->monitor_bit, (uint32_t *)&monitor_page-> trigger_group[channel->monitor_group].u.pending); } else { - hv_vmbus_set_event(channel); + hypercall_signal_event(channel->ch_sigevt_dma.hv_paddr); } } @@ -342,8 +343,7 @@ hv_vmbus_channel_establish_gpadl(struct /* * Allocate GPADL id. */ - gpadl = atomic_fetchadd_int( - &hv_vmbus_g_connection.next_gpadl_handle, 1); + gpadl = vmbus_gpadl_alloc(sc); *gpadl0 = gpadl; /* Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:35:29 2016 (r307018) @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -49,18 +50,10 @@ static void vmbus_chan_detach_task(void static void vmbus_channel_on_offer(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_open_result(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_gpadl_created(struct vmbus_softc *, - const struct vmbus_message *); -static void vmbus_channel_on_gpadl_torndown(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_version_response(struct vmbus_softc *, - const struct vmbus_message *); /** * Channel message dispatch table @@ -74,13 +67,13 @@ vmbus_chanmsg_process[HV_CHANNEL_MESSAGE [HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED] = vmbus_channel_on_offers_delivered, [HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT] = - vmbus_channel_on_open_result, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_GPADL_CREATED] = - vmbus_channel_on_gpadl_created, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_GPADL_TORNDOWN] = - vmbus_channel_on_gpadl_torndown, + vmbus_msghc_wakeup, [HV_CHANNEL_MESSAGE_VERSION_RESPONSE] = - vmbus_channel_on_version_response + vmbus_msghc_wakeup }; /** @@ -118,6 +111,7 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_cha static void vmbus_channel_process_offer(hv_vmbus_channel *new_channel) { + struct vmbus_softc *sc = new_channel->vmbus_sc; hv_vmbus_channel* channel; uint32_t relid; @@ -125,7 +119,7 @@ vmbus_channel_process_offer(hv_vmbus_cha /* * Make sure this is a new offer */ - mtx_lock(&hv_vmbus_g_connection.channel_lock); + mtx_lock(&sc->vmbus_chlist_lock); if (relid == 0) { /* * XXX channel0 will not be processed; skip it. @@ -135,8 +129,7 @@ vmbus_channel_process_offer(hv_vmbus_cha hv_vmbus_g_connection.channels[relid] = new_channel; } - TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor, - list_entry) { + TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { if (memcmp(&channel->offer_msg.offer.interface_type, &new_channel->offer_msg.offer.interface_type, sizeof(hv_guid)) == 0 && @@ -148,10 +141,9 @@ vmbus_channel_process_offer(hv_vmbus_cha if (channel == NULL) { /* Install the new primary channel */ - TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, - new_channel, list_entry); + TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, ch_link); } - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + mtx_unlock(&sc->vmbus_chlist_lock); if (channel != NULL) { /* @@ -175,11 +167,19 @@ vmbus_channel_process_offer(hv_vmbus_cha new_channel->offer_msg.offer.sub_channel_index); } - /* Insert new channel into channel_anchor. */ - mtx_lock(&hv_vmbus_g_connection.channel_lock); - TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, - new_channel, list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + /* + * Insert the new channel to the end of the global + * channel list. + * + * NOTE: + * The new sub-channel MUST be inserted AFTER it's + * primary channel, so that the primary channel will + * be found in the above loop for its baby siblings. + */ + mtx_lock(&sc->vmbus_chlist_lock); + TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, + ch_link); + mtx_unlock(&sc->vmbus_chlist_lock); if(bootverbose) printf("VMBUS: new multi-channel offer <%p>, " @@ -232,8 +232,8 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch { KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu)); - if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || - hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { + if (chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WS2008 || + chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WIN7) { /* Only cpu0 is supported */ cpu = 0; } @@ -248,61 +248,25 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch } } -/** - * Array of device guids that are performance critical. We try to distribute - * the interrupt load for these devices across all online cpus. - */ -static const hv_guid high_perf_devices[] = { - {HV_NIC_GUID, }, - {HV_IDE_GUID, }, - {HV_SCSI_GUID, }, -}; - -enum { - PERF_CHN_NIC = 0, - PERF_CHN_IDE, - PERF_CHN_SCSI, - MAX_PERF_CHN, -}; +void +vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan) +{ + static uint32_t vmbus_chan_nextcpu; + int cpu; -/* - * We use this static number to distribute the channel interrupt load. - */ -static uint32_t next_vcpu; + cpu = atomic_fetchadd_int(&vmbus_chan_nextcpu, 1) % mp_ncpus; + vmbus_channel_cpu_set(chan, cpu); +} -/** - * Starting with Win8, we can statically distribute the incoming - * channel interrupt load by binding a channel to VCPU. We - * implement here a simple round robin scheme for distributing - * the interrupt load. - * We will bind channels that are not performance critical to cpu 0 and - * performance critical channels (IDE, SCSI and Network) will be uniformly - * distributed across all available CPUs. - */ static void -vmbus_channel_select_defcpu(struct hv_vmbus_channel *channel) +vmbus_channel_select_defcpu(struct hv_vmbus_channel *chan) { - uint32_t current_cpu; - int i; - boolean_t is_perf_channel = FALSE; - const hv_guid *guid = &channel->offer_msg.offer.interface_type; - - for (i = PERF_CHN_NIC; i < MAX_PERF_CHN; i++) { - if (memcmp(guid->data, high_perf_devices[i].data, - sizeof(hv_guid)) == 0) { - is_perf_channel = TRUE; - break; - } - } - - if (!is_perf_channel) { - /* Stick to cpu0 */ - vmbus_channel_cpu_set(channel, 0); - return; - } - /* mp_ncpus should have the number cpus currently online */ - current_cpu = (++next_vcpu % mp_ncpus); - vmbus_channel_cpu_set(channel, current_cpu); + /* + * By default, pin the channel to cpu0. Devices having + * special channel-cpu mapping requirement should call + * vmbus_channel_cpu_{set,rr}(). + */ + vmbus_channel_cpu_set(chan, 0); } /** @@ -338,23 +302,23 @@ vmbus_channel_on_offer_internal(struct v */ new_channel->batched_reading = TRUE; - new_channel->signal_event_param = - (hv_vmbus_input_signal_event *) - (HV_ALIGN_UP((unsigned long) - &new_channel->signal_event_buffer, - HV_HYPERCALL_PARAM_ALIGN)); - - new_channel->signal_event_param->connection_id.as_uint32_t = 0; - new_channel->signal_event_param->connection_id.u.id = - HV_VMBUS_EVENT_CONNECTION_ID; - new_channel->signal_event_param->flag_number = 0; - new_channel->signal_event_param->rsvd_z = 0; + new_channel->ch_sigevt = hyperv_dmamem_alloc( + bus_get_dma_tag(sc->vmbus_dev), + HYPERCALL_SIGEVTIN_ALIGN, 0, sizeof(struct hypercall_sigevt_in), + &new_channel->ch_sigevt_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (new_channel->ch_sigevt == NULL) { + device_printf(sc->vmbus_dev, "sigevt alloc failed\n"); + /* XXX */ + mtx_destroy(&new_channel->sc_lock); + free(new_channel, M_DEVBUF); + return; + } + new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT; - if (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) { + if (sc->vmbus_version != VMBUS_VERSION_WS2008) { new_channel->is_dedicated_interrupt = (offer->is_dedicated_interrupt != 0); - new_channel->signal_event_param->connection_id.u.id = - offer->connection_id; + new_channel->ch_sigevt->hc_connid = offer->connection_id; } memcpy(&new_channel->offer_msg, offer, @@ -418,67 +382,18 @@ vmbus_channel_on_offers_delivered(struct } /** - * @brief Open result handler. - * - * This is invoked when we received a response - * to our channel open request. - */ -static void -vmbus_channel_on_open_result(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** - * @brief GPADL created handler. - * - * This is invoked when we received a response - * to our gpadl create request. Find the matching request, copy the - * response and signal the requesting thread. - */ -static void -vmbus_channel_on_gpadl_created(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** - * @brief GPADL torndown handler. - * - * This is invoked when we received a respons - * to our gpadl teardown request. Find the matching request, copy the - * response and signal the requesting thread - */ -static void -vmbus_channel_on_gpadl_torndown(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -static void -vmbus_channel_on_version_response(struct vmbus_softc *sc, - const struct vmbus_message *msg) -{ - vmbus_msghc_wakeup(sc, msg); -} - -/** * @brief Release channels that are unattached/unconnected (i.e., no drivers associated) */ void -hv_vmbus_release_unattached_channels(void) +hv_vmbus_release_unattached_channels(struct vmbus_softc *sc) { hv_vmbus_channel *channel; - mtx_lock(&hv_vmbus_g_connection.channel_lock); + mtx_lock(&sc->vmbus_chlist_lock); - while (!TAILQ_EMPTY(&hv_vmbus_g_connection.channel_anchor)) { - channel = TAILQ_FIRST(&hv_vmbus_g_connection.channel_anchor); - TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor, - channel, list_entry); + while (!TAILQ_EMPTY(&sc->vmbus_chlist)) { + channel = TAILQ_FIRST(&sc->vmbus_chlist); + TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link); if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { /* Only primary channel owns the hv_device */ @@ -488,7 +403,8 @@ hv_vmbus_release_unattached_channels(voi } bzero(hv_vmbus_g_connection.channels, sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX); - mtx_unlock(&hv_vmbus_g_connection.channel_lock); + + mtx_unlock(&sc->vmbus_chlist_lock); } /** Modified: stable/10/sys/dev/hyperv/vmbus/hv_connection.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c Tue Oct 11 06:35:29 2016 (r307018) @@ -50,10 +50,7 @@ __FBSDID("$FreeBSD$"); * Globals */ hv_vmbus_connection hv_vmbus_g_connection = - { .connect_state = HV_DISCONNECTED, - .next_gpadl_handle = 0xE1E10, }; - -uint32_t hv_vmbus_protocal_version; + { .connect_state = HV_DISCONNECTED }; /** * Send a connect request on the partition service connection @@ -73,10 +70,6 @@ hv_vmbus_connect(struct vmbus_softc *sc) */ hv_vmbus_g_connection.connect_state = HV_CONNECTING; - TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor); - mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel", - NULL, MTX_DEF); - hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); @@ -161,23 +154,6 @@ vmbus_event_proc_compat(struct vmbus_sof } } -/** - * Send an event notification to the parent - */ -int -hv_vmbus_set_event(hv_vmbus_channel *channel) -{ - struct vmbus_softc *sc = channel->vmbus_sc; - int ret = 0; - uint32_t chanid = channel->offer_msg.child_rel_id; - - atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], - 1UL << (chanid & VMBUS_EVTFLAG_MASK)); - ret = hv_vmbus_signal_event(channel->signal_event_param); - - return (ret); -} - void vmbus_on_channel_open(const struct hv_vmbus_channel *chan) { Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:35:29 2016 (r307018) @@ -38,28 +38,7 @@ #include - -/* - * Status codes for hypervisor operations. - */ - -typedef uint16_t hv_vmbus_status; - -#define HV_MESSAGE_SIZE (256) -#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240) -#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30) -#define HV_ANY_VP (0xFFFFFFFF) - -/* - * MessageId: HV_STATUS_INSUFFICIENT_BUFFERS - * MessageText: - * You did not supply enough message buffers to send a message. - */ - -#define HV_STATUS_SUCCESS ((uint16_t)0) -#define HV_STATUS_INSUFFICIENT_BUFFERS ((uint16_t)0x0013) - -typedef void (*hv_vmbus_channel_callback)(void *context); +struct vmbus_softc; typedef struct { void* data; @@ -118,74 +97,6 @@ typedef struct hv_vmbus_channel_packet_m hv_vmbus_multipage_buffer range; } __packed hv_vmbus_channel_packet_multipage_buffer; -enum { - HV_VMBUS_MESSAGE_CONNECTION_ID = 1, - HV_VMBUS_MESSAGE_PORT_ID = 1, - HV_VMBUS_EVENT_CONNECTION_ID = 2, - HV_VMBUS_EVENT_PORT_ID = 2, - HV_VMBUS_MONITOR_CONNECTION_ID = 3, - HV_VMBUS_MONITOR_PORT_ID = 3, -}; - -#define HV_PRESENT_BIT 0x80000000 - -#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t) - -/* - * Define hypervisor message types - */ -typedef enum { - - HV_MESSAGE_TYPE_NONE = 0x00000000, - - /* - * Memory access messages - */ - HV_MESSAGE_TYPE_UNMAPPED_GPA = 0x80000000, - HV_MESSAGE_TYPE_GPA_INTERCEPT = 0x80000001, - - /* - * Timer notification messages - */ - HV_MESSAGE_TIMER_EXPIRED = 0x80000010, - - /* - * Error messages - */ - HV_MESSAGE_TYPE_INVALID_VP_REGISTER_VALUE = 0x80000020, - HV_MESSAGE_TYPE_UNRECOVERABLE_EXCEPTION = 0x80000021, - HV_MESSAGE_TYPE_UNSUPPORTED_FEATURE = 0x80000022, - - /* - * Trace buffer complete messages - */ - HV_MESSAGE_TYPE_EVENT_LOG_BUFFER_COMPLETE = 0x80000040, - - /* - * Platform-specific processor intercept messages - */ - HV_MESSAGE_TYPE_X64_IO_PORT_INTERCEPT = 0x80010000, - HV_MESSAGE_TYPE_X64_MSR_INTERCEPT = 0x80010001, - HV_MESSAGE_TYPE_X64_CPU_INTERCEPT = 0x80010002, - HV_MESSAGE_TYPE_X64_EXCEPTION_INTERCEPT = 0x80010003, - HV_MESSAGE_TYPE_X64_APIC_EOI = 0x80010004, - HV_MESSAGE_TYPE_X64_LEGACY_FP_ERROR = 0x80010005 - -} hv_vmbus_msg_type; - -/* - * Define port identifier type - */ -typedef union _hv_vmbus_port_id { - uint32_t as_uint32_t; - struct { - uint32_t id:24; - uint32_t reserved:8; - } u ; -} hv_vmbus_port_id; - -typedef uint64_t hv_vmbus_partition_id; - /* * VM Bus connection states */ @@ -196,19 +107,8 @@ typedef enum { HV_DISCONNECTING } hv_vmbus_connect_state; -#define HV_MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT - - typedef struct { hv_vmbus_connect_state connect_state; - uint32_t next_gpadl_handle; - - /** - * List of primary channels. Sub channels will be linked - * under their primary channel. - */ - TAILQ_HEAD(, hv_vmbus_channel) channel_anchor; - struct mtx channel_lock; /** * channel table for fast lookup through id. @@ -277,14 +177,6 @@ typedef struct { uint8_t rsvd_z4[1984]; } hv_vmbus_monitor_page; -/* - * Declare the various hypercall operations - */ -typedef enum { - HV_CALL_POST_MESSAGE = 0x005c, - HV_CALL_SIGNAL_EVENT = 0x005d, -} hv_vmbus_call_code; - /** * Global variables */ @@ -342,17 +234,14 @@ uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); -void hv_vmbus_release_unattached_channels(void); - -uint16_t hv_vmbus_signal_event(void *con_id); +void hv_vmbus_release_unattached_channels( + struct vmbus_softc *); struct hv_device* hv_vmbus_child_device_create( hv_guid device_type, hv_guid device_instance, hv_vmbus_channel *channel); -struct vmbus_softc; - void hv_vmbus_child_device_register(struct vmbus_softc *, struct hv_device *child_dev); int hv_vmbus_child_device_unregister( @@ -363,6 +252,5 @@ int hv_vmbus_child_device_unregister( */ int hv_vmbus_connect(struct vmbus_softc *); int hv_vmbus_disconnect(void); -int hv_vmbus_set_event(hv_vmbus_channel *channel); #endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 06:35:29 2016 (r307018) @@ -101,23 +101,6 @@ hyperv_get_timecount(struct timecounter return rdmsr(MSR_HV_TIME_REF_COUNT); } -/** - * @brief Invoke the specified hypercall - */ -static uint64_t -hv_vmbus_do_hypercall(uint64_t value, void *input, void *output) -{ - uint64_t in_paddr = 0, out_paddr = 0; - - if (input != NULL) - in_paddr = hv_get_phys_addr(input); - if (output != NULL) - out_paddr = hv_get_phys_addr(output); - - return hypercall_md(hypercall_context.hc_addr, value, - in_paddr, out_paddr); -} - uint64_t hypercall_post_message(bus_addr_t msg_paddr) { @@ -125,21 +108,11 @@ hypercall_post_message(bus_addr_t msg_pa HYPERCALL_POST_MESSAGE, msg_paddr, 0); } -/** - * @brief Signal an event on the specified connection using the hypervisor - * event IPC. (This involves a hypercall.) - */ -hv_vmbus_status -hv_vmbus_signal_event(void *con_id) -{ - hv_vmbus_status status; - - status = hv_vmbus_do_hypercall( - HV_CALL_SIGNAL_EVENT, - con_id, - 0) & 0xFFFF; - - return (status); +uint64_t +hypercall_signal_event(bus_addr_t sigevt_paddr) +{ + return hypercall_md(hypercall_context.hc_addr, + HYPERCALL_SIGNAL_EVENT, sigevt_paddr, 0); } int Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 06:35:29 2016 (r307018) @@ -148,6 +148,7 @@ * Hypercall input values */ #define HYPERCALL_POST_MESSAGE 0x005c +#define HYPERCALL_SIGNAL_EVENT 0x005d /* * Hypercall input parameters @@ -169,4 +170,15 @@ struct hypercall_postmsg_in { } __packed; CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); +/* + * HYPERCALL_SIGNAL_EVENT + */ +#define HYPERCALL_SIGEVTIN_ALIGN 8 + +struct hypercall_sigevt_in { + uint32_t hc_connid; + uint16_t hc_evtflag_ofs; + uint16_t hc_rsvd; +} __packed; + #endif /* !_HYPERV_REG_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 06:35:29 2016 (r307018) @@ -41,5 +41,6 @@ extern u_int hyperv_features; extern u_int hyperv_recommends; uint64_t hypercall_post_message(bus_addr_t msg_paddr); +uint64_t hypercall_signal_event(bus_addr_t sigevt_paddr); #endif /* !_HYPERV_VAR_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:19:06 2016 (r307017) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:35:29 2016 (r307018) @@ -68,12 +68,9 @@ __FBSDID("$FreeBSD$"); #include #include "acpi_if.h" +#include "vmbus_if.h" -/* - * NOTE: DO NOT CHANGE THESE - */ -#define VMBUS_CONNID_MESSAGE 1 -#define VMBUS_CONNID_EVENT 2 +#define VMBUS_GPADL_START 0xe1e10 struct vmbus_msghc { struct hypercall_postmsg_in *mh_inprm; @@ -96,10 +93,9 @@ struct vmbus_msghc_ctx { #define VMBUS_MSGHC_CTXF_DESTROY 0x0001 static int vmbus_init(struct vmbus_softc *); -static int vmbus_init_contact(struct vmbus_softc *, - uint32_t); +static int vmbus_connect(struct vmbus_softc *, uint32_t); static int vmbus_req_channels(struct vmbus_softc *sc); -static void vmbus_uninit(struct vmbus_softc *); +static void vmbus_disconnect(struct vmbus_softc *); static int vmbus_scan(struct vmbus_softc *); static void vmbus_scan_wait(struct vmbus_softc *); static void vmbus_scan_newdev(struct vmbus_softc *); @@ -120,10 +116,10 @@ struct vmbus_softc *vmbus_sc; extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr); static const uint32_t vmbus_version[] = { - HV_VMBUS_VERSION_WIN8_1, - HV_VMBUS_VERSION_WIN8, - HV_VMBUS_VERSION_WIN7, - HV_VMBUS_VERSION_WS2008 + VMBUS_VERSION_WIN8_1, + VMBUS_VERSION_WIN8, + VMBUS_VERSION_WIN7, + VMBUS_VERSION_WS2008 }; static struct vmbus_msghc * @@ -378,21 +374,26 @@ vmbus_msghc_wakeup(struct vmbus_softc *s wakeup(&mhc->mhc_active); } +uint32_t +vmbus_gpadl_alloc(struct vmbus_softc *sc) +{ + return atomic_fetchadd_int(&sc->vmbus_gpadl, 1); +} + static int *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Tue Oct 11 06:46:26 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 87E90C0CDD0; Tue, 11 Oct 2016 06:46:26 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5F7F6988; Tue, 11 Oct 2016 06:46:26 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B6kPnv091859; Tue, 11 Oct 2016 06:46:25 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B6kOVK091854; Tue, 11 Oct 2016 06:46:24 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110646.u9B6kOVK091854@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 06:46:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307019 - in stable/10/sys/dev/hyperv: include netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 06:46:26 -0000 Author: sephe Date: Tue Oct 11 06:46:24 2016 New Revision: 307019 URL: https://svnweb.freebsd.org/changeset/base/307019 Log: MFC 302632-302634 302632 hyperv/vmbus: More verbose for GPADL_connect/chan_{rescind,offer} Reviewed by: Dexuan Cui , Hongjiang Zhang Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6976 302633 hyperv/vmbus: Free sysctl properly upon channel close. Prepare for sub-channel re-open. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6977 302634 hyperv/vmbus: Fix sub-channel re-open support. For multi-channel devices, once the primary channel is closed, a set of 'rescind' messages for sub-channels will be delivered by Hypervisor. Sub-channel MUST be freed according to these 'rescind' messages; directly re-openning sub-channels in the same fashion as the primary channel's re-opening does NOT work at all. After the primary channel is re-opened, requested # of sub- channels will be delivered though 'channel offer' messages, and this set of newly offered channels can be opened along side with the primary channel. This unbreaks the MTU setting for hn(4), which requires re- openning all existsing channels upon MTU change. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6978 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:35:29 2016 (r307018) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 06:46:24 2016 (r307019) @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -627,6 +628,8 @@ typedef struct hv_vmbus_channel { struct task ch_detach_task; TAILQ_ENTRY(hv_vmbus_channel) ch_link; + + struct sysctl_ctx_list ch_sysctl_ctx; } hv_vmbus_channel; #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) @@ -714,6 +717,7 @@ void vmbus_channel_cpu_rr(struct hv_vmb struct hv_vmbus_channel ** vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt); void vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt); +void vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan); /** * @brief Get physical address from virtual Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:35:29 2016 (r307018) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 06:46:24 2016 (r307019) @@ -349,6 +349,7 @@ static void hn_destroy_rx_data(struct hn static void hn_set_tx_chimney_size(struct hn_softc *, int); static void hn_channel_attach(struct hn_softc *, struct hv_vmbus_channel *); static void hn_subchan_attach(struct hn_softc *, struct hv_vmbus_channel *); +static void hn_subchan_setup(struct hn_softc *); static int hn_transmit(struct ifnet *, struct mbuf *); static void hn_xmit_qflush(struct ifnet *); @@ -591,25 +592,8 @@ netvsc_attach(device_t dev) device_printf(dev, "%d TX ring, %d RX ring\n", sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); - if (sc->net_dev->num_channel > 1) { - struct hv_vmbus_channel **subchan; - int subchan_cnt = sc->net_dev->num_channel - 1; - int i; - - /* Wait for sub-channels setup to complete. */ - subchan = vmbus_get_subchan(pri_chan, subchan_cnt); - - /* Attach the sub-channels. */ - for (i = 0; i < subchan_cnt; ++i) { - /* NOTE: Calling order is critical. */ - hn_subchan_attach(sc, subchan[i]); - hv_nv_subchan_attach(subchan[i]); - } - - /* Release the sub-channels */ - vmbus_rel_subchan(subchan, subchan_cnt); - device_printf(dev, "%d sub-channels setup done\n", subchan_cnt); - } + if (sc->net_dev->num_channel > 1) + hn_subchan_setup(sc); #if __FreeBSD_version >= 1100099 if (sc->hn_rx_ring_inuse > 1) { @@ -1637,6 +1621,10 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, NV_UNLOCK(sc); break; } + + /* Wait for subchannels to be destroyed */ + vmbus_drain_subchan(hn_dev->channel); + error = hv_rf_on_device_add(hn_dev, &device_info, sc->hn_rx_ring_inuse); if (error) { @@ -1645,6 +1633,26 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, NV_UNLOCK(sc); break; } + KASSERT(sc->hn_rx_ring_cnt == sc->net_dev->num_channel, + ("RX ring count %d and channel count %u mismatch", + sc->hn_rx_ring_cnt, sc->net_dev->num_channel)); + if (sc->net_dev->num_channel > 1) { + int r; + + /* + * Skip the rings on primary channel; they are + * handled by the hv_rf_on_device_add() above. + */ + for (r = 1; r < sc->hn_rx_ring_cnt; ++r) { + sc->hn_rx_ring[r].hn_rx_flags &= + ~HN_RX_FLAG_ATTACHED; + } + for (r = 1; r < sc->hn_tx_ring_cnt; ++r) { + sc->hn_tx_ring[r].hn_tx_flags &= + ~HN_TX_FLAG_ATTACHED; + } + hn_subchan_setup(sc); + } sc->hn_tx_chimney_max = sc->net_dev->send_section_size; if (sc->hn_tx_ring[0].hn_tx_chimney_size > @@ -3036,6 +3044,29 @@ hn_subchan_attach(struct hn_softc *sc, s } static void +hn_subchan_setup(struct hn_softc *sc) +{ + struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev); + struct hv_vmbus_channel **subchan; + int subchan_cnt = sc->net_dev->num_channel - 1; + int i; + + /* Wait for sub-channels setup to complete. */ + subchan = vmbus_get_subchan(device_ctx->channel, subchan_cnt); + + /* Attach the sub-channels. */ + for (i = 0; i < subchan_cnt; ++i) { + /* NOTE: Calling order is critical. */ + hn_subchan_attach(sc, subchan[i]); + hv_nv_subchan_attach(subchan[i]); + } + + /* Release the sub-channels */ + vmbus_rel_subchan(subchan, subchan_cnt); + if_printf(sc->hn_ifp, "%d sub-channels setup done\n", subchan_cnt); +} + +static void hn_tx_taskq_create(void *arg __unused) { if (!hn_share_tx_taskq) Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:35:29 2016 (r307018) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:46:24 2016 (r307019) @@ -111,7 +111,8 @@ vmbus_channel_sysctl_create(hv_vmbus_cha ch_id = primary_ch->offer_msg.child_rel_id; sub_ch_id = channel->offer_msg.offer.sub_channel_index; } - ctx = device_get_sysctl_ctx(dev); + ctx = &channel->ch_sysctl_ctx; + sysctl_ctx_init(ctx); /* This creates dev.DEVNAME.DEVUNIT.channel tree */ devch_sysctl = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), @@ -423,6 +424,11 @@ hv_vmbus_channel_establish_gpadl(struct device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " "status %u\n", channel->offer_msg.child_rel_id, status); return EIO; + } else { + if (bootverbose) { + device_printf(sc->vmbus_dev, "gpadl->chan%u " + "succeeded\n", channel->offer_msg.child_rel_id); + } } return 0; } @@ -477,6 +483,7 @@ hv_vmbus_channel_close_internal(hv_vmbus int error; channel->state = HV_CHANNEL_OPEN_STATE; + sysctl_ctx_free(&channel->ch_sysctl_ctx); /* * set rxq to NULL to avoid more requests be scheduled Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:35:29 2016 (r307018) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:46:24 2016 (r307019) @@ -145,6 +145,19 @@ vmbus_channel_process_offer(hv_vmbus_cha } mtx_unlock(&sc->vmbus_chlist_lock); + if (bootverbose) { + char logstr[64]; + + logstr[0] = '\0'; + if (channel != NULL) { + snprintf(logstr, sizeof(logstr), ", primary chan%u", + channel->offer_msg.child_rel_id); + } + device_printf(sc->vmbus_dev, "chan%u subchanid%u offer%s\n", + new_channel->offer_msg.child_rel_id, + new_channel->offer_msg.offer.sub_channel_index, logstr); + } + if (channel != NULL) { /* * Check if this is a sub channel. @@ -160,13 +173,6 @@ vmbus_channel_process_offer(hv_vmbus_cha new_channel, sc_list_entry); mtx_unlock(&channel->sc_lock); - if (bootverbose) { - printf("VMBUS get multi-channel offer, " - "rel=%u, sub=%u\n", - new_channel->offer_msg.child_rel_id, - new_channel->offer_msg.offer.sub_channel_index); - } - /* * Insert the new channel to the end of the global * channel list. @@ -181,11 +187,6 @@ vmbus_channel_process_offer(hv_vmbus_cha ch_link); mtx_unlock(&sc->vmbus_chlist_lock); - if(bootverbose) - printf("VMBUS: new multi-channel offer <%p>, " - "its primary channel is <%p>.\n", - new_channel, new_channel->primary_channel); - new_channel->state = HV_CHANNEL_OPEN_STATE; /* @@ -348,6 +349,10 @@ vmbus_channel_on_offer_rescind(struct vm hv_vmbus_channel* channel; rescind = (const hv_vmbus_channel_rescind_offer *)msg->msg_data; + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u rescind\n", + rescind->child_rel_id); + } channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; if (channel == NULL) @@ -365,6 +370,54 @@ vmbus_chan_detach_task(void *xchan, int if (HV_VMBUS_CHAN_ISPRIMARY(chan)) { /* Only primary channel owns the hv_device */ hv_vmbus_child_device_unregister(chan->device); + /* NOTE: DO NOT free primary channel for now */ + } else { + struct vmbus_softc *sc = chan->vmbus_sc; + struct hv_vmbus_channel *pri_chan = chan->primary_channel; + struct vmbus_chanmsg_chfree *req; + struct vmbus_msghc *mh; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chfree(chan%u)\n", + chan->offer_msg.child_rel_id); + goto remove; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE; + req->chm_chanid = chan->offer_msg.child_rel_id; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, + "chfree(chan%u) failed: %d", + chan->offer_msg.child_rel_id, error); + /* NOTE: Move on! */ + } else { + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u freed\n", + chan->offer_msg.child_rel_id); + } + } +remove: + mtx_lock(&sc->vmbus_chlist_lock); + TAILQ_REMOVE(&sc->vmbus_chlist, chan, ch_link); + mtx_unlock(&sc->vmbus_chlist_lock); + + mtx_lock(&pri_chan->sc_lock); + TAILQ_REMOVE(&pri_chan->sc_list_anchor, chan, sc_list_entry); + KASSERT(pri_chan->subchan_cnt > 0, + ("invalid subchan_cnt %d", pri_chan->subchan_cnt)); + pri_chan->subchan_cnt--; + mtx_unlock(&pri_chan->sc_lock); + wakeup(pri_chan); + + hv_vmbus_free_vmbus_channel(chan); } } @@ -502,6 +555,15 @@ vmbus_rel_subchan(struct hv_vmbus_channe } void +vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan) +{ + mtx_lock(&pri_chan->sc_lock); + while (pri_chan->subchan_cnt > 0) + mtx_sleep(pri_chan, &pri_chan->sc_lock, 0, "dsubch", 0); + mtx_unlock(&pri_chan->sc_lock); +} + +void vmbus_chan_msgproc(struct vmbus_softc *sc, const struct vmbus_message *msg) { vmbus_chanmsg_proc_t msg_proc; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 06:35:29 2016 (r307018) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 06:46:24 2016 (r307019) @@ -102,6 +102,7 @@ struct vmbus_gpa_range { #define VMBUS_CHANMSG_TYPE_GPADL_CONNRESP 10 /* RESP */ #define VMBUS_CHANMSG_TYPE_GPADL_DISCONN 11 /* REQ */ #define VMBUS_CHANMSG_TYPE_GPADL_DISCONNRESP 12 /* RESP */ +#define VMBUS_CHANMSG_TYPE_CHFREE 13 /* REQ */ #define VMBUS_CHANMSG_TYPE_CONNECT 14 /* REQ */ #define VMBUS_CHANMSG_TYPE_CONNECT_RESP 15 /* RESP */ #define VMBUS_CHANMSG_TYPE_DISCONNECT 16 /* REQ */ @@ -206,4 +207,10 @@ struct vmbus_chanmsg_gpadl_disconn { uint32_t chm_gpadl; } __packed; +/* VMBUS_CHANMSG_TYPE_CHFREE */ +struct vmbus_chanmsg_chfree { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; +} __packed; + #endif /* !_VMBUS_REG_H_ */ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:00:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 15CE6C0D233; Tue, 11 Oct 2016 07:00:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E6C3161; Tue, 11 Oct 2016 07:00:44 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B70iK6096529; Tue, 11 Oct 2016 07:00:44 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B70hZl096520; Tue, 11 Oct 2016 07:00:43 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110700.u9B70hZl096520@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:00:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307020 - in stable/10/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:00:45 -0000 Author: sephe Date: Tue Oct 11 07:00:43 2016 New Revision: 307020 URL: https://svnweb.freebsd.org/changeset/base/307020 Log: MFC 302636-302638,302692 302636 hyperv/vmbus: Move channel map to vmbus_softc Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6982 302637 hyperv/vmbus: Remove needed bits Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7002 302638 hyperv/vmbus: Destroy channel list lock upon attach failure and detach. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7003 302692 hyperv/vmbus: Merge hv_connection.c into hv_channel.c Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7004 Deleted: stable/10/sys/dev/hyperv/vmbus/hv_connection.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/conf/files.amd64 Tue Oct 11 07:00:43 2016 (r307020) @@ -273,7 +273,6 @@ dev/hyperv/utilities/hv_timesync.c opt dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv -dev/hyperv/vmbus/hv_connection.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/conf/files.i386 Tue Oct 11 07:00:43 2016 (r307020) @@ -250,7 +250,6 @@ dev/hyperv/utilities/hv_timesync.c opt dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv -dev/hyperv/vmbus/hv_connection.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:00:43 2016 (r307020) @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); static void vmbus_channel_set_event(hv_vmbus_channel* channel); static void VmbusProcessChannelEvent(void* channel, int pending); +static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, + const struct hv_vmbus_channel *); /** * @brief Trigger an event notification on the specified channel @@ -207,7 +209,7 @@ hv_vmbus_channel_open( new_channel->on_channel_callback = pfn_on_channel_callback; new_channel->channel_callback_context = context; - vmbus_on_channel_open(new_channel); + vmbus_chan_update_evtflagcnt(sc, new_channel); new_channel->rxq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, new_channel->target_cpu); @@ -883,3 +885,95 @@ VmbusProcessChannelEvent(void* context, } while (is_batched_reading && (bytes_to_read != 0)); } } + +static __inline void +vmbus_event_flags_proc(struct vmbus_softc *sc, volatile u_long *event_flags, + int flag_cnt) +{ + int f; + + for (f = 0; f < flag_cnt; ++f) { + uint32_t rel_id_base; + u_long flags; + int bit; + + if (event_flags[f] == 0) + continue; + + flags = atomic_swap_long(&event_flags[f], 0); + rel_id_base = f << VMBUS_EVTFLAG_SHIFT; + + while ((bit = ffsl(flags)) != 0) { + struct hv_vmbus_channel *channel; + uint32_t rel_id; + + --bit; /* NOTE: ffsl is 1-based */ + flags &= ~(1UL << bit); + + rel_id = rel_id_base + bit; + channel = sc->vmbus_chmap[rel_id]; + + /* if channel is closed or closing */ + if (channel == NULL || channel->rxq == NULL) + continue; + + if (channel->batched_reading) + hv_ring_buffer_read_begin(&channel->inbound); + taskqueue_enqueue(channel->rxq, &channel->channel_task); + } + } +} + +void +vmbus_event_proc(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + /* + * On Host with Win8 or above, the event page can be checked directly + * to get the id of the channel that has the pending interrupt. + */ + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + vmbus_event_flags_proc(sc, eventf->evt_flags, + VMBUS_PCPU_GET(sc, event_flags_cnt, cpu)); +} + +void +vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) { + vmbus_event_flags_proc(sc, sc->vmbus_rx_evtflags, + VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT); + } +} + +static void +vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc, + const struct hv_vmbus_channel *chan) +{ + volatile int *flag_cnt_ptr; + int flag_cnt; + + flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1; + flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->target_cpu); + + for (;;) { + int old_flag_cnt; + + old_flag_cnt = *flag_cnt_ptr; + if (old_flag_cnt >= flag_cnt) + break; + if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) { + if (bootverbose) { + device_printf(sc->vmbus_dev, + "channel%u update cpu%d flag_cnt to %d\n", + chan->offer_msg.child_rel_id, + chan->target_cpu, flag_cnt); + } + break; + } + } +} Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:00:43 2016 (r307020) @@ -126,7 +126,7 @@ vmbus_channel_process_offer(hv_vmbus_cha */ printf("VMBUS: got channel0 offer\n"); } else { - hv_vmbus_g_connection.channels[relid] = new_channel; + sc->vmbus_chmap[relid] = new_channel; } TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { @@ -354,10 +354,10 @@ vmbus_channel_on_offer_rescind(struct vm rescind->child_rel_id); } - channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; + channel = sc->vmbus_chmap[rescind->child_rel_id]; if (channel == NULL) return; - hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; + sc->vmbus_chmap[rescind->child_rel_id] = NULL; taskqueue_enqueue(taskqueue_thread, &channel->ch_detach_task); } @@ -454,8 +454,8 @@ hv_vmbus_release_unattached_channels(str } hv_vmbus_free_vmbus_channel(channel); } - bzero(hv_vmbus_g_connection.channels, - sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX); + bzero(sc->vmbus_chmap, + sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX); mtx_unlock(&sc->vmbus_chlist_lock); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 07:00:43 2016 (r307020) @@ -97,25 +97,6 @@ typedef struct hv_vmbus_channel_packet_m hv_vmbus_multipage_buffer range; } __packed hv_vmbus_channel_packet_multipage_buffer; -/* - * VM Bus connection states - */ -typedef enum { - HV_DISCONNECTED, - HV_CONNECTING, - HV_CONNECTED, - HV_DISCONNECTING -} hv_vmbus_connect_state; - -typedef struct { - hv_vmbus_connect_state connect_state; - - /** - * channel table for fast lookup through id. - */ - hv_vmbus_channel **channels; -} hv_vmbus_connection; - typedef union { uint32_t as_uint32_t; struct { @@ -177,12 +158,6 @@ typedef struct { uint8_t rsvd_z4[1984]; } hv_vmbus_monitor_page; -/** - * Global variables - */ - -extern hv_vmbus_connection hv_vmbus_g_connection; - /* * Private, VM Bus functions */ @@ -247,10 +222,4 @@ void hv_vmbus_child_device_register(st int hv_vmbus_child_device_unregister( struct hv_device *child_dev); -/** - * Connection interfaces - */ -int hv_vmbus_connect(struct vmbus_softc *); -int hv_vmbus_disconnect(void); - #endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:00:43 2016 (r307020) @@ -1212,6 +1212,9 @@ vmbus_doattach(struct vmbus_softc *sc) sc->vmbus_gpadl = VMBUS_GPADL_START; mtx_init(&sc->vmbus_chlist_lock, "vmbus chlist", NULL, MTX_DEF); TAILQ_INIT(&sc->vmbus_chlist); + sc->vmbus_chmap = malloc( + sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF, + M_WAITOK | M_ZERO); /* * Create context for "post message" Hypercalls @@ -1246,12 +1249,8 @@ vmbus_doattach(struct vmbus_softc *sc) sc->vmbus_flags |= VMBUS_FLAG_SYNIC; /* - * Connect to VMBus in the root partition + * Initialize vmbus, e.g. connect to Hypervisor. */ - ret = hv_vmbus_connect(sc); - if (ret != 0) - goto cleanup; - ret = vmbus_init(sc); if (ret != 0) goto cleanup; @@ -1281,7 +1280,9 @@ cleanup: vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc); sc->vmbus_msg_hc = NULL; } + free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); + mtx_destroy(&sc->vmbus_chlist_lock); return (ret); } @@ -1342,7 +1343,6 @@ vmbus_detach(device_t dev) hv_vmbus_release_unattached_channels(sc); vmbus_disconnect(sc); - hv_vmbus_disconnect(); if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) { sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC; @@ -1357,7 +1357,10 @@ vmbus_detach(device_t dev) sc->vmbus_msg_hc = NULL; } + free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); + mtx_destroy(&sc->vmbus_chlist_lock); + return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 07:00:43 2016 (r307020) @@ -74,6 +74,7 @@ struct vmbus_softc { u_long *vmbus_rx_evtflags; /* compat evtflgs from host */ + struct hv_vmbus_channel **vmbus_chmap; struct vmbus_msghc_ctx *vmbus_msg_hc; struct vmbus_pcpu_data vmbus_pcpu[MAXCPU]; @@ -129,7 +130,6 @@ struct trapframe; struct vmbus_message; struct vmbus_msghc; -void vmbus_on_channel_open(const struct hv_vmbus_channel *); void vmbus_event_proc(struct vmbus_softc *, int); void vmbus_event_proc_compat(struct vmbus_softc *, int); void vmbus_handle_intr(struct trapframe *); Modified: stable/10/sys/modules/hyperv/vmbus/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 06:46:24 2016 (r307019) +++ stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 07:00:43 2016 (r307020) @@ -6,7 +6,6 @@ KMOD= hv_vmbus SRCS= hv_channel.c \ hv_channel_mgmt.c \ - hv_connection.c \ hv_ring_buffer.c \ hyperv.c \ hyperv_busdma.c \ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:10:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EC085C0D525; Tue, 11 Oct 2016 07:10:13 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B543F74F; Tue, 11 Oct 2016 07:10:13 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B7ACdu099600; Tue, 11 Oct 2016 07:10:12 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B7ACqT099594; Tue, 11 Oct 2016 07:10:12 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110710.u9B7ACqT099594@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:10:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307021 - in stable/10/sys/dev/hyperv: include netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:10:14 -0000 Author: sephe Date: Tue Oct 11 07:10:12 2016 New Revision: 307021 URL: https://svnweb.freebsd.org/changeset/base/307021 Log: MFC 302693-302697 302693 hyperv/vmbus: Make channel id a field of hv_vmbus_channel. This prepares to remove the unnecessary offer message embedding in hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7014 302694 hyperv/vmbus: Make subchan index a field of hv_vmbus_channel. This prepares to remove the unnecessary offer message embedding in hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7015 302695 hyperv/vmbus: Add flags field into hv_vmbus_channel for MNF indication This prepares to remove the unnecessary offer message embedding in hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7019 302696 hyperv/vmbus: Add type/instance guid fields into hv_vmbus_channel This prepares to remove the unnecessary offer message embedding in hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7020 302697 hyperv/vmbus: Remove the embedded offer message from hv_vmbus_channel Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7021 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:10:12 2016 (r307021) @@ -537,7 +537,8 @@ typedef struct hv_vmbus_channel { struct hv_device* device; struct vmbus_softc *vmbus_sc; hv_vmbus_channel_state state; - hv_vmbus_channel_offer_channel offer_msg; + uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ + uint32_t ch_id; /* channel id */ /* * These are based on the offer_msg.monitor_id. * Save it here for easy access. @@ -628,12 +629,18 @@ typedef struct hv_vmbus_channel { struct task ch_detach_task; TAILQ_ENTRY(hv_vmbus_channel) ch_link; + uint32_t ch_subidx; /* subchan index */ + + struct hv_guid ch_guid_type; + struct hv_guid ch_guid_inst; struct sysctl_ctx_list ch_sysctl_ctx; } hv_vmbus_channel; #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) +#define VMBUS_CHAN_FLAG_HASMNF 0x0001 + static inline void hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state) { Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 07:10:12 2016 (r307021) @@ -534,9 +534,9 @@ netvsc_attach(device_t dev) */ pri_chan = device_ctx->channel; KASSERT(HV_VMBUS_CHAN_ISPRIMARY(pri_chan), ("not primary channel")); - KASSERT(pri_chan->offer_msg.offer.sub_channel_index == 0, + KASSERT(pri_chan->ch_subidx == 0, ("primary channel subidx %u", - pri_chan->offer_msg.offer.sub_channel_index)); + pri_chan->ch_subidx)); hn_channel_attach(sc, pri_chan); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -821,8 +821,8 @@ hn_tx_done(struct hv_vmbus_channel *chan txr = txd->txr; KASSERT(txr->hn_chan == chan, ("channel mismatch, on channel%u, should be channel%u", - chan->offer_msg.offer.sub_channel_index, - txr->hn_chan->offer_msg.offer.sub_channel_index)); + chan->ch_subidx, + txr->hn_chan->ch_subidx)); txr->hn_has_txeof = 1; hn_txdesc_put(txr, txd); @@ -2996,7 +2996,7 @@ hn_channel_attach(struct hn_softc *sc, s struct hn_rx_ring *rxr; int idx; - idx = chan->offer_msg.offer.sub_channel_index; + idx = chan->ch_subidx; KASSERT(idx >= 0 && idx < sc->hn_rx_ring_inuse, ("invalid channel index %d, should > 0 && < %d", @@ -3009,7 +3009,7 @@ hn_channel_attach(struct hn_softc *sc, s chan->hv_chan_rxr = rxr; if (bootverbose) { if_printf(sc->hn_ifp, "link RX ring %d to channel%u\n", - idx, chan->offer_msg.child_rel_id); + idx, chan->ch_id); } if (idx < sc->hn_tx_ring_inuse) { @@ -3023,7 +3023,7 @@ hn_channel_attach(struct hn_softc *sc, s txr->hn_chan = chan; if (bootverbose) { if_printf(sc->hn_ifp, "link TX ring %d to channel%u\n", - idx, chan->offer_msg.child_rel_id); + idx, chan->ch_id); } } @@ -3037,9 +3037,9 @@ hn_subchan_attach(struct hn_softc *sc, s KASSERT(!HV_VMBUS_CHAN_ISPRIMARY(chan), ("subchannel callback on primary channel")); - KASSERT(chan->offer_msg.offer.sub_channel_index > 0, + KASSERT(chan->ch_subidx > 0, ("invalid channel subidx %u", - chan->offer_msg.offer.sub_channel_index)); + chan->ch_subidx)); hn_channel_attach(sc, chan); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:10:12 2016 (r307021) @@ -62,12 +62,12 @@ static void vmbus_channel_set_event(hv_vmbus_channel *channel) { struct vmbus_softc *sc = channel->vmbus_sc; - uint32_t chanid = channel->offer_msg.child_rel_id; + uint32_t chanid = channel->ch_id; atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], 1UL << (chanid & VMBUS_EVTFLAG_MASK)); - if (channel->offer_msg.monitor_allocated) { + if (channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { hv_vmbus_monitor_page *monitor_page; monitor_page = sc->vmbus_mnf2; @@ -86,7 +86,7 @@ vmbus_channel_sysctl_monalloc(SYSCTL_HAN struct hv_vmbus_channel *chan = arg1; int alloc = 0; - if (chan->offer_msg.monitor_allocated) + if (chan->ch_flags & VMBUS_CHAN_FLAG_HASMNF) alloc = 1; return sysctl_handle_int(oidp, &alloc, 0, req); } @@ -107,11 +107,11 @@ vmbus_channel_sysctl_create(hv_vmbus_cha if (primary_ch == NULL) { dev = channel->device->device; - ch_id = channel->offer_msg.child_rel_id; + ch_id = channel->ch_id; } else { dev = primary_ch->device->device; - ch_id = primary_ch->offer_msg.child_rel_id; - sub_ch_id = channel->offer_msg.offer.sub_channel_index; + ch_id = primary_ch->ch_id; + sub_ch_id = channel->ch_subidx; } ctx = &channel->ch_sysctl_ctx; sysctl_ctx_init(ctx); @@ -136,7 +136,7 @@ vmbus_channel_sysctl_create(hv_vmbus_cha SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, "chanid", CTLFLAG_RD, - &channel->offer_msg.child_rel_id, 0, "channel id"); + &channel->ch_id, 0, "channel id"); } SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, "cpu", CTLFLAG_RD, &channel->target_cpu, 0, "owner CPU id"); @@ -190,7 +190,7 @@ hv_vmbus_channel_open( if (user_data_len > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { device_printf(sc->vmbus_dev, "invalid udata len %u for chan%u\n", - user_data_len, new_channel->offer_msg.child_rel_id); + user_data_len, new_channel->ch_id); return EINVAL; } @@ -261,14 +261,14 @@ hv_vmbus_channel_open( if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for chopen(chan%u)\n", - new_channel->offer_msg.child_rel_id); + new_channel->ch_id); return ENXIO; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; - req->chm_chanid = new_channel->offer_msg.child_rel_id; - req->chm_openid = new_channel->offer_msg.child_rel_id; + req->chm_chanid = new_channel->ch_id; + req->chm_openid = new_channel->ch_id; req->chm_gpadl = new_channel->ring_buffer_gpadl_handle; req->chm_vcpuid = new_channel->target_vcpu; req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; @@ -279,7 +279,7 @@ hv_vmbus_channel_open( if (ret != 0) { device_printf(sc->vmbus_dev, "chopen(chan%u) msg hypercall exec failed: %d\n", - new_channel->offer_msg.child_rel_id, ret); + new_channel->ch_id, ret); vmbus_msghc_put(sc, mh); return ret; } @@ -294,11 +294,11 @@ hv_vmbus_channel_open( new_channel->state = HV_CHANNEL_OPENED_STATE; if (bootverbose) { device_printf(sc->vmbus_dev, "chan%u opened\n", - new_channel->offer_msg.child_rel_id); + new_channel->ch_id); } } else { device_printf(sc->vmbus_dev, "failed to open chan%u\n", - new_channel->offer_msg.child_rel_id); + new_channel->ch_id); ret = ENXIO; } return (ret); @@ -369,13 +369,13 @@ hv_vmbus_channel_establish_gpadl(struct if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for gpadl->chan%u\n", - channel->offer_msg.child_rel_id); + channel->ch_id); return EIO; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_CONN; - req->chm_chanid = channel->offer_msg.child_rel_id; + req->chm_chanid = channel->ch_id; req->chm_gpadl = gpadl; req->chm_range_len = range_len; req->chm_range_cnt = 1; @@ -388,7 +388,7 @@ hv_vmbus_channel_establish_gpadl(struct if (error) { device_printf(sc->vmbus_dev, "gpadl->chan%u msg hypercall exec failed: %d\n", - channel->offer_msg.child_rel_id, error); + channel->ch_id, error); vmbus_msghc_put(sc, mh); return error; } @@ -424,12 +424,12 @@ hv_vmbus_channel_establish_gpadl(struct if (status != 0) { device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " - "status %u\n", channel->offer_msg.child_rel_id, status); + "status %u\n", channel->ch_id, status); return EIO; } else { if (bootverbose) { device_printf(sc->vmbus_dev, "gpadl->chan%u " - "succeeded\n", channel->offer_msg.child_rel_id); + "succeeded\n", channel->ch_id); } } return 0; @@ -450,20 +450,20 @@ hv_vmbus_channel_teardown_gpdal(struct h if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for gpa x->chan%u\n", - chan->offer_msg.child_rel_id); + chan->ch_id); return EBUSY; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_DISCONN; - req->chm_chanid = chan->offer_msg.child_rel_id; + req->chm_chanid = chan->ch_id; req->chm_gpadl = gpadl; error = vmbus_msghc_exec(sc, mh); if (error) { device_printf(sc->vmbus_dev, "gpa x->chan%u msg hypercall exec failed: %d\n", - chan->offer_msg.child_rel_id, error); + chan->ch_id, error); vmbus_msghc_put(sc, mh); return error; } @@ -502,13 +502,13 @@ hv_vmbus_channel_close_internal(hv_vmbus if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for chclose(chan%u)\n", - channel->offer_msg.child_rel_id); + channel->ch_id); return; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHCLOSE; - req->chm_chanid = channel->offer_msg.child_rel_id; + req->chm_chanid = channel->ch_id; error = vmbus_msghc_exec_noresult(mh); vmbus_msghc_put(sc, mh); @@ -516,11 +516,11 @@ hv_vmbus_channel_close_internal(hv_vmbus if (error) { device_printf(sc->vmbus_dev, "chclose(chan%u) msg hypercall exec failed: %d\n", - channel->offer_msg.child_rel_id, error); + channel->ch_id, error); return; } else if (bootverbose) { device_printf(sc->vmbus_dev, "close chan%u\n", - channel->offer_msg.child_rel_id); + channel->ch_id); } /* Tear down the gpadl for the channel's ring buffer */ @@ -957,7 +957,7 @@ vmbus_chan_update_evtflagcnt(struct vmbu volatile int *flag_cnt_ptr; int flag_cnt; - flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1; + flag_cnt = (chan->ch_id / VMBUS_EVTFLAG_LEN) + 1; flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->target_cpu); for (;;) { @@ -970,7 +970,7 @@ vmbus_chan_update_evtflagcnt(struct vmbu if (bootverbose) { device_printf(sc->vmbus_dev, "channel%u update cpu%d flag_cnt to %d\n", - chan->offer_msg.child_rel_id, + chan->ch_id, chan->target_cpu, flag_cnt); } break; Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:10:12 2016 (r307021) @@ -115,7 +115,7 @@ vmbus_channel_process_offer(hv_vmbus_cha hv_vmbus_channel* channel; uint32_t relid; - relid = new_channel->offer_msg.child_rel_id; + relid = new_channel->ch_id; /* * Make sure this is a new offer */ @@ -130,11 +130,9 @@ vmbus_channel_process_offer(hv_vmbus_cha } TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { - if (memcmp(&channel->offer_msg.offer.interface_type, - &new_channel->offer_msg.offer.interface_type, + if (memcmp(&channel->ch_guid_type, &new_channel->ch_guid_type, sizeof(hv_guid)) == 0 && - memcmp(&channel->offer_msg.offer.interface_instance, - &new_channel->offer_msg.offer.interface_instance, + memcmp(&channel->ch_guid_inst, &new_channel->ch_guid_inst, sizeof(hv_guid)) == 0) break; } @@ -151,18 +149,18 @@ vmbus_channel_process_offer(hv_vmbus_cha logstr[0] = '\0'; if (channel != NULL) { snprintf(logstr, sizeof(logstr), ", primary chan%u", - channel->offer_msg.child_rel_id); + channel->ch_id); } device_printf(sc->vmbus_dev, "chan%u subchanid%u offer%s\n", - new_channel->offer_msg.child_rel_id, - new_channel->offer_msg.offer.sub_channel_index, logstr); + new_channel->ch_id, + new_channel->ch_subidx, logstr); } if (channel != NULL) { /* * Check if this is a sub channel. */ - if (new_channel->offer_msg.offer.sub_channel_index != 0) { + if (new_channel->ch_subidx != 0) { /* * It is a sub channel offer, process it. */ @@ -203,7 +201,7 @@ vmbus_channel_process_offer(hv_vmbus_cha } printf("VMBUS: duplicated primary channel%u\n", - new_channel->offer_msg.child_rel_id); + new_channel->ch_id); hv_vmbus_free_vmbus_channel(new_channel); return; } @@ -215,9 +213,7 @@ vmbus_channel_process_offer(hv_vmbus_cha * (We need to set the device field before calling * hv_vmbus_child_device_add()) */ - new_channel->device = hv_vmbus_child_device_create( - new_channel->offer_msg.offer.interface_type, - new_channel->offer_msg.offer.interface_instance, new_channel); + new_channel->device = hv_vmbus_child_device_create(new_channel); /* * Add the new device to the bus. This will kick off device-driver @@ -244,7 +240,7 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch if (bootverbose) { printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", - chan->offer_msg.child_rel_id, + chan->ch_id, chan->target_cpu, chan->target_vcpu); } } @@ -295,6 +291,12 @@ vmbus_channel_on_offer_internal(struct v /* Allocate the channel object and save this offer */ new_channel = hv_vmbus_allocate_channel(sc); + new_channel->ch_id = offer->child_rel_id; + new_channel->ch_subidx = offer->offer.sub_channel_index; + if (offer->monitor_allocated) + new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; + new_channel->ch_guid_type = offer->offer.interface_type; + new_channel->ch_guid_inst = offer->offer.interface_instance; /* * By default we setup state to enable batched @@ -322,8 +324,6 @@ vmbus_channel_on_offer_internal(struct v new_channel->ch_sigevt->hc_connid = offer->connection_id; } - memcpy(&new_channel->offer_msg, offer, - sizeof(hv_vmbus_channel_offer_channel)); new_channel->monitor_group = (uint8_t) offer->monitor_id / 32; new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32; @@ -382,13 +382,13 @@ vmbus_chan_detach_task(void *xchan, int if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for chfree(chan%u)\n", - chan->offer_msg.child_rel_id); + chan->ch_id); goto remove; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE; - req->chm_chanid = chan->offer_msg.child_rel_id; + req->chm_chanid = chan->ch_id; error = vmbus_msghc_exec_noresult(mh); vmbus_msghc_put(sc, mh); @@ -396,12 +396,12 @@ vmbus_chan_detach_task(void *xchan, int if (error) { device_printf(sc->vmbus_dev, "chfree(chan%u) failed: %d", - chan->offer_msg.child_rel_id, error); + chan->ch_id, error); /* NOTE: Move on! */ } else { if (bootverbose) { device_printf(sc->vmbus_dev, "chan%u freed\n", - chan->offer_msg.child_rel_id); + chan->ch_id); } } remove: Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 07:10:12 2016 (r307021) @@ -213,9 +213,7 @@ void hv_vmbus_release_unattached_chann struct vmbus_softc *); struct hv_device* hv_vmbus_child_device_create( - hv_guid device_type, - hv_guid device_instance, - hv_vmbus_channel *channel); + struct hv_vmbus_channel *channel); void hv_vmbus_child_device_register(struct vmbus_softc *, struct hv_device *child_dev); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:00:43 2016 (r307020) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:10:12 2016 (r307021) @@ -1097,8 +1097,7 @@ vmbus_child_pnpinfo_str(device_t dev, de } struct hv_device * -hv_vmbus_child_device_create(hv_guid type, hv_guid instance, - hv_vmbus_channel *channel) +hv_vmbus_child_device_create(struct hv_vmbus_channel *channel) { hv_device *child_dev; @@ -1108,8 +1107,8 @@ hv_vmbus_child_device_create(hv_guid typ child_dev = malloc(sizeof(hv_device), M_DEVBUF, M_WAITOK | M_ZERO); child_dev->channel = channel; - memcpy(&child_dev->class_id, &type, sizeof(hv_guid)); - memcpy(&child_dev->device_id, &instance, sizeof(hv_guid)); + child_dev->class_id = channel->ch_guid_type; + child_dev->device_id = channel->ch_guid_inst; return (child_dev); } From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:31:01 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1CDF6C0DBFD; Tue, 11 Oct 2016 07:31:01 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A989E1B2; Tue, 11 Oct 2016 07:31:00 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B7Uxxi009580; Tue, 11 Oct 2016 07:30:59 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B7Uxon009572; Tue, 11 Oct 2016 07:30:59 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110730.u9B7Uxon009572@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:30:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307022 - in stable/10/sys: dev/hyperv/include dev/hyperv/netvsc dev/hyperv/storvsc dev/hyperv/utilities dev/hyperv/vmbus modules/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:31:01 -0000 Author: sephe Date: Tue Oct 11 07:30:59 2016 New Revision: 307022 URL: https://svnweb.freebsd.org/changeset/base/307022 Log: MFC 302698-302704,302706 302698 hyperv/vmbus: Add vmbus method for GUID base device probing. Reduce the exposure of hv_device. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7024 302699 hyperv/vmbus: All ivars are read-only; nuke unnecessary write_ivar Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7025 302700 hyperv/vmbus: Add channel ivar accessor. This makes life easier during the transition period to nuke the hv_device. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7026 302701 hyperv/stor: Avoid the hv_device and nuke the broken get_stor_device This paves way to nuke the hv_device, which is actually an unncessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7027 302702 hyperv/util: Avoid the hv_device This paves way to nuke the hv_device, which is actually an unncessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7028 302703 hyperv/vmbus: Deprecate the usage of hv_device. This paves way to nuke the hv_device, which is actually an unncessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7032 302704 hyperv/hn: Avoid the hv_device This paves way to nuke the hv_device, which is actually an unncessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7033 302706 hyperv: Get rid of hv_device, which is unnecessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7034 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_if.m stable/10/sys/modules/hyperv/utilities/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:30:59 2016 (r307022) @@ -399,20 +399,6 @@ typedef struct { #define HW_MACADDR_LEN 6 -enum { - HV_VMBUS_IVAR_TYPE, - HV_VMBUS_IVAR_INSTANCE, - HV_VMBUS_IVAR_NODE, - HV_VMBUS_IVAR_DEVCTX -}; - -#define HV_VMBUS_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(vmbus, var, HV_VMBUS, ivar, type) - -HV_VMBUS_ACCESSOR(type, TYPE, const char *) -HV_VMBUS_ACCESSOR(devctx, DEVCTX, struct hv_device *) - - /* * Common defines for Hyper-V ICs */ @@ -534,7 +520,7 @@ typedef union { } __packed hv_vmbus_connection_id; typedef struct hv_vmbus_channel { - struct hv_device* device; + device_t ch_dev; struct vmbus_softc *vmbus_sc; hv_vmbus_channel_state state; uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ @@ -647,15 +633,6 @@ hv_set_channel_read_state(hv_vmbus_chann channel->batched_reading = state; } -typedef struct hv_device { - hv_guid class_id; - hv_guid device_id; - device_t device; - hv_vmbus_channel* channel; -} hv_device; - - - int hv_vmbus_channel_recv_packet( hv_vmbus_channel* channel, void* buffer, @@ -737,4 +714,10 @@ hv_get_phys_addr(void *virt) return (ret); } +static __inline struct hv_vmbus_channel * +vmbus_get_channel(device_t dev) +{ + return device_get_ivars(dev); +} + #endif /* __HYPERV_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 07:30:59 2016 (r307022) @@ -57,31 +57,30 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper * Forward declarations */ static void hv_nv_on_channel_callback(void *xchan); -static int hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device); -static int hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device); +static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); +static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev); static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); -static int hv_nv_connect_to_vsp(struct hv_device *device); +static int hv_nv_connect_to_vsp(struct hn_softc *sc); static void hv_nv_on_send_completion(netvsc_dev *net_dev, - struct hv_device *device, struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt); + struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt); static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, uint64_t tid, uint32_t status); static void hv_nv_on_receive(netvsc_dev *net_dev, - struct hv_device *device, struct hv_vmbus_channel *chan, + struct hn_softc *sc, struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt); /* * */ static inline netvsc_dev * -hv_nv_alloc_net_device(struct hv_device *device) +hv_nv_alloc_net_device(struct hn_softc *sc) { netvsc_dev *net_dev; - hn_softc_t *sc = device_get_softc(device->device); net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO); - net_dev->dev = device; + net_dev->sc = sc; net_dev->destroy = FALSE; sc->net_dev = net_dev; @@ -89,43 +88,21 @@ hv_nv_alloc_net_device(struct hv_device } /* - * + * XXX unnecessary; nuke it. */ static inline netvsc_dev * -hv_nv_get_outbound_net_device(struct hv_device *device) +hv_nv_get_outbound_net_device(struct hn_softc *sc) { - hn_softc_t *sc = device_get_softc(device->device); - netvsc_dev *net_dev = sc->net_dev;; - - if ((net_dev != NULL) && net_dev->destroy) { - return (NULL); - } - - return (net_dev); + return sc->net_dev; } /* - * + * XXX unnecessary; nuke it. */ static inline netvsc_dev * -hv_nv_get_inbound_net_device(struct hv_device *device) +hv_nv_get_inbound_net_device(struct hn_softc *sc) { - hn_softc_t *sc = device_get_softc(device->device); - netvsc_dev *net_dev = sc->net_dev;; - - if (net_dev == NULL) { - return (net_dev); - } - /* - * When the device is being destroyed; we only - * permit incoming packets if and only if there - * are outstanding sends. - */ - if (net_dev->destroy) { - return (NULL); - } - - return (net_dev); + return sc->net_dev; } int @@ -163,13 +140,13 @@ hv_nv_get_next_send_section(netvsc_dev * * Hyper-V extensible switch and the synthetic data path. */ static int -hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device) +hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) { netvsc_dev *net_dev; nvsp_msg *init_pkt; int ret = 0; - net_dev = hv_nv_get_outbound_net_device(device); + net_dev = hv_nv_get_outbound_net_device(sc); if (!net_dev) { return (ENODEV); } @@ -184,7 +161,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct * GPADL: Guest physical address descriptor list. */ ret = hv_vmbus_channel_establish_gpadl( - device->channel, net_dev->rx_buf, + sc->hn_prichan, net_dev->rx_buf, net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle); if (ret != 0) { goto cleanup; @@ -205,7 +182,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct /* Send the gpadl notification request */ - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -255,13 +232,13 @@ exit: * Net VSC initialize send buffer with net VSP */ static int -hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device) +hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) { netvsc_dev *net_dev; nvsp_msg *init_pkt; int ret = 0; - net_dev = hv_nv_get_outbound_net_device(device); + net_dev = hv_nv_get_outbound_net_device(sc); if (!net_dev) { return (ENODEV); } @@ -278,7 +255,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru * Note: This call uses the vmbus connection rather than the * channel to establish the gpadl handle. */ - ret = hv_vmbus_channel_establish_gpadl(device->channel, + ret = hv_vmbus_channel_establish_gpadl(sc->hn_prichan, net_dev->send_buf, net_dev->send_buf_size, &net_dev->send_buf_gpadl_handle); if (ret != 0) { @@ -299,7 +276,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru /* Send the gpadl notification request */ - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -359,7 +336,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id = NETVSC_RECEIVE_BUFFER_ID; - ret = hv_vmbus_channel_send_packet(net_dev->dev->channel, + ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, revoke_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)revoke_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); @@ -375,7 +352,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ /* Tear down the gpadl on the vsp end */ if (net_dev->rx_buf_gpadl_handle) { - ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel, + ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan, net_dev->rx_buf_gpadl_handle); /* * If we failed here, we might as well return and have a leak @@ -427,7 +404,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id = NETVSC_SEND_BUFFER_ID; - ret = hv_vmbus_channel_send_packet(net_dev->dev->channel, + ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, revoke_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)revoke_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); @@ -442,7 +419,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne /* Tear down the gpadl on the vsp end */ if (net_dev->send_buf_gpadl_handle) { - ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel, + ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan, net_dev->send_buf_gpadl_handle); /* @@ -477,7 +454,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne * to the negotiated version, so we cannot rely on that. */ static int -hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev, +hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev, uint32_t nvsp_ver) { nvsp_msg *init_pkt; @@ -494,7 +471,7 @@ hv_nv_negotiate_nvsp_protocol(struct hv_ init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver; /* Send the init request */ - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -515,13 +492,13 @@ hv_nv_negotiate_nvsp_protocol(struct hv_ * Not valid for NDIS version 1. */ static int -hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu) +hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu) { netvsc_dev *net_dev; nvsp_msg *init_pkt; int ret; - net_dev = hv_nv_get_outbound_net_device(device); + net_dev = hv_nv_get_outbound_net_device(sc); if (!net_dev) return (-ENODEV); @@ -538,7 +515,7 @@ hv_nv_send_ndis_config(struct hv_device = 1; /* Send the configuration packet */ - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); if (ret != 0) @@ -551,7 +528,7 @@ hv_nv_send_ndis_config(struct hv_device * Net VSC connect to VSP */ static int -hv_nv_connect_to_vsp(struct hv_device *device) +hv_nv_connect_to_vsp(struct hn_softc *sc) { netvsc_dev *net_dev; nvsp_msg *init_pkt; @@ -563,20 +540,16 @@ hv_nv_connect_to_vsp(struct hv_device *d int i; int protocol_number = nitems(protocol_list); int ret = 0; - device_t dev = device->device; - hn_softc_t *sc = device_get_softc(dev); + device_t dev = sc->hn_dev; struct ifnet *ifp = sc->arpcom.ac_ifp; - net_dev = hv_nv_get_outbound_net_device(device); - if (!net_dev) { - return (ENODEV); - } + net_dev = hv_nv_get_outbound_net_device(sc); /* * Negotiate the NVSP version. Try the latest NVSP first. */ for (i = protocol_number - 1; i >= 0; i--) { - if (hv_nv_negotiate_nvsp_protocol(device, net_dev, + if (hv_nv_negotiate_nvsp_protocol(sc, net_dev, protocol_list[i]) == 0) { net_dev->nvsp_version = protocol_list[i]; if (bootverbose) @@ -598,7 +571,7 @@ hv_nv_connect_to_vsp(struct hv_device *d * This needs to be right after the NVSP init message per Haiyang */ if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) - ret = hv_nv_send_ndis_config(device, ifp->if_mtu); + ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); /* * Send the NDIS version @@ -621,7 +594,7 @@ hv_nv_connect_to_vsp(struct hv_device *d /* Send the init request */ - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); if (ret != 0) { @@ -642,9 +615,9 @@ hv_nv_connect_to_vsp(struct hv_device *d net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE; - ret = hv_nv_init_rx_buffer_with_net_vsp(device); + ret = hv_nv_init_rx_buffer_with_net_vsp(sc); if (ret == 0) - ret = hv_nv_init_send_buffer_with_net_vsp(device); + ret = hv_nv_init_send_buffer_with_net_vsp(sc); cleanup: return (ret); @@ -676,13 +649,13 @@ hv_nv_subchan_attach(struct hv_vmbus_cha * Callback when the device belonging to this driver is added */ netvsc_dev * -hv_nv_on_device_add(struct hv_device *device, void *additional_info) +hv_nv_on_device_add(struct hn_softc *sc, void *additional_info) { - struct hv_vmbus_channel *chan = device->channel; + struct hv_vmbus_channel *chan = sc->hn_prichan; netvsc_dev *net_dev; int ret = 0; - net_dev = hv_nv_alloc_net_device(device); + net_dev = hv_nv_alloc_net_device(sc); if (net_dev == NULL) return NULL; @@ -706,7 +679,7 @@ hv_nv_on_device_add(struct hv_device *de /* * Connect with the NetVsp */ - ret = hv_nv_connect_to_vsp(device); + ret = hv_nv_connect_to_vsp(sc); if (ret != 0) goto close; @@ -732,9 +705,8 @@ cleanup: * Net VSC on device remove */ int -hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel) +hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) { - hn_softc_t *sc = device_get_softc(device->device); netvsc_dev *net_dev = sc->net_dev;; /* Stop outbound traffic ie sends and receives completions */ @@ -747,12 +719,12 @@ hv_nv_on_device_remove(struct hv_device /* Now, we can close the channel safely */ if (!destroy_channel) { - device->channel->state = + sc->hn_prichan->state = HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE; } - free(device->channel->hv_chan_rdbuf, M_NETVSC); - hv_vmbus_channel_close(device->channel); + free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC); + hv_vmbus_channel_close(sc->hn_prichan); sema_destroy(&net_dev->channel_init_sema); free(net_dev, M_NETVSC); @@ -764,8 +736,7 @@ hv_nv_on_device_remove(struct hv_device * Net VSC on send completion */ static void -hv_nv_on_send_completion(netvsc_dev *net_dev, - struct hv_device *device, struct hv_vmbus_channel *chan, +hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt) { nvsp_msg *nvsp_msg_pkt; @@ -870,14 +841,14 @@ hv_nv_on_send(struct hv_vmbus_channel *c * with virtual addresses. */ static void -hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device, +hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc, struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt) { hv_vm_transfer_page_packet_header *vm_xfer_page_pkt; nvsp_msg *nvsp_msg_pkt; netvsc_packet vsc_pkt; netvsc_packet *net_vsc_pkt = &vsc_pkt; - device_t dev = device->device; + device_t dev = sc->hn_dev; int count = 0; int i = 0; int status = nvsp_status_success; @@ -911,7 +882,6 @@ hv_nv_on_receive(netvsc_dev *net_dev, st } count = vm_xfer_page_pkt->range_count; - net_vsc_pkt->device = device; /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ for (i = 0; i < count; i++) { @@ -921,7 +891,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st net_vsc_pkt->tot_data_buf_len = vm_xfer_page_pkt->ranges[i].byte_count; - hv_rf_on_receive(net_dev, device, chan, net_vsc_pkt); + hv_rf_on_receive(net_dev, chan, net_vsc_pkt); if (net_vsc_pkt->status != nvsp_status_success) { status = nvsp_status_failure; } @@ -977,14 +947,14 @@ retry_send_cmplt: * Net VSC receiving vRSS send table from VSP */ static void -hv_nv_send_table(struct hv_device *device, hv_vm_packet_descriptor *pkt) +hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt) { netvsc_dev *net_dev; nvsp_msg *nvsp_msg_pkt; int i; uint32_t count, *table; - net_dev = hv_nv_get_inbound_net_device(device); + net_dev = hv_nv_get_inbound_net_device(sc); if (!net_dev) return; @@ -1020,9 +990,9 @@ static void hv_nv_on_channel_callback(void *xchan) { struct hv_vmbus_channel *chan = xchan; - struct hv_device *device = chan->device; + device_t dev = chan->ch_dev; + struct hn_softc *sc = device_get_softc(dev); netvsc_dev *net_dev; - device_t dev = device->device; uint32_t bytes_rxed; uint64_t request_id; hv_vm_packet_descriptor *desc; @@ -1030,7 +1000,7 @@ hv_nv_on_channel_callback(void *xchan) int bufferlen = NETVSC_PACKET_SIZE; int ret = 0; - net_dev = hv_nv_get_inbound_net_device(device); + net_dev = hv_nv_get_inbound_net_device(sc); if (net_dev == NULL) return; @@ -1044,14 +1014,14 @@ hv_nv_on_channel_callback(void *xchan) desc = (hv_vm_packet_descriptor *)buffer; switch (desc->type) { case HV_VMBUS_PACKET_TYPE_COMPLETION: - hv_nv_on_send_completion(net_dev, device, - chan, desc); + hv_nv_on_send_completion(net_dev, chan, + desc); break; case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES: - hv_nv_on_receive(net_dev, device, chan, desc); + hv_nv_on_receive(net_dev, sc, chan, desc); break; case HV_VMBUS_PACKET_TYPE_DATA_IN_BAND: - hv_nv_send_table(device, desc); + hv_nv_send_table(sc, desc); break; default: device_printf(dev, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Tue Oct 11 07:30:59 2016 (r307022) @@ -1040,7 +1040,7 @@ typedef struct nvsp_msg_ { * Per netvsc channel-specific */ typedef struct netvsc_dev_ { - struct hv_device *dev; + struct hn_softc *sc; /* Send buffer allocated by us but manages by NetVSP */ void *send_buf; @@ -1107,7 +1107,6 @@ typedef void (*pfn_on_send_rx_completion #endif typedef struct netvsc_packet_ { - struct hv_device *device; hv_bool_uint8_t is_data_pkt; /* One byte */ uint16_t vlan_tci; uint32_t status; @@ -1240,8 +1239,8 @@ typedef struct hn_softc { int hn_initdone; /* See hv_netvsc_drv_freebsd.c for rules on how to use */ int temp_unusable; - struct hv_device *hn_dev_obj; netvsc_dev *net_dev; + struct hv_vmbus_channel *hn_prichan; int hn_rx_ring_cnt; int hn_rx_ring_inuse; @@ -1263,10 +1262,10 @@ typedef struct hn_softc { */ extern int hv_promisc_mode; -void netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status); -netvsc_dev *hv_nv_on_device_add(struct hv_device *device, +void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); +netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc, void *additional_info); -int hv_nv_on_device_remove(struct hv_device *device, +int hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); int hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt); int hv_nv_get_next_send_section(netvsc_dev *net_dev); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 07:30:59 2016 (r307022) @@ -415,18 +415,12 @@ static const hv_guid g_net_vsc_device_ty static int netvsc_probe(device_t dev) { - const char *p; - - p = vmbus_get_type(dev); - if (!memcmp(p, &g_net_vsc_device_type.data, sizeof(hv_guid))) { + if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, + &g_net_vsc_device_type) == 0) { device_set_desc(dev, "Hyper-V Network Interface"); - if (bootverbose) - printf("Netvsc probe... DONE \n"); - - return (BUS_PROBE_DEFAULT); + return BUS_PROBE_DEFAULT; } - - return (ENXIO); + return ENXIO; } static void @@ -451,8 +445,6 @@ hn_cpuset_setthread_task(void *xmask, in static int netvsc_attach(device_t dev) { - struct hv_device *device_ctx = vmbus_get_devctx(dev); - struct hv_vmbus_channel *pri_chan; netvsc_device_info device_info; hn_softc_t *sc; int unit = device_get_unit(dev); @@ -464,6 +456,7 @@ netvsc_attach(device_t dev) sc->hn_unit = unit; sc->hn_dev = dev; + sc->hn_prichan = vmbus_get_channel(dev); if (hn_tx_taskq == NULL) { sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK, @@ -488,8 +481,6 @@ netvsc_attach(device_t dev) } NV_LOCK_INIT(sc, "NetVSCLock"); - sc->hn_dev_obj = device_ctx; - ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER); ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -532,12 +523,7 @@ netvsc_attach(device_t dev) /* * Associate the first TX/RX ring w/ the primary channel. */ - pri_chan = device_ctx->channel; - KASSERT(HV_VMBUS_CHAN_ISPRIMARY(pri_chan), ("not primary channel")); - KASSERT(pri_chan->ch_subidx == 0, - ("primary channel subidx %u", - pri_chan->ch_subidx)); - hn_channel_attach(sc, pri_chan); + hn_channel_attach(sc, sc->hn_prichan); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; @@ -574,7 +560,7 @@ netvsc_attach(device_t dev) IFCAP_LRO; ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; - error = hv_rf_on_device_add(device_ctx, &device_info, ring_cnt); + error = hv_rf_on_device_add(sc, &device_info, ring_cnt); if (error) goto failed; KASSERT(sc->net_dev->num_channel > 0 && @@ -644,7 +630,6 @@ static int netvsc_detach(device_t dev) { struct hn_softc *sc = device_get_softc(dev); - struct hv_device *hv_device = vmbus_get_devctx(dev); if (bootverbose) printf("netvsc_detach\n"); @@ -660,7 +645,7 @@ netvsc_detach(device_t dev) * the netdevice. */ - hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL); + hv_rf_on_device_remove(sc, HV_RF_NV_DESTROY_CHANNEL); hn_stop_tx_tasks(sc); @@ -1224,10 +1209,8 @@ hn_start_locked(struct hn_tx_ring *txr, * Link up/down notification */ void -netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status) +netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status) { - hn_softc_t *sc = device_get_softc(device_obj->device); - if (status == 1) { sc->hn_carrier = 1; } else { @@ -1548,7 +1531,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, struct ifaddr *ifa = (struct ifaddr *)data; #endif netvsc_device_info device_info; - struct hv_device *hn_dev; int mask, error = 0; int retry_cnt = 500; @@ -1566,8 +1548,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, error = ether_ioctl(ifp, cmd, data); break; case SIOCSIFMTU: - hn_dev = vmbus_get_devctx(sc->hn_dev); - /* Check MTU value change */ if (ifp->if_mtu == ifr->ifr_mtu) break; @@ -1614,7 +1594,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, * MTU to take effect. This includes tearing down, but not * deleting the channel, then bringing it back up. */ - error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL); + error = hv_rf_on_device_remove(sc, HV_RF_NV_RETAIN_CHANNEL); if (error) { NV_LOCK(sc); sc->temp_unusable = FALSE; @@ -1623,9 +1603,9 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, } /* Wait for subchannels to be destroyed */ - vmbus_drain_subchan(hn_dev->channel); + vmbus_drain_subchan(sc->hn_prichan); - error = hv_rf_on_device_add(hn_dev, &device_info, + error = hv_rf_on_device_add(sc, &device_info, sc->hn_rx_ring_inuse); if (error) { NV_LOCK(sc); @@ -1790,7 +1770,6 @@ hn_stop(hn_softc_t *sc) { struct ifnet *ifp; int ret, i; - struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev); ifp = sc->hn_ifp; @@ -1805,7 +1784,7 @@ hn_stop(hn_softc_t *sc) if_link_state_change(ifp, LINK_STATE_DOWN); sc->hn_initdone = 0; - ret = hv_rf_on_close(device_ctx); + ret = hv_rf_on_close(sc); } /* @@ -1873,7 +1852,6 @@ static void hn_ifinit_locked(hn_softc_t *sc) { struct ifnet *ifp; - struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev); int ret, i; ifp = sc->hn_ifp; @@ -1884,7 +1862,7 @@ hn_ifinit_locked(hn_softc_t *sc) hv_promisc_mode = 1; - ret = hv_rf_on_open(device_ctx); + ret = hv_rf_on_open(sc); if (ret != 0) { return; } else { @@ -3046,13 +3024,12 @@ hn_subchan_attach(struct hn_softc *sc, s static void hn_subchan_setup(struct hn_softc *sc) { - struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev); struct hv_vmbus_channel **subchan; int subchan_cnt = sc->net_dev->num_channel - 1; int i; /* Wait for sub-channels setup to complete. */ - subchan = vmbus_get_subchan(device_ctx->channel, subchan_cnt); + subchan = vmbus_get_subchan(sc->hn_prichan, subchan_cnt); /* Attach the sub-channels. */ for (i = 0; i < subchan_cnt; ++i) { Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Tue Oct 11 07:30:59 2016 (r307022) @@ -89,7 +89,7 @@ static int hv_rf_close_device(rndis_dev static void hv_rf_on_send_request_completion(struct hv_vmbus_channel *, void *context); static void hv_rf_on_send_request_halt_completion(struct hv_vmbus_channel *, void *context); int -hv_rf_send_offload_request(struct hv_device *device, +hv_rf_send_offload_request(struct hn_softc *sc, rndis_offload_params *offloads); /* * Set the Per-Packet-Info with the specified type @@ -299,7 +299,7 @@ hv_rf_send_request(rndis_device *device, packet->send_buf_section_size = 0; sendit: - ret = hv_nv_on_send(device->net_dev->dev->channel, packet); + ret = hv_nv_on_send(device->net_dev->sc->hn_prichan, packet); return (ret); } @@ -351,7 +351,7 @@ hv_rf_receive_response(rndis_device *dev } int -hv_rf_send_offload_request(struct hv_device *device, +hv_rf_send_offload_request(struct hn_softc *sc, rndis_offload_params *offloads) { rndis_request *request; @@ -359,8 +359,7 @@ hv_rf_send_offload_request(struct hv_dev rndis_offload_params *offload_req; rndis_set_complete *set_complete; rndis_device *rndis_dev; - hn_softc_t *sc = device_get_softc(device->device); - device_t dev = device->device; + device_t dev = sc->hn_dev; netvsc_dev *net_dev = sc->net_dev; uint32_t vsp_version = net_dev->nvsp_version; uint32_t extlen = sizeof(rndis_offload_params); @@ -437,14 +436,14 @@ hv_rf_receive_indicate_status(rndis_devi switch(indicate->status) { case RNDIS_STATUS_MEDIA_CONNECT: - netvsc_linkstatus_callback(device->net_dev->dev, 1); + netvsc_linkstatus_callback(device->net_dev->sc, 1); break; case RNDIS_STATUS_MEDIA_DISCONNECT: - netvsc_linkstatus_callback(device->net_dev->dev, 0); + netvsc_linkstatus_callback(device->net_dev->sc, 0); break; default: /* TODO: */ - device_printf(device->net_dev->dev->device, + device_printf(device->net_dev->sc->hn_dev, "unknown status %d received\n", indicate->status); break; } @@ -537,7 +536,7 @@ hv_rf_receive_data(rndis_device *device, { rndis_packet *rndis_pkt; uint32_t data_offset; - device_t dev = device->net_dev->dev->device; + device_t dev = device->net_dev->sc->hn_dev; struct hv_rf_recvinfo info; rndis_pkt = &message->msg.packet; @@ -580,7 +579,7 @@ hv_rf_receive_data(rndis_device *device, * RNDIS filter on receive */ int -hv_rf_on_receive(netvsc_dev *net_dev, struct hv_device *device, +hv_rf_on_receive(netvsc_dev *net_dev, struct hv_vmbus_channel *chan, netvsc_packet *pkt) { rndis_device *rndis_dev; @@ -1062,7 +1061,7 @@ hv_rf_close_device(rndis_device *device) * RNDIS filter on device add */ int -hv_rf_on_device_add(struct hv_device *device, void *additl_info, +hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan) { int ret; @@ -1073,7 +1072,7 @@ hv_rf_on_device_add(struct hv_device *de struct rndis_recv_scale_cap rsscaps; uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; - device_t dev = device->device; + device_t dev = sc->hn_dev; rndis_dev = hv_get_rndis_device(); if (rndis_dev == NULL) { @@ -1086,7 +1085,7 @@ hv_rf_on_device_add(struct hv_device *de * (hv_rf_on_receive()) before this call is completed. * Note: Earlier code used a function pointer here. */ - net_dev = hv_nv_on_device_add(device, additl_info); + net_dev = hv_nv_on_device_add(sc, additl_info); if (!net_dev) { hv_put_rndis_device(rndis_dev); @@ -1124,7 +1123,7 @@ hv_rf_on_device_add(struct hv_device *de offloads.udp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; offloads.lso_v2_ipv4 = RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED; - ret = hv_rf_send_offload_request(device, &offloads); + ret = hv_rf_send_offload_request(sc, &offloads); if (ret != 0) { /* TODO: shut down rndis device and the channel */ device_printf(dev, @@ -1171,7 +1170,7 @@ hv_rf_on_device_add(struct hv_device *de init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels = net_dev->num_channel - 1; - ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, + ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1205,9 +1204,8 @@ out: * RNDIS filter on device remove */ int -hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel) +hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) { - hn_softc_t *sc = device_get_softc(device->device); netvsc_dev *net_dev = sc->net_dev; rndis_device *rndis_dev = (rndis_device *)net_dev->extension; int ret; @@ -1219,7 +1217,7 @@ hv_rf_on_device_remove(struct hv_device net_dev->extension = NULL; /* Pass control to inner driver to remove the device */ - ret |= hv_nv_on_device_remove(device, destroy_channel); + ret |= hv_nv_on_device_remove(sc, destroy_channel); return (ret); } @@ -1228,9 +1226,8 @@ hv_rf_on_device_remove(struct hv_device * RNDIS filter on open */ int -hv_rf_on_open(struct hv_device *device) +hv_rf_on_open(struct hn_softc *sc) { - hn_softc_t *sc = device_get_softc(device->device); netvsc_dev *net_dev = sc->net_dev; return (hv_rf_open_device((rndis_device *)net_dev->extension)); @@ -1240,9 +1237,8 @@ hv_rf_on_open(struct hv_device *device) * RNDIS filter on close */ int -hv_rf_on_close(struct hv_device *device) +hv_rf_on_close(struct hn_softc *sc) { - hn_softc_t *sc = device_get_softc(device->device); netvsc_dev *net_dev = sc->net_dev; return (hv_rf_close_device((rndis_device *)net_dev->extension)); Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Tue Oct 11 07:30:59 2016 (r307022) @@ -111,15 +111,16 @@ typedef struct rndis_device_ { * Externs */ struct hv_vmbus_channel; +struct hn_softc; -int hv_rf_on_receive(netvsc_dev *net_dev, struct hv_device *device, +int hv_rf_on_receive(netvsc_dev *net_dev, struct hv_vmbus_channel *chan, netvsc_packet *pkt); void hv_rf_receive_rollup(netvsc_dev *net_dev); void hv_rf_channel_rollup(struct hv_vmbus_channel *chan); -int hv_rf_on_device_add(struct hv_device *device, void *additl_info, int nchan); -int hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel); -int hv_rf_on_open(struct hv_device *device); -int hv_rf_on_close(struct hv_device *device); +int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan); +int hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); +int hv_rf_on_open(struct hn_softc *sc); +int hv_rf_on_close(struct hn_softc *sc); #endif /* __HV_RNDIS_FILTER_H__ */ Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 07:10:12 2016 (r307021) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 07:30:59 2016 (r307022) @@ -125,7 +125,7 @@ struct hv_storvsc_request { }; struct storvsc_softc { - struct hv_device *hs_dev; + struct hv_vmbus_channel *hs_chan; LIST_HEAD(, hv_storvsc_request) hs_free_list; struct mtx hs_lock; struct storvsc_driver_props *hs_drv_props; @@ -139,6 +139,7 @@ struct storvsc_softc { struct sema hs_drain_sema; struct hv_storvsc_request hs_init_req; struct hv_storvsc_request hs_reset_req; + device_t hs_dev; }; @@ -264,11 +265,11 @@ static int create_storvsc_request(union static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp); static enum hv_storage_type storvsc_get_storage_type(device_t dev); static void hv_storvsc_rescan_target(struct storvsc_softc *sc); -static void hv_storvsc_on_channel_callback(void *context); +static void hv_storvsc_on_channel_callback(void *xchan); static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc, struct vstor_packet *vstor_packet, struct hv_storvsc_request *request); -static int hv_storvsc_connect_vsp(struct hv_device *device); +static int hv_storvsc_connect_vsp(struct storvsc_softc *); static void storvsc_io_done(struct hv_storvsc_request *reqp); static void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, bus_dma_segment_t *orig_sgl, @@ -297,72 +298,16 @@ DRIVER_MODULE(storvsc, vmbus, storvsc_dr MODULE_VERSION(storvsc, 1); MODULE_DEPEND(storvsc, vmbus, 1, 1, 1); - -/** - * The host is capable of sending messages to us that are - * completely unsolicited. So, we need to address the race - * condition where we may be in the process of unloading the - * driver when the host may send us an unsolicited message. - * We address this issue by implementing a sequentially - * consistent protocol: - * - * 1. Channel callback is invoked while holding the the channel lock - * and an unloading driver will reset the channel callback under - * the protection of this channel lock. - * - * 2. To ensure bounded wait time for unloading a driver, we don't - * permit outgoing traffic once the device is marked as being - * destroyed. - * - * 3. Once the device is marked as being destroyed, we only - * permit incoming traffic to properly account for - * packets already sent out. - */ -static inline struct storvsc_softc * -get_stor_device(struct hv_device *device, - boolean_t outbound) -{ - struct storvsc_softc *sc; - - sc = device_get_softc(device->device); - - if (outbound) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:37:46 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EB6FDC0DD55; Tue, 11 Oct 2016 07:37:46 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C6946873; Tue, 11 Oct 2016 07:37:46 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B7bjkx011137; Tue, 11 Oct 2016 07:37:45 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B7bjWN011133; Tue, 11 Oct 2016 07:37:45 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110737.u9B7bjWN011133@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:37:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307023 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:37:47 -0000 Author: sephe Date: Tue Oct 11 07:37:45 2016 New Revision: 307023 URL: https://svnweb.freebsd.org/changeset/base/307023 Log: MFC 302707-302709 302707 hyperv/vmbus: Nuke unused field from hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7036 302708 hyperv/bufring: Remove unused fields Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7037 302709 hyperv/vmbus: Pack bool field into flags field Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7038 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:30:59 2016 (r307022) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:37:45 2016 (r307023) @@ -471,7 +471,7 @@ typedef struct { uint8_t reserved[4084]; /* - * WARNING: Ring data starts here + ring_data_start_offset + * WARNING: Ring data starts here * !!! DO NOT place any fields below this !!! */ uint8_t buffer[0]; /* doubles as interrupt mask */ @@ -491,10 +491,8 @@ typedef struct { typedef struct { hv_vmbus_ring_buffer* ring_buffer; - uint32_t ring_size; /* Include the shared header */ struct mtx ring_lock; uint32_t ring_data_size; /* ring_size */ - uint32_t ring_data_start_offset; } hv_vmbus_ring_buffer_info; typedef void (*hv_vmbus_pfn_channel_callback)(void *context); @@ -553,19 +551,6 @@ typedef struct hv_vmbus_channel { hv_vmbus_pfn_channel_callback on_channel_callback; void* channel_callback_context; - /* - * If batched_reading is set to "true", mask the interrupt - * and read until the channel is empty. - * If batched_reading is set to "false", the channel is not - * going to perform batched reading. - * - * Batched reading is enabled by default; specific - * drivers that don't want this behavior can turn it off. - */ - boolean_t batched_reading; - - boolean_t is_dedicated_interrupt; - struct hypercall_sigevt_in *ch_sigevt; struct hyperv_dma ch_sigevt_dma; @@ -626,11 +611,23 @@ typedef struct hv_vmbus_channel { #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) #define VMBUS_CHAN_FLAG_HASMNF 0x0001 +/* + * If this flag is set, this channel's interrupt will be masked in ISR, + * and the RX bufring will be drained before this channel's interrupt is + * unmasked. + * + * This flag is turned on by default. Drivers can turn it off according + * to their own requirement. + */ +#define VMBUS_CHAN_FLAG_BATCHREAD 0x0002 static inline void -hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state) +hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on) { - channel->batched_reading = state; + if (!on) + channel->ch_flags &= ~VMBUS_CHAN_FLAG_BATCHREAD; + else + channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; } int hv_vmbus_channel_recv_packet( Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:30:59 2016 (r307022) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:37:45 2016 (r307023) @@ -856,11 +856,13 @@ VmbusProcessChannelEvent(void* context, void* arg; uint32_t bytes_to_read; hv_vmbus_channel* channel = (hv_vmbus_channel*)context; - boolean_t is_batched_reading; + bool is_batched_reading = false; + + if (channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) + is_batched_reading = true; if (channel->on_channel_callback != NULL) { arg = channel->channel_callback_context; - is_batched_reading = channel->batched_reading; /* * Optimize host to guest signaling by ensuring: * 1. While reading the channel, we disable interrupts from @@ -917,7 +919,7 @@ vmbus_event_flags_proc(struct vmbus_soft if (channel == NULL || channel->rxq == NULL) continue; - if (channel->batched_reading) + if (channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) hv_ring_buffer_read_begin(&channel->inbound); taskqueue_enqueue(channel->rxq, &channel->channel_task); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:30:59 2016 (r307022) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:37:45 2016 (r307023) @@ -285,21 +285,19 @@ vmbus_channel_on_offer_internal(struct v { hv_vmbus_channel* new_channel; - /* Allocate the channel object and save this offer */ + /* + * Allocate the channel object and save this offer + */ new_channel = hv_vmbus_allocate_channel(sc); new_channel->ch_id = offer->child_rel_id; new_channel->ch_subidx = offer->offer.sub_channel_index; - if (offer->monitor_allocated) - new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; new_channel->ch_guid_type = offer->offer.interface_type; new_channel->ch_guid_inst = offer->offer.interface_instance; - /* - * By default we setup state to enable batched - * reading. A specific service can choose to - * disable this prior to opening the channel. - */ - new_channel->batched_reading = TRUE; + /* Batch reading is on by default */ + new_channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; + if (offer->monitor_allocated) + new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; new_channel->ch_sigevt = hyperv_dmamem_alloc( bus_get_dma_tag(sc->vmbus_dev), @@ -313,12 +311,8 @@ vmbus_channel_on_offer_internal(struct v return; } new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT; - - if (sc->vmbus_version != VMBUS_VERSION_WS2008) { - new_channel->is_dedicated_interrupt = - (offer->is_dedicated_interrupt != 0); + if (sc->vmbus_version != VMBUS_VERSION_WS2008) new_channel->ch_sigevt->hc_connid = offer->connection_id; - } new_channel->monitor_group = (uint8_t) offer->monitor_id / 32; new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32; Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Tue Oct 11 07:30:59 2016 (r307022) +++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Tue Oct 11 07:37:45 2016 (r307023) @@ -288,7 +288,6 @@ hv_vmbus_ring_buffer_init( ring_info->ring_buffer->read_index = ring_info->ring_buffer->write_index = 0; - ring_info->ring_size = buffer_len; ring_info->ring_data_size = buffer_len - sizeof(hv_vmbus_ring_buffer); mtx_init(&ring_info->ring_lock, "vmbus ring buffer", NULL, MTX_SPIN); From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:44:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 41139C0DF9F; Tue, 11 Oct 2016 07:44:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1B08CDFB; Tue, 11 Oct 2016 07:44:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B7iRvB014874; Tue, 11 Oct 2016 07:44:27 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B7iR6t014873; Tue, 11 Oct 2016 07:44:27 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110744.u9B7iR6t014873@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:44:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307024 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:44:28 -0000 Author: sephe Date: Tue Oct 11 07:44:26 2016 New Revision: 307024 URL: https://svnweb.freebsd.org/changeset/base/307024 Log: MFC 302710,302713 302710 hyperv/vmbus: Remove unnecessary callback check. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7046 302713 hyperv/vmbus: Install different task function for batch/non-batch channels This avoids bunch of unnecessary checks on hot path and simplifies the channel processing. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7085 Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:37:45 2016 (r307023) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:44:26 2016 (r307024) @@ -51,9 +51,10 @@ __FBSDID("$FreeBSD$"); #include static void vmbus_channel_set_event(hv_vmbus_channel* channel); -static void VmbusProcessChannelEvent(void* channel, int pending); static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, const struct hv_vmbus_channel *); +static void vmbus_chan_task(void *, int); +static void vmbus_chan_task_nobatch(void *, int); /** * @brief Trigger an event notification on the specified channel @@ -213,7 +214,13 @@ hv_vmbus_channel_open( new_channel->rxq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, new_channel->target_cpu); - TASK_INIT(&new_channel->channel_task, 0, VmbusProcessChannelEvent, new_channel); + if (new_channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) { + TASK_INIT(&new_channel->channel_task, 0, + vmbus_chan_task, new_channel); + } else { + TASK_INIT(&new_channel->channel_task, 0, + vmbus_chan_task_nobatch, new_channel); + } /* Allocate the ring buffer */ out = contigmalloc((send_ring_buffer_size + recv_ring_buffer_size), @@ -846,46 +853,48 @@ hv_vmbus_channel_recv_packet_raw( return (0); } - -/** - * Process a channel event notification - */ static void -VmbusProcessChannelEvent(void* context, int pending) +vmbus_chan_task(void *xchan, int pending __unused) { - void* arg; - uint32_t bytes_to_read; - hv_vmbus_channel* channel = (hv_vmbus_channel*)context; - bool is_batched_reading = false; + struct hv_vmbus_channel *chan = xchan; + void (*callback)(void *); + void *arg; + + arg = chan->channel_callback_context; + callback = chan->on_channel_callback; + + /* + * Optimize host to guest signaling by ensuring: + * 1. While reading the channel, we disable interrupts from + * host. + * 2. Ensure that we process all posted messages from the host + * before returning from this callback. + * 3. Once we return, enable signaling from the host. Once this + * state is set we check to see if additional packets are + * available to read. In this case we repeat the process. + * + * NOTE: Interrupt has been disabled in the ISR. + */ + for (;;) { + uint32_t left; - if (channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) - is_batched_reading = true; + callback(arg); - if (channel->on_channel_callback != NULL) { - arg = channel->channel_callback_context; - /* - * Optimize host to guest signaling by ensuring: - * 1. While reading the channel, we disable interrupts from - * host. - * 2. Ensure that we process all posted messages from the host - * before returning from this callback. - * 3. Once we return, enable signaling from the host. Once this - * state is set we check to see if additional packets are - * available to read. In this case we repeat the process. - */ - do { - if (is_batched_reading) - hv_ring_buffer_read_begin(&channel->inbound); + left = hv_ring_buffer_read_end(&chan->inbound); + if (left == 0) { + /* No more data in RX bufring; done */ + break; + } + hv_ring_buffer_read_begin(&chan->inbound); + } +} - channel->on_channel_callback(arg); +static void +vmbus_chan_task_nobatch(void *xchan, int pending __unused) +{ + struct hv_vmbus_channel *chan = xchan; - if (is_batched_reading) - bytes_to_read = - hv_ring_buffer_read_end(&channel->inbound); - else - bytes_to_read = 0; - } while (is_batched_reading && (bytes_to_read != 0)); - } + chan->on_channel_callback(chan->channel_callback_context); } static __inline void From owner-svn-src-stable-10@freebsd.org Tue Oct 11 07:50:11 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B96DCC0D155; Tue, 11 Oct 2016 07:50:11 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 947BF163; Tue, 11 Oct 2016 07:50:11 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B7oA0F015445; Tue, 11 Oct 2016 07:50:10 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B7o90c015436; Tue, 11 Oct 2016 07:50:09 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110750.u9B7o90c015436@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 07:50:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307025 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 07:50:11 -0000 Author: sephe Date: Tue Oct 11 07:50:09 2016 New Revision: 307025 URL: https://svnweb.freebsd.org/changeset/base/307025 Log: MFC 302723,302726,302731 302723 hyperv: All Hypercall parameters have same alignment requirement. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7086 302726 hyperv: Signal event input parameter is shared w/ MNF Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7087 302731 hyperv/vmbus: Reorganize MNF event sending. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7088 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h stable/10/sys/dev/hyperv/vmbus/hyperv_var.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:50:09 2016 (r307025) @@ -523,12 +523,13 @@ typedef struct hv_vmbus_channel { hv_vmbus_channel_state state; uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ uint32_t ch_id; /* channel id */ + /* * These are based on the offer_msg.monitor_id. * Save it here for easy access. */ - uint8_t monitor_group; - uint8_t monitor_bit; + int ch_montrig_idx; /* MNF trig index */ + uint32_t ch_montrig_mask;/* MNF trig mask */ uint32_t ring_buffer_gpadl_handle; /* @@ -551,8 +552,8 @@ typedef struct hv_vmbus_channel { hv_vmbus_pfn_channel_callback on_channel_callback; void* channel_callback_context; - struct hypercall_sigevt_in *ch_sigevt; - struct hyperv_dma ch_sigevt_dma; + struct hyperv_mon_param *ch_monprm; + struct hyperv_dma ch_monprm_dma; /* * From Win8, this field specifies the target virtual process Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:50:09 2016 (r307025) @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include -static void vmbus_channel_set_event(hv_vmbus_channel* channel); +static void vmbus_chan_send_event(hv_vmbus_channel* channel); static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, const struct hv_vmbus_channel *); static void vmbus_chan_task(void *, int); @@ -60,7 +60,7 @@ static void vmbus_chan_task_nobatch(void * @brief Trigger an event notification on the specified channel */ static void -vmbus_channel_set_event(hv_vmbus_channel *channel) +vmbus_chan_send_event(hv_vmbus_channel *channel) { struct vmbus_softc *sc = channel->vmbus_sc; uint32_t chanid = channel->ch_id; @@ -69,16 +69,12 @@ vmbus_channel_set_event(hv_vmbus_channel 1UL << (chanid & VMBUS_EVTFLAG_MASK)); if (channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { - hv_vmbus_monitor_page *monitor_page; - - monitor_page = sc->vmbus_mnf2; - synch_set_bit(channel->monitor_bit, - (uint32_t *)&monitor_page-> - trigger_group[channel->monitor_group].u.pending); + atomic_set_int( + &sc->vmbus_mnf2->mnf_trigs[channel->ch_montrig_idx].mt_pending, + channel->ch_montrig_mask); } else { - hypercall_signal_event(channel->ch_sigevt_dma.hv_paddr); + hypercall_signal_event(channel->ch_monprm_dma.hv_paddr); } - } static int @@ -622,9 +618,8 @@ hv_vmbus_channel_send_packet( &need_sig); /* TODO: We should determine if this is optional */ - if (ret == 0 && need_sig) { - vmbus_channel_set_event(channel); - } + if (ret == 0 && need_sig) + vmbus_chan_send_event(channel); return (ret); } @@ -690,9 +685,8 @@ hv_vmbus_channel_send_packet_pagebuffer( &need_sig); /* TODO: We should determine if this is optional */ - if (ret == 0 && need_sig) { - vmbus_channel_set_event(channel); - } + if (ret == 0 && need_sig) + vmbus_chan_send_event(channel); return (ret); } @@ -766,9 +760,8 @@ hv_vmbus_channel_send_packet_multipagebu &need_sig); /* TODO: We should determine if this is optional */ - if (ret == 0 && need_sig) { - vmbus_channel_set_event(channel); - } + if (ret == 0 && need_sig) + vmbus_chan_send_event(channel); return (ret); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:50:09 2016 (r307025) @@ -299,23 +299,29 @@ vmbus_channel_on_offer_internal(struct v if (offer->monitor_allocated) new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; - new_channel->ch_sigevt = hyperv_dmamem_alloc( + new_channel->ch_monprm = hyperv_dmamem_alloc( bus_get_dma_tag(sc->vmbus_dev), - HYPERCALL_SIGEVTIN_ALIGN, 0, sizeof(struct hypercall_sigevt_in), - &new_channel->ch_sigevt_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); - if (new_channel->ch_sigevt == NULL) { - device_printf(sc->vmbus_dev, "sigevt alloc failed\n"); + HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), + &new_channel->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (new_channel->ch_monprm == NULL) { + device_printf(sc->vmbus_dev, "monprm alloc failed\n"); /* XXX */ mtx_destroy(&new_channel->sc_lock); free(new_channel, M_DEVBUF); return; } - new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT; + new_channel->ch_monprm->mp_connid = VMBUS_CONNID_EVENT; if (sc->vmbus_version != VMBUS_VERSION_WS2008) - new_channel->ch_sigevt->hc_connid = offer->connection_id; + new_channel->ch_monprm->mp_connid = offer->connection_id; - new_channel->monitor_group = (uint8_t) offer->monitor_id / 32; - new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32; + if (new_channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { + new_channel->ch_montrig_idx = + offer->monitor_id / VMBUS_MONTRIG_LEN; + if (new_channel->ch_montrig_idx >= VMBUS_MONTRIGS_MAX) + panic("invalid monitor id %u", offer->monitor_id); + new_channel->ch_montrig_mask = + 1 << (offer->monitor_id % VMBUS_MONTRIG_LEN); + } /* Select default cpu for this channel. */ vmbus_channel_select_defcpu(new_channel); Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 07:50:09 2016 (r307025) @@ -109,10 +109,10 @@ hypercall_post_message(bus_addr_t msg_pa } uint64_t -hypercall_signal_event(bus_addr_t sigevt_paddr) +hypercall_signal_event(bus_addr_t monprm_paddr) { return hypercall_md(hypercall_context.hc_addr, - HYPERCALL_SIGNAL_EVENT, sigevt_paddr, 0); + HYPERCALL_SIGNAL_EVENT, monprm_paddr, 0); } int Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Tue Oct 11 07:50:09 2016 (r307025) @@ -133,6 +133,15 @@ #define CPUID_LEAF_HV_HWFEATURES 0x40000006 /* + * Hyper-V Monitor Notification Facility + */ +struct hyperv_mon_param { + uint32_t mp_connid; + uint16_t mp_evtflag_ofs; + uint16_t mp_rsvd; +} __packed; + +/* * Hyper-V message types */ #define HYPERV_MSGTYPE_NONE 0 @@ -153,13 +162,22 @@ /* * Hypercall input parameters */ +#define HYPERCALL_PARAM_ALIGN 8 +#if 0 +/* + * XXX + * <> requires + * input parameters size to be multiple of 8, however, many post + * message input parameters do _not_ meet this requirement. + */ +#define HYPERCALL_PARAM_SIZE_ALIGN 8 +#endif /* * HYPERCALL_POST_MESSAGE */ #define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 #define HYPERCALL_POSTMSGIN_SIZE 256 -#define HYPERCALL_POSTMSGIN_ALIGN 8 struct hypercall_postmsg_in { uint32_t hc_connid; @@ -172,13 +190,8 @@ CTASSERT(sizeof(struct hypercall_postmsg /* * HYPERCALL_SIGNAL_EVENT + * + * struct hyperv_mon_param. */ -#define HYPERCALL_SIGEVTIN_ALIGN 8 - -struct hypercall_sigevt_in { - uint32_t hc_connid; - uint16_t hc_evtflag_ofs; - uint16_t hc_rsvd; -} __packed; #endif /* !_HYPERV_REG_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_var.h Tue Oct 11 07:50:09 2016 (r307025) @@ -41,6 +41,6 @@ extern u_int hyperv_features; extern u_int hyperv_recommends; uint64_t hypercall_post_message(bus_addr_t msg_paddr); -uint64_t hypercall_signal_event(bus_addr_t sigevt_paddr); +uint64_t hypercall_signal_event(bus_addr_t monprm_paddr); #endif /* !_HYPERV_VAR_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:50:09 2016 (r307025) @@ -130,7 +130,7 @@ vmbus_msghc_alloc(bus_dma_tag_t parent_d mh = malloc(sizeof(*mh), M_DEVBUF, M_WAITOK | M_ZERO); mh->mh_inprm = hyperv_dmamem_alloc(parent_dtag, - HYPERCALL_POSTMSGIN_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE, + HYPERCALL_PARAM_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE, &mh->mh_inprm_dma, BUS_DMA_WAITOK); if (mh->mh_inprm == NULL) { free(mh, M_DEVBUF); @@ -835,7 +835,8 @@ vmbus_dma_alloc(struct vmbus_softc *sc) return ENOMEM; sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, - PAGE_SIZE, &sc->vmbus_mnf2_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); if (sc->vmbus_mnf2 == NULL) return ENOMEM; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 07:50:09 2016 (r307025) @@ -72,6 +72,34 @@ struct vmbus_evtflags { CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE); /* + * Hyper-V Monitor Notification Facility + */ + +struct vmbus_mon_trig { + uint32_t mt_pending; + uint32_t mt_armed; +} __packed; + +#define VMBUS_MONTRIGS_MAX 4 +#define VMBUS_MONTRIG_LEN 32 + +struct vmbus_mnf { + uint32_t mnf_state; + uint32_t mnf_rsvd1; + + struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX]; + uint8_t mnf_rsvd2[536]; + + uint16_t mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN]; + uint8_t mnf_rsvd3[256]; + + struct hyperv_mon_param + mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN]; + uint8_t mnf_rsvd4[1984]; +} __packed; +CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE); + +/* * Channel */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 07:44:26 2016 (r307024) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 07:50:09 2016 (r307025) @@ -70,7 +70,7 @@ struct vmbus_softc { void (*vmbus_event_proc)(struct vmbus_softc *, int); u_long *vmbus_tx_evtflags; /* event flags to host */ - void *vmbus_mnf2; /* monitored by host */ + struct vmbus_mnf *vmbus_mnf2; /* monitored by host */ u_long *vmbus_rx_evtflags; /* compat evtflgs from host */ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:01:46 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E192DC0D689; Tue, 11 Oct 2016 08:01:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7F6FBA71; Tue, 11 Oct 2016 08:01:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B81iJq019924; Tue, 11 Oct 2016 08:01:44 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B81hjB019910; Tue, 11 Oct 2016 08:01:43 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110801.u9B81hjB019910@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:01:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307026 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:01:46 -0000 Author: sephe Date: Tue Oct 11 08:01:43 2016 New Revision: 307026 URL: https://svnweb.freebsd.org/changeset/base/307026 Log: MFC 302733,302737,302801-302806 302733 hyperv/vmbus: Remove unused code Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7089 302737 hyperv/vmbus: Cleanup channel rescind Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7090 302801 hyperv/vmbus: Remove unused bits Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7091 302802 hyperv: hv_guid -> struct hyperv_guid. This paves way for the further cleanup/disentangle. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7092 302803 hyperv/vmbus: Move channel offer message definition to vmbus_reg.h - Avoid bit fields. - Avoid unnecessary indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7093 302804 hyperv/vmbus: Switch to vmbus channel message macros Prepare for more cleanup. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7094 302805 hyperv/vmbus: Remove unused bits Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7095 302806 hyperv/vmbus: Get rid of rel{_id,id}, use channel id consistently. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7100 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_if.m stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:01:43 2016 (r307026) @@ -82,32 +82,6 @@ typedef uint8_t hv_bool_uint8_t; #define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) #define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) -/* - * Make maximum size of pipe payload of 16K - */ - -#define HV_MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384) - -/* - * Define pipe_mode values - */ - -#define HV_VMBUS_PIPE_TYPE_BYTE 0x00000000 -#define HV_VMBUS_PIPE_TYPE_MESSAGE 0x00000004 - -/* - * The size of the user defined data buffer for non-pipe offers - */ - -#define HV_MAX_USER_DEFINED_BYTES 120 - -/* - * The size of the user defined data buffer for pipe offers - */ - -#define HV_MAX_PIPE_USER_DEFINED_BYTES 116 - - #define HV_MAX_PAGE_BUFFER_COUNT 32 #define HV_MAX_MULTIPAGE_BUFFER_COUNT 32 @@ -121,68 +95,13 @@ typedef uint8_t hv_bool_uint8_t; ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \ HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT ) -typedef struct hv_guid { - uint8_t data[16]; -} __packed hv_guid; +struct hyperv_guid { + uint8_t hv_guid[16]; +} __packed; #define HYPERV_GUID_STRLEN 40 -int hyperv_guid2str(const struct hv_guid *, char *, size_t); - -#define HV_NIC_GUID \ - .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \ - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E} - -#define HV_IDE_GUID \ - .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5} - -#define HV_SCSI_GUID \ - .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f} - -/* - * At the center of the Channel Management library is - * the Channel Offer. This struct contains the - * fundamental information about an offer. - */ - -typedef struct hv_vmbus_channel_offer { - hv_guid interface_type; - hv_guid interface_instance; - uint64_t interrupt_latency_in_100ns_units; - uint32_t interface_revision; - uint32_t server_context_area_size; /* in bytes */ - uint16_t channel_flags; - uint16_t mmio_megabytes; /* in bytes * 1024 * 1024 */ - union - { - /* - * Non-pipes: The user has HV_MAX_USER_DEFINED_BYTES bytes. - */ - struct { - uint8_t user_defined[HV_MAX_USER_DEFINED_BYTES]; - } __packed standard; - - /* - * Pipes: The following structure is an integrated pipe protocol, which - * is implemented on top of standard user-defined data. pipe - * clients have HV_MAX_PIPE_USER_DEFINED_BYTES left for their - * own use. - */ - struct { - uint32_t pipe_mode; - uint8_t user_defined[HV_MAX_PIPE_USER_DEFINED_BYTES]; - } __packed pipe; - } u; - - /* - * Sub_channel_index, newly added in Win8. - */ - uint16_t sub_channel_index; - uint16_t padding; - -} __packed hv_vmbus_channel_offer; +int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); typedef struct { uint16_t type; @@ -192,13 +111,6 @@ typedef struct { uint64_t transaction_id; } __packed hv_vm_packet_descriptor; -typedef uint32_t hv_previous_packet_offset; - -typedef struct { - hv_previous_packet_offset previous_packet_start_offset; - hv_vm_packet_descriptor descriptor; -} __packed hv_vm_packet_header; - typedef struct { uint32_t byte_count; uint32_t byte_offset; @@ -213,91 +125,6 @@ typedef struct { hv_vm_transfer_page ranges[1]; } __packed hv_vm_transfer_page_packet_header; -typedef struct { - hv_vm_packet_descriptor d; - uint32_t gpadl; - uint32_t reserved; -} __packed hv_vm_gpadl_packet_header; - -typedef struct { - hv_vm_packet_descriptor d; - uint32_t gpadl; - uint16_t transfer_page_set_id; - uint16_t reserved; -} __packed hv_vm_add_remove_transfer_page_set; - -/* - * This structure defines a range in guest - * physical space that can be made - * to look virtually contiguous. - */ - -typedef struct { - uint32_t byte_count; - uint32_t byte_offset; - uint64_t pfn_array[0]; -} __packed hv_gpa_range; - -/* - * This is the format for an Establish Gpadl packet, which contains a handle - * by which this GPADL will be known and a set of GPA ranges associated with - * it. This can be converted to a MDL by the guest OS. If there are multiple - * GPA ranges, then the resulting MDL will be "chained," representing multiple - * VA ranges. - */ - -typedef struct { - hv_vm_packet_descriptor d; - uint32_t gpadl; - uint32_t range_count; - hv_gpa_range range[1]; -} __packed hv_vm_establish_gpadl; - -/* - * This is the format for a Teardown Gpadl packet, which indicates that the - * GPADL handle in the Establish Gpadl packet will never be referenced again. - */ - -typedef struct { - hv_vm_packet_descriptor d; - uint32_t gpadl; - /* for alignment to a 8-byte boundary */ - uint32_t reserved; -} __packed hv_vm_teardown_gpadl; - -/* - * This is the format for a GPA-Direct packet, which contains a set of GPA - * ranges, in addition to commands and/or data. - */ - -typedef struct { - hv_vm_packet_descriptor d; - uint32_t reserved; - uint32_t range_count; - hv_gpa_range range[1]; -} __packed hv_vm_data_gpa_direct; - -/* - * This is the format for a Additional data Packet. - */ -typedef struct { - hv_vm_packet_descriptor d; - uint64_t total_bytes; - uint32_t byte_offset; - uint32_t byte_count; - uint8_t data[1]; -} __packed hv_vm_additional_data; - -typedef union { - hv_vm_packet_descriptor simple_header; - hv_vm_transfer_page_packet_header transfer_page_header; - hv_vm_gpadl_packet_header gpadl_header; - hv_vm_add_remove_transfer_page_set add_remove_transfer_page_header; - hv_vm_establish_gpadl establish_gpadl_header; - hv_vm_teardown_gpadl teardown_gpadl_header; - hv_vm_data_gpa_direct data_gpa_direct_header; -} __packed hv_vm_packet_largest_possible_header; - typedef enum { HV_VMBUS_PACKET_TYPE_INVALID = 0x0, HV_VMBUS_PACKET_TYPES_SYNCH = 0x1, @@ -317,86 +144,6 @@ typedef enum { #define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 -/* - * Version 1 messages - */ -typedef enum { - HV_CHANNEL_MESSAGE_INVALID = 0, - HV_CHANNEL_MESSAGE_OFFER_CHANNEL = 1, - HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER = 2, - HV_CHANNEL_MESSAGE_REQUEST_OFFERS = 3, - HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED = 4, - HV_CHANNEL_MESSAGE_OPEN_CHANNEL = 5, - HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT = 6, - HV_CHANNEL_MESSAGE_CLOSE_CHANNEL = 7, - HV_CHANNEL_MESSAGEL_GPADL_HEADER = 8, - HV_CHANNEL_MESSAGE_GPADL_BODY = 9, - HV_CHANNEL_MESSAGE_GPADL_CREATED = 10, - HV_CHANNEL_MESSAGE_GPADL_TEARDOWN = 11, - HV_CHANNEL_MESSAGE_GPADL_TORNDOWN = 12, - HV_CHANNEL_MESSAGE_REL_ID_RELEASED = 13, - HV_CHANNEL_MESSAGE_INITIATED_CONTACT = 14, - HV_CHANNEL_MESSAGE_VERSION_RESPONSE = 15, - HV_CHANNEL_MESSAGE_UNLOAD = 16, - HV_CHANNEL_MESSAGE_COUNT -} hv_vmbus_channel_msg_type; - -typedef struct { - hv_vmbus_channel_msg_type message_type; - uint32_t padding; -} __packed hv_vmbus_channel_msg_header; - -/* - * Query VMBus Version parameters - */ -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t version; -} __packed hv_vmbus_channel_query_vmbus_version; - -/* - * Channel Offer parameters - */ -typedef struct { - hv_vmbus_channel_msg_header header; - hv_vmbus_channel_offer offer; - uint32_t child_rel_id; - uint8_t monitor_id; - /* - * This field has been split into a bit field on Win7 - * and higher. - */ - uint8_t monitor_allocated:1; - uint8_t reserved:7; - /* - * Following fields were added in win7 and higher. - * Make sure to check the version before accessing these fields. - * - * If "is_dedicated_interrupt" is set, we must not set the - * associated bit in the channel bitmap while sending the - * interrupt to the host. - * - * connection_id is used in signaling the host. - */ - uint16_t is_dedicated_interrupt:1; - uint16_t reserved1:15; - uint32_t connection_id; -} __packed hv_vmbus_channel_offer_channel; - -/* - * Rescind Offer parameters - */ -typedef struct -{ - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; -} __packed hv_vmbus_channel_rescind_offer; - -typedef struct { - hv_vmbus_channel_msg_header header; - uint32_t child_rel_id; -} __packed hv_vmbus_channel_relid_released; - #define HW_MACADDR_LEN 6 /* @@ -505,18 +252,6 @@ typedef enum { HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE, } hv_vmbus_channel_state; -/* - * Connection identifier type - */ -typedef union { - uint32_t as_uint32_t; - struct { - uint32_t id:24; - uint32_t reserved:8; - } u; - -} __packed hv_vmbus_connection_id; - typedef struct hv_vmbus_channel { device_t ch_dev; struct vmbus_softc *vmbus_sc; @@ -603,8 +338,8 @@ typedef struct hv_vmbus_channel { TAILQ_ENTRY(hv_vmbus_channel) ch_link; uint32_t ch_subidx; /* subchan index */ - struct hv_guid ch_guid_type; - struct hv_guid ch_guid_inst; + struct hyperv_guid ch_guid_type; + struct hyperv_guid ch_guid_inst; struct sysctl_ctx_list ch_sysctl_ctx; } hv_vmbus_channel; Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 08:01:43 2016 (r307026) @@ -403,8 +403,8 @@ hn_ifmedia_sts(struct ifnet *ifp, struct } /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ -static const hv_guid g_net_vsc_device_type = { - .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, +static const struct hyperv_guid g_net_vsc_device_type = { + .hv_guid = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E} }; Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 08:01:43 2016 (r307026) @@ -180,14 +180,14 @@ enum hv_storage_type { #define HV_STORAGE_SUPPORTS_MULTI_CHANNEL 0x1 /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ -static const hv_guid gStorVscDeviceType={ - .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, +static const struct hyperv_guid gStorVscDeviceType={ + .hv_guid = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f} }; /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ -static const hv_guid gBlkVscDeviceType={ - .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, +static const struct hyperv_guid gBlkVscDeviceType={ + .hv_guid = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5} }; Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Tue Oct 11 08:01:43 2016 (r307026) @@ -39,7 +39,7 @@ #include "vmbus_if.h" /* Heartbeat Service */ -static const hv_guid service_guid = { .data = +static const struct hyperv_guid service_guid = { .hv_guid = {0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} }; Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Tue Oct 11 08:01:43 2016 (r307026) @@ -90,7 +90,7 @@ static int hv_kvp_log = 0; log(LOG_INFO, "hv_kvp: " __VA_ARGS__); \ } while (0) -static const hv_guid service_guid = { .data = +static const struct hyperv_guid service_guid = { .hv_guid = {0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6} }; Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Tue Oct 11 08:01:43 2016 (r307026) @@ -43,7 +43,7 @@ #include "hv_util.h" #include "vmbus_if.h" -static const hv_guid service_guid = { .data = +static const struct hyperv_guid service_guid = { .hv_guid = {0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB} }; Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Tue Oct 11 08:01:43 2016 (r307026) @@ -55,7 +55,7 @@ typedef struct { } time_sync_data; /* Time Synch Service */ -static const hv_guid service_guid = {.data = +static const struct hyperv_guid service_guid = {.hv_guid = {0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } }; Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:01:43 2016 (r307026) @@ -897,25 +897,23 @@ vmbus_event_flags_proc(struct vmbus_soft int f; for (f = 0; f < flag_cnt; ++f) { - uint32_t rel_id_base; + uint32_t chid_base; u_long flags; - int bit; + int chid_ofs; if (event_flags[f] == 0) continue; flags = atomic_swap_long(&event_flags[f], 0); - rel_id_base = f << VMBUS_EVTFLAG_SHIFT; + chid_base = f << VMBUS_EVTFLAG_SHIFT; - while ((bit = ffsl(flags)) != 0) { + while ((chid_ofs = ffsl(flags)) != 0) { struct hv_vmbus_channel *channel; - uint32_t rel_id; - --bit; /* NOTE: ffsl is 1-based */ - flags &= ~(1UL << bit); + --chid_ofs; /* NOTE: ffsl is 1-based */ + flags &= ~(1UL << chid_ofs); - rel_id = rel_id_base + bit; - channel = sc->vmbus_chmap[rel_id]; + channel = sc->vmbus_chmap[chid_base + chid_ofs]; /* if channel is closed or closing */ if (channel == NULL || channel->rxq == NULL) Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:01:43 2016 (r307026) @@ -45,37 +45,40 @@ typedef void (*vmbus_chanmsg_proc_t) static struct hv_vmbus_channel *hv_vmbus_allocate_channel(struct vmbus_softc *); static void vmbus_channel_on_offer_internal(struct vmbus_softc *, - const hv_vmbus_channel_offer_channel *offer); + const struct vmbus_chanmsg_choffer *); static void vmbus_chan_detach_task(void *, int); static void vmbus_channel_on_offer(struct vmbus_softc *, const struct vmbus_message *); -static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, const struct vmbus_message *); +static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, + const struct vmbus_message *); -/** - * Channel message dispatch table +/* + * Vmbus channel message processing. */ + +#define VMBUS_CHANMSG_PROC(name, func) \ + [VMBUS_CHANMSG_TYPE_##name] = func +#define VMBUS_CHANMSG_PROC_WAKEUP(name) \ + VMBUS_CHANMSG_PROC(name, vmbus_msghc_wakeup) + static const vmbus_chanmsg_proc_t -vmbus_chanmsg_process[HV_CHANNEL_MESSAGE_COUNT] = { - [HV_CHANNEL_MESSAGE_OFFER_CHANNEL] = - vmbus_channel_on_offer, - [HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER] = - vmbus_channel_on_offer_rescind, - [HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED] = - vmbus_channel_on_offers_delivered, - [HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT] = - vmbus_msghc_wakeup, - [HV_CHANNEL_MESSAGE_GPADL_CREATED] = - vmbus_msghc_wakeup, - [HV_CHANNEL_MESSAGE_GPADL_TORNDOWN] = - vmbus_msghc_wakeup, - [HV_CHANNEL_MESSAGE_VERSION_RESPONSE] = - vmbus_msghc_wakeup +vmbus_chanmsg_process[VMBUS_CHANMSG_TYPE_MAX] = { + VMBUS_CHANMSG_PROC(CHOFFER, vmbus_channel_on_offer), + VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind), + VMBUS_CHANMSG_PROC(CHOFFER_DONE,vmbus_channel_on_offers_delivered), + + VMBUS_CHANMSG_PROC_WAKEUP(CHOPEN_RESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_CONNRESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP), + VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) }; +#undef VMBUS_CHANMSG_PROC_WAKEUP +#undef VMBUS_CHANMSG_PROC + /** * @brief Allocate and initialize a vmbus channel object */ @@ -113,27 +116,25 @@ vmbus_channel_process_offer(hv_vmbus_cha { struct vmbus_softc *sc = new_channel->vmbus_sc; hv_vmbus_channel* channel; - uint32_t relid; - relid = new_channel->ch_id; /* * Make sure this is a new offer */ mtx_lock(&sc->vmbus_chlist_lock); - if (relid == 0) { + if (new_channel->ch_id == 0) { /* * XXX channel0 will not be processed; skip it. */ printf("VMBUS: got channel0 offer\n"); } else { - sc->vmbus_chmap[relid] = new_channel; + sc->vmbus_chmap[new_channel->ch_id] = new_channel; } TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { if (memcmp(&channel->ch_guid_type, &new_channel->ch_guid_type, - sizeof(hv_guid)) == 0 && + sizeof(struct hyperv_guid)) == 0 && memcmp(&channel->ch_guid_inst, &new_channel->ch_guid_inst, - sizeof(hv_guid)) == 0) + sizeof(struct hyperv_guid)) == 0) break; } @@ -270,18 +271,16 @@ vmbus_channel_select_defcpu(struct hv_vm static void vmbus_channel_on_offer(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_offer_channel *offer; - /* New channel is offered by vmbus */ vmbus_scan_newchan(sc); - offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data; - vmbus_channel_on_offer_internal(sc, offer); + vmbus_channel_on_offer_internal(sc, + (const struct vmbus_chanmsg_choffer *)msg->msg_data); } static void vmbus_channel_on_offer_internal(struct vmbus_softc *sc, - const hv_vmbus_channel_offer_channel *offer) + const struct vmbus_chanmsg_choffer *offer) { hv_vmbus_channel* new_channel; @@ -289,14 +288,14 @@ vmbus_channel_on_offer_internal(struct v * Allocate the channel object and save this offer */ new_channel = hv_vmbus_allocate_channel(sc); - new_channel->ch_id = offer->child_rel_id; - new_channel->ch_subidx = offer->offer.sub_channel_index; - new_channel->ch_guid_type = offer->offer.interface_type; - new_channel->ch_guid_inst = offer->offer.interface_instance; + new_channel->ch_id = offer->chm_chanid; + new_channel->ch_subidx = offer->chm_subidx; + new_channel->ch_guid_type = offer->chm_chtype; + new_channel->ch_guid_inst = offer->chm_chinst; /* Batch reading is on by default */ new_channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; - if (offer->monitor_allocated) + if (offer->chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; new_channel->ch_monprm = hyperv_dmamem_alloc( @@ -312,15 +311,15 @@ vmbus_channel_on_offer_internal(struct v } new_channel->ch_monprm->mp_connid = VMBUS_CONNID_EVENT; if (sc->vmbus_version != VMBUS_VERSION_WS2008) - new_channel->ch_monprm->mp_connid = offer->connection_id; + new_channel->ch_monprm->mp_connid = offer->chm_connid; if (new_channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { new_channel->ch_montrig_idx = - offer->monitor_id / VMBUS_MONTRIG_LEN; + offer->chm_montrig / VMBUS_MONTRIG_LEN; if (new_channel->ch_montrig_idx >= VMBUS_MONTRIGS_MAX) - panic("invalid monitor id %u", offer->monitor_id); + panic("invalid monitor trigger %u", offer->chm_montrig); new_channel->ch_montrig_mask = - 1 << (offer->monitor_id % VMBUS_MONTRIG_LEN); + 1 << (offer->chm_montrig % VMBUS_MONTRIG_LEN); } /* Select default cpu for this channel. */ @@ -329,33 +328,34 @@ vmbus_channel_on_offer_internal(struct v vmbus_channel_process_offer(new_channel); } -/** - * @brief Rescind offer handler. - * - * We queue a work item to process this offer - * synchronously. - * +/* * XXX pretty broken; need rework. */ static void -vmbus_channel_on_offer_rescind(struct vmbus_softc *sc, +vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc, const struct vmbus_message *msg) { - const hv_vmbus_channel_rescind_offer *rescind; - hv_vmbus_channel* channel; + const struct vmbus_chanmsg_chrescind *note; + struct hv_vmbus_channel *chan; + + note = (const struct vmbus_chanmsg_chrescind *)msg->msg_data; + if (note->chm_chanid > VMBUS_CHAN_MAX) { + device_printf(sc->vmbus_dev, "invalid rescinded chan%u\n", + note->chm_chanid); + return; + } - rescind = (const hv_vmbus_channel_rescind_offer *)msg->msg_data; if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u rescind\n", - rescind->child_rel_id); + device_printf(sc->vmbus_dev, "chan%u rescinded\n", + note->chm_chanid); } - channel = sc->vmbus_chmap[rescind->child_rel_id]; - if (channel == NULL) - return; - sc->vmbus_chmap[rescind->child_rel_id] = NULL; + chan = sc->vmbus_chmap[note->chm_chanid]; + if (chan == NULL) + return; + sc->vmbus_chmap[note->chm_chanid] = NULL; - taskqueue_enqueue(taskqueue_thread, &channel->ch_detach_task); + taskqueue_enqueue(taskqueue_thread, &chan->ch_detach_task); } static void @@ -566,7 +566,7 @@ vmbus_chan_msgproc(struct vmbus_softc *s uint32_t msg_type; msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type; - if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) { + if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) { device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", msg_type); return; Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:01:43 2016 (r307026) @@ -56,8 +56,8 @@ typedef struct { typedef struct { uint32_t rel_id; hv_vmbus_channel_state state; - hv_guid interface_type; - hv_guid interface_instance; + struct hyperv_guid interface_type; + struct hyperv_guid interface_instance; uint32_t monitor_id; uint32_t server_monitor_pending; uint32_t server_monitor_latency; @@ -97,67 +97,6 @@ typedef struct hv_vmbus_channel_packet_m hv_vmbus_multipage_buffer range; } __packed hv_vmbus_channel_packet_multipage_buffer; -typedef union { - uint32_t as_uint32_t; - struct { - uint32_t group_enable :4; - uint32_t rsvd_z :28; - } u; -} hv_vmbus_monitor_trigger_state; - -typedef union { - uint64_t as_uint64_t; - struct { - uint32_t pending; - uint32_t armed; - } u; -} hv_vmbus_monitor_trigger_group; - -typedef struct { - hv_vmbus_connection_id connection_id; - uint16_t flag_number; - uint16_t rsvd_z; -} hv_vmbus_monitor_parameter; - -/* - * hv_vmbus_monitor_page Layout - * ------------------------------------------------------ - * | 0 | trigger_state (4 bytes) | Rsvd1 (4 bytes) | - * | 8 | trigger_group[0] | - * | 10 | trigger_group[1] | - * | 18 | trigger_group[2] | - * | 20 | trigger_group[3] | - * | 28 | Rsvd2[0] | - * | 30 | Rsvd2[1] | - * | 38 | Rsvd2[2] | - * | 40 | next_check_time[0][0] | next_check_time[0][1] | - * | ... | - * | 240 | latency[0][0..3] | - * | 340 | Rsvz3[0] | - * | 440 | parameter[0][0] | - * | 448 | parameter[0][1] | - * | ... | - * | 840 | Rsvd4[0] | - * ------------------------------------------------------ - */ - -typedef struct { - hv_vmbus_monitor_trigger_state trigger_state; - uint32_t rsvd_z1; - - hv_vmbus_monitor_trigger_group trigger_group[4]; - uint64_t rsvd_z2[3]; - - int32_t next_check_time[4][32]; - - uint16_t latency[4][32]; - uint64_t rsvd_z3[32]; - - hv_vmbus_monitor_parameter parameter[4][32]; - - uint8_t rsvd_z4[1984]; -} hv_vmbus_monitor_page; - /* * Private, VM Bus functions */ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Tue Oct 11 08:01:43 2016 (r307026) @@ -116,9 +116,9 @@ hypercall_signal_event(bus_addr_t monprm } int -hyperv_guid2str(const struct hv_guid *guid, char *buf, size_t sz) +hyperv_guid2str(const struct hyperv_guid *guid, char *buf, size_t sz) { - const uint8_t *d = guid->data; + const uint8_t *d = guid->hv_guid; return snprintf(buf, sz, "%02x%02x%02x%02x-" "%02x%02x-%02x%02x-%02x%02x-" Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:01:43 2016 (r307026) @@ -1131,11 +1131,12 @@ vmbus_get_version_method(device_t bus, d } static int -vmbus_probe_guid_method(device_t bus, device_t dev, const struct hv_guid *guid) +vmbus_probe_guid_method(device_t bus, device_t dev, + const struct hyperv_guid *guid) { const struct hv_vmbus_channel *chan = vmbus_get_channel(dev); - if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hv_guid)) == 0) + if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0) return 0; return ENXIO; } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_if.m ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_if.m Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_if.m Tue Oct 11 08:01:43 2016 (r307026) @@ -32,7 +32,7 @@ INTERFACE vmbus; HEADER { - struct hv_guid; + struct hyperv_guid; }; METHOD uint32_t get_version { @@ -43,5 +43,5 @@ METHOD uint32_t get_version { METHOD int probe_guid { device_t bus; device_t dev; - const struct hv_guid *guid; + const struct hyperv_guid *guid; }; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 07:50:09 2016 (r307025) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Oct 11 08:01:43 2016 (r307026) @@ -31,6 +31,7 @@ #include #include +#include /* XXX for hyperv_guid */ /* * Hyper-V SynIC message format. @@ -117,11 +118,14 @@ struct vmbus_gpa_range { /* * Channel messages - * - Embedded in vmbus_message.msg_data, e.g. response. + * - Embedded in vmbus_message.msg_data, e.g. response and notification. * - Embedded in hypercall_postmsg_in.hc_data, e.g. request. */ +#define VMBUS_CHANMSG_TYPE_CHOFFER 1 /* NOTE */ +#define VMBUS_CHANMSG_TYPE_CHRESCIND 2 /* NOTE */ #define VMBUS_CHANMSG_TYPE_CHREQUEST 3 /* REQ */ +#define VMBUS_CHANMSG_TYPE_CHOFFER_DONE 4 /* NOTE */ #define VMBUS_CHANMSG_TYPE_CHOPEN 5 /* REQ */ #define VMBUS_CHANMSG_TYPE_CHOPEN_RESP 6 /* RESP */ #define VMBUS_CHANMSG_TYPE_CHCLOSE 7 /* REQ */ @@ -134,6 +138,7 @@ struct vmbus_gpa_range { #define VMBUS_CHANMSG_TYPE_CONNECT 14 /* REQ */ #define VMBUS_CHANMSG_TYPE_CONNECT_RESP 15 /* RESP */ #define VMBUS_CHANMSG_TYPE_DISCONNECT 16 /* REQ */ +#define VMBUS_CHANMSG_TYPE_MAX 22 struct vmbus_chanmsg_hdr { uint32_t chm_type; /* VMBUS_CHANMSG_TYPE_ */ @@ -241,4 +246,33 @@ struct vmbus_chanmsg_chfree { uint32_t chm_chanid; } __packed; +/* VMBUS_CHANMSG_TYPE_CHRESCIND */ +struct vmbus_chanmsg_chrescind { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; +} __packed; + +/* VMBUS_CHANMSG_TYPE_CHOFFER */ +struct vmbus_chanmsg_choffer { + struct vmbus_chanmsg_hdr chm_hdr; + struct hyperv_guid chm_chtype; + struct hyperv_guid chm_chinst; + uint64_t chm_chlat; /* unit: 100ns */ + uint32_t chm_chrev; + uint32_t chm_svrctx_sz; + uint16_t chm_chflags; + uint16_t chm_mmio_sz; /* unit: MB */ + uint8_t chm_udata[120]; + uint16_t chm_subidx; + uint16_t chm_rsvd; + uint32_t chm_chanid; + uint8_t chm_montrig; + uint8_t chm_flags1; /* VMBUS_CHOFFER_FLAG1_ */ + uint16_t chm_flags2; + uint32_t chm_connid; +} __packed; +CTASSERT(sizeof(struct vmbus_chanmsg_choffer) <= VMBUS_MSG_DSIZE_MAX); + +#define VMBUS_CHOFFER_FLAG1_HASMNF 0x01 + #endif /* !_VMBUS_REG_H_ */ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:14:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0CD30C0DA58; Tue, 11 Oct 2016 08:14:13 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C4C8E21B; Tue, 11 Oct 2016 08:14:12 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8EB9V026680; Tue, 11 Oct 2016 08:14:11 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8EBnw026673; Tue, 11 Oct 2016 08:14:11 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110814.u9B8EBnw026673@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:14:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307027 - in stable/10/sys/dev/hyperv: include netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:14:13 -0000 Author: sephe Date: Tue Oct 11 08:14:11 2016 New Revision: 307027 URL: https://svnweb.freebsd.org/changeset/base/307027 Log: MFC 302808-302815 302808 hyperv/vmbus: Alloc/Free monitor param in vmbus channel alloc/free. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7101 302809 hyperv/vmbus: Move device register and channel free to the caller. This paves the way for more cleanup/disentangle. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7102 302810 hyperv/vmbus: Move new channel scan notification to device register And nuke now unnecessary function indirection. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7103 302811 hyperv/vmbus: Cleanup vmbus_chan_msgproc_choffer Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7104 302812 hyperv/vmbus: Nuke the channel open state. Channel is either opened or not-opened. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7105 302813 hyperv/vmbus: Cleanup vmbus_chan_add() Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7106 302814 hyperv/vmbus: Use sub-channel index to detect primary channel In case that VMBUS_CHAN_ISPRIMARY is needed in the early place of channel setup. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7108 302815 hyperv/vmbus: Only add primary channels to vmbus channel list - Make the vmbus_chan_add more straightforward. - Partially fix the hv_vmbus_release_unattached_channels(). Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7109 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:14:11 2016 (r307027) @@ -244,18 +244,9 @@ typedef struct { typedef void (*hv_vmbus_pfn_channel_callback)(void *context); -typedef enum { - HV_CHANNEL_OFFER_STATE, - HV_CHANNEL_OPENING_STATE, - HV_CHANNEL_OPEN_STATE, - HV_CHANNEL_OPENED_STATE, - HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE, -} hv_vmbus_channel_state; - typedef struct hv_vmbus_channel { device_t ch_dev; struct vmbus_softc *vmbus_sc; - hv_vmbus_channel_state state; uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ uint32_t ch_id; /* channel id */ @@ -337,14 +328,15 @@ typedef struct hv_vmbus_channel { struct task ch_detach_task; TAILQ_ENTRY(hv_vmbus_channel) ch_link; uint32_t ch_subidx; /* subchan index */ - + volatile uint32_t ch_stflags; /* atomic-op */ + /* VMBUS_CHAN_ST_ */ struct hyperv_guid ch_guid_type; struct hyperv_guid ch_guid_inst; struct sysctl_ctx_list ch_sysctl_ctx; } hv_vmbus_channel; -#define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) +#define VMBUS_CHAN_ISPRIMARY(chan) ((chan)->ch_subidx == 0) #define VMBUS_CHAN_FLAG_HASMNF 0x0001 /* @@ -357,6 +349,9 @@ typedef struct hv_vmbus_channel { */ #define VMBUS_CHAN_FLAG_BATCHREAD 0x0002 +#define VMBUS_CHAN_ST_OPENED_SHIFT 0 +#define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) + static inline void hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on) { Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 08:14:11 2016 (r307027) @@ -718,11 +718,6 @@ hv_nv_on_device_remove(struct hn_softc * /* Now, we can close the channel safely */ - if (!destroy_channel) { - sc->hn_prichan->state = - HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE; - } - free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC); hv_vmbus_channel_close(sc->hn_prichan); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 08:14:11 2016 (r307027) @@ -3013,7 +3013,7 @@ static void hn_subchan_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan) { - KASSERT(!HV_VMBUS_CHAN_ISPRIMARY(chan), + KASSERT(!VMBUS_CHAN_ISPRIMARY(chan), ("subchannel callback on primary channel")); KASSERT(chan->ch_subidx > 0, ("invalid channel subidx %u", Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:14:11 2016 (r307027) @@ -191,17 +191,9 @@ hv_vmbus_channel_open( return EINVAL; } - mtx_lock(&new_channel->sc_lock); - if (new_channel->state == HV_CHANNEL_OPEN_STATE) { - new_channel->state = HV_CHANNEL_OPENING_STATE; - } else { - mtx_unlock(&new_channel->sc_lock); - if(bootverbose) - printf("VMBUS: Trying to open channel <%p> which in " - "%d state.\n", new_channel, new_channel->state); - return (EINVAL); - } - mtx_unlock(&new_channel->sc_lock); + if (atomic_testandset_int(&new_channel->ch_stflags, + VMBUS_CHAN_ST_OPENED_SHIFT)) + panic("double-open chan%u", new_channel->ch_id); new_channel->on_channel_callback = pfn_on_channel_callback; new_channel->channel_callback_context = context; @@ -223,8 +215,10 @@ hv_vmbus_channel_open( M_DEVBUF, M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); KASSERT(out != NULL, ("Error VMBUS: contigmalloc failed to allocate Ring Buffer!")); - if (out == NULL) - return (ENOMEM); + if (out == NULL) { + ret = ENOMEM; + goto failed; + } in = ((uint8_t *) out + send_ring_buffer_size); @@ -265,7 +259,8 @@ hv_vmbus_channel_open( device_printf(sc->vmbus_dev, "can not get msg hypercall for chopen(chan%u)\n", new_channel->ch_id); - return ENXIO; + ret = ENXIO; + goto failed; } req = vmbus_msghc_dataptr(mh); @@ -284,7 +279,7 @@ hv_vmbus_channel_open( "chopen(chan%u) msg hypercall exec failed: %d\n", new_channel->ch_id, ret); vmbus_msghc_put(sc, mh); - return ret; + goto failed; } msg = vmbus_msghc_wait_result(sc, mh); @@ -294,17 +289,20 @@ hv_vmbus_channel_open( vmbus_msghc_put(sc, mh); if (status == 0) { - new_channel->state = HV_CHANNEL_OPENED_STATE; if (bootverbose) { device_printf(sc->vmbus_dev, "chan%u opened\n", new_channel->ch_id); } - } else { - device_printf(sc->vmbus_dev, "failed to open chan%u\n", - new_channel->ch_id); - ret = ENXIO; + return 0; } - return (ret); + + device_printf(sc->vmbus_dev, "failed to open chan%u\n", + new_channel->ch_id); + ret = ENXIO; + +failed: + atomic_clear_int(&new_channel->ch_stflags, VMBUS_CHAN_ST_OPENED); + return ret; } /** @@ -487,7 +485,9 @@ hv_vmbus_channel_close_internal(hv_vmbus struct taskqueue *rxq = channel->rxq; int error; - channel->state = HV_CHANNEL_OPEN_STATE; + /* TODO: stringent check */ + atomic_clear_int(&channel->ch_stflags, VMBUS_CHAN_ST_OPENED); + sysctl_ctx_free(&channel->ch_sysctl_ctx); /* @@ -563,7 +563,7 @@ hv_vmbus_channel_close(hv_vmbus_channel */ TAILQ_FOREACH(sub_channel, &channel->sc_list_anchor, sc_list_entry) { - if (sub_channel->state != HV_CHANNEL_OPENED_STATE) + if ((sub_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) continue; hv_vmbus_channel_close_internal(sub_channel); } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:14:11 2016 (r307027) @@ -43,15 +43,12 @@ __FBSDID("$FreeBSD$"); typedef void (*vmbus_chanmsg_proc_t) (struct vmbus_softc *, const struct vmbus_message *); -static struct hv_vmbus_channel *hv_vmbus_allocate_channel(struct vmbus_softc *); -static void vmbus_channel_on_offer_internal(struct vmbus_softc *, - const struct vmbus_chanmsg_choffer *); static void vmbus_chan_detach_task(void *, int); -static void vmbus_channel_on_offer(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, const struct vmbus_message *); +static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, + const struct vmbus_message *); static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, const struct vmbus_message *); @@ -66,7 +63,7 @@ static void vmbus_chan_msgproc_chrescind static const vmbus_chanmsg_proc_t vmbus_chanmsg_process[VMBUS_CHANMSG_TYPE_MAX] = { - VMBUS_CHANMSG_PROC(CHOFFER, vmbus_channel_on_offer), + VMBUS_CHANMSG_PROC(CHOFFER, vmbus_chan_msgproc_choffer), VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind), VMBUS_CHANMSG_PROC(CHOFFER_DONE,vmbus_channel_on_offers_delivered), @@ -79,146 +76,125 @@ vmbus_chanmsg_process[VMBUS_CHANMSG_TYPE #undef VMBUS_CHANMSG_PROC_WAKEUP #undef VMBUS_CHANMSG_PROC -/** - * @brief Allocate and initialize a vmbus channel object - */ static struct hv_vmbus_channel * -hv_vmbus_allocate_channel(struct vmbus_softc *sc) +vmbus_chan_alloc(struct vmbus_softc *sc) { - struct hv_vmbus_channel *channel; + struct hv_vmbus_channel *chan; - channel = malloc(sizeof(*channel), M_DEVBUF, M_WAITOK | M_ZERO); - channel->vmbus_sc = sc; + chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO); - mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF); - TAILQ_INIT(&channel->sc_list_anchor); - TASK_INIT(&channel->ch_detach_task, 0, vmbus_chan_detach_task, channel); + chan->ch_monprm = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), + &chan->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (chan->ch_monprm == NULL) { + device_printf(sc->vmbus_dev, "monprm alloc failed\n"); + free(chan, M_DEVBUF); + return NULL; + } - return (channel); + chan->vmbus_sc = sc; + mtx_init(&chan->sc_lock, "vmbus multi channel", NULL, MTX_DEF); + TAILQ_INIT(&chan->sc_list_anchor); + TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); + + return chan; } -/** - * @brief Release the resources used by the vmbus channel object - */ -void -hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel) +static void +vmbus_chan_free(struct hv_vmbus_channel *chan) { - mtx_destroy(&channel->sc_lock); - free(channel, M_DEVBUF); + /* TODO: assert sub-channel list is empty */ + /* TODO: asset no longer on the primary channel's sub-channel list */ + /* TODO: asset no longer on the vmbus channel list */ + hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); + mtx_destroy(&chan->sc_lock); + free(chan, M_DEVBUF); } -/** - * @brief Process the offer by creating a channel/device - * associated with this offer - */ -static void -vmbus_channel_process_offer(hv_vmbus_channel *new_channel) +static int +vmbus_chan_add(struct hv_vmbus_channel *newchan) { - struct vmbus_softc *sc = new_channel->vmbus_sc; - hv_vmbus_channel* channel; + struct vmbus_softc *sc = newchan->vmbus_sc; + struct hv_vmbus_channel *prichan; - /* - * Make sure this is a new offer - */ - mtx_lock(&sc->vmbus_chlist_lock); - if (new_channel->ch_id == 0) { + if (newchan->ch_id == 0) { /* - * XXX channel0 will not be processed; skip it. + * XXX + * Chan0 will neither be processed nor should be offered; + * skip it. */ - printf("VMBUS: got channel0 offer\n"); - } else { - sc->vmbus_chmap[new_channel->ch_id] = new_channel; + device_printf(sc->vmbus_dev, "got chan0 offer, discard\n"); + return EINVAL; + } else if (newchan->ch_id >= VMBUS_CHAN_MAX) { + device_printf(sc->vmbus_dev, "invalid chan%u offer\n", + newchan->ch_id); + return EINVAL; } + sc->vmbus_chmap[newchan->ch_id] = newchan; - TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) { - if (memcmp(&channel->ch_guid_type, &new_channel->ch_guid_type, + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u subidx%u offer\n", + newchan->ch_id, newchan->ch_subidx); + } + + mtx_lock(&sc->vmbus_chlist_lock); + TAILQ_FOREACH(prichan, &sc->vmbus_chlist, ch_link) { + if (memcmp(&prichan->ch_guid_type, &newchan->ch_guid_type, sizeof(struct hyperv_guid)) == 0 && - memcmp(&channel->ch_guid_inst, &new_channel->ch_guid_inst, + memcmp(&prichan->ch_guid_inst, &newchan->ch_guid_inst, sizeof(struct hyperv_guid)) == 0) break; } - - if (channel == NULL) { - /* Install the new primary channel */ - TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, ch_link); - } - mtx_unlock(&sc->vmbus_chlist_lock); - - if (bootverbose) { - char logstr[64]; - - logstr[0] = '\0'; - if (channel != NULL) { - snprintf(logstr, sizeof(logstr), ", primary chan%u", - channel->ch_id); + if (VMBUS_CHAN_ISPRIMARY(newchan)) { + if (prichan == NULL) { + /* Install the new primary channel */ + TAILQ_INSERT_TAIL(&sc->vmbus_chlist, newchan, ch_link); + mtx_unlock(&sc->vmbus_chlist_lock); + return 0; + } else { + mtx_unlock(&sc->vmbus_chlist_lock); + device_printf(sc->vmbus_dev, "duplicated primary " + "chan%u\n", newchan->ch_id); + return EINVAL; } - device_printf(sc->vmbus_dev, "chan%u subchanid%u offer%s\n", - new_channel->ch_id, - new_channel->ch_subidx, logstr); - } - - if (channel != NULL) { - /* - * Check if this is a sub channel. - */ - if (new_channel->ch_subidx != 0) { - /* - * It is a sub channel offer, process it. - */ - new_channel->primary_channel = channel; - new_channel->ch_dev = channel->ch_dev; - mtx_lock(&channel->sc_lock); - TAILQ_INSERT_TAIL(&channel->sc_list_anchor, - new_channel, sc_list_entry); - mtx_unlock(&channel->sc_lock); - - /* - * Insert the new channel to the end of the global - * channel list. - * - * NOTE: - * The new sub-channel MUST be inserted AFTER it's - * primary channel, so that the primary channel will - * be found in the above loop for its baby siblings. - */ - mtx_lock(&sc->vmbus_chlist_lock); - TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, - ch_link); + } else { /* Sub-channel */ + if (prichan == NULL) { mtx_unlock(&sc->vmbus_chlist_lock); - - new_channel->state = HV_CHANNEL_OPEN_STATE; - - /* - * Bump up sub-channel count and notify anyone that is - * interested in this sub-channel, after this sub-channel - * is setup. - */ - mtx_lock(&channel->sc_lock); - channel->subchan_cnt++; - mtx_unlock(&channel->sc_lock); - wakeup(channel); - - return; + device_printf(sc->vmbus_dev, "no primary chan for " + "chan%u\n", newchan->ch_id); + return EINVAL; } - - printf("VMBUS: duplicated primary channel%u\n", - new_channel->ch_id); - hv_vmbus_free_vmbus_channel(new_channel); - return; + /* + * Found the primary channel for this sub-channel and + * move on. + * + * XXX refcnt prichan + */ } + mtx_unlock(&sc->vmbus_chlist_lock); + + /* + * This is a sub-channel; link it with the primary channel. + */ + KASSERT(!VMBUS_CHAN_ISPRIMARY(newchan), + ("new channel is not sub-channel")); + KASSERT(prichan != NULL, ("no primary channel")); - new_channel->state = HV_CHANNEL_OPEN_STATE; + newchan->primary_channel = prichan; + newchan->ch_dev = prichan->ch_dev; + mtx_lock(&prichan->sc_lock); + TAILQ_INSERT_TAIL(&prichan->sc_list_anchor, newchan, sc_list_entry); /* - * Add the new device to the bus. This will kick off device-driver - * binding which eventually invokes the device driver's AddDevice() - * method. - * - * NOTE: - * Error is ignored here; don't have much to do if error really - * happens. + * Bump up sub-channel count and notify anyone that is + * interested in this sub-channel, after this sub-channel + * is setup. */ - hv_vmbus_child_device_register(new_channel); + prichan->subchan_cnt++; + mtx_unlock(&prichan->sc_lock); + wakeup(prichan); + + return 0; } void @@ -253,7 +229,7 @@ vmbus_channel_cpu_rr(struct hv_vmbus_cha } static void -vmbus_channel_select_defcpu(struct hv_vmbus_channel *chan) +vmbus_chan_cpu_default(struct hv_vmbus_channel *chan) { /* * By default, pin the channel to cpu0. Devices having @@ -263,69 +239,68 @@ vmbus_channel_select_defcpu(struct hv_vm vmbus_channel_cpu_set(chan, 0); } -/** - * @brief Handler for channel offers from Hyper-V/Azure - * - * Handler for channel offers from vmbus in parent partition. - */ static void -vmbus_channel_on_offer(struct vmbus_softc *sc, const struct vmbus_message *msg) +vmbus_chan_msgproc_choffer(struct vmbus_softc *sc, + const struct vmbus_message *msg) { - /* New channel is offered by vmbus */ - vmbus_scan_newchan(sc); + const struct vmbus_chanmsg_choffer *offer; + struct hv_vmbus_channel *chan; + int error; - vmbus_channel_on_offer_internal(sc, - (const struct vmbus_chanmsg_choffer *)msg->msg_data); -} + offer = (const struct vmbus_chanmsg_choffer *)msg->msg_data; -static void -vmbus_channel_on_offer_internal(struct vmbus_softc *sc, - const struct vmbus_chanmsg_choffer *offer) -{ - hv_vmbus_channel* new_channel; + chan = vmbus_chan_alloc(sc); + if (chan == NULL) { + device_printf(sc->vmbus_dev, "allocate chan%u failed\n", + offer->chm_chanid); + return; + } - /* - * Allocate the channel object and save this offer - */ - new_channel = hv_vmbus_allocate_channel(sc); - new_channel->ch_id = offer->chm_chanid; - new_channel->ch_subidx = offer->chm_subidx; - new_channel->ch_guid_type = offer->chm_chtype; - new_channel->ch_guid_inst = offer->chm_chinst; + chan->ch_id = offer->chm_chanid; + chan->ch_subidx = offer->chm_subidx; + chan->ch_guid_type = offer->chm_chtype; + chan->ch_guid_inst = offer->chm_chinst; /* Batch reading is on by default */ - new_channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; - if (offer->chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) - new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; + chan->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; - new_channel->ch_monprm = hyperv_dmamem_alloc( - bus_get_dma_tag(sc->vmbus_dev), - HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), - &new_channel->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); - if (new_channel->ch_monprm == NULL) { - device_printf(sc->vmbus_dev, "monprm alloc failed\n"); - /* XXX */ - mtx_destroy(&new_channel->sc_lock); - free(new_channel, M_DEVBUF); - return; - } - new_channel->ch_monprm->mp_connid = VMBUS_CONNID_EVENT; + chan->ch_monprm->mp_connid = VMBUS_CONNID_EVENT; if (sc->vmbus_version != VMBUS_VERSION_WS2008) - new_channel->ch_monprm->mp_connid = offer->chm_connid; + chan->ch_monprm->mp_connid = offer->chm_connid; - if (new_channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { - new_channel->ch_montrig_idx = - offer->chm_montrig / VMBUS_MONTRIG_LEN; - if (new_channel->ch_montrig_idx >= VMBUS_MONTRIGS_MAX) + if (offer->chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) { + /* + * Setup MNF stuffs. + */ + chan->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; + chan->ch_montrig_idx = offer->chm_montrig / VMBUS_MONTRIG_LEN; + if (chan->ch_montrig_idx >= VMBUS_MONTRIGS_MAX) panic("invalid monitor trigger %u", offer->chm_montrig); - new_channel->ch_montrig_mask = + chan->ch_montrig_mask = 1 << (offer->chm_montrig % VMBUS_MONTRIG_LEN); } /* Select default cpu for this channel. */ - vmbus_channel_select_defcpu(new_channel); + vmbus_chan_cpu_default(chan); - vmbus_channel_process_offer(new_channel); + error = vmbus_chan_add(chan); + if (error) { + device_printf(sc->vmbus_dev, "add chan%u failed: %d\n", + chan->ch_id, error); + vmbus_chan_free(chan); + return; + } + + if (VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * Add device for this primary channel. + * + * NOTE: + * Error is ignored here; don't have much to do if error + * really happens. + */ + hv_vmbus_child_device_register(chan); + } } /* @@ -363,7 +338,7 @@ vmbus_chan_detach_task(void *xchan, int { struct hv_vmbus_channel *chan = xchan; - if (HV_VMBUS_CHAN_ISPRIMARY(chan)) { + if (VMBUS_CHAN_ISPRIMARY(chan)) { /* Only primary channel owns the device */ hv_vmbus_child_device_unregister(chan); /* NOTE: DO NOT free primary channel for now */ @@ -401,10 +376,6 @@ vmbus_chan_detach_task(void *xchan, int } } remove: - mtx_lock(&sc->vmbus_chlist_lock); - TAILQ_REMOVE(&sc->vmbus_chlist, chan, ch_link); - mtx_unlock(&sc->vmbus_chlist_lock); - mtx_lock(&pri_chan->sc_lock); TAILQ_REMOVE(&pri_chan->sc_list_anchor, chan, sc_list_entry); KASSERT(pri_chan->subchan_cnt > 0, @@ -413,7 +384,7 @@ remove: mtx_unlock(&pri_chan->sc_lock); wakeup(pri_chan); - hv_vmbus_free_vmbus_channel(chan); + vmbus_chan_free(chan); } } @@ -442,13 +413,11 @@ hv_vmbus_release_unattached_channels(str while (!TAILQ_EMPTY(&sc->vmbus_chlist)) { channel = TAILQ_FIRST(&sc->vmbus_chlist); + KASSERT(VMBUS_CHAN_ISPRIMARY(channel), ("not primary channel")); TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link); - if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { - /* Only primary channel owns the device */ - hv_vmbus_child_device_unregister(channel); - } - hv_vmbus_free_vmbus_channel(channel); + hv_vmbus_child_device_unregister(channel); + vmbus_chan_free(channel); } bzero(sc->vmbus_chmap, sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX); @@ -486,7 +455,7 @@ vmbus_select_outgoing_channel(struct hv_ cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) { - if (new_channel->state != HV_CHANNEL_OPENED_STATE){ + if ((new_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) { continue; } Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:14:11 2016 (r307027) @@ -55,7 +55,6 @@ typedef struct { typedef struct { uint32_t rel_id; - hv_vmbus_channel_state state; struct hyperv_guid interface_type; struct hyperv_guid interface_instance; uint32_t monitor_id; @@ -147,7 +146,6 @@ void hv_ring_buffer_read_begin( uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); -void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); void hv_vmbus_release_unattached_channels( struct vmbus_softc *); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:01:43 2016 (r307026) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:14:11 2016 (r307027) @@ -1074,6 +1074,9 @@ hv_vmbus_child_device_register(struct hv device_t parent = sc->vmbus_dev; int error = 0; + /* New channel has been offered */ + vmbus_scan_newchan(sc); + chan->ch_dev = device_add_child(parent, NULL, -1); if (chan->ch_dev == NULL) { device_printf(parent, "device_add_child for chan%u failed\n", From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:22:19 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B2C90C0DECD; Tue, 11 Oct 2016 08:22:19 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8F8B5CAA; Tue, 11 Oct 2016 08:22:19 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8MINw030437; Tue, 11 Oct 2016 08:22:18 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8MIH8030431; Tue, 11 Oct 2016 08:22:18 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110822.u9B8MIH8030431@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:22:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307028 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:22:19 -0000 Author: sephe Date: Tue Oct 11 08:22:17 2016 New Revision: 307028 URL: https://svnweb.freebsd.org/changeset/base/307028 Log: MFC 302816-302818 302816 hyperv/vmbus: Release vmbus channel lock before detach devices Device detach method may sleep. While I'm here, rename the function, fix indentation and function comment. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7110 302817 hyperv/vmbus: Field renaming to reflect reality Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7111 302818 hyperv/vmbus: Fix the racy channel close. It is not safe to iterate the sub-channel list w/o lock on the close path, while it's even more difficult to hold the lock and iterate the sub-channel list. We leverage the vmbua_{get,rel}_subchan() functions to solve this dilemma. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7112 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:22:17 2016 (r307028) @@ -326,7 +326,7 @@ typedef struct hv_vmbus_channel { void *hv_chan_priv3; struct task ch_detach_task; - TAILQ_ENTRY(hv_vmbus_channel) ch_link; + TAILQ_ENTRY(hv_vmbus_channel) ch_prilink; /* primary chan link */ uint32_t ch_subidx; /* subchan index */ volatile uint32_t ch_stflags; /* atomic-op */ /* VMBUS_CHAN_ST_ */ Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:22:17 2016 (r307028) @@ -542,35 +542,40 @@ hv_vmbus_channel_close_internal(hv_vmbus M_DEVBUF); } -/** - * @brief Close the specified channel +/* + * Caller should make sure that all sub-channels have + * been added to 'chan' and all to-be-closed channels + * are not being opened. */ void -hv_vmbus_channel_close(hv_vmbus_channel *channel) +hv_vmbus_channel_close(struct hv_vmbus_channel *chan) { - hv_vmbus_channel* sub_channel; + int subchan_cnt; - if (channel->primary_channel != NULL) { + if (!VMBUS_CHAN_ISPRIMARY(chan)) { /* - * We only close multi-channels when the primary is - * closed. + * Sub-channel is closed when its primary channel + * is closed; done. */ return; } /* - * Close all multi-channels first. + * Close all sub-channels, if any. */ - TAILQ_FOREACH(sub_channel, &channel->sc_list_anchor, - sc_list_entry) { - if ((sub_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) - continue; - hv_vmbus_channel_close_internal(sub_channel); + subchan_cnt = chan->subchan_cnt; + if (subchan_cnt > 0) { + struct hv_vmbus_channel **subchan; + int i; + + subchan = vmbus_get_subchan(chan, subchan_cnt); + for (i = 0; i < subchan_cnt; ++i) + hv_vmbus_channel_close_internal(subchan[i]); + vmbus_rel_subchan(subchan, subchan_cnt); } - /* - * Then close the primary channel. - */ - hv_vmbus_channel_close_internal(channel); + + /* Then close the primary channel. */ + hv_vmbus_channel_close_internal(chan); } /** Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:22:17 2016 (r307028) @@ -137,8 +137,8 @@ vmbus_chan_add(struct hv_vmbus_channel * newchan->ch_id, newchan->ch_subidx); } - mtx_lock(&sc->vmbus_chlist_lock); - TAILQ_FOREACH(prichan, &sc->vmbus_chlist, ch_link) { + mtx_lock(&sc->vmbus_prichan_lock); + TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) { if (memcmp(&prichan->ch_guid_type, &newchan->ch_guid_type, sizeof(struct hyperv_guid)) == 0 && memcmp(&prichan->ch_guid_inst, &newchan->ch_guid_inst, @@ -148,18 +148,19 @@ vmbus_chan_add(struct hv_vmbus_channel * if (VMBUS_CHAN_ISPRIMARY(newchan)) { if (prichan == NULL) { /* Install the new primary channel */ - TAILQ_INSERT_TAIL(&sc->vmbus_chlist, newchan, ch_link); - mtx_unlock(&sc->vmbus_chlist_lock); + TAILQ_INSERT_TAIL(&sc->vmbus_prichans, newchan, + ch_prilink); + mtx_unlock(&sc->vmbus_prichan_lock); return 0; } else { - mtx_unlock(&sc->vmbus_chlist_lock); + mtx_unlock(&sc->vmbus_prichan_lock); device_printf(sc->vmbus_dev, "duplicated primary " "chan%u\n", newchan->ch_id); return EINVAL; } } else { /* Sub-channel */ if (prichan == NULL) { - mtx_unlock(&sc->vmbus_chlist_lock); + mtx_unlock(&sc->vmbus_prichan_lock); device_printf(sc->vmbus_dev, "no primary chan for " "chan%u\n", newchan->ch_id); return EINVAL; @@ -171,7 +172,7 @@ vmbus_chan_add(struct hv_vmbus_channel * * XXX refcnt prichan */ } - mtx_unlock(&sc->vmbus_chlist_lock); + mtx_unlock(&sc->vmbus_prichan_lock); /* * This is a sub-channel; link it with the primary channel. @@ -401,28 +402,28 @@ vmbus_channel_on_offers_delivered(struct vmbus_scan_done(sc); } -/** - * @brief Release channels that are unattached/unconnected (i.e., no drivers associated) +/* + * Detach all devices and destroy the corresponding primary channels. */ void -hv_vmbus_release_unattached_channels(struct vmbus_softc *sc) +vmbus_chan_destroy_all(struct vmbus_softc *sc) { - hv_vmbus_channel *channel; + struct hv_vmbus_channel *chan; - mtx_lock(&sc->vmbus_chlist_lock); + mtx_lock(&sc->vmbus_prichan_lock); + while ((chan = TAILQ_FIRST(&sc->vmbus_prichans)) != NULL) { + KASSERT(VMBUS_CHAN_ISPRIMARY(chan), ("not primary channel")); + TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink); + mtx_unlock(&sc->vmbus_prichan_lock); - while (!TAILQ_EMPTY(&sc->vmbus_chlist)) { - channel = TAILQ_FIRST(&sc->vmbus_chlist); - KASSERT(VMBUS_CHAN_ISPRIMARY(channel), ("not primary channel")); - TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link); + hv_vmbus_child_device_unregister(chan); + vmbus_chan_free(chan); - hv_vmbus_child_device_unregister(channel); - vmbus_chan_free(channel); + mtx_lock(&sc->vmbus_prichan_lock); } bzero(sc->vmbus_chmap, sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX); - - mtx_unlock(&sc->vmbus_chlist_lock); + mtx_unlock(&sc->vmbus_prichan_lock); } /** Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:22:17 2016 (r307028) @@ -146,9 +146,6 @@ void hv_ring_buffer_read_begin( uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); -void hv_vmbus_release_unattached_channels( - struct vmbus_softc *); - int hv_vmbus_child_device_register( struct hv_vmbus_channel *chan); int hv_vmbus_child_device_unregister( Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:22:17 2016 (r307028) @@ -1184,8 +1184,8 @@ vmbus_doattach(struct vmbus_softc *sc) mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF); sc->vmbus_gpadl = VMBUS_GPADL_START; - mtx_init(&sc->vmbus_chlist_lock, "vmbus chlist", NULL, MTX_DEF); - TAILQ_INIT(&sc->vmbus_chlist); + mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF); + TAILQ_INIT(&sc->vmbus_prichans); sc->vmbus_chmap = malloc( sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); @@ -1256,7 +1256,7 @@ cleanup: } free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); - mtx_destroy(&sc->vmbus_chlist_lock); + mtx_destroy(&sc->vmbus_prichan_lock); return (ret); } @@ -1314,7 +1314,7 @@ vmbus_detach(device_t dev) { struct vmbus_softc *sc = device_get_softc(dev); - hv_vmbus_release_unattached_channels(sc); + vmbus_chan_destroy_all(sc); vmbus_disconnect(sc); @@ -1333,7 +1333,7 @@ vmbus_detach(device_t dev) free(sc->vmbus_chmap, M_DEVBUF); mtx_destroy(&sc->vmbus_scan_lock); - mtx_destroy(&sc->vmbus_chlist_lock); + mtx_destroy(&sc->vmbus_prichan_lock); return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:14:11 2016 (r307027) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:22:17 2016 (r307028) @@ -101,8 +101,9 @@ struct vmbus_softc { #define VMBUS_SCAN_CHCNT_DONE 0x80000000 uint32_t vmbus_scan_devcnt; - struct mtx vmbus_chlist_lock; - TAILQ_HEAD(, hv_vmbus_channel) vmbus_chlist; + /* Primary channels */ + struct mtx vmbus_prichan_lock; + TAILQ_HEAD(, hv_vmbus_channel) vmbus_prichans; }; #define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */ @@ -137,6 +138,7 @@ void vmbus_handle_intr(struct trapframe void vmbus_et_intr(struct trapframe *); void vmbus_chan_msgproc(struct vmbus_softc *, const struct vmbus_message *); +void vmbus_chan_destroy_all(struct vmbus_softc *); struct vmbus_msghc *vmbus_msghc_get(struct vmbus_softc *, size_t); void vmbus_msghc_put(struct vmbus_softc *, struct vmbus_msghc *); From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:29:06 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9088EC0C0E1; Tue, 11 Oct 2016 08:29:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 60E1EA8; Tue, 11 Oct 2016 08:29:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8T5pH030808; Tue, 11 Oct 2016 08:29:05 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8T5kq030803; Tue, 11 Oct 2016 08:29:05 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110829.u9B8T5kq030803@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:29:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307029 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:29:06 -0000 Author: sephe Date: Tue Oct 11 08:29:04 2016 New Revision: 307029 URL: https://svnweb.freebsd.org/changeset/base/307029 Log: MFC 302819,302823 302819 hyperv/vmbus: Sub-channel related fields renaming And reorganize comment. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7113 302823 hyperv/vmbus: Move bus related message processing into vmbus. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7125 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:22:17 2016 (r307028) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:29:04 2016 (r307029) @@ -293,30 +293,17 @@ typedef struct hv_vmbus_channel { uint32_t target_cpu; /* - * Support for multi-channels. - * The initial offer is considered the primary channel and this - * offer message will indicate if the host supports multi-channels. - * The guest is free to ask for multi-channels to be offerred and can - * open these multi-channels as a normal "primary" channel. However, - * all multi-channels will have the same type and instance guids as the - * primary channel. Requests sent on a given channel will result in a - * response on the same channel. + * If this is a primary channel, ch_subchan* fields + * contain sub-channels belonging to this primary + * channel. */ - - struct mtx sc_lock; - - /* - * Link list of all the multi-channels if this is a primary channel - */ - TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor; - TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry; - int subchan_cnt; - - /* - * The primary channel this sub-channle belongs to. - * This will be NULL for the primary channel. - */ - struct hv_vmbus_channel *primary_channel; + struct mtx ch_subchan_lock; + TAILQ_HEAD(, hv_vmbus_channel) ch_subchans; + int ch_subchan_cnt; + + /* If this is a sub-channel */ + TAILQ_ENTRY(hv_vmbus_channel) ch_sublink; /* sub-channel link */ + struct hv_vmbus_channel *ch_prichan; /* owner primary chan */ /* * Driver private data Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:22:17 2016 (r307028) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:29:04 2016 (r307029) @@ -100,7 +100,7 @@ vmbus_channel_sysctl_create(hv_vmbus_cha uint16_t sub_ch_id; char name[16]; - hv_vmbus_channel* primary_ch = channel->primary_channel; + hv_vmbus_channel* primary_ch = channel->ch_prichan; if (primary_ch == NULL) { dev = channel->ch_dev; @@ -563,7 +563,7 @@ hv_vmbus_channel_close(struct hv_vmbus_c /* * Close all sub-channels, if any. */ - subchan_cnt = chan->subchan_cnt; + subchan_cnt = chan->ch_subchan_cnt; if (subchan_cnt > 0) { struct hv_vmbus_channel **subchan; int i; Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:22:17 2016 (r307028) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Oct 11 08:29:04 2016 (r307029) @@ -40,13 +40,8 @@ __FBSDID("$FreeBSD$"); #include #include -typedef void (*vmbus_chanmsg_proc_t) - (struct vmbus_softc *, const struct vmbus_message *); - static void vmbus_chan_detach_task(void *, int); -static void vmbus_channel_on_offers_delivered(struct vmbus_softc *, - const struct vmbus_message *); static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, const struct vmbus_message *); static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, @@ -55,27 +50,16 @@ static void vmbus_chan_msgproc_chrescind /* * Vmbus channel message processing. */ - -#define VMBUS_CHANMSG_PROC(name, func) \ - [VMBUS_CHANMSG_TYPE_##name] = func -#define VMBUS_CHANMSG_PROC_WAKEUP(name) \ - VMBUS_CHANMSG_PROC(name, vmbus_msghc_wakeup) - static const vmbus_chanmsg_proc_t -vmbus_chanmsg_process[VMBUS_CHANMSG_TYPE_MAX] = { +vmbus_chan_msgprocs[VMBUS_CHANMSG_TYPE_MAX] = { VMBUS_CHANMSG_PROC(CHOFFER, vmbus_chan_msgproc_choffer), VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind), - VMBUS_CHANMSG_PROC(CHOFFER_DONE,vmbus_channel_on_offers_delivered), VMBUS_CHANMSG_PROC_WAKEUP(CHOPEN_RESP), VMBUS_CHANMSG_PROC_WAKEUP(GPADL_CONNRESP), - VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP), - VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP) }; -#undef VMBUS_CHANMSG_PROC_WAKEUP -#undef VMBUS_CHANMSG_PROC - static struct hv_vmbus_channel * vmbus_chan_alloc(struct vmbus_softc *sc) { @@ -93,8 +77,8 @@ vmbus_chan_alloc(struct vmbus_softc *sc) } chan->vmbus_sc = sc; - mtx_init(&chan->sc_lock, "vmbus multi channel", NULL, MTX_DEF); - TAILQ_INIT(&chan->sc_list_anchor); + mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); + TAILQ_INIT(&chan->ch_subchans); TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); return chan; @@ -107,7 +91,7 @@ vmbus_chan_free(struct hv_vmbus_channel /* TODO: asset no longer on the primary channel's sub-channel list */ /* TODO: asset no longer on the vmbus channel list */ hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); - mtx_destroy(&chan->sc_lock); + mtx_destroy(&chan->ch_subchan_lock); free(chan, M_DEVBUF); } @@ -139,6 +123,10 @@ vmbus_chan_add(struct hv_vmbus_channel * mtx_lock(&sc->vmbus_prichan_lock); TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) { + /* + * Sub-channel will have the same type GUID and instance + * GUID as its primary channel. + */ if (memcmp(&prichan->ch_guid_type, &newchan->ch_guid_type, sizeof(struct hyperv_guid)) == 0 && memcmp(&prichan->ch_guid_inst, &newchan->ch_guid_inst, @@ -181,18 +169,18 @@ vmbus_chan_add(struct hv_vmbus_channel * ("new channel is not sub-channel")); KASSERT(prichan != NULL, ("no primary channel")); - newchan->primary_channel = prichan; + newchan->ch_prichan = prichan; newchan->ch_dev = prichan->ch_dev; - mtx_lock(&prichan->sc_lock); - TAILQ_INSERT_TAIL(&prichan->sc_list_anchor, newchan, sc_list_entry); + mtx_lock(&prichan->ch_subchan_lock); + TAILQ_INSERT_TAIL(&prichan->ch_subchans, newchan, ch_sublink); /* * Bump up sub-channel count and notify anyone that is * interested in this sub-channel, after this sub-channel * is setup. */ - prichan->subchan_cnt++; - mtx_unlock(&prichan->sc_lock); + prichan->ch_subchan_cnt++; + mtx_unlock(&prichan->ch_subchan_lock); wakeup(prichan); return 0; @@ -345,7 +333,7 @@ vmbus_chan_detach_task(void *xchan, int /* NOTE: DO NOT free primary channel for now */ } else { struct vmbus_softc *sc = chan->vmbus_sc; - struct hv_vmbus_channel *pri_chan = chan->primary_channel; + struct hv_vmbus_channel *pri_chan = chan->ch_prichan; struct vmbus_chanmsg_chfree *req; struct vmbus_msghc *mh; int error; @@ -377,31 +365,18 @@ vmbus_chan_detach_task(void *xchan, int } } remove: - mtx_lock(&pri_chan->sc_lock); - TAILQ_REMOVE(&pri_chan->sc_list_anchor, chan, sc_list_entry); - KASSERT(pri_chan->subchan_cnt > 0, - ("invalid subchan_cnt %d", pri_chan->subchan_cnt)); - pri_chan->subchan_cnt--; - mtx_unlock(&pri_chan->sc_lock); + mtx_lock(&pri_chan->ch_subchan_lock); + TAILQ_REMOVE(&pri_chan->ch_subchans, chan, ch_sublink); + KASSERT(pri_chan->ch_subchan_cnt > 0, + ("invalid subchan_cnt %d", pri_chan->ch_subchan_cnt)); + pri_chan->ch_subchan_cnt--; + mtx_unlock(&pri_chan->ch_subchan_lock); wakeup(pri_chan); vmbus_chan_free(chan); } } -/** - * - * @brief Invoked when all offers have been delivered. - */ -static void -vmbus_channel_on_offers_delivered(struct vmbus_softc *sc, - const struct vmbus_message *msg __unused) -{ - - /* No more new channels for the channel request. */ - vmbus_scan_done(sc); -} - /* * Detach all devices and destroy the corresponding primary channels. */ @@ -445,7 +420,7 @@ vmbus_select_outgoing_channel(struct hv_ int cur_vcpu = 0; int smp_pro_id = PCPU_GET(cpuid); - if (TAILQ_EMPTY(&primary->sc_list_anchor)) { + if (TAILQ_EMPTY(&primary->ch_subchans)) { return outgoing_channel; } @@ -455,7 +430,8 @@ vmbus_select_outgoing_channel(struct hv_ cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); - TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) { + /* XXX need lock */ + TAILQ_FOREACH(new_channel, &primary->ch_subchans, ch_sublink) { if ((new_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) { continue; } @@ -491,13 +467,13 @@ vmbus_get_subchan(struct hv_vmbus_channe ret = malloc(subchan_cnt * sizeof(struct hv_vmbus_channel *), M_TEMP, M_WAITOK); - mtx_lock(&pri_chan->sc_lock); + mtx_lock(&pri_chan->ch_subchan_lock); - while (pri_chan->subchan_cnt < subchan_cnt) - mtx_sleep(pri_chan, &pri_chan->sc_lock, 0, "subch", 0); + while (pri_chan->ch_subchan_cnt < subchan_cnt) + mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "subch", 0); i = 0; - TAILQ_FOREACH(chan, &pri_chan->sc_list_anchor, sc_list_entry) { + TAILQ_FOREACH(chan, &pri_chan->ch_subchans, ch_sublink) { /* TODO: refcnt chan */ ret[i] = chan; @@ -506,9 +482,9 @@ vmbus_get_subchan(struct hv_vmbus_channe break; } KASSERT(i == subchan_cnt, ("invalid subchan count %d, should be %d", - pri_chan->subchan_cnt, subchan_cnt)); + pri_chan->ch_subchan_cnt, subchan_cnt)); - mtx_unlock(&pri_chan->sc_lock); + mtx_unlock(&pri_chan->ch_subchan_lock); return ret; } @@ -523,10 +499,10 @@ vmbus_rel_subchan(struct hv_vmbus_channe void vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan) { - mtx_lock(&pri_chan->sc_lock); - while (pri_chan->subchan_cnt > 0) - mtx_sleep(pri_chan, &pri_chan->sc_lock, 0, "dsubch", 0); - mtx_unlock(&pri_chan->sc_lock); + mtx_lock(&pri_chan->ch_subchan_lock); + while (pri_chan->ch_subchan_cnt > 0) + mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "dsubch", 0); + mtx_unlock(&pri_chan->ch_subchan_lock); } void @@ -536,13 +512,10 @@ vmbus_chan_msgproc(struct vmbus_softc *s uint32_t msg_type; msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type; - if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) { - device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", - msg_type); - return; - } + KASSERT(msg_type < VMBUS_CHANMSG_TYPE_MAX, + ("invalid message type %u", msg_type)); - msg_proc = vmbus_chanmsg_process[msg_type]; + msg_proc = vmbus_chan_msgprocs[msg_type]; if (msg_proc != NULL) msg_proc(sc, msg); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:22:17 2016 (r307028) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:29:04 2016 (r307029) @@ -98,7 +98,12 @@ static int vmbus_req_channels(struct v static void vmbus_disconnect(struct vmbus_softc *); static int vmbus_scan(struct vmbus_softc *); static void vmbus_scan_wait(struct vmbus_softc *); +static void vmbus_scan_newchan(struct vmbus_softc *); static void vmbus_scan_newdev(struct vmbus_softc *); +static void vmbus_scan_done(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_chanmsg_handle(struct vmbus_softc *, + const struct vmbus_message *); static int vmbus_sysctl_version(SYSCTL_HANDLER_ARGS); @@ -122,6 +127,12 @@ static const uint32_t vmbus_version[] = VMBUS_VERSION_WS2008 }; +static const vmbus_chanmsg_proc_t +vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = { + VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done), + VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) +}; + static struct vmbus_msghc * vmbus_msghc_alloc(bus_dma_tag_t parent_dtag) { @@ -480,7 +491,7 @@ vmbus_req_channels(struct vmbus_softc *s return error; } -void +static void vmbus_scan_newchan(struct vmbus_softc *sc) { mtx_lock(&sc->vmbus_scan_lock); @@ -489,8 +500,9 @@ vmbus_scan_newchan(struct vmbus_softc *s mtx_unlock(&sc->vmbus_scan_lock); } -void -vmbus_scan_done(struct vmbus_softc *sc) +static void +vmbus_scan_done(struct vmbus_softc *sc, + const struct vmbus_message *msg __unused) { mtx_lock(&sc->vmbus_scan_lock); sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE; @@ -560,6 +572,27 @@ vmbus_scan(struct vmbus_softc *sc) } static void +vmbus_chanmsg_handle(struct vmbus_softc *sc, const struct vmbus_message *msg) +{ + vmbus_chanmsg_proc_t msg_proc; + uint32_t msg_type; + + msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type; + if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) { + device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", + msg_type); + return; + } + + msg_proc = vmbus_chanmsg_handlers[msg_type]; + if (msg_proc != NULL) + msg_proc(sc, msg); + + /* Channel specific processing */ + vmbus_chan_msgproc(sc, msg); +} + +static void vmbus_msg_task(void *xsc, int pending __unused) { struct vmbus_softc *sc = xsc; @@ -572,7 +605,7 @@ vmbus_msg_task(void *xsc, int pending __ break; } else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) { /* Channel message */ - vmbus_chan_msgproc(sc, + vmbus_chanmsg_handle(sc, __DEVOLATILE(const struct vmbus_message *, msg)); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:22:17 2016 (r307028) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:29:04 2016 (r307029) @@ -51,6 +51,17 @@ #define VMBUS_CONNID_MESSAGE 1 #define VMBUS_CONNID_EVENT 2 +struct vmbus_message; +struct vmbus_softc; + +typedef void (*vmbus_chanmsg_proc_t)(struct vmbus_softc *, + const struct vmbus_message *); + +#define VMBUS_CHANMSG_PROC(name, func) \ + [VMBUS_CHANMSG_TYPE_##name] = func +#define VMBUS_CHANMSG_PROC_WAKEUP(name) \ + VMBUS_CHANMSG_PROC(name, vmbus_msghc_wakeup) + struct vmbus_pcpu_data { u_long *intr_cnt; /* Hyper-V interrupt counter */ struct vmbus_message *message; /* shared messages */ @@ -150,9 +161,6 @@ const struct vmbus_message *vmbus_msghc_ void vmbus_msghc_wakeup(struct vmbus_softc *, const struct vmbus_message *); void vmbus_msghc_reset(struct vmbus_msghc *, size_t); -void vmbus_scan_done(struct vmbus_softc *); -void vmbus_scan_newchan(struct vmbus_softc *); - uint32_t vmbus_gpadl_alloc(struct vmbus_softc *); #endif /* !_VMBUS_VAR_H_ */ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:41:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D40B1C0C453; Tue, 11 Oct 2016 08:41:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A034F987; Tue, 11 Oct 2016 08:41:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8fRPD037395; Tue, 11 Oct 2016 08:41:27 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8fRCm037391; Tue, 11 Oct 2016 08:41:27 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110841.u9B8fRCm037391@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:41:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307030 - in stable/10/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:41:28 -0000 Author: sephe Date: Tue Oct 11 08:41:27 2016 New Revision: 307030 URL: https://svnweb.freebsd.org/changeset/base/307030 Log: MFC 302864 hyperv/vmbus: Merge hv_channel_mgmt.c into hv_channel.c Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7126 Deleted: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Tue Oct 11 08:29:04 2016 (r307029) +++ stable/10/sys/conf/files.amd64 Tue Oct 11 08:41:27 2016 (r307030) @@ -272,7 +272,6 @@ dev/hyperv/utilities/hv_shutdown.c opt dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv -dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Tue Oct 11 08:29:04 2016 (r307029) +++ stable/10/sys/conf/files.i386 Tue Oct 11 08:41:27 2016 (r307030) @@ -249,7 +249,6 @@ dev/hyperv/utilities/hv_shutdown.c opt dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv dev/hyperv/vmbus/hv_channel.c optional hyperv -dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:29:04 2016 (r307029) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:41:27 2016 (r307030) @@ -53,8 +53,28 @@ __FBSDID("$FreeBSD$"); static void vmbus_chan_send_event(hv_vmbus_channel* channel); static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, const struct hv_vmbus_channel *); + static void vmbus_chan_task(void *, int); static void vmbus_chan_task_nobatch(void *, int); +static void vmbus_chan_detach_task(void *, int); + +static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, + const struct vmbus_message *); + +/* + * Vmbus channel message processing. + */ +static const vmbus_chanmsg_proc_t +vmbus_chan_msgprocs[VMBUS_CHANMSG_TYPE_MAX] = { + VMBUS_CHANMSG_PROC(CHOFFER, vmbus_chan_msgproc_choffer), + VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind), + + VMBUS_CHANMSG_PROC_WAKEUP(CHOPEN_RESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_CONNRESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP) +}; /** * @brief Trigger an event notification on the specified channel @@ -984,3 +1004,463 @@ vmbus_chan_update_evtflagcnt(struct vmbu } } } + +static struct hv_vmbus_channel * +vmbus_chan_alloc(struct vmbus_softc *sc) +{ + struct hv_vmbus_channel *chan; + + chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO); + + chan->ch_monprm = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), + &chan->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (chan->ch_monprm == NULL) { + device_printf(sc->vmbus_dev, "monprm alloc failed\n"); + free(chan, M_DEVBUF); + return NULL; + } + + chan->vmbus_sc = sc; + mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); + TAILQ_INIT(&chan->ch_subchans); + TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); + + return chan; +} + +static void +vmbus_chan_free(struct hv_vmbus_channel *chan) +{ + /* TODO: assert sub-channel list is empty */ + /* TODO: asset no longer on the primary channel's sub-channel list */ + /* TODO: asset no longer on the vmbus channel list */ + hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); + mtx_destroy(&chan->ch_subchan_lock); + free(chan, M_DEVBUF); +} + +static int +vmbus_chan_add(struct hv_vmbus_channel *newchan) +{ + struct vmbus_softc *sc = newchan->vmbus_sc; + struct hv_vmbus_channel *prichan; + + if (newchan->ch_id == 0) { + /* + * XXX + * Chan0 will neither be processed nor should be offered; + * skip it. + */ + device_printf(sc->vmbus_dev, "got chan0 offer, discard\n"); + return EINVAL; + } else if (newchan->ch_id >= VMBUS_CHAN_MAX) { + device_printf(sc->vmbus_dev, "invalid chan%u offer\n", + newchan->ch_id); + return EINVAL; + } + sc->vmbus_chmap[newchan->ch_id] = newchan; + + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u subidx%u offer\n", + newchan->ch_id, newchan->ch_subidx); + } + + mtx_lock(&sc->vmbus_prichan_lock); + TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) { + /* + * Sub-channel will have the same type GUID and instance + * GUID as its primary channel. + */ + if (memcmp(&prichan->ch_guid_type, &newchan->ch_guid_type, + sizeof(struct hyperv_guid)) == 0 && + memcmp(&prichan->ch_guid_inst, &newchan->ch_guid_inst, + sizeof(struct hyperv_guid)) == 0) + break; + } + if (VMBUS_CHAN_ISPRIMARY(newchan)) { + if (prichan == NULL) { + /* Install the new primary channel */ + TAILQ_INSERT_TAIL(&sc->vmbus_prichans, newchan, + ch_prilink); + mtx_unlock(&sc->vmbus_prichan_lock); + return 0; + } else { + mtx_unlock(&sc->vmbus_prichan_lock); + device_printf(sc->vmbus_dev, "duplicated primary " + "chan%u\n", newchan->ch_id); + return EINVAL; + } + } else { /* Sub-channel */ + if (prichan == NULL) { + mtx_unlock(&sc->vmbus_prichan_lock); + device_printf(sc->vmbus_dev, "no primary chan for " + "chan%u\n", newchan->ch_id); + return EINVAL; + } + /* + * Found the primary channel for this sub-channel and + * move on. + * + * XXX refcnt prichan + */ + } + mtx_unlock(&sc->vmbus_prichan_lock); + + /* + * This is a sub-channel; link it with the primary channel. + */ + KASSERT(!VMBUS_CHAN_ISPRIMARY(newchan), + ("new channel is not sub-channel")); + KASSERT(prichan != NULL, ("no primary channel")); + + newchan->ch_prichan = prichan; + newchan->ch_dev = prichan->ch_dev; + + mtx_lock(&prichan->ch_subchan_lock); + TAILQ_INSERT_TAIL(&prichan->ch_subchans, newchan, ch_sublink); + /* + * Bump up sub-channel count and notify anyone that is + * interested in this sub-channel, after this sub-channel + * is setup. + */ + prichan->ch_subchan_cnt++; + mtx_unlock(&prichan->ch_subchan_lock); + wakeup(prichan); + + return 0; +} + +void +vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu) +{ + KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu)); + + if (chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WS2008 || + chan->vmbus_sc->vmbus_version == VMBUS_VERSION_WIN7) { + /* Only cpu0 is supported */ + cpu = 0; + } + + chan->target_cpu = cpu; + chan->target_vcpu = VMBUS_PCPU_GET(chan->vmbus_sc, vcpuid, cpu); + + if (bootverbose) { + printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", + chan->ch_id, + chan->target_cpu, chan->target_vcpu); + } +} + +void +vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan) +{ + static uint32_t vmbus_chan_nextcpu; + int cpu; + + cpu = atomic_fetchadd_int(&vmbus_chan_nextcpu, 1) % mp_ncpus; + vmbus_channel_cpu_set(chan, cpu); +} + +static void +vmbus_chan_cpu_default(struct hv_vmbus_channel *chan) +{ + /* + * By default, pin the channel to cpu0. Devices having + * special channel-cpu mapping requirement should call + * vmbus_channel_cpu_{set,rr}(). + */ + vmbus_channel_cpu_set(chan, 0); +} + +static void +vmbus_chan_msgproc_choffer(struct vmbus_softc *sc, + const struct vmbus_message *msg) +{ + const struct vmbus_chanmsg_choffer *offer; + struct hv_vmbus_channel *chan; + int error; + + offer = (const struct vmbus_chanmsg_choffer *)msg->msg_data; + + chan = vmbus_chan_alloc(sc); + if (chan == NULL) { + device_printf(sc->vmbus_dev, "allocate chan%u failed\n", + offer->chm_chanid); + return; + } + + chan->ch_id = offer->chm_chanid; + chan->ch_subidx = offer->chm_subidx; + chan->ch_guid_type = offer->chm_chtype; + chan->ch_guid_inst = offer->chm_chinst; + + /* Batch reading is on by default */ + chan->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; + + chan->ch_monprm->mp_connid = VMBUS_CONNID_EVENT; + if (sc->vmbus_version != VMBUS_VERSION_WS2008) + chan->ch_monprm->mp_connid = offer->chm_connid; + + if (offer->chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) { + /* + * Setup MNF stuffs. + */ + chan->ch_flags |= VMBUS_CHAN_FLAG_HASMNF; + chan->ch_montrig_idx = offer->chm_montrig / VMBUS_MONTRIG_LEN; + if (chan->ch_montrig_idx >= VMBUS_MONTRIGS_MAX) + panic("invalid monitor trigger %u", offer->chm_montrig); + chan->ch_montrig_mask = + 1 << (offer->chm_montrig % VMBUS_MONTRIG_LEN); + } + + /* Select default cpu for this channel. */ + vmbus_chan_cpu_default(chan); + + error = vmbus_chan_add(chan); + if (error) { + device_printf(sc->vmbus_dev, "add chan%u failed: %d\n", + chan->ch_id, error); + vmbus_chan_free(chan); + return; + } + + if (VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * Add device for this primary channel. + * + * NOTE: + * Error is ignored here; don't have much to do if error + * really happens. + */ + hv_vmbus_child_device_register(chan); + } +} + +/* + * XXX pretty broken; need rework. + */ +static void +vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc, + const struct vmbus_message *msg) +{ + const struct vmbus_chanmsg_chrescind *note; + struct hv_vmbus_channel *chan; + + note = (const struct vmbus_chanmsg_chrescind *)msg->msg_data; + if (note->chm_chanid > VMBUS_CHAN_MAX) { + device_printf(sc->vmbus_dev, "invalid rescinded chan%u\n", + note->chm_chanid); + return; + } + + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u rescinded\n", + note->chm_chanid); + } + + chan = sc->vmbus_chmap[note->chm_chanid]; + if (chan == NULL) + return; + sc->vmbus_chmap[note->chm_chanid] = NULL; + + taskqueue_enqueue(taskqueue_thread, &chan->ch_detach_task); +} + +static void +vmbus_chan_detach_task(void *xchan, int pending __unused) +{ + struct hv_vmbus_channel *chan = xchan; + + if (VMBUS_CHAN_ISPRIMARY(chan)) { + /* Only primary channel owns the device */ + hv_vmbus_child_device_unregister(chan); + /* NOTE: DO NOT free primary channel for now */ + } else { + struct vmbus_softc *sc = chan->vmbus_sc; + struct hv_vmbus_channel *pri_chan = chan->ch_prichan; + struct vmbus_chanmsg_chfree *req; + struct vmbus_msghc *mh; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chfree(chan%u)\n", + chan->ch_id); + goto remove; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE; + req->chm_chanid = chan->ch_id; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, + "chfree(chan%u) failed: %d", + chan->ch_id, error); + /* NOTE: Move on! */ + } else { + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u freed\n", + chan->ch_id); + } + } +remove: + mtx_lock(&pri_chan->ch_subchan_lock); + TAILQ_REMOVE(&pri_chan->ch_subchans, chan, ch_sublink); + KASSERT(pri_chan->ch_subchan_cnt > 0, + ("invalid subchan_cnt %d", pri_chan->ch_subchan_cnt)); + pri_chan->ch_subchan_cnt--; + mtx_unlock(&pri_chan->ch_subchan_lock); + wakeup(pri_chan); + + vmbus_chan_free(chan); + } +} + +/* + * Detach all devices and destroy the corresponding primary channels. + */ +void +vmbus_chan_destroy_all(struct vmbus_softc *sc) +{ + struct hv_vmbus_channel *chan; + + mtx_lock(&sc->vmbus_prichan_lock); + while ((chan = TAILQ_FIRST(&sc->vmbus_prichans)) != NULL) { + KASSERT(VMBUS_CHAN_ISPRIMARY(chan), ("not primary channel")); + TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink); + mtx_unlock(&sc->vmbus_prichan_lock); + + hv_vmbus_child_device_unregister(chan); + vmbus_chan_free(chan); + + mtx_lock(&sc->vmbus_prichan_lock); + } + bzero(sc->vmbus_chmap, + sizeof(struct hv_vmbus_channel *) * VMBUS_CHAN_MAX); + mtx_unlock(&sc->vmbus_prichan_lock); +} + +/** + * @brief Select the best outgoing channel + * + * The channel whose vcpu binding is closest to the currect vcpu will + * be selected. + * If no multi-channel, always select primary channel + * + * @param primary - primary channel + */ +struct hv_vmbus_channel * +vmbus_select_outgoing_channel(struct hv_vmbus_channel *primary) +{ + hv_vmbus_channel *new_channel = NULL; + hv_vmbus_channel *outgoing_channel = primary; + int old_cpu_distance = 0; + int new_cpu_distance = 0; + int cur_vcpu = 0; + int smp_pro_id = PCPU_GET(cpuid); + + if (TAILQ_EMPTY(&primary->ch_subchans)) { + return outgoing_channel; + } + + if (smp_pro_id >= MAXCPU) { + return outgoing_channel; + } + + cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); + + /* XXX need lock */ + TAILQ_FOREACH(new_channel, &primary->ch_subchans, ch_sublink) { + if ((new_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) { + continue; + } + + if (new_channel->target_vcpu == cur_vcpu){ + return new_channel; + } + + old_cpu_distance = ((outgoing_channel->target_vcpu > cur_vcpu) ? + (outgoing_channel->target_vcpu - cur_vcpu) : + (cur_vcpu - outgoing_channel->target_vcpu)); + + new_cpu_distance = ((new_channel->target_vcpu > cur_vcpu) ? + (new_channel->target_vcpu - cur_vcpu) : + (cur_vcpu - new_channel->target_vcpu)); + + if (old_cpu_distance < new_cpu_distance) { + continue; + } + + outgoing_channel = new_channel; + } + + return(outgoing_channel); +} + +struct hv_vmbus_channel ** +vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt) +{ + struct hv_vmbus_channel **ret, *chan; + int i; + + ret = malloc(subchan_cnt * sizeof(struct hv_vmbus_channel *), M_TEMP, + M_WAITOK); + + mtx_lock(&pri_chan->ch_subchan_lock); + + while (pri_chan->ch_subchan_cnt < subchan_cnt) + mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "subch", 0); + + i = 0; + TAILQ_FOREACH(chan, &pri_chan->ch_subchans, ch_sublink) { + /* TODO: refcnt chan */ + ret[i] = chan; + + ++i; + if (i == subchan_cnt) + break; + } + KASSERT(i == subchan_cnt, ("invalid subchan count %d, should be %d", + pri_chan->ch_subchan_cnt, subchan_cnt)); + + mtx_unlock(&pri_chan->ch_subchan_lock); + + return ret; +} + +void +vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt __unused) +{ + + free(subchan, M_TEMP); +} + +void +vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan) +{ + mtx_lock(&pri_chan->ch_subchan_lock); + while (pri_chan->ch_subchan_cnt > 0) + mtx_sleep(pri_chan, &pri_chan->ch_subchan_lock, 0, "dsubch", 0); + mtx_unlock(&pri_chan->ch_subchan_lock); +} + +void +vmbus_chan_msgproc(struct vmbus_softc *sc, const struct vmbus_message *msg) +{ + vmbus_chanmsg_proc_t msg_proc; + uint32_t msg_type; + + msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type; + KASSERT(msg_type < VMBUS_CHANMSG_TYPE_MAX, + ("invalid message type %u", msg_type)); + + msg_proc = vmbus_chan_msgprocs[msg_type]; + if (msg_proc != NULL) + msg_proc(sc, msg); +} Modified: stable/10/sys/modules/hyperv/vmbus/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 08:29:04 2016 (r307029) +++ stable/10/sys/modules/hyperv/vmbus/Makefile Tue Oct 11 08:41:27 2016 (r307030) @@ -5,7 +5,6 @@ KMOD= hv_vmbus SRCS= hv_channel.c \ - hv_channel_mgmt.c \ hv_ring_buffer.c \ hyperv.c \ hyperv_busdma.c \ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:48:37 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E70BDC0C605; Tue, 11 Oct 2016 08:48:37 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C370BCDE; Tue, 11 Oct 2016 08:48:37 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8mar7038329; Tue, 11 Oct 2016 08:48:36 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8maju038324; Tue, 11 Oct 2016 08:48:36 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110848.u9B8maju038324@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:48:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307031 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:48:38 -0000 Author: sephe Date: Tue Oct 11 08:48:36 2016 New Revision: 307031 URL: https://svnweb.freebsd.org/changeset/base/307031 Log: MFC 302867-302870 302867 hyperv/vmbus: Remove unused struct Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7127 302868 hyperv/vmbus: Function rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7129 302869 hyperv/vmbus: Remove unused function definition/declaration. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7131 302870 hyperv/vmbus: Use iovec for bufring scatter/gather list. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7134 Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:41:27 2016 (r307030) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:48:36 2016 (r307031) @@ -616,7 +616,7 @@ hv_vmbus_channel_send_packet( uint64_t aligned_data; uint32_t packet_len_aligned; boolean_t need_sig; - hv_vmbus_sg_buffer_list buffer_list[3]; + struct iovec iov[3]; packet_len = sizeof(hv_vm_packet_descriptor) + buffer_len; packet_len_aligned = HV_ALIGN_UP(packet_len, sizeof(uint64_t)); @@ -630,17 +630,16 @@ hv_vmbus_channel_send_packet( desc.length8 = (uint16_t) (packet_len_aligned >> 3); desc.transaction_id = request_id; - buffer_list[0].data = &desc; - buffer_list[0].length = sizeof(hv_vm_packet_descriptor); + iov[0].iov_base = &desc; + iov[0].iov_len = sizeof(hv_vm_packet_descriptor); - buffer_list[1].data = buffer; - buffer_list[1].length = buffer_len; + iov[1].iov_base = buffer; + iov[1].iov_len = buffer_len; - buffer_list[2].data = &aligned_data; - buffer_list[2].length = packet_len_aligned - packet_len; + iov[2].iov_base = &aligned_data; + iov[2].iov_len = packet_len_aligned - packet_len; - ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3, - &need_sig); + ret = hv_ring_buffer_write(&channel->outbound, iov, 3, &need_sig); /* TODO: We should determine if this is optional */ if (ret == 0 && need_sig) @@ -668,7 +667,7 @@ hv_vmbus_channel_send_packet_pagebuffer( uint32_t packet_len; uint32_t page_buflen; uint32_t packetLen_aligned; - hv_vmbus_sg_buffer_list buffer_list[4]; + struct iovec iov[4]; hv_vmbus_channel_packet_page_buffer desc; uint32_t descSize; uint64_t alignedData = 0; @@ -694,20 +693,19 @@ hv_vmbus_channel_send_packet_pagebuffer( desc.transaction_id = request_id; desc.range_count = page_count; - buffer_list[0].data = &desc; - buffer_list[0].length = descSize; + iov[0].iov_base = &desc; + iov[0].iov_len = descSize; - buffer_list[1].data = page_buffers; - buffer_list[1].length = page_buflen; + iov[1].iov_base = page_buffers; + iov[1].iov_len = page_buflen; - buffer_list[2].data = buffer; - buffer_list[2].length = buffer_len; + iov[2].iov_base = buffer; + iov[2].iov_len = buffer_len; - buffer_list[3].data = &alignedData; - buffer_list[3].length = packetLen_aligned - packet_len; + iov[3].iov_base = &alignedData; + iov[3].iov_len = packetLen_aligned - packet_len; - ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 4, - &need_sig); + ret = hv_ring_buffer_write(&channel->outbound, iov, 4, &need_sig); /* TODO: We should determine if this is optional */ if (ret == 0 && need_sig) @@ -735,7 +733,7 @@ hv_vmbus_channel_send_packet_multipagebu uint32_t packet_len_aligned; uint32_t pfn_count; uint64_t aligned_data = 0; - hv_vmbus_sg_buffer_list buffer_list[3]; + struct iovec iov[3]; hv_vmbus_channel_packet_multipage_buffer desc; pfn_count = @@ -772,17 +770,16 @@ hv_vmbus_channel_send_packet_multipagebu memcpy(desc.range.pfn_array, multi_page_buffer->pfn_array, pfn_count * sizeof(uint64_t)); - buffer_list[0].data = &desc; - buffer_list[0].length = desc_size; + iov[0].iov_base = &desc; + iov[0].iov_len = desc_size; - buffer_list[1].data = buffer; - buffer_list[1].length = buffer_len; + iov[1].iov_base = buffer; + iov[1].iov_len = buffer_len; - buffer_list[2].data = &aligned_data; - buffer_list[2].length = packet_len_aligned - packet_len; + iov[2].iov_base = &aligned_data; + iov[2].iov_len = packet_len_aligned - packet_len; - ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3, - &need_sig); + ret = hv_ring_buffer_write(&channel->outbound, iov, 3, &need_sig); /* TODO: We should determine if this is optional */ if (ret == 0 && need_sig) @@ -1233,7 +1230,7 @@ vmbus_chan_msgproc_choffer(struct vmbus_ * Error is ignored here; don't have much to do if error * really happens. */ - hv_vmbus_child_device_register(chan); + vmbus_add_child(chan); } } @@ -1274,7 +1271,7 @@ vmbus_chan_detach_task(void *xchan, int if (VMBUS_CHAN_ISPRIMARY(chan)) { /* Only primary channel owns the device */ - hv_vmbus_child_device_unregister(chan); + vmbus_delete_child(chan); /* NOTE: DO NOT free primary channel for now */ } else { struct vmbus_softc *sc = chan->vmbus_sc; @@ -1336,7 +1333,7 @@ vmbus_chan_destroy_all(struct vmbus_soft TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink); mtx_unlock(&sc->vmbus_prichan_lock); - hv_vmbus_child_device_unregister(chan); + vmbus_delete_child(chan); vmbus_chan_free(chan); mtx_lock(&sc->vmbus_prichan_lock); Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Tue Oct 11 08:41:27 2016 (r307030) +++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Tue Oct 11 08:48:36 2016 (r307031) @@ -254,7 +254,7 @@ hv_ring_buffer_needsig_on_write( static uint32_t copy_to_ring_buffer( hv_vmbus_ring_buffer_info* ring_info, uint32_t start_write_offset, - char* src, + const uint8_t *src, uint32_t src_len); static uint32_t copy_from_ring_buffer( @@ -263,16 +263,6 @@ static uint32_t copy_from_ring_buffer( uint32_t dest_len, uint32_t start_read_offset); - -/** - * @brief Get the interrupt mask for the specified ring buffer. - */ -uint32_t -hv_vmbus_get_ring_buffer_interrupt_mask(hv_vmbus_ring_buffer_info *rbi) -{ - return rbi->ring_buffer->interrupt_mask; -} - /** * @brief Initialize the ring buffer. */ @@ -309,8 +299,8 @@ void hv_ring_buffer_cleanup(hv_vmbus_rin int hv_ring_buffer_write( hv_vmbus_ring_buffer_info* out_ring_info, - hv_vmbus_sg_buffer_list sg_buffers[], - uint32_t sg_buffer_count, + const struct iovec iov[], + uint32_t iovlen, boolean_t *need_sig) { int i = 0; @@ -322,8 +312,8 @@ hv_ring_buffer_write( volatile uint32_t next_write_location; uint64_t prev_indices = 0; - for (i = 0; i < sg_buffer_count; i++) { - total_bytes_to_write += sg_buffers[i].length; + for (i = 0; i < iovlen; i++) { + total_bytes_to_write += iov[i].iov_len; } total_bytes_to_write += sizeof(uint64_t); @@ -352,10 +342,9 @@ hv_ring_buffer_write( old_write_location = next_write_location; - for (i = 0; i < sg_buffer_count; i++) { + for (i = 0; i < iovlen; i++) { next_write_location = copy_to_ring_buffer(out_ring_info, - next_write_location, (char *) sg_buffers[i].data, - sg_buffers[i].length); + next_write_location, iov[i].iov_base, iov[i].iov_len); } /* @@ -494,11 +483,11 @@ hv_ring_buffer_read( * * Assume there is enough room. Handles wrap-around in dest case only! */ -uint32_t +static uint32_t copy_to_ring_buffer( hv_vmbus_ring_buffer_info* ring_info, uint32_t start_write_offset, - char* src, + const uint8_t *src, uint32_t src_len) { char *ring_buffer = get_ring_buffer(ring_info); Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:41:27 2016 (r307030) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Oct 11 08:48:36 2016 (r307031) @@ -35,39 +35,12 @@ #include #include #include +#include #include struct vmbus_softc; -typedef struct { - void* data; - uint32_t length; -} hv_vmbus_sg_buffer_list; - -typedef struct { - uint32_t current_interrupt_mask; - uint32_t current_read_index; - uint32_t current_write_index; - uint32_t bytes_avail_to_read; - uint32_t bytes_avail_to_write; -} hv_vmbus_ring_buffer_debug_info; - -typedef struct { - uint32_t rel_id; - struct hyperv_guid interface_type; - struct hyperv_guid interface_instance; - uint32_t monitor_id; - uint32_t server_monitor_pending; - uint32_t server_monitor_latency; - uint32_t server_monitor_connection_id; - uint32_t client_monitor_pending; - uint32_t client_monitor_latency; - uint32_t client_monitor_connection_id; - hv_vmbus_ring_buffer_debug_info inbound; - hv_vmbus_ring_buffer_debug_info outbound; -} hv_vmbus_channel_debug_info; - /* * The format must be the same as hv_vm_data_gpa_direct */ @@ -118,8 +91,8 @@ void hv_ring_buffer_cleanup( int hv_ring_buffer_write( hv_vmbus_ring_buffer_info *ring_info, - hv_vmbus_sg_buffer_list sg_buffers[], - uint32_t sg_buff_count, + const struct iovec iov[], + uint32_t iovlen, boolean_t *need_sig); int hv_ring_buffer_peek( @@ -133,22 +106,10 @@ int hv_ring_buffer_read( uint32_t buffer_len, uint32_t offset); -uint32_t hv_vmbus_get_ring_buffer_interrupt_mask( - hv_vmbus_ring_buffer_info *ring_info); - -void hv_vmbus_dump_ring_info( - hv_vmbus_ring_buffer_info *ring_info, - char *prefix); - void hv_ring_buffer_read_begin( hv_vmbus_ring_buffer_info *ring_info); uint32_t hv_ring_buffer_read_end( hv_vmbus_ring_buffer_info *ring_info); -int hv_vmbus_child_device_register( - struct hv_vmbus_channel *chan); -int hv_vmbus_child_device_unregister( - struct hv_vmbus_channel *chan); - #endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:41:27 2016 (r307030) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:48:36 2016 (r307031) @@ -1101,7 +1101,7 @@ vmbus_child_pnpinfo_str(device_t dev, de } int -hv_vmbus_child_device_register(struct hv_vmbus_channel *chan) +vmbus_add_child(struct hv_vmbus_channel *chan) { struct vmbus_softc *sc = chan->vmbus_sc; device_t parent = sc->vmbus_dev; @@ -1126,7 +1126,7 @@ done: } int -hv_vmbus_child_device_unregister(struct hv_vmbus_channel *chan) +vmbus_delete_child(struct hv_vmbus_channel *chan) { int error; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:41:27 2016 (r307030) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Tue Oct 11 08:48:36 2016 (r307031) @@ -145,6 +145,8 @@ struct vmbus_msghc; void vmbus_event_proc(struct vmbus_softc *, int); void vmbus_event_proc_compat(struct vmbus_softc *, int); void vmbus_handle_intr(struct trapframe *); +int vmbus_add_child(struct hv_vmbus_channel *); +int vmbus_delete_child(struct hv_vmbus_channel *); void vmbus_et_intr(struct trapframe *); From owner-svn-src-stable-10@freebsd.org Tue Oct 11 08:52:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9F9DEC0C7D2; Tue, 11 Oct 2016 08:52:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 763E4BF; Tue, 11 Oct 2016 08:52:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B8qRjJ041799; Tue, 11 Oct 2016 08:52:27 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B8qRnN041797; Tue, 11 Oct 2016 08:52:27 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110852.u9B8qRnN041797@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 08:52:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307032 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 08:52:28 -0000 Author: sephe Date: Tue Oct 11 08:52:27 2016 New Revision: 307032 URL: https://svnweb.freebsd.org/changeset/base/307032 Log: MFC 302871,302872 302871 hyperv/vmbus: Add vmbus_chan_gpadl_connect, which takes GPA physaddr Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7139 302872 hyperv/vmbus: Busdma-fy channel bufring. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7140 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:48:36 2016 (r307031) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:52:27 2016 (r307032) @@ -257,13 +257,6 @@ typedef struct hv_vmbus_channel { int ch_montrig_idx; /* MNF trig index */ uint32_t ch_montrig_mask;/* MNF trig mask */ - uint32_t ring_buffer_gpadl_handle; - /* - * Allocated memory for ring buffer - */ - void* ring_buffer_pages; - unsigned long ring_buffer_size; - uint32_t ring_buffer_page_count; /* * send to parent */ @@ -312,6 +305,10 @@ typedef struct hv_vmbus_channel { void *hv_chan_priv2; void *hv_chan_priv3; + void *ch_bufring; /* TX+RX bufrings */ + struct hyperv_dma ch_bufring_dma; + uint32_t ch_bufring_gpadl; + struct task ch_detach_task; TAILQ_ENTRY(hv_vmbus_channel) ch_prilink; /* primary chan link */ uint32_t ch_subidx; /* subchan index */ @@ -409,6 +406,9 @@ int hv_vmbus_channel_teardown_gpdal( hv_vmbus_channel* channel, uint32_t gpadl_handle); +int vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, + bus_addr_t paddr, int size, uint32_t *gpadl); + struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); void vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu); Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:48:36 2016 (r307031) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:52:27 2016 (r307032) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -202,7 +203,7 @@ hv_vmbus_channel_open( struct vmbus_msghc *mh; uint32_t status; int ret = 0; - void *in, *out; + uint8_t *br; if (user_data_len > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { device_printf(sc->vmbus_dev, @@ -210,6 +211,10 @@ hv_vmbus_channel_open( user_data_len, new_channel->ch_id); return EINVAL; } + KASSERT((send_ring_buffer_size & PAGE_MASK) == 0, + ("send bufring size is not multiple page")); + KASSERT((recv_ring_buffer_size & PAGE_MASK) == 0, + ("recv bufring size is not multiple page")); if (atomic_testandset_int(&new_channel->ch_stflags, VMBUS_CHAN_ST_OPENED_SHIFT)) @@ -230,46 +235,43 @@ hv_vmbus_channel_open( vmbus_chan_task_nobatch, new_channel); } - /* Allocate the ring buffer */ - out = contigmalloc((send_ring_buffer_size + recv_ring_buffer_size), - M_DEVBUF, M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); - KASSERT(out != NULL, - ("Error VMBUS: contigmalloc failed to allocate Ring Buffer!")); - if (out == NULL) { + /* + * Allocate the TX+RX bufrings. + * XXX should use ch_dev dtag + */ + br = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + PAGE_SIZE, 0, send_ring_buffer_size + recv_ring_buffer_size, + &new_channel->ch_bufring_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (br == NULL) { + device_printf(sc->vmbus_dev, "bufring allocation failed\n"); ret = ENOMEM; goto failed; } + new_channel->ch_bufring = br; - in = ((uint8_t *) out + send_ring_buffer_size); - - new_channel->ring_buffer_pages = out; - new_channel->ring_buffer_page_count = (send_ring_buffer_size + - recv_ring_buffer_size) >> PAGE_SHIFT; - new_channel->ring_buffer_size = send_ring_buffer_size + - recv_ring_buffer_size; - - hv_vmbus_ring_buffer_init( - &new_channel->outbound, - out, - send_ring_buffer_size); - - hv_vmbus_ring_buffer_init( - &new_channel->inbound, - in, - recv_ring_buffer_size); + /* TX bufring comes first */ + hv_vmbus_ring_buffer_init(&new_channel->outbound, + br, send_ring_buffer_size); + /* RX bufring immediately follows TX bufring */ + hv_vmbus_ring_buffer_init(&new_channel->inbound, + br + send_ring_buffer_size, recv_ring_buffer_size); /* Create sysctl tree for this channel */ vmbus_channel_sysctl_create(new_channel); - /** - * Establish the gpadl for the ring buffer + /* + * Connect the bufrings, both RX and TX, to this channel. */ - new_channel->ring_buffer_gpadl_handle = 0; - - ret = hv_vmbus_channel_establish_gpadl(new_channel, - new_channel->outbound.ring_buffer, + ret = vmbus_chan_gpadl_connect(new_channel, + new_channel->ch_bufring_dma.hv_paddr, send_ring_buffer_size + recv_ring_buffer_size, - &new_channel->ring_buffer_gpadl_handle); + &new_channel->ch_bufring_gpadl); + if (ret != 0) { + device_printf(sc->vmbus_dev, + "failed to connect bufring GPADL to chan%u\n", + new_channel->ch_id); + goto failed; + } /* * Open channel w/ the bufring GPADL on the target CPU. @@ -287,7 +289,7 @@ hv_vmbus_channel_open( req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; req->chm_chanid = new_channel->ch_id; req->chm_openid = new_channel->ch_id; - req->chm_gpadl = new_channel->ring_buffer_gpadl_handle; + req->chm_gpadl = new_channel->ch_bufring_gpadl; req->chm_vcpuid = new_channel->target_vcpu; req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; if (user_data_len) @@ -321,6 +323,16 @@ hv_vmbus_channel_open( ret = ENXIO; failed: + if (new_channel->ch_bufring_gpadl) { + hv_vmbus_channel_teardown_gpdal(new_channel, + new_channel->ch_bufring_gpadl); + new_channel->ch_bufring_gpadl = 0; + } + if (new_channel->ch_bufring != NULL) { + hyperv_dmamem_free(&new_channel->ch_bufring_dma, + new_channel->ch_bufring); + new_channel->ch_bufring = NULL; + } atomic_clear_int(&new_channel->ch_stflags, VMBUS_CHAN_ST_OPENED); return ret; } @@ -330,26 +342,33 @@ failed: */ int hv_vmbus_channel_establish_gpadl(struct hv_vmbus_channel *channel, - void *contig_buffer, uint32_t size, uint32_t *gpadl0) + void *contig_buffer, uint32_t size, uint32_t *gpadl) { - struct vmbus_softc *sc = channel->vmbus_sc; + return vmbus_chan_gpadl_connect(channel, + hv_get_phys_addr(contig_buffer), size, gpadl); +} + +int +vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, bus_addr_t paddr, + int size, uint32_t *gpadl0) +{ + struct vmbus_softc *sc = chan->vmbus_sc; struct vmbus_msghc *mh; struct vmbus_chanmsg_gpadl_conn *req; const struct vmbus_message *msg; size_t reqsz; uint32_t gpadl, status; int page_count, range_len, i, cnt, error; - uint64_t page_id, paddr; + uint64_t page_id; /* * Preliminary checks. */ KASSERT((size & PAGE_MASK) == 0, - ("invalid GPA size %u, not multiple page size", size)); + ("invalid GPA size %d, not multiple page size", size)); page_count = size >> PAGE_SHIFT; - paddr = hv_get_phys_addr(contig_buffer); KASSERT((paddr & PAGE_MASK) == 0, ("GPA is not page aligned %jx", (uintmax_t)paddr)); page_id = paddr >> PAGE_SHIFT; @@ -390,13 +409,13 @@ hv_vmbus_channel_establish_gpadl(struct if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for gpadl->chan%u\n", - channel->ch_id); + chan->ch_id); return EIO; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_CONN; - req->chm_chanid = channel->ch_id; + req->chm_chanid = chan->ch_id; req->chm_gpadl = gpadl; req->chm_range_len = range_len; req->chm_range_cnt = 1; @@ -409,7 +428,7 @@ hv_vmbus_channel_establish_gpadl(struct if (error) { device_printf(sc->vmbus_dev, "gpadl->chan%u msg hypercall exec failed: %d\n", - channel->ch_id, error); + chan->ch_id, error); vmbus_msghc_put(sc, mh); return error; } @@ -445,12 +464,12 @@ hv_vmbus_channel_establish_gpadl(struct if (status != 0) { device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " - "status %u\n", channel->ch_id, status); + "status %u\n", chan->ch_id, status); return EIO; } else { if (bootverbose) { device_printf(sc->vmbus_dev, "gpadl->chan%u " - "succeeded\n", channel->ch_id); + "succeeded\n", chan->ch_id); } } return 0; @@ -547,9 +566,10 @@ hv_vmbus_channel_close_internal(hv_vmbus } /* Tear down the gpadl for the channel's ring buffer */ - if (channel->ring_buffer_gpadl_handle) { + if (channel->ch_bufring_gpadl) { hv_vmbus_channel_teardown_gpdal(channel, - channel->ring_buffer_gpadl_handle); + channel->ch_bufring_gpadl); + channel->ch_bufring_gpadl = 0; } /* TODO: Send a msg to release the childRelId */ @@ -558,8 +578,11 @@ hv_vmbus_channel_close_internal(hv_vmbus hv_ring_buffer_cleanup(&channel->outbound); hv_ring_buffer_cleanup(&channel->inbound); - contigfree(channel->ring_buffer_pages, channel->ring_buffer_size, - M_DEVBUF); + if (channel->ch_bufring != NULL) { + hyperv_dmamem_free(&channel->ch_bufring_dma, + channel->ch_bufring); + channel->ch_bufring = NULL; + } } /* From owner-svn-src-stable-10@freebsd.org Tue Oct 11 09:02:56 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8A31DC0CD18; Tue, 11 Oct 2016 09:02:56 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4D0A1982; Tue, 11 Oct 2016 09:02:56 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B92t0O045904; Tue, 11 Oct 2016 09:02:55 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B92tkh045901; Tue, 11 Oct 2016 09:02:55 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110902.u9B92tkh045901@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 09:02:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307033 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 09:02:56 -0000 Author: sephe Date: Tue Oct 11 09:02:55 2016 New Revision: 307033 URL: https://svnweb.freebsd.org/changeset/base/307033 Log: MFC 302873,302874 302873 hyperv/vmbus: Set vcpuid to 0, if MSR_HV_VP_INDEX does not exist. Mainly for compatibility. While I'm here, rename cpuid related fields in hv_vmbus_channel. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7141 302874 hyperv/vmbus: Field rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7146 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/vmbus.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 08:52:27 2016 (r307032) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 09:02:55 2016 (r307033) @@ -242,7 +242,7 @@ typedef struct { uint32_t ring_data_size; /* ring_size */ } hv_vmbus_ring_buffer_info; -typedef void (*hv_vmbus_pfn_channel_callback)(void *context); +typedef void (*vmbus_chan_callback_t)(void *); typedef struct hv_vmbus_channel { device_t ch_dev; @@ -266,24 +266,21 @@ typedef struct hv_vmbus_channel { */ hv_vmbus_ring_buffer_info inbound; - struct taskqueue * rxq; - struct task channel_task; - hv_vmbus_pfn_channel_callback on_channel_callback; - void* channel_callback_context; + struct taskqueue *ch_tq; + struct task ch_task; + vmbus_chan_callback_t ch_cb; + void *ch_cbarg; struct hyperv_mon_param *ch_monprm; struct hyperv_dma ch_monprm_dma; + int ch_cpuid; /* owner cpu */ /* - * From Win8, this field specifies the target virtual process - * on which to deliver the interupt from the host to guest. - * Before Win8, all channel interrupts would only be - * delivered on cpu 0. Setting this value to 0 would preserve - * the earlier behavior. - */ - uint32_t target_vcpu; - /* The corresponding CPUID in the guest */ - uint32_t target_cpu; + * Virtual cpuid for ch_cpuid; it is used to communicate cpuid + * related information w/ Hyper-V. If MSR_HV_VP_INDEX does not + * exist, ch_vcpuid will always be 0 for compatibility. + */ + uint32_t ch_vcpuid; /* * If this is a primary channel, ch_subchan* fields @@ -365,9 +362,8 @@ int hv_vmbus_channel_open( uint32_t recv_ring_buffer_size, void* user_data, uint32_t user_data_len, - hv_vmbus_pfn_channel_callback - pfn_on_channel_callback, - void* context); + vmbus_chan_callback_t cb, + void *cbarg); void hv_vmbus_channel_close(hv_vmbus_channel *channel); Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 08:52:27 2016 (r307032) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 09:02:55 2016 (r307033) @@ -157,7 +157,7 @@ vmbus_channel_sysctl_create(hv_vmbus_cha &channel->ch_id, 0, "channel id"); } SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, - "cpu", CTLFLAG_RD, &channel->target_cpu, 0, "owner CPU id"); + "cpu", CTLFLAG_RD, &channel->ch_cpuid, 0, "owner CPU id"); SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, "monitor_allocated", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, channel, 0, vmbus_channel_sysctl_monalloc, "I", @@ -193,8 +193,8 @@ hv_vmbus_channel_open( uint32_t recv_ring_buffer_size, void* user_data, uint32_t user_data_len, - hv_vmbus_pfn_channel_callback pfn_on_channel_callback, - void* context) + vmbus_chan_callback_t cb, + void *cbarg) { struct vmbus_softc *sc = new_channel->vmbus_sc; const struct vmbus_chanmsg_chopen_resp *resp; @@ -220,19 +220,19 @@ hv_vmbus_channel_open( VMBUS_CHAN_ST_OPENED_SHIFT)) panic("double-open chan%u", new_channel->ch_id); - new_channel->on_channel_callback = pfn_on_channel_callback; - new_channel->channel_callback_context = context; + new_channel->ch_cb = cb; + new_channel->ch_cbarg = cbarg; vmbus_chan_update_evtflagcnt(sc, new_channel); - new_channel->rxq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, - new_channel->target_cpu); + new_channel->ch_tq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, + new_channel->ch_cpuid); if (new_channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) { - TASK_INIT(&new_channel->channel_task, 0, - vmbus_chan_task, new_channel); + TASK_INIT(&new_channel->ch_task, 0, vmbus_chan_task, + new_channel); } else { - TASK_INIT(&new_channel->channel_task, 0, - vmbus_chan_task_nobatch, new_channel); + TASK_INIT(&new_channel->ch_task, 0, vmbus_chan_task_nobatch, + new_channel); } /* @@ -290,7 +290,7 @@ hv_vmbus_channel_open( req->chm_chanid = new_channel->ch_id; req->chm_openid = new_channel->ch_id; req->chm_gpadl = new_channel->ch_bufring_gpadl; - req->chm_vcpuid = new_channel->target_vcpu; + req->chm_vcpuid = new_channel->ch_vcpuid; req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; if (user_data_len) memcpy(req->chm_udata, user_data, user_data_len); @@ -521,7 +521,7 @@ hv_vmbus_channel_close_internal(hv_vmbus struct vmbus_softc *sc = channel->vmbus_sc; struct vmbus_msghc *mh; struct vmbus_chanmsg_chclose *req; - struct taskqueue *rxq = channel->rxq; + struct taskqueue *tq = channel->ch_tq; int error; /* TODO: stringent check */ @@ -530,11 +530,11 @@ hv_vmbus_channel_close_internal(hv_vmbus sysctl_ctx_free(&channel->ch_sysctl_ctx); /* - * set rxq to NULL to avoid more requests be scheduled + * Set ch_tq to NULL to avoid more requests be scheduled */ - channel->rxq = NULL; - taskqueue_drain(rxq, &channel->channel_task); - channel->on_channel_callback = NULL; + channel->ch_tq = NULL; + taskqueue_drain(tq, &channel->ch_task); + channel->ch_cb = NULL; /** * Send a closing message @@ -895,11 +895,8 @@ static void vmbus_chan_task(void *xchan, int pending __unused) { struct hv_vmbus_channel *chan = xchan; - void (*callback)(void *); - void *arg; - - arg = chan->channel_callback_context; - callback = chan->on_channel_callback; + vmbus_chan_callback_t cb = chan->ch_cb; + void *cbarg = chan->ch_cbarg; /* * Optimize host to guest signaling by ensuring: @@ -916,7 +913,7 @@ vmbus_chan_task(void *xchan, int pending for (;;) { uint32_t left; - callback(arg); + cb(cbarg); left = hv_ring_buffer_read_end(&chan->inbound); if (left == 0) { @@ -932,7 +929,7 @@ vmbus_chan_task_nobatch(void *xchan, int { struct hv_vmbus_channel *chan = xchan; - chan->on_channel_callback(chan->channel_callback_context); + chan->ch_cb(chan->ch_cbarg); } static __inline void @@ -961,12 +958,12 @@ vmbus_event_flags_proc(struct vmbus_soft channel = sc->vmbus_chmap[chid_base + chid_ofs]; /* if channel is closed or closing */ - if (channel == NULL || channel->rxq == NULL) + if (channel == NULL || channel->ch_tq == NULL) continue; if (channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) hv_ring_buffer_read_begin(&channel->inbound); - taskqueue_enqueue(channel->rxq, &channel->channel_task); + taskqueue_enqueue(channel->ch_tq, &channel->ch_task); } } } @@ -1005,7 +1002,7 @@ vmbus_chan_update_evtflagcnt(struct vmbu int flag_cnt; flag_cnt = (chan->ch_id / VMBUS_EVTFLAG_LEN) + 1; - flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->target_cpu); + flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->ch_cpuid); for (;;) { int old_flag_cnt; @@ -1017,8 +1014,7 @@ vmbus_chan_update_evtflagcnt(struct vmbu if (bootverbose) { device_printf(sc->vmbus_dev, "channel%u update cpu%d flag_cnt to %d\n", - chan->ch_id, - chan->target_cpu, flag_cnt); + chan->ch_id, chan->ch_cpuid, flag_cnt); } break; } @@ -1162,13 +1158,12 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch cpu = 0; } - chan->target_cpu = cpu; - chan->target_vcpu = VMBUS_PCPU_GET(chan->vmbus_sc, vcpuid, cpu); + chan->ch_cpuid = cpu; + chan->ch_vcpuid = VMBUS_PCPU_GET(chan->vmbus_sc, vcpuid, cpu); if (bootverbose) { printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", - chan->ch_id, - chan->target_cpu, chan->target_vcpu); + chan->ch_id, chan->ch_cpuid, chan->ch_vcpuid); } } @@ -1401,17 +1396,17 @@ vmbus_select_outgoing_channel(struct hv_ continue; } - if (new_channel->target_vcpu == cur_vcpu){ + if (new_channel->ch_vcpuid == cur_vcpu){ return new_channel; } - old_cpu_distance = ((outgoing_channel->target_vcpu > cur_vcpu) ? - (outgoing_channel->target_vcpu - cur_vcpu) : - (cur_vcpu - outgoing_channel->target_vcpu)); - - new_cpu_distance = ((new_channel->target_vcpu > cur_vcpu) ? - (new_channel->target_vcpu - cur_vcpu) : - (cur_vcpu - new_channel->target_vcpu)); + old_cpu_distance = ((outgoing_channel->ch_vcpuid > cur_vcpu) ? + (outgoing_channel->ch_vcpuid - cur_vcpu) : + (cur_vcpu - outgoing_channel->ch_vcpuid)); + + new_cpu_distance = ((new_channel->ch_vcpuid > cur_vcpu) ? + (new_channel->ch_vcpuid - cur_vcpu) : + (cur_vcpu - new_channel->ch_vcpuid)); if (old_cpu_distance < new_cpu_distance) { continue; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 08:52:27 2016 (r307032) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Tue Oct 11 09:02:55 2016 (r307033) @@ -726,19 +726,11 @@ vmbus_synic_setup(void *xsc) uint32_t sint; if (hyperv_features & CPUID_HV_MSR_VP_INDEX) { - /* - * Save virtual processor id. - */ + /* Save virtual processor id. */ VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX); } else { - /* - * XXX - * Virtual processoor id is only used by a pretty broken - * channel selection code from storvsc. It's nothing - * critical even if CPUID_HV_MSR_VP_INDEX is not set; keep - * moving on. - */ - VMBUS_PCPU_GET(sc, vcpuid, cpu) = cpu; + /* Set virtual processor id to 0 for compatibility. */ + VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0; } /* From owner-svn-src-stable-10@freebsd.org Tue Oct 11 09:11:25 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D148CC0CEF4; Tue, 11 Oct 2016 09:11:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6E7B3D8A; Tue, 11 Oct 2016 09:11:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B9BOaU048914; Tue, 11 Oct 2016 09:11:24 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B9BNmd048898; Tue, 11 Oct 2016 09:11:23 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110911.u9B9BNmd048898@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 09:11:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307034 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 09:11:26 -0000 Author: sephe Date: Tue Oct 11 09:11:23 2016 New Revision: 307034 URL: https://svnweb.freebsd.org/changeset/base/307034 Log: MFC 302875,302876,302878-302881 302875 hyperv/vmbus: Redefine channel packet. The channel packet header will be shared w/ PRP (physical region page) list channel packet and SG (scatter gather) list channel packet. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7155 302876 hyperv/vmbus: Rework sglist sending. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7156 302878 hyeprv/vmbus: Rework prplist sending. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7175 302879 hyperv/vmbus: Move channel packet flags definition to vmbus.h Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7176 302880 hyperv/vmbus: Move channel packet types definition to vmbus.h Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7177 302881 hyperv/vmbus: Cleanup channel sending Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7178 Added: stable/10/sys/dev/hyperv/include/vmbus.h - copied, changed from r302876, head/sys/dev/hyperv/include/vmbus.h Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/include/hyperv.h Tue Oct 11 09:11:23 2016 (r307034) @@ -82,19 +82,6 @@ typedef uint8_t hv_bool_uint8_t; #define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) #define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) -#define HV_MAX_PAGE_BUFFER_COUNT 32 -#define HV_MAX_MULTIPAGE_BUFFER_COUNT 32 - -#define HV_ALIGN_UP(value, align) \ - (((value) & (align-1)) ? \ - (((value) + (align-1)) & ~(align-1) ) : (value)) - -#define HV_ALIGN_DOWN(value, align) ( (value) & ~(align-1) ) - -#define HV_NUM_PAGES_SPANNED(addr, len) \ - ((HV_ALIGN_UP(addr+len, PAGE_SIZE) - \ - HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT ) - struct hyperv_guid { uint8_t hv_guid[16]; } __packed; @@ -125,25 +112,6 @@ typedef struct { hv_vm_transfer_page ranges[1]; } __packed hv_vm_transfer_page_packet_header; -typedef enum { - HV_VMBUS_PACKET_TYPE_INVALID = 0x0, - HV_VMBUS_PACKET_TYPES_SYNCH = 0x1, - HV_VMBUS_PACKET_TYPE_ADD_TRANSFER_PAGE_SET = 0x2, - HV_VMBUS_PACKET_TYPE_REMOVE_TRANSFER_PAGE_SET = 0x3, - HV_VMBUS_PACKET_TYPE_ESTABLISH_GPADL = 0x4, - HV_VMBUS_PACKET_TYPE_TEAR_DOWN_GPADL = 0x5, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND = 0x6, - HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES = 0x7, - HV_VMBUS_PACKET_TYPE_DATA_USING_GPADL = 0x8, - HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT = 0x9, - HV_VMBUS_PACKET_TYPE_CANCEL_REQUEST = 0xa, - HV_VMBUS_PACKET_TYPE_COMPLETION = 0xb, - HV_VMBUS_PACKET_TYPE_DATA_USING_ADDITIONAL_PACKETS = 0xc, - HV_VMBUS_PACKET_TYPE_ADDITIONAL_DATA = 0xd -} hv_vmbus_packet_type; - -#define HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 - #define HW_MACADDR_LEN 6 /* @@ -225,18 +193,6 @@ typedef struct { } __packed hv_vmbus_ring_buffer; typedef struct { - int length; - int offset; - uint64_t pfn; -} __packed hv_vmbus_page_buffer; - -typedef struct { - int length; - int offset; - uint64_t pfn_array[HV_MAX_MULTIPAGE_BUFFER_COUNT]; -} __packed hv_vmbus_multipage_buffer; - -typedef struct { hv_vmbus_ring_buffer* ring_buffer; struct mtx ring_lock; uint32_t ring_data_size; /* ring_size */ @@ -372,23 +328,8 @@ int hv_vmbus_channel_send_packet( void* buffer, uint32_t buffer_len, uint64_t request_id, - hv_vmbus_packet_type type, - uint32_t flags); - -int hv_vmbus_channel_send_packet_pagebuffer( - hv_vmbus_channel* channel, - hv_vmbus_page_buffer page_buffers[], - uint32_t page_count, - void* buffer, - uint32_t buffer_len, - uint64_t request_id); - -int hv_vmbus_channel_send_packet_multipagebuffer( - hv_vmbus_channel* channel, - hv_vmbus_multipage_buffer* multi_page_buffer, - void* buffer, - uint32_t buffer_len, - uint64_t request_id); + uint16_t type, + uint16_t flags); int hv_vmbus_channel_establish_gpadl( hv_vmbus_channel* channel, Copied and modified: stable/10/sys/dev/hyperv/include/vmbus.h (from r302876, head/sys/dev/hyperv/include/vmbus.h) ============================================================================== --- head/sys/dev/hyperv/include/vmbus.h Fri Jul 15 06:29:19 2016 (r302876, copy source) +++ stable/10/sys/dev/hyperv/include/vmbus.h Tue Oct 11 09:11:23 2016 (r307034) @@ -31,6 +31,15 @@ #include +/* + * GPA stuffs. + */ +struct vmbus_gpa_range { + uint32_t gpa_len; + uint32_t gpa_ofs; + uint64_t gpa_page[0]; +} __packed; + /* This is actually vmbus_gpa_range.gpa_page[1] */ struct vmbus_gpa { uint32_t gpa_len; @@ -38,12 +47,23 @@ struct vmbus_gpa { uint64_t gpa_page; } __packed; -#define VMBUS_CHAN_SGLIST_MAX 32 +#define VMBUS_CHANPKT_TYPE_INBAND 0x0006 +#define VMBUS_CHANPKT_TYPE_RXBUF 0x0007 +#define VMBUS_CHANPKT_TYPE_GPA 0x0009 +#define VMBUS_CHANPKT_TYPE_COMP 0x000b + +#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */ + +#define VMBUS_CHAN_SGLIST_MAX 32 +#define VMBUS_CHAN_PRPLIST_MAX 32 struct hv_vmbus_channel; int vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid); +int vmbus_chan_send_prplist(struct hv_vmbus_channel *chan, + struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen, + uint64_t xactid); #endif /* !_VMBUS_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Tue Oct 11 09:11:23 2016 (r307034) @@ -184,8 +184,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); if (ret != 0) { goto cleanup; } @@ -278,8 +277,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); if (ret != 0) { goto cleanup; } @@ -339,7 +337,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, revoke_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)revoke_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); /* * If we failed here, we might as well return and have a leak @@ -407,7 +405,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, revoke_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)revoke_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); /* * If we failed here, we might as well return and have a leak * rather than continue and a bugchk @@ -473,8 +471,7 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ /* Send the init request */ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); if (ret != 0) return (-1); @@ -517,7 +514,7 @@ hv_nv_send_ndis_config(struct hn_softc * /* Send the configuration packet */ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); if (ret != 0) return (-EINVAL); @@ -596,15 +593,14 @@ hv_nv_connect_to_vsp(struct hn_softc *sc ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); if (ret != 0) { goto cleanup; } /* * TODO: BUGBUG - We have to wait for the above msg since the netvsp * uses KMCL which acknowledges packet (completion packet) - * since our Vmbus always set the - * HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag + * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag */ /* sema_wait(&NetVscChannel->channel_init_sema); */ @@ -815,15 +811,13 @@ hv_nv_on_send(struct hv_vmbus_channel *c send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = pkt->send_buf_section_size; - if (pkt->page_buf_count) { - ret = hv_vmbus_channel_send_packet_pagebuffer(chan, - pkt->page_buffers, pkt->page_buf_count, + if (pkt->gpa_cnt) { + ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt, &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); } else { ret = hv_vmbus_channel_send_packet(chan, &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); } return (ret); @@ -852,7 +846,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st * All inbound packets other than send completion should be * xfer page packet. */ - if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES) { + if (pkt->type != VMBUS_CHANPKT_TYPE_RXBUF) { device_printf(dev, "packet type %d is invalid!\n", pkt->type); return; } @@ -923,7 +917,7 @@ hv_nv_on_receive_completion(struct hv_vm retry_send_cmplt: /* Send the completion */ ret = hv_vmbus_channel_send_packet(chan, &rx_comp_msg, - sizeof(nvsp_msg), tid, HV_VMBUS_PACKET_TYPE_COMPLETION, 0); + sizeof(nvsp_msg), tid, VMBUS_CHANPKT_TYPE_COMP, 0); if (ret == 0) { /* success */ /* no-op */ @@ -1008,14 +1002,14 @@ hv_nv_on_channel_callback(void *xchan) if (bytes_rxed > 0) { desc = (hv_vm_packet_descriptor *)buffer; switch (desc->type) { - case HV_VMBUS_PACKET_TYPE_COMPLETION: + case VMBUS_CHANPKT_TYPE_COMP: hv_nv_on_send_completion(net_dev, chan, desc); break; - case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES: + case VMBUS_CHANPKT_TYPE_RXBUF: hv_nv_on_receive(net_dev, sc, chan, desc); break; - case HV_VMBUS_PACKET_TYPE_DATA_IN_BAND: + case VMBUS_CHANPKT_TYPE_INBAND: hv_nv_send_table(sc, desc); break; default: Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Tue Oct 11 09:11:23 2016 (r307034) @@ -57,6 +57,7 @@ #include #include +#include #define HN_USE_TXDESC_BUFRING @@ -1082,8 +1083,6 @@ struct hv_vmbus_channel; typedef void (*pfn_on_send_rx_completion)(struct hv_vmbus_channel *, void *); #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) -#define NETVSC_PACKET_MAXPAGE 32 - #define NETVSC_VLAN_PRIO_MASK 0xe000 #define NETVSC_VLAN_PRIO_SHIFT 13 @@ -1132,8 +1131,8 @@ typedef struct netvsc_packet_ { void *rndis_mesg; uint32_t tot_data_buf_len; void *data; - uint32_t page_buf_count; - hv_vmbus_page_buffer page_buffers[NETVSC_PACKET_MAXPAGE]; + uint32_t gpa_cnt; + struct vmbus_gpa gpa[VMBUS_CHAN_SGLIST_MAX]; } netvsc_packet; typedef struct { Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Tue Oct 11 09:11:23 2016 (r307034) @@ -156,7 +156,7 @@ __FBSDID("$FreeBSD$"); #define HN_TX_DATA_MAXSIZE IP_MAXPACKET #define HN_TX_DATA_SEGSIZE PAGE_SIZE #define HN_TX_DATA_SEGCNT_MAX \ - (NETVSC_PACKET_MAXPAGE - HV_RF_NUM_TX_RESERVED_PAGE_BUFS) + (VMBUS_CHAN_SGLIST_MAX - HV_RF_NUM_TX_RESERVED_PAGE_BUFS) #define HN_DIRECT_TX_SIZE_DEF 128 @@ -1015,7 +1015,7 @@ hn_encap(struct hn_tx_ring *txr, struct packet->send_buf_section_idx = send_buf_section_idx; packet->send_buf_section_size = packet->tot_data_buf_len; - packet->page_buf_count = 0; + packet->gpa_cnt = 0; txr->hn_tx_chimney++; goto done; } @@ -1041,24 +1041,24 @@ hn_encap(struct hn_tx_ring *txr, struct } *m_head0 = m_head; - packet->page_buf_count = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS; + packet->gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS; /* send packet with page buffer */ - packet->page_buffers[0].pfn = atop(txd->rndis_msg_paddr); - packet->page_buffers[0].offset = txd->rndis_msg_paddr & PAGE_MASK; - packet->page_buffers[0].length = rndis_msg_size; + packet->gpa[0].gpa_page = atop(txd->rndis_msg_paddr); + packet->gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; + packet->gpa[0].gpa_len = rndis_msg_size; /* * Fill the page buffers with mbuf info starting at index * HV_RF_NUM_TX_RESERVED_PAGE_BUFS. */ for (i = 0; i < nsegs; ++i) { - hv_vmbus_page_buffer *pb = &packet->page_buffers[ + struct vmbus_gpa *gpa = &packet->gpa[ i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS]; - pb->pfn = atop(segs[i].ds_addr); - pb->offset = segs[i].ds_addr & PAGE_MASK; - pb->length = segs[i].ds_len; + gpa->gpa_page = atop(segs[i].ds_addr); + gpa->gpa_ofs = segs[i].ds_addr & PAGE_MASK; + gpa->gpa_len = segs[i].ds_len; } packet->send_buf_section_idx = Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Tue Oct 11 09:11:23 2016 (r307034) @@ -249,26 +249,23 @@ hv_rf_send_request(rndis_device *device, packet->is_data_pkt = FALSE; packet->tot_data_buf_len = request->request_msg.msg_len; - packet->page_buf_count = 1; + packet->gpa_cnt = 1; - packet->page_buffers[0].pfn = + packet->gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT; - packet->page_buffers[0].length = request->request_msg.msg_len; - packet->page_buffers[0].offset = + packet->gpa[0].gpa_len = request->request_msg.msg_len; + packet->gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1); - if (packet->page_buffers[0].offset + - packet->page_buffers[0].length > PAGE_SIZE) { - packet->page_buf_count = 2; - packet->page_buffers[0].length = - PAGE_SIZE - packet->page_buffers[0].offset; - packet->page_buffers[1].pfn = + if (packet->gpa[0].gpa_ofs + packet->gpa[0].gpa_len > PAGE_SIZE) { + packet->gpa_cnt = 2; + packet->gpa[0].gpa_len = PAGE_SIZE - packet->gpa[0].gpa_ofs; + packet->gpa[1].gpa_page = hv_get_phys_addr((char*)&request->request_msg + - packet->page_buffers[0].length) >> PAGE_SHIFT; - packet->page_buffers[1].offset = 0; - packet->page_buffers[1].length = - request->request_msg.msg_len - - packet->page_buffers[0].length; + packet->gpa[0].gpa_len) >> PAGE_SHIFT; + packet->gpa[1].gpa_ofs = 0; + packet->gpa[1].gpa_len = request->request_msg.msg_len - + packet->gpa[0].gpa_len; } packet->compl.send.send_completion_context = request; /* packet */ @@ -290,7 +287,7 @@ hv_rf_send_request(rndis_device *device, memcpy(dest, &request->request_msg, request->request_msg.msg_len); packet->send_buf_section_idx = send_buf_section_idx; packet->send_buf_section_size = packet->tot_data_buf_len; - packet->page_buf_count = 0; + packet->gpa_cnt = 0; goto sendit; } /* Failed to allocate chimney send buffer; move on */ @@ -1172,8 +1169,7 @@ hv_rf_on_device_add(struct hn_softc *sc, ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); if (ret != 0) { device_printf(dev, "Fail to allocate subchannel\n"); goto out; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Tue Oct 11 09:11:23 2016 (r307034) @@ -74,7 +74,6 @@ typedef struct rndis_request_ { /* Simplify allocation by having a netvsc packet inline */ netvsc_packet pkt; - hv_vmbus_page_buffer buffer; /* * The max request size is sizeof(rndis_msg) + PAGE_SIZE. Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Tue Oct 11 09:11:23 2016 (r307034) @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include "hv_vstorage.h" #include "vmbus_if.h" @@ -100,7 +101,7 @@ struct hv_sgl_page_pool{ boolean_t is_init; } g_hv_sgl_page_pool; -#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * HV_MAX_MULTIPAGE_BUFFER_COUNT +#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * VMBUS_CHAN_PRPLIST_MAX enum storvsc_request_type { WRITE_TYPE, @@ -108,10 +109,16 @@ enum storvsc_request_type { UNKNOWN_TYPE }; +struct hvs_gpa_range { + struct vmbus_gpa_range gpa_range; + uint64_t gpa_page[VMBUS_CHAN_PRPLIST_MAX]; +} __packed; + struct hv_storvsc_request { LIST_ENTRY(hv_storvsc_request) link; struct vstor_packet vstor_packet; - hv_vmbus_multipage_buffer data_buf; + int prp_cnt; + struct hvs_gpa_range prp_list; void *sense_data; uint8_t sense_info_len; uint8_t retries; @@ -354,8 +361,8 @@ storvsc_send_multichannel_request(struct vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); /* wait for 5 seconds */ ret = sema_timedwait(&request->synch_sema, 5 * hz); @@ -425,8 +432,8 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); if (ret != 0) goto cleanup; @@ -459,8 +466,8 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); if (ret != 0) goto cleanup; @@ -502,8 +509,8 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); if ( ret != 0) goto cleanup; @@ -538,8 +545,8 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); if (ret != 0) { goto cleanup; @@ -628,8 +635,8 @@ hv_storvsc_host_reset(struct storvsc_sof vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)&sc->hs_reset_req, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); if (ret != 0) { goto cleanup; @@ -675,29 +682,26 @@ hv_storvsc_io_request(struct storvsc_sof vstor_packet->u.vm_srb.sense_info_len = sense_buffer_size; - vstor_packet->u.vm_srb.transfer_len = request->data_buf.length; + vstor_packet->u.vm_srb.transfer_len = + request->prp_list.gpa_range.gpa_len; vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB; outgoing_channel = vmbus_select_outgoing_channel(sc->hs_chan); mtx_unlock(&request->softc->hs_lock); - if (request->data_buf.length) { - ret = hv_vmbus_channel_send_packet_multipagebuffer( - outgoing_channel, - &request->data_buf, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request); - + if (request->prp_list.gpa_range.gpa_len) { + ret = vmbus_chan_send_prplist(outgoing_channel, + &request->prp_list.gpa_range, request->prp_cnt, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); } else { ret = hv_vmbus_channel_send_packet( outgoing_channel, vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, - HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + VMBUS_CHANPKT_TYPE_INBAND, + VMBUS_CHANPKT_FLAG_RC); } mtx_lock(&request->softc->hs_lock); @@ -956,7 +960,7 @@ storvsc_attach(device_t dev) /* * Pre-create SG list, each SG list with - * HV_MAX_MULTIPAGE_BUFFER_COUNT segments, each + * VMBUS_CHAN_PRPLIST_MAX segments, each * segment has one page buffer */ for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) { @@ -964,10 +968,10 @@ storvsc_attach(device_t dev) M_DEVBUF, M_WAITOK|M_ZERO); sgl_node->sgl_data = - sglist_alloc(HV_MAX_MULTIPAGE_BUFFER_COUNT, + sglist_alloc(VMBUS_CHAN_PRPLIST_MAX, M_WAITOK|M_ZERO); - for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) { + for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) { tmp_buff = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK|M_ZERO); @@ -1054,7 +1058,7 @@ cleanup: while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); - for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) { + for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) { if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); @@ -1117,7 +1121,7 @@ storvsc_detach(device_t dev) while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); - for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){ + for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++){ if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); @@ -1668,6 +1672,7 @@ create_storvsc_request(union ccb *ccb, s uint32_t pfn_num = 0; uint32_t pfn; uint64_t not_aligned_seg_bits = 0; + struct hvs_gpa_range *prplist; /* refer to struct vmscsi_req for meanings of these two fields */ reqp->vstor_packet.u.vm_srb.port = @@ -1711,22 +1716,23 @@ create_storvsc_request(union ccb *ccb, s return (0); } - reqp->data_buf.length = csio->dxfer_len; + prplist = &reqp->prp_list; + prplist->gpa_range.gpa_len = csio->dxfer_len; switch (ccb->ccb_h.flags & CAM_DATA_MASK) { case CAM_DATA_VADDR: { bytes_to_copy = csio->dxfer_len; phys_addr = vtophys(csio->data_ptr); - reqp->data_buf.offset = phys_addr & PAGE_MASK; + prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK; while (bytes_to_copy != 0) { int bytes, page_offset; phys_addr = - vtophys(&csio->data_ptr[reqp->data_buf.length - + vtophys(&csio->data_ptr[prplist->gpa_range.gpa_len - bytes_to_copy]); pfn = phys_addr >> PAGE_SHIFT; - reqp->data_buf.pfn_array[pfn_num] = pfn; + prplist->gpa_page[pfn_num] = pfn; page_offset = phys_addr & PAGE_MASK; bytes = min(PAGE_SIZE - page_offset, bytes_to_copy); @@ -1734,6 +1740,7 @@ create_storvsc_request(union ccb *ccb, s bytes_to_copy -= bytes; pfn_num++; } + reqp->prp_cnt = pfn_num; break; } @@ -1750,10 +1757,10 @@ create_storvsc_request(union ccb *ccb, s printf("Storvsc: get SG I/O operation, %d\n", reqp->vstor_packet.u.vm_srb.data_in); - if (storvsc_sg_count > HV_MAX_MULTIPAGE_BUFFER_COUNT){ + if (storvsc_sg_count > VMBUS_CHAN_PRPLIST_MAX){ printf("Storvsc: %d segments is too much, " "only support %d segments\n", - storvsc_sg_count, HV_MAX_MULTIPAGE_BUFFER_COUNT); + storvsc_sg_count, VMBUS_CHAN_PRPLIST_MAX); return (EINVAL); } @@ -1806,10 +1813,10 @@ create_storvsc_request(union ccb *ccb, s phys_addr = vtophys(storvsc_sglist[0].ds_addr); } - reqp->data_buf.offset = phys_addr & PAGE_MASK; + prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK; pfn = phys_addr >> PAGE_SHIFT; - reqp->data_buf.pfn_array[0] = pfn; + prplist->gpa_page[0] = pfn; for (i = 1; i < storvsc_sg_count; i++) { if (reqp->not_aligned_seg_bits & (1 << i)) { @@ -1821,27 +1828,31 @@ create_storvsc_request(union ccb *ccb, s } pfn = phys_addr >> PAGE_SHIFT; - reqp->data_buf.pfn_array[i] = pfn; + prplist->gpa_page[i] = pfn; } + reqp->prp_cnt = i; } else { phys_addr = vtophys(storvsc_sglist[0].ds_addr); - reqp->data_buf.offset = phys_addr & PAGE_MASK; + prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK; for (i = 0; i < storvsc_sg_count; i++) { phys_addr = vtophys(storvsc_sglist[i].ds_addr); pfn = phys_addr >> PAGE_SHIFT; - reqp->data_buf.pfn_array[i] = pfn; + prplist->gpa_page[i] = pfn; } + reqp->prp_cnt = i; /* check the last segment cross boundary or not */ offset = phys_addr & PAGE_MASK; if (offset) { + /* Add one more PRP entry */ phys_addr = vtophys(storvsc_sglist[i-1].ds_addr + PAGE_SIZE - offset); pfn = phys_addr >> PAGE_SHIFT; - reqp->data_buf.pfn_array[i] = pfn; + prplist->gpa_page[i] = pfn; + reqp->prp_cnt++; } reqp->bounce_sgl_count = 0; Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Tue Oct 11 09:11:23 2016 (r307034) @@ -35,6 +35,7 @@ #include #include +#include #include "hv_util.h" #include "vmbus_if.h" @@ -87,7 +88,7 @@ hv_heartbeat_cb(void *context) HV_ICMSGHDRFLAG_RESPONSE; hv_vmbus_channel_send_packet(channel, buf, recvlen, requestid, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); } } Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Tue Oct 11 09:11:23 2016 (r307034) @@ -578,7 +578,7 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int e error = hv_vmbus_channel_send_packet(sc->util_sc.channel, sc->rcv_buf, sc->host_msg_len, sc->host_msg_id, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); if (error) hv_kvp_log_info("%s: hv_kvp_respond_host: sendpacket error:%d\n", Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Tue Oct 11 09:11:23 2016 (r307034) @@ -40,6 +40,7 @@ #include #include +#include #include "hv_util.h" #include "vmbus_if.h" @@ -106,7 +107,7 @@ hv_shutdown_cb(void *context) hv_vmbus_channel_send_packet(channel, buf, recv_len, request_id, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); } if (execute_shutdown) Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Tue Oct 11 09:11:23 2016 (r307034) @@ -40,6 +40,7 @@ #include #include +#include #include "hv_util.h" #include "vmbus_if.h" @@ -164,7 +165,7 @@ hv_timesync_cb(void *context) hv_vmbus_channel_send_packet(channel, time_buf, recvlen, requestId, - HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); + VMBUS_CHANPKT_TYPE_INBAND, 0); } } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 09:02:55 2016 (r307033) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Tue Oct 11 09:11:23 2016 (r307034) @@ -621,194 +621,119 @@ hv_vmbus_channel_close(struct hv_vmbus_c hv_vmbus_channel_close_internal(chan); } -/** - * @brief Send the specified buffer on the given channel - */ int -hv_vmbus_channel_send_packet( - hv_vmbus_channel* channel, - void* buffer, - uint32_t buffer_len, - uint64_t request_id, - hv_vmbus_packet_type type, - uint32_t flags) +hv_vmbus_channel_send_packet(struct hv_vmbus_channel *chan, + void *data, uint32_t dlen, uint64_t xactid, uint16_t type, uint16_t flags) { - int ret = 0; - hv_vm_packet_descriptor desc; - uint32_t packet_len; - uint64_t aligned_data; - uint32_t packet_len_aligned; - boolean_t need_sig; - struct iovec iov[3]; - - packet_len = sizeof(hv_vm_packet_descriptor) + buffer_len; - packet_len_aligned = HV_ALIGN_UP(packet_len, sizeof(uint64_t)); - aligned_data = 0; - - /* Setup the descriptor */ - desc.type = type; /* HV_VMBUS_PACKET_TYPE_DATA_IN_BAND; */ - desc.flags = flags; /* HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED */ - /* in 8-bytes granularity */ - desc.data_offset8 = sizeof(hv_vm_packet_descriptor) >> 3; - desc.length8 = (uint16_t) (packet_len_aligned >> 3); - desc.transaction_id = request_id; - - iov[0].iov_base = &desc; - iov[0].iov_len = sizeof(hv_vm_packet_descriptor); - - iov[1].iov_base = buffer; - iov[1].iov_len = buffer_len; - - iov[2].iov_base = &aligned_data; - iov[2].iov_len = packet_len_aligned - packet_len; - - ret = hv_ring_buffer_write(&channel->outbound, iov, 3, &need_sig); - - /* TODO: We should determine if this is optional */ - if (ret == 0 && need_sig) - vmbus_chan_send_event(channel); - - return (ret); + struct vmbus_chanpkt pkt; + int pktlen, pad_pktlen, hlen, error; + uint64_t pad = 0; + struct iovec iov[3]; + boolean_t send_evt; + + hlen = sizeof(pkt); + pktlen = hlen + dlen; + pad_pktlen = roundup2(pktlen, VMBUS_CHANPKT_SIZE_ALIGN); + + pkt.cp_hdr.cph_type = type; + pkt.cp_hdr.cph_flags = flags; + pkt.cp_hdr.cph_data_ofs = hlen >> VMBUS_CHANPKT_SIZE_SHIFT; + pkt.cp_hdr.cph_len = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT; + pkt.cp_hdr.cph_xactid = xactid; + + iov[0].iov_base = &pkt; + iov[0].iov_len = hlen; + iov[1].iov_base = data; + iov[1].iov_len = dlen; + iov[2].iov_base = &pad; + iov[2].iov_len = pad_pktlen - pktlen; + + error = hv_ring_buffer_write(&chan->outbound, iov, 3, &send_evt); + if (!error && send_evt) + vmbus_chan_send_event(chan); + return error; } -/** - * @brief Send a range of single-page buffer packets using - * a GPADL Direct packet type - */ int -hv_vmbus_channel_send_packet_pagebuffer( - hv_vmbus_channel* channel, - hv_vmbus_page_buffer page_buffers[], - uint32_t page_count, - void* buffer, - uint32_t buffer_len, - uint64_t request_id) +vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, + struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid) { - - int ret = 0; - boolean_t need_sig; - uint32_t packet_len; - uint32_t page_buflen; - uint32_t packetLen_aligned; - struct iovec iov[4]; - hv_vmbus_channel_packet_page_buffer desc; - uint32_t descSize; - uint64_t alignedData = 0; - - if (page_count > HV_MAX_PAGE_BUFFER_COUNT) - return (EINVAL); - - /* - * Adjust the size down since hv_vmbus_channel_packet_page_buffer - * is the largest size we support - */ - descSize = __offsetof(hv_vmbus_channel_packet_page_buffer, range); - page_buflen = sizeof(hv_vmbus_page_buffer) * page_count; - packet_len = descSize + page_buflen + buffer_len; - packetLen_aligned = HV_ALIGN_UP(packet_len, sizeof(uint64_t)); - - /* Setup the descriptor */ - desc.type = HV_VMBUS_PACKET_TYPE_DATA_USING_GPA_DIRECT; - desc.flags = HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; - /* in 8-bytes granularity */ - desc.data_offset8 = (descSize + page_buflen) >> 3; - desc.length8 = (uint16_t) (packetLen_aligned >> 3); - desc.transaction_id = request_id; - desc.range_count = page_count; - - iov[0].iov_base = &desc; - iov[0].iov_len = descSize; - - iov[1].iov_base = page_buffers; - iov[1].iov_len = page_buflen; - - iov[2].iov_base = buffer; - iov[2].iov_len = buffer_len; - - iov[3].iov_base = &alignedData; - iov[3].iov_len = packetLen_aligned - packet_len; - - ret = hv_ring_buffer_write(&channel->outbound, iov, 4, &need_sig); - - /* TODO: We should determine if this is optional */ - if (ret == 0 && need_sig) - vmbus_chan_send_event(channel); - - return (ret); + struct vmbus_chanpkt_sglist pkt; + int pktlen, pad_pktlen, hlen, error; + struct iovec iov[4]; + boolean_t send_evt; + uint64_t pad = 0; + + KASSERT(sglen < VMBUS_CHAN_SGLIST_MAX, + ("invalid sglist len %d", sglen)); + + hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]); + pktlen = hlen + dlen; + pad_pktlen = roundup2(pktlen, VMBUS_CHANPKT_SIZE_ALIGN); + + pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; + pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; + pkt.cp_hdr.cph_data_ofs = hlen >> VMBUS_CHANPKT_SIZE_SHIFT; + pkt.cp_hdr.cph_len = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT; + pkt.cp_hdr.cph_xactid = xactid; + pkt.cp_rsvd = 0; + pkt.cp_gpa_cnt = sglen; + + iov[0].iov_base = &pkt; + iov[0].iov_len = sizeof(pkt); + iov[1].iov_base = sg; + iov[1].iov_len = sizeof(struct vmbus_gpa) * sglen; + iov[2].iov_base = data; + iov[2].iov_len = dlen; + iov[3].iov_base = &pad; + iov[3].iov_len = pad_pktlen - pktlen; + + error = hv_ring_buffer_write(&chan->outbound, iov, 4, &send_evt); + if (!error && send_evt) + vmbus_chan_send_event(chan); + return error; } -/** - * @brief Send a multi-page buffer packet using a GPADL Direct packet type - */ int -hv_vmbus_channel_send_packet_multipagebuffer( - hv_vmbus_channel* channel, - hv_vmbus_multipage_buffer* multi_page_buffer, - void* buffer, - uint32_t buffer_len, - uint64_t request_id) -{ - - int ret = 0; - uint32_t desc_size; - boolean_t need_sig; - uint32_t packet_len; - uint32_t packet_len_aligned; - uint32_t pfn_count; - uint64_t aligned_data = 0; - struct iovec iov[3]; - hv_vmbus_channel_packet_multipage_buffer desc; - - pfn_count = - HV_NUM_PAGES_SPANNED( - multi_page_buffer->offset, - multi_page_buffer->length); - - if ((pfn_count == 0) || (pfn_count > HV_MAX_MULTIPAGE_BUFFER_COUNT)) - return (EINVAL); - /* - * Adjust the size down since hv_vmbus_channel_packet_multipage_buffer - * is the largest size we support - */ - desc_size = - sizeof(hv_vmbus_channel_packet_multipage_buffer) - - ((HV_MAX_MULTIPAGE_BUFFER_COUNT - pfn_count) * - sizeof(uint64_t)); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Tue Oct 11 09:19:31 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 69848C0B3CE; Tue, 11 Oct 2016 09:19:31 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 394F63B0; Tue, 11 Oct 2016 09:19:31 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9B9JUk0049882; Tue, 11 Oct 2016 09:19:30 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9B9JUlv049881; Tue, 11 Oct 2016 09:19:30 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610110919.u9B9JUlv049881@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 11 Oct 2016 09:19:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307035 - stable/10/sys/conf X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 09:19:31 -0000 Author: sephe Date: Tue Oct 11 09:19:30 2016 New Revision: 307035 URL: https://svnweb.freebsd.org/changeset/base/307035 Log: build: Add vmbus_if.m This is a direct commit, which reflects the difference between current and 10-stable. Sponsored by: Microsoft Modified: stable/10/sys/conf/kmod.mk Modified: stable/10/sys/conf/kmod.mk ============================================================================== --- stable/10/sys/conf/kmod.mk Tue Oct 11 09:11:23 2016 (r307034) +++ stable/10/sys/conf/kmod.mk Tue Oct 11 09:19:30 2016 (r307035) @@ -364,6 +364,7 @@ CFLAGS+= ${CONF_CFLAGS} MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m \ dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/fb/fb_if.m dev/gpio/gpio_if.m dev/gpio/gpiobus_if.m \ + dev/hyperv/vmbus/vmbus_if.m \ dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \ dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \ dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \ From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:46:17 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E314CC0C5F0; Tue, 11 Oct 2016 16:46:17 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 97DF5309; Tue, 11 Oct 2016 16:46:17 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGkGbc022272; Tue, 11 Oct 2016 16:46:16 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGkG4Y022271; Tue, 11 Oct 2016 16:46:16 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111646.u9BGkG4Y022271@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:46:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307052 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:46:18 -0000 Author: mav Date: Tue Oct 11 16:46:16 2016 New Revision: 307052 URL: https://svnweb.freebsd.org/changeset/base/307052 Log: MFC r305193: MFV r302642: 6876 Stack corruption after importing a pool with a too-long name illumos/illumos-gate@c971037baa5d64dfecf6d87ed602fc3116ebec41 https://github.com/illumos/illumos-gate/commit/c971037baa5d64dfecf6d87ed602fc3116ebec41 https://www.illumos.org/issues/6876 Calling dsl_dataset_name on a dataset with a 256 byte buffer is asking for trouble. We should check every dataset on import, using a 1024 byte buffer and checking each time to see if the dataset's new name is longer than 256 bytes. Reviewed by: Prakash Surya Reviewed by: Dan Kimmel Reviewed by: George Wilson Reviewed by: Yuri Pankov Approved by: Richard Lowe Author: Paul Dagnelie Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Tue Oct 11 16:38:39 2016 (r307051) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Tue Oct 11 16:46:16 2016 (r307052) @@ -1975,6 +1975,19 @@ spa_load_verify_cb(spa_t *spa, zilog_t * return (0); } +/* ARGSUSED */ +int +verify_dataset_name_len(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg) +{ + char namebuf[MAXPATHLEN]; + dsl_dataset_name(ds, namebuf); + if (strlen(namebuf) > MAXNAMELEN) { + return (SET_ERROR(ENAMETOOLONG)); + } + + return (0); +} + static int spa_load_verify(spa_t *spa) { @@ -1989,6 +2002,14 @@ spa_load_verify(spa_t *spa) if (policy.zrp_request & ZPOOL_NEVER_REWIND) return (0); + dsl_pool_config_enter(spa->spa_dsl_pool, FTAG); + error = dmu_objset_find_dp(spa->spa_dsl_pool, + spa->spa_dsl_pool->dp_root_dir_obj, verify_dataset_name_len, NULL, + DS_FIND_CHILDREN); + dsl_pool_config_exit(spa->spa_dsl_pool, FTAG); + if (error != 0) + return (error); + rio = zio_root(spa, NULL, &sle, ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE); From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:47:23 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4B8EAC0C69E; Tue, 11 Oct 2016 16:47:23 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 24F5A6A2; Tue, 11 Oct 2016 16:47:23 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGlMsi022374; Tue, 11 Oct 2016 16:47:22 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGlLjE022364; Tue, 11 Oct 2016 16:47:21 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111647.u9BGlLjE022364@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:47:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307053 - in stable/10: cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/lib/libzfs/common sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/cddl/contrib/opensolaris/uts/commo... X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:47:23 -0000 Author: mav Date: Tue Oct 11 16:47:21 2016 New Revision: 307053 URL: https://svnweb.freebsd.org/changeset/base/307053 Log: MFC r305195: MFV r302643: 6902 speed up listing of snapshots if requesting name only and sorting by name This was our change from the beginning, so just reduce the upstream diff. Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c Tue Oct 11 16:47:21 2016 (r307053) @@ -21,8 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. */ @@ -320,8 +319,8 @@ zfs_sort(const void *larg, const void *r } else if (psc->sc_prop == ZFS_PROP_NAME) { lvalid = rvalid = B_TRUE; - (void) strlcpy(lbuf, zfs_get_name(l), sizeof(lbuf)); - (void) strlcpy(rbuf, zfs_get_name(r), sizeof(rbuf)); + (void) strlcpy(lbuf, zfs_get_name(l), sizeof (lbuf)); + (void) strlcpy(rbuf, zfs_get_name(r), sizeof (rbuf)); lstr = lbuf; rstr = rbuf; Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.h Tue Oct 11 16:47:21 2016 (r307053) @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Tue Oct 11 16:47:21 2016 (r307053) @@ -24,8 +24,7 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. - * Copyright (c) 2011-2012 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. @@ -3008,7 +3007,7 @@ print_dataset(zfs_handle_t *zhp, list_cb if (pl->pl_prop == ZFS_PROP_NAME) { (void) strlcpy(property, zfs_get_name(zhp), - sizeof(property)); + sizeof (property)); propstr = property; right_justify = zfs_prop_align_right(pl->pl_prop); } else if (pl->pl_prop != ZPROP_INVAL) { Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Tue Oct 11 16:47:21 2016 (r307053) @@ -21,8 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Tue Oct 11 16:47:21 2016 (r307053) @@ -24,9 +24,8 @@ * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. - * Copyright (c) 2011-2012 Pawel Jakub Dawidek . - * All rights reserved. - * Copyright (c) 2012 Martin Matuska . All rights reserved. + * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. + * Copyright (c) 2013 Martin Matuska. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h Tue Oct 11 16:47:21 2016 (r307053) @@ -21,8 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013 Martin Matuska . All rights reserved. */ Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Tue Oct 11 16:47:21 2016 (r307053) @@ -22,8 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015 by Delphix. All rights reserved. - * Copyright (c) 2012 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Tue Oct 11 16:47:21 2016 (r307053) @@ -23,8 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. - * Copyright (c) 2012 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Tue Oct 11 16:47:21 2016 (r307053) @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright 2016 RackTop Systems. * Copyright (c) 2014 Integros [integros.com] Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:46:16 2016 (r307052) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:47:21 2016 (r307053) @@ -21,8 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011-2012 Pawel Jakub Dawidek . - * All rights reserved. + * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright 2013 Martin Matuska . All rights reserved. * Copyright 2014 Xin Li . All rights reserved. * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:48:14 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 224BCC0C7B0; Tue, 11 Oct 2016 16:48:14 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EDE31878; Tue, 11 Oct 2016 16:48:13 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGmDJf022461; Tue, 11 Oct 2016 16:48:13 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGmCbS022457; Tue, 11 Oct 2016 16:48:12 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111648.u9BGmCbS022457@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:48:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307054 - in stable/10/sys/cddl/contrib/opensolaris: common/zfs uts/common/fs/zfs uts/common/fs/zfs/sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:48:14 -0000 Author: mav Date: Tue Oct 11 16:48:12 2016 New Revision: 307054 URL: https://svnweb.freebsd.org/changeset/base/307054 Log: MFC r305197: MFV r302646: 6980 6902 causes zfs send to break due to 32-bit/64-bit struct mismatch illumos/illumos-gate@ea4a67f462de0a39a9adea8197bcdef849de5371 https://github.com/illumos/illumos-gate/commit/ea4a67f462de0a39a9adea8197bcdef84 9de5371 https://www.illumos.org/issues/6980 doing zfs send -i snap1 snap2 >testfile results in internal error: Invalid argument Abort (core dumped) Reviewed by: Paul Dagnelie Reviewed by: George Wilson Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Tue Oct 11 16:47:21 2016 (r307053) +++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Tue Oct 11 16:48:12 2016 (r307054) @@ -55,8 +55,52 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_ zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; zfs_cmd_resume_t *resume_c; + zfs_cmd_inlanes_t *inlanes_c; switch (cflag) { + case ZFS_CMD_COMPAT_INLANES: + inlanes_c = (void *)addr; + /* zc */ + strlcpy(zc->zc_name, inlanes_c->zc_name, MAXPATHLEN); + strlcpy(zc->zc_value, inlanes_c->zc_value, MAXPATHLEN * 2); + strlcpy(zc->zc_string, inlanes_c->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) zc->field = inlanes_c->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_resumable); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_RESUME: resume_c = (void *)addr; /* zc */ @@ -434,8 +478,50 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_ zfs_cmd_zcmd_t *zcmd_c; zfs_cmd_edbp_t *edbp_c; zfs_cmd_resume_t *resume_c; + zfs_cmd_inlanes_t *inlanes_c; switch (cflag) { + case ZFS_CMD_COMPAT_INLANES: + inlanes_c = (void *)addr; + strlcpy(inlanes_c->zc_name, zc->zc_name, MAXPATHLEN); + strlcpy(inlanes_c->zc_value, zc->zc_value, MAXPATHLEN * 2); + strlcpy(inlanes_c->zc_string, zc->zc_string, MAXPATHLEN); + +#define FIELD_COPY(field) inlanes_c->field = zc->field + FIELD_COPY(zc_nvlist_src); + FIELD_COPY(zc_nvlist_src_size); + FIELD_COPY(zc_nvlist_dst); + FIELD_COPY(zc_nvlist_dst_size); + FIELD_COPY(zc_nvlist_dst_filled); + FIELD_COPY(zc_pad2); + FIELD_COPY(zc_history); + FIELD_COPY(zc_guid); + FIELD_COPY(zc_nvlist_conf); + FIELD_COPY(zc_nvlist_conf_size); + FIELD_COPY(zc_cookie); + FIELD_COPY(zc_objset_type); + FIELD_COPY(zc_perm_action); + FIELD_COPY(zc_history_len); + FIELD_COPY(zc_history_offset); + FIELD_COPY(zc_obj); + FIELD_COPY(zc_iflags); + FIELD_COPY(zc_share); + FIELD_COPY(zc_jailid); + FIELD_COPY(zc_objset_stats); + FIELD_COPY(zc_begin_record); + FIELD_COPY(zc_inject_record); + FIELD_COPY(zc_defer_destroy); + FIELD_COPY(zc_flags); + FIELD_COPY(zc_action_handle); + FIELD_COPY(zc_cleanup_fd); + FIELD_COPY(zc_simple); + FIELD_COPY(zc_sendobj); + FIELD_COPY(zc_fromobj); + FIELD_COPY(zc_createtxg); + FIELD_COPY(zc_stat); +#undef FIELD_COPY + break; + case ZFS_CMD_COMPAT_RESUME: resume_c = (void *)addr; strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN); @@ -987,6 +1073,12 @@ zcmd_ioctl_compat(int fd, int request, z zp.zfs_cmd_size = sizeof(zfs_cmd_t); zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT; return (ioctl(fd, ncmd, &zp)); + case ZFS_CMD_COMPAT_INLANES: + ncmd = _IOWR('Z', request, struct zfs_iocparm); + zp.zfs_cmd = (uint64_t)zc; + zp.zfs_cmd_size = sizeof(zfs_cmd_inlanes_t); + zp.zfs_ioctl_version = ZFS_IOCVER_INLANES; + return (ioctl(fd, ncmd, &zp)); case ZFS_CMD_COMPAT_RESUME: ncmd = _IOWR('Z', request, struct zfs_iocparm); zp.zfs_cmd = (uint64_t)zc; @@ -1104,7 +1196,7 @@ zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nv if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || - cflag == ZFS_CMD_COMPAT_RESUME) + cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES) goto out; switch (vec) { @@ -1257,7 +1349,7 @@ zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, n if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP || - cflag == ZFS_CMD_COMPAT_RESUME) + cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES) return (outnvl); switch (vec) { Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Tue Oct 11 16:47:21 2016 (r307053) +++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Tue Oct 11 16:48:12 2016 (r307054) @@ -54,7 +54,8 @@ extern "C" { #define ZFS_IOCVER_EDBP 4 #define ZFS_IOCVER_RESUME 5 #define ZFS_IOCVER_INLANES 6 -#define ZFS_IOCVER_CURRENT ZFS_IOCVER_INLANES +#define ZFS_IOCVER_PAD 7 +#define ZFS_IOCVER_CURRENT ZFS_IOCVER_PAD /* compatibility conversion flag */ #define ZFS_CMD_COMPAT_NONE 0 @@ -65,6 +66,7 @@ extern "C" { #define ZFS_CMD_COMPAT_ZCMD 5 #define ZFS_CMD_COMPAT_EDBP 6 #define ZFS_CMD_COMPAT_RESUME 7 +#define ZFS_CMD_COMPAT_INLANES 8 #define ZFS_IOC_COMPAT_PASS 254 #define ZFS_IOC_COMPAT_FAIL 255 @@ -355,6 +357,49 @@ typedef struct zfs_cmd_resume { zfs_stat_t zc_stat; } zfs_cmd_resume_t; +typedef struct zfs_cmd_inlanes { + char zc_name[MAXPATHLEN]; /* name of pool or dataset */ + uint64_t zc_nvlist_src; /* really (char *) */ + uint64_t zc_nvlist_src_size; + uint64_t zc_nvlist_dst; /* really (char *) */ + uint64_t zc_nvlist_dst_size; + boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ + int zc_pad2; + + /* + * The following members are for legacy ioctls which haven't been + * converted to the new method. + */ + uint64_t zc_history; /* really (char *) */ + char zc_value[MAXPATHLEN * 2]; + char zc_string[MAXNAMELEN]; + uint64_t zc_guid; + uint64_t zc_nvlist_conf; /* really (char *) */ + uint64_t zc_nvlist_conf_size; + uint64_t zc_cookie; + uint64_t zc_objset_type; + uint64_t zc_perm_action; + uint64_t zc_history_len; + uint64_t zc_history_offset; + uint64_t zc_obj; + uint64_t zc_iflags; /* internal to zfs(7fs) */ + zfs_share_t zc_share; + uint64_t zc_jailid; + dmu_objset_stats_t zc_objset_stats; + dmu_replay_record_t zc_begin_record; + zinject_record_t zc_inject_record; + uint32_t zc_defer_destroy; + uint32_t zc_flags; + uint64_t zc_action_handle; + int zc_cleanup_fd; + uint8_t zc_simple; + boolean_t zc_resumable; + uint64_t zc_sendobj; + uint64_t zc_fromobj; + uint64_t zc_createtxg; + zfs_stat_t zc_stat; +} zfs_cmd_inlanes_t; + #ifdef _KERNEL unsigned static long zfs_ioctl_v15_to_v28[] = { 0, /* 0 ZFS_IOC_POOL_CREATE */ Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Tue Oct 11 16:47:21 2016 (r307053) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h Tue Oct 11 16:48:12 2016 (r307054) @@ -353,6 +353,12 @@ typedef enum zfs_case { ZFS_CASE_MIXED } zfs_case_t; +/* + * Note: this struct must have the same layout in 32-bit and 64-bit, so + * that 32-bit processes (like /sbin/zfs) can pass it to the 64-bit + * kernel. Therefore, we add padding to it so that no "hidden" padding + * is automatically added on 64-bit (but not on 32-bit). + */ typedef struct zfs_cmd { char zc_name[MAXPATHLEN]; /* name of pool or dataset */ uint64_t zc_nvlist_src; /* really (char *) */ @@ -389,7 +395,9 @@ typedef struct zfs_cmd { uint64_t zc_action_handle; int zc_cleanup_fd; uint8_t zc_simple; + uint8_t zc_pad3[3]; boolean_t zc_resumable; + uint32_t zc_pad4; uint64_t zc_sendobj; uint64_t zc_fromobj; uint64_t zc_createtxg; Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:47:21 2016 (r307053) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:48:12 2016 (r307054) @@ -6251,6 +6251,14 @@ zfsdev_ioctl(struct cdev *dev, u_long zc goto out; } break; + case ZFS_IOCVER_INLANES: + if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_inlanes_t)) { + error = SET_ERROR(EFAULT); + goto out; + } + compat = B_TRUE; + cflag = ZFS_CMD_COMPAT_INLANES; + break; case ZFS_IOCVER_RESUME: if (zc_iocparm->zfs_cmd_size != sizeof(zfs_cmd_resume_t)) { error = SET_ERROR(EFAULT); From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:49:17 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C197CC0C840; Tue, 11 Oct 2016 16:49:17 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9C0259EC; Tue, 11 Oct 2016 16:49:17 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGnG8r022549; Tue, 11 Oct 2016 16:49:16 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGnGTv022547; Tue, 11 Oct 2016 16:49:16 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111649.u9BGnGTv022547@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:49:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307055 - in stable/10/sys/cddl/contrib/opensolaris/uts/common: fs/zfs sys/sysevent X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:49:17 -0000 Author: mav Date: Tue Oct 11 16:49:16 2016 New Revision: 307055 URL: https://svnweb.freebsd.org/changeset/base/307055 Log: MFC r305198: MFV r302647: 6922 Emit ESC_ZFS_VDEV_REMOVE_AUX after removing an aux device illumos/illumos-gate@63364b0ee2604783e7a55f8425888867768eafa4 https://github.com/illumos/illumos-gate/commit/63364b0ee2604783e7a55f84258888677 68eafa4 https://www.illumos.org/issues/6922 ZFS does not do a config_sync after removing an aux (spare, log, or cache) device. AFAICT this isn't being done because it is slow and was deemed unnecessary. However, it should be such a rare operation that speed doesn't matter, and not doing it results in two problems: 1) It is theoretically possible to remove an aux device from one pool and attach it to another, then lose power. When power is restored, both pools woul d think that they own the aux device. 2) Removal of the aux device doesn't send any useful sysevents to userland. Reviewed by: George Wilson Reviewed by: Matthew Ahrens Approved by: Dan McDonald Author: Alan Somers Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent/eventdefs.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Tue Oct 11 16:48:12 2016 (r307054) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Tue Oct 11 16:49:16 2016 (r307055) @@ -5680,6 +5680,7 @@ spa_vdev_remove(spa_t *spa, uint64_t gui } else { error = SET_ERROR(EBUSY); } + spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); } else if (spa->spa_l2cache.sav_vdevs != NULL && nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0 && @@ -5691,6 +5692,7 @@ spa_vdev_remove(spa_t *spa, uint64_t gui ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache, nv); spa_load_l2cache(spa); spa->spa_l2cache.sav_sync = B_TRUE; + spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); } else if (vd != NULL && vd->vdev_islog) { ASSERT(!locked); ASSERT(vd == vd->vdev_top); @@ -5729,6 +5731,7 @@ spa_vdev_remove(spa_t *spa, uint64_t gui */ spa_vdev_remove_from_namespace(spa, vd); + spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_DEV); } else if (vd != NULL) { /* * Normal vdevs cannot be removed (yet). @@ -5742,7 +5745,7 @@ spa_vdev_remove(spa_t *spa, uint64_t gui } if (!locked) - return (spa_vdev_exit(spa, NULL, txg, error)); + error = spa_vdev_exit(spa, NULL, txg, error); return (error); } Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent/eventdefs.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent/eventdefs.h Tue Oct 11 16:48:12 2016 (r307054) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/sysevent/eventdefs.h Tue Oct 11 16:49:16 2016 (r307055) @@ -249,6 +249,8 @@ extern "C" { #define ESC_ZFS_RESILVER_START "ESC_ZFS_resilver_start" #define ESC_ZFS_RESILVER_FINISH "ESC_ZFS_resilver_finish" #define ESC_ZFS_VDEV_REMOVE "ESC_ZFS_vdev_remove" +#define ESC_ZFS_VDEV_REMOVE_AUX "ESC_ZFS_vdev_remove_aux" +#define ESC_ZFS_VDEV_REMOVE_DEV "ESC_ZFS_vdev_remove_dev" #define ESC_ZFS_POOL_CREATE "ESC_ZFS_pool_create" #define ESC_ZFS_POOL_DESTROY "ESC_ZFS_pool_destroy" #define ESC_ZFS_POOL_IMPORT "ESC_ZFS_pool_import" From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:50:47 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0689CC0C94E; Tue, 11 Oct 2016 16:50:47 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D7B70C58; Tue, 11 Oct 2016 16:50:46 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGok6A022679; Tue, 11 Oct 2016 16:50:46 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGokIb022678; Tue, 11 Oct 2016 16:50:46 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111650.u9BGokIb022678@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:50:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307056 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:50:47 -0000 Author: mav Date: Tue Oct 11 16:50:45 2016 New Revision: 307056 URL: https://svnweb.freebsd.org/changeset/base/307056 Log: MFC r305199: MFV r302648: 7019 zfsdev_ioctl skips secpolicy when FKIOCTL is set Note that the bulk of the upstream change is not applicable to FreeBSD and the affected files are not even in the vendor area. illumos/illumos-gate@45b1747515a17db45e8971501ee84a26bdff37b2 https://github.com/illumos/illumos-gate/commit/45b1747515a17db45e8971501ee84a26bdff37b2 https://www.illumos.org/issues/7019 Currently zfsdev_ioctl, when confronted by a request with the FKIOCTL flag set, skips all processing of secpolicy functions. This means that ZFS is not doing any kind of verification of the credentials or access rights of the caller and assuming that (as it is an in-kernel client) all such checks have already been done. This turns out to be quite a dangerous assumption, especially with respect to sdev. In general I don't think it's particularly reasonable to offload this enforcement of access rights onto other kernel subsystems when ZFS has some particular local semantics in this area (delegated datasets etc) and does not provide any kind of API to allow other subsystems to avoid code duplication when doing it. ZFS should apply its normal access policy to requests from within the kernel, and callers should take care to give it the correct credentials and call it from the correct context in order to get the results they need. You can observe the currently unfortunate consequences of this bug in any non- global zone that has access to /dev/zvol or any subset of it via sdev profiles. In particular, a zone used to contain a KVM or similar which has a single zvol passed through to it using a Reviewed by: Richard Lowe Reviewed by: Matthew Ahrens Approved by: Dan McDonald Author: Alex Wilson Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:49:16 2016 (r307055) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Tue Oct 11 16:50:45 2016 (r307056) @@ -26,7 +26,7 @@ * Copyright 2014 Xin Li . All rights reserved. * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. @@ -6366,7 +6366,7 @@ zfsdev_ioctl(struct cdev *dev, u_long zc break; } - if (error == 0 && !(flag & FKIOCTL)) + if (error == 0) error = vec->zvec_secpolicy(zc, innvl, cr); if (error != 0) From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:52:59 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 67CA1C0CC0B; Tue, 11 Oct 2016 16:52:59 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 35E8EE; Tue, 11 Oct 2016 16:52:59 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGqwM5026183; Tue, 11 Oct 2016 16:52:58 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGqvRd026177; Tue, 11 Oct 2016 16:52:57 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111652.u9BGqvRd026177@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:52:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307057 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:52:59 -0000 Author: mav Date: Tue Oct 11 16:52:57 2016 New Revision: 307057 URL: https://svnweb.freebsd.org/changeset/base/307057 Log: MFC r305200: MFV r302651: 7054 dmu_tx_hold_t should use refcount_t to track space illumos/illumos-gate@0c779ad424a92a84d1e07d47cab7f8009189202b https://github.com/illumos/illumos-gate/commit/0c779ad424a92a84d1e07d47cab7f8009 189202b https://www.illumos.org/issues/7054 upstream: ee0003de7d3e598499be7ac3fe6b61efcc47cb7f DLPX-40399 dmu_tx_hold_t should use refcount_t to track space Reviewed by: George Wilson Reviewed by: Paul Dagnelie Reviewed by: Igor Kozhukhov Approved by: Dan McDonald Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Tue Oct 11 16:52:57 2016 (r307057) @@ -129,6 +129,12 @@ dmu_tx_hold_object_impl(dmu_tx_t *tx, ob txh = kmem_zalloc(sizeof (dmu_tx_hold_t), KM_SLEEP); txh->txh_tx = tx; txh->txh_dnode = dn; + refcount_create(&txh->txh_space_towrite); + refcount_create(&txh->txh_space_tofree); + refcount_create(&txh->txh_space_tooverwrite); + refcount_create(&txh->txh_space_tounref); + refcount_create(&txh->txh_memory_tohold); + refcount_create(&txh->txh_fudge); #ifdef ZFS_DEBUG txh->txh_type = type; txh->txh_arg1 = arg1; @@ -201,12 +207,18 @@ dmu_tx_count_twig(dmu_tx_hold_t *txh, dn freeable = (bp && (freeable || dsl_dataset_block_freeable(ds, bp, bp->blk_birth))); - if (freeable) - txh->txh_space_tooverwrite += space; - else - txh->txh_space_towrite += space; - if (bp) - txh->txh_space_tounref += bp_get_dsize(os->os_spa, bp); + if (freeable) { + (void) refcount_add_many(&txh->txh_space_tooverwrite, + space, FTAG); + } else { + (void) refcount_add_many(&txh->txh_space_towrite, + space, FTAG); + } + + if (bp) { + (void) refcount_add_many(&txh->txh_space_tounref, + bp_get_dsize(os->os_spa, bp), FTAG); + } dmu_tx_count_twig(txh, dn, parent, level + 1, blkid >> epbs, freeable, history); @@ -336,8 +348,11 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, u bits = 64 - min_bs; epbs = min_ibs - SPA_BLKPTRSHIFT; for (bits -= epbs * (nlvls - 1); - bits >= 0; bits -= epbs) - txh->txh_fudge += 1ULL << max_ibs; + bits >= 0; bits -= epbs) { + (void) refcount_add_many( + &txh->txh_fudge, + 1ULL << max_ibs, FTAG); + } goto out; } off += delta; @@ -353,7 +368,8 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, u */ start = P2ALIGN(off, 1ULL << max_bs); end = P2ROUNDUP(off + len, 1ULL << max_bs) - 1; - txh->txh_space_towrite += end - start + 1; + (void) refcount_add_many(&txh->txh_space_towrite, + end - start + 1, FTAG); start >>= min_bs; end >>= min_bs; @@ -368,18 +384,21 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, u start >>= epbs; end >>= epbs; ASSERT3U(end, >=, start); - txh->txh_space_towrite += (end - start + 1) << max_ibs; + (void) refcount_add_many(&txh->txh_space_towrite, + (end - start + 1) << max_ibs, FTAG); if (start != 0) { /* * We also need a new blkid=0 indirect block * to reference any existing file data. */ - txh->txh_space_towrite += 1ULL << max_ibs; + (void) refcount_add_many(&txh->txh_space_towrite, + 1ULL << max_ibs, FTAG); } } out: - if (txh->txh_space_towrite + txh->txh_space_tooverwrite > + if (refcount_count(&txh->txh_space_towrite) + + refcount_count(&txh->txh_space_tooverwrite) > 2 * DMU_MAX_ACCESS) err = SET_ERROR(EFBIG); @@ -398,12 +417,15 @@ dmu_tx_count_dnode(dmu_tx_hold_t *txh) if (dn && dn->dn_dbuf->db_blkptr && dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset, dn->dn_dbuf->db_blkptr, dn->dn_dbuf->db_blkptr->blk_birth)) { - txh->txh_space_tooverwrite += space; - txh->txh_space_tounref += space; + (void) refcount_add_many(&txh->txh_space_tooverwrite, + space, FTAG); + (void) refcount_add_many(&txh->txh_space_tounref, space, FTAG); } else { - txh->txh_space_towrite += space; - if (dn && dn->dn_dbuf->db_blkptr) - txh->txh_space_tounref += space; + (void) refcount_add_many(&txh->txh_space_towrite, space, FTAG); + if (dn && dn->dn_dbuf->db_blkptr) { + (void) refcount_add_many(&txh->txh_space_tounref, + space, FTAG); + } } } @@ -525,7 +547,8 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, ui break; } - txh->txh_memory_tohold += dbuf->db.db_size; + (void) refcount_add_many(&txh->txh_memory_tohold, + dbuf->db.db_size, FTAG); /* * We don't check memory_tohold against DMU_MAX_ACCESS because @@ -578,20 +601,23 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, ui (dn->dn_indblkshift - SPA_BLKPTRSHIFT); while (level++ < maxlevel) { - txh->txh_memory_tohold += MAX(MIN(blkcnt, nl1blks), 1) - << dn->dn_indblkshift; + (void) refcount_add_many(&txh->txh_memory_tohold, + MAX(MIN(blkcnt, nl1blks), 1) << dn->dn_indblkshift, + FTAG); blkcnt = 1 + (blkcnt >> epbs); } } /* account for new level 1 indirect blocks that might show up */ if (skipped > 0) { - txh->txh_fudge += skipped << dn->dn_indblkshift; + (void) refcount_add_many(&txh->txh_fudge, + skipped << dn->dn_indblkshift, FTAG); skipped = MIN(skipped, DMU_MAX_DELETEBLKCNT >> epbs); - txh->txh_memory_tohold += skipped << dn->dn_indblkshift; + (void) refcount_add_many(&txh->txh_memory_tohold, + skipped << dn->dn_indblkshift, FTAG); } - txh->txh_space_tofree += space; - txh->txh_space_tounref += unref; + (void) refcount_add_many(&txh->txh_space_tofree, space, FTAG); + (void) refcount_add_many(&txh->txh_space_tounref, unref, FTAG); } /* @@ -617,7 +643,10 @@ dmu_tx_mark_netfree(dmu_tx_t *tx) * cause overflows when doing math with these values (e.g. in * dmu_tx_try_assign()). */ - txh->txh_space_tofree = txh->txh_space_tounref = 1024 * 1024 * 1024; + (void) refcount_add_many(&txh->txh_space_tofree, + 1024 * 1024 * 1024, FTAG); + (void) refcount_add_many(&txh->txh_space_tounref, + 1024 * 1024 * 1024, FTAG); } void @@ -717,9 +746,7 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t o { dmu_tx_hold_t *txh; dnode_t *dn; - dsl_dataset_phys_t *ds_phys; - uint64_t nblocks; - int epbs, err; + int err; ASSERT(tx->tx_txg == 0); @@ -762,12 +789,17 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t o */ bp = &dn->dn_phys->dn_blkptr[0]; if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset, - bp, bp->blk_birth)) - txh->txh_space_tooverwrite += MZAP_MAX_BLKSZ; - else - txh->txh_space_towrite += MZAP_MAX_BLKSZ; - if (!BP_IS_HOLE(bp)) - txh->txh_space_tounref += MZAP_MAX_BLKSZ; + bp, bp->blk_birth)) { + (void) refcount_add_many(&txh->txh_space_tooverwrite, + MZAP_MAX_BLKSZ, FTAG); + } else { + (void) refcount_add_many(&txh->txh_space_towrite, + MZAP_MAX_BLKSZ, FTAG); + } + if (!BP_IS_HOLE(bp)) { + (void) refcount_add_many(&txh->txh_space_tounref, + MZAP_MAX_BLKSZ, FTAG); + } return; } @@ -789,15 +821,29 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t o /* * If the modified blocks are scattered to the four winds, - * we'll have to modify an indirect twig for each. + * we'll have to modify an indirect twig for each. We can make + * modifications at up to 3 locations: + * - header block at the beginning of the object + * - target leaf block + * - end of the object, where we might need to write: + * - a new leaf block if the target block needs to be split + * - the new pointer table, if it is growing + * - the new cookie table, if it is growing */ - epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; - ds_phys = dsl_dataset_phys(dn->dn_objset->os_dsl_dataset); - for (nblocks = dn->dn_maxblkid >> epbs; nblocks != 0; nblocks >>= epbs) - if (ds_phys->ds_prev_snap_obj) - txh->txh_space_towrite += 3 << dn->dn_indblkshift; - else - txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift; + int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; + dsl_dataset_phys_t *ds_phys = + dsl_dataset_phys(dn->dn_objset->os_dsl_dataset); + for (int lvl = 1; lvl < dn->dn_nlevels; lvl++) { + uint64_t num_indirects = 1 + (dn->dn_maxblkid >> (epbs * lvl)); + uint64_t spc = MIN(3, num_indirects) << dn->dn_indblkshift; + if (ds_phys->ds_prev_snap_obj != 0) { + (void) refcount_add_many(&txh->txh_space_towrite, + spc, FTAG); + } else { + (void) refcount_add_many(&txh->txh_space_tooverwrite, + spc, FTAG); + } + } } void @@ -822,7 +868,7 @@ dmu_tx_hold_space(dmu_tx_t *tx, uint64_t txh = dmu_tx_hold_object_impl(tx, tx->tx_objset, DMU_NEW_OBJECT, THT_SPACE, space, 0); - txh->txh_space_towrite += space; + (void) refcount_add_many(&txh->txh_space_towrite, space, FTAG); } int @@ -1175,12 +1221,12 @@ dmu_tx_try_assign(dmu_tx_t *tx, txg_how_ (void) refcount_add(&dn->dn_tx_holds, tx); mutex_exit(&dn->dn_mtx); } - towrite += txh->txh_space_towrite; - tofree += txh->txh_space_tofree; - tooverwrite += txh->txh_space_tooverwrite; - tounref += txh->txh_space_tounref; - tohold += txh->txh_memory_tohold; - fudge += txh->txh_fudge; + towrite += refcount_count(&txh->txh_space_towrite); + tofree += refcount_count(&txh->txh_space_tofree); + tooverwrite += refcount_count(&txh->txh_space_tooverwrite); + tounref += refcount_count(&txh->txh_space_tounref); + tohold += refcount_count(&txh->txh_memory_tohold); + fudge += refcount_count(&txh->txh_fudge); } /* @@ -1383,24 +1429,59 @@ dmu_tx_willuse_space(dmu_tx_t *tx, int64 #endif } -void -dmu_tx_commit(dmu_tx_t *tx) +static void +dmu_tx_destroy(dmu_tx_t *tx) { dmu_tx_hold_t *txh; + while ((txh = list_head(&tx->tx_holds)) != NULL) { + dnode_t *dn = txh->txh_dnode; + + list_remove(&tx->tx_holds, txh); + refcount_destroy_many(&txh->txh_space_towrite, + refcount_count(&txh->txh_space_towrite)); + refcount_destroy_many(&txh->txh_space_tofree, + refcount_count(&txh->txh_space_tofree)); + refcount_destroy_many(&txh->txh_space_tooverwrite, + refcount_count(&txh->txh_space_tooverwrite)); + refcount_destroy_many(&txh->txh_space_tounref, + refcount_count(&txh->txh_space_tounref)); + refcount_destroy_many(&txh->txh_memory_tohold, + refcount_count(&txh->txh_memory_tohold)); + refcount_destroy_many(&txh->txh_fudge, + refcount_count(&txh->txh_fudge)); + kmem_free(txh, sizeof (dmu_tx_hold_t)); + if (dn != NULL) + dnode_rele(dn, tx); + } + + list_destroy(&tx->tx_callbacks); + list_destroy(&tx->tx_holds); +#ifdef ZFS_DEBUG + refcount_destroy_many(&tx->tx_space_written, + refcount_count(&tx->tx_space_written)); + refcount_destroy_many(&tx->tx_space_freed, + refcount_count(&tx->tx_space_freed)); +#endif + kmem_free(tx, sizeof (dmu_tx_t)); +} + +void +dmu_tx_commit(dmu_tx_t *tx) +{ ASSERT(tx->tx_txg != 0); /* * Go through the transaction's hold list and remove holds on * associated dnodes, notifying waiters if no holds remain. */ - while (txh = list_head(&tx->tx_holds)) { + for (dmu_tx_hold_t *txh = list_head(&tx->tx_holds); txh != NULL; + txh = list_next(&tx->tx_holds, txh)) { dnode_t *dn = txh->txh_dnode; - list_remove(&tx->tx_holds, txh); - kmem_free(txh, sizeof (dmu_tx_hold_t)); if (dn == NULL) continue; + mutex_enter(&dn->dn_mtx); ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg); @@ -1409,7 +1490,6 @@ dmu_tx_commit(dmu_tx_t *tx) cv_broadcast(&dn->dn_notxholds); } mutex_exit(&dn->dn_mtx); - dnode_rele(dn, tx); } if (tx->tx_tempreserve_cookie) @@ -1421,51 +1501,26 @@ dmu_tx_commit(dmu_tx_t *tx) if (tx->tx_anyobj == FALSE) txg_rele_to_sync(&tx->tx_txgh); - list_destroy(&tx->tx_callbacks); - list_destroy(&tx->tx_holds); #ifdef ZFS_DEBUG dprintf("towrite=%llu written=%llu tofree=%llu freed=%llu\n", tx->tx_space_towrite, refcount_count(&tx->tx_space_written), tx->tx_space_tofree, refcount_count(&tx->tx_space_freed)); - refcount_destroy_many(&tx->tx_space_written, - refcount_count(&tx->tx_space_written)); - refcount_destroy_many(&tx->tx_space_freed, - refcount_count(&tx->tx_space_freed)); #endif - kmem_free(tx, sizeof (dmu_tx_t)); + dmu_tx_destroy(tx); } void dmu_tx_abort(dmu_tx_t *tx) { - dmu_tx_hold_t *txh; - ASSERT(tx->tx_txg == 0); - while (txh = list_head(&tx->tx_holds)) { - dnode_t *dn = txh->txh_dnode; - - list_remove(&tx->tx_holds, txh); - kmem_free(txh, sizeof (dmu_tx_hold_t)); - if (dn != NULL) - dnode_rele(dn, tx); - } - /* * Call any registered callbacks with an error code. */ if (!list_is_empty(&tx->tx_callbacks)) dmu_tx_do_callbacks(&tx->tx_callbacks, ECANCELED); - list_destroy(&tx->tx_callbacks); - list_destroy(&tx->tx_holds); -#ifdef ZFS_DEBUG - refcount_destroy_many(&tx->tx_space_written, - refcount_count(&tx->tx_space_written)); - refcount_destroy_many(&tx->tx_space_freed, - refcount_count(&tx->tx_space_freed)); -#endif - kmem_free(tx, sizeof (dmu_tx_t)); + dmu_tx_destroy(tx); } uint64_t @@ -1504,7 +1559,7 @@ dmu_tx_do_callbacks(list_t *cb_list, int { dmu_tx_callback_t *dcb; - while (dcb = list_head(cb_list)) { + while ((dcb = list_head(cb_list)) != NULL) { list_remove(cb_list, dcb); dcb->dcb_func(dcb->dcb_data, error); kmem_free(dcb, sizeof (dmu_tx_callback_t)); @@ -1562,18 +1617,24 @@ dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t /* If blkptr doesn't exist then add space to towrite */ if (!(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR)) { - txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE; + (void) refcount_add_many(&txh->txh_space_towrite, + SPA_OLD_MAXBLOCKSIZE, FTAG); } else { blkptr_t *bp; bp = &dn->dn_phys->dn_spill; if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset, - bp, bp->blk_birth)) - txh->txh_space_tooverwrite += SPA_OLD_MAXBLOCKSIZE; - else - txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE; - if (!BP_IS_HOLE(bp)) - txh->txh_space_tounref += SPA_OLD_MAXBLOCKSIZE; + bp, bp->blk_birth)) { + (void) refcount_add_many(&txh->txh_space_tooverwrite, + SPA_OLD_MAXBLOCKSIZE, FTAG); + } else { + (void) refcount_add_many(&txh->txh_space_towrite, + SPA_OLD_MAXBLOCKSIZE, FTAG); + } + if (!BP_IS_HOLE(bp)) { + (void) refcount_add_many(&txh->txh_space_tounref, + SPA_OLD_MAXBLOCKSIZE, FTAG); + } } } Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h Tue Oct 11 16:52:57 2016 (r307057) @@ -23,7 +23,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_DMU_TX_H @@ -101,12 +101,12 @@ typedef struct dmu_tx_hold { dmu_tx_t *txh_tx; list_node_t txh_node; struct dnode *txh_dnode; - uint64_t txh_space_towrite; - uint64_t txh_space_tofree; - uint64_t txh_space_tooverwrite; - uint64_t txh_space_tounref; - uint64_t txh_memory_tohold; - uint64_t txh_fudge; + refcount_t txh_space_towrite; + refcount_t txh_space_tofree; + refcount_t txh_space_tooverwrite; + refcount_t txh_space_tounref; + refcount_t txh_memory_tohold; + refcount_t txh_fudge; #ifdef ZFS_DEBUG enum dmu_tx_hold_type txh_type; uint64_t txh_arg1; Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Tue Oct 11 16:52:57 2016 (r307057) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_ZAP_H @@ -80,6 +80,7 @@ */ #include +#include #ifdef __cplusplus extern "C" { @@ -217,7 +218,7 @@ int zap_prefetch_uint64(objset_t *os, ui int key_numints); int zap_count_write(objset_t *os, uint64_t zapobj, const char *name, - int add, uint64_t *towrite, uint64_t *tooverwrite); + int add, refcount_t *towrite, refcount_t *tooverwrite); /* * Create an attribute with the given name and value. Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h Tue Oct 11 16:52:57 2016 (r307057) @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -213,8 +214,8 @@ int fzap_lookup(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, void *buf, char *realname, int rn_len, boolean_t *normalization_conflictp); void fzap_prefetch(zap_name_t *zn); -int fzap_count_write(zap_name_t *zn, int add, uint64_t *towrite, - uint64_t *tooverwrite); +int fzap_count_write(zap_name_t *zn, int add, refcount_t *towrite, + refcount_t *tooverwrite); int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); int fzap_update(zap_name_t *zn, Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Tue Oct 11 16:52:57 2016 (r307057) @@ -1335,8 +1335,8 @@ fzap_get_stats(zap_t *zap, zap_stats_t * } int -fzap_count_write(zap_name_t *zn, int add, uint64_t *towrite, - uint64_t *tooverwrite) +fzap_count_write(zap_name_t *zn, int add, refcount_t *towrite, + refcount_t *tooverwrite) { zap_t *zap = zn->zn_zap; zap_leaf_t *l; @@ -1346,9 +1346,11 @@ fzap_count_write(zap_name_t *zn, int add * Account for the header block of the fatzap. */ if (!add && dmu_buf_freeable(zap->zap_dbuf)) { - *tooverwrite += zap->zap_dbuf->db_size; + (void) refcount_add_many(tooverwrite, + zap->zap_dbuf->db_size, FTAG); } else { - *towrite += zap->zap_dbuf->db_size; + (void) refcount_add_many(towrite, + zap->zap_dbuf->db_size, FTAG); } /* @@ -1360,10 +1362,13 @@ fzap_count_write(zap_name_t *zn, int add * could extend the table. */ if (add) { - if (zap_f_phys(zap)->zap_ptrtbl.zt_blk == 0) - *towrite += zap->zap_dbuf->db_size; - else - *towrite += (zap->zap_dbuf->db_size * 3); + if (zap_f_phys(zap)->zap_ptrtbl.zt_blk == 0) { + (void) refcount_add_many(towrite, + zap->zap_dbuf->db_size, FTAG); + } else { + (void) refcount_add_many(towrite, + zap->zap_dbuf->db_size * 3, FTAG); + } } /* @@ -1376,13 +1381,14 @@ fzap_count_write(zap_name_t *zn, int add } if (!add && dmu_buf_freeable(l->l_dbuf)) { - *tooverwrite += l->l_dbuf->db_size; + (void) refcount_add_many(tooverwrite, l->l_dbuf->db_size, FTAG); } else { /* * If this an add operation, the leaf block could split. * Hence, we need to account for an additional leaf block. */ - *towrite += (add ? 2 : 1) * l->l_dbuf->db_size; + (void) refcount_add_many(towrite, + (add ? 2 : 1) * l->l_dbuf->db_size, FTAG); } zap_put_leaf(l); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Tue Oct 11 16:50:45 2016 (r307056) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Tue Oct 11 16:52:57 2016 (r307057) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -1396,7 +1396,7 @@ zap_get_stats(objset_t *os, uint64_t zap int zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, - uint64_t *towrite, uint64_t *tooverwrite) + refcount_t *towrite, refcount_t *tooverwrite) { zap_t *zap; int err = 0; @@ -1406,14 +1406,15 @@ zap_count_write(objset_t *os, uint64_t z * be affected in this operation. So, account for the worst case : * - 3 blocks overwritten: target leaf, ptrtbl block, header block * - 4 new blocks written if adding: - * - 2 blocks for possibly split leaves, - * - 2 grown ptrtbl blocks + * - 2 blocks for possibly split leaves, + * - 2 grown ptrtbl blocks * * This also accomodates the case where an add operation to a fairly * large microzap results in a promotion to fatzap. */ if (name == NULL) { - *towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE; + (void) refcount_add_many(towrite, + (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE, FTAG); return (err); } @@ -1437,7 +1438,8 @@ zap_count_write(objset_t *os, uint64_t z /* * We treat this case as similar to (name == NULL) */ - *towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE; + (void) refcount_add_many(towrite, + (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE, FTAG); } } else { /* @@ -1455,13 +1457,17 @@ zap_count_write(objset_t *os, uint64_t z * 4 new blocks written : 2 new split leaf, 2 grown * ptrtbl blocks */ - if (dmu_buf_freeable(zap->zap_dbuf)) - *tooverwrite += MZAP_MAX_BLKSZ; - else - *towrite += MZAP_MAX_BLKSZ; + if (dmu_buf_freeable(zap->zap_dbuf)) { + (void) refcount_add_many(tooverwrite, + MZAP_MAX_BLKSZ, FTAG); + } else { + (void) refcount_add_many(towrite, + MZAP_MAX_BLKSZ, FTAG); + } if (add) { - *towrite += 4 * MZAP_MAX_BLKSZ; + (void) refcount_add_many(towrite, + 4 * MZAP_MAX_BLKSZ, FTAG); } } From owner-svn-src-stable-10@freebsd.org Tue Oct 11 16:53:52 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 17BE3C0CCB9; Tue, 11 Oct 2016 16:53:52 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D97201D0; Tue, 11 Oct 2016 16:53:51 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BGrod6026274; Tue, 11 Oct 2016 16:53:50 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BGro3O026266; Tue, 11 Oct 2016 16:53:50 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610111653.u9BGro3O026266@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 11 Oct 2016 16:53:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307058 - in stable/10: cddl/contrib/opensolaris/lib/libzfs/common sys/cddl/contrib/opensolaris/common/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 16:53:52 -0000 Author: mav Date: Tue Oct 11 16:53:50 2016 New Revision: 307058 URL: https://svnweb.freebsd.org/changeset/base/307058 Log: MFC r305207: MFV r302659: 6931 lib/libzfs: cleanup gcc warnings illumos/illumos-gate@88f61dee20b358671b1b643e9d1dbf220a1d69be https://github.com/illumos/illumos-gate/commit/88f61dee20b358671b1b643e9d1dbf220a1d69be https://www.illumos.org/issues/6931 need cleanup: CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-unused-function Reviewed by: Matthew Ahrens Approved by: Robert Mustacchi Author: Igor Kozhukhov Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c Tue Oct 11 16:53:50 2016 (r307058) @@ -24,9 +24,9 @@ * Use is subject to license terms. * * Portions Copyright 2007 Ramprakash Jelari - * * Copyright (c) 2011 Pawel Jakub Dawidek . * All rights reserved. + * Copyright 2016 Igor Kozhukhov */ #include @@ -136,6 +136,9 @@ changelist_prefix(prop_changelist_t *clp case ZFS_PROP_SHARESMB: (void) zfs_unshare_smb(cn->cn_handle, NULL); break; + + default: + break; } } } Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Tue Oct 11 16:53:50 2016 (r307058) @@ -29,6 +29,7 @@ * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Igor Kozhukhov */ #include @@ -78,55 +79,18 @@ zfs_type_to_name(zfs_type_t type) return (dgettext(TEXT_DOMAIN, "snapshot")); case ZFS_TYPE_VOLUME: return (dgettext(TEXT_DOMAIN, "volume")); + case ZFS_TYPE_POOL: + return (dgettext(TEXT_DOMAIN, "pool")); + case ZFS_TYPE_BOOKMARK: + return (dgettext(TEXT_DOMAIN, "bookmark")); + default: + assert(!"unhandled zfs_type_t"); } return (NULL); } /* - * Given a path and mask of ZFS types, return a string describing this dataset. - * This is used when we fail to open a dataset and we cannot get an exact type. - * We guess what the type would have been based on the path and the mask of - * acceptable types. - */ -static const char * -path_to_str(const char *path, int types) -{ - /* - * When given a single type, always report the exact type. - */ - if (types == ZFS_TYPE_SNAPSHOT) - return (dgettext(TEXT_DOMAIN, "snapshot")); - if (types == ZFS_TYPE_FILESYSTEM) - return (dgettext(TEXT_DOMAIN, "filesystem")); - if (types == ZFS_TYPE_VOLUME) - return (dgettext(TEXT_DOMAIN, "volume")); - - /* - * The user is requesting more than one type of dataset. If this is the - * case, consult the path itself. If we're looking for a snapshot, and - * a '@' is found, then report it as "snapshot". Otherwise, remove the - * snapshot attribute and try again. - */ - if (types & ZFS_TYPE_SNAPSHOT) { - if (strchr(path, '@') != NULL) - return (dgettext(TEXT_DOMAIN, "snapshot")); - return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT)); - } - - /* - * The user has requested either filesystems or volumes. - * We have no way of knowing a priori what type this would be, so always - * report it as "filesystem" or "volume", our two primitive types. - */ - if (types & ZFS_TYPE_FILESYSTEM) - return (dgettext(TEXT_DOMAIN, "filesystem")); - - assert(types & ZFS_TYPE_VOLUME); - return (dgettext(TEXT_DOMAIN, "volume")); -} - -/* * Validate a ZFS path. This is used even before trying to open the dataset, to * provide a more meaningful error message. We call zfs_error_aux() to * explain exactly why the name was not valid. @@ -187,6 +151,11 @@ zfs_validate_name(libzfs_handle_t *hdl, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "reserved disk name")); break; + + default: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "(%d) not defined"), why); + break; } } @@ -769,7 +738,8 @@ libzfs_mnttab_fini(libzfs_handle_t *hdl) void *cookie = NULL; mnttab_node_t *mtn; - while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) { + while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) + != NULL) { free(mtn->mtn_mt.mnt_special); free(mtn->mtn_mt.mnt_mountp); free(mtn->mtn_mt.mnt_fstype); @@ -841,7 +811,8 @@ libzfs_mnttab_remove(libzfs_handle_t *hd mnttab_node_t *ret; find.mtn_mt.mnt_special = (char *)fsname; - if (ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) { + if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) + != NULL) { avl_remove(&hdl->libzfs_mnttab_cache, ret); free(ret->mtn_mt.mnt_special); free(ret->mtn_mt.mnt_mountp); @@ -1193,6 +1164,13 @@ badlabel: "component of '%s' is too long"), propname); break; + + default: + zfs_error_aux(hdl, + dgettext(TEXT_DOMAIN, + "(%d) not defined"), + why); + break; } (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; @@ -1311,12 +1289,17 @@ badlabel: } break; + case ZFS_PROP_UTF8ONLY: chosen_utf = (int)intval; break; + case ZFS_PROP_NORMALIZE: chosen_normal = (int)intval; break; + + default: + break; } /* @@ -1365,6 +1348,9 @@ badlabel: goto error; } break; + + default: + break; } } } @@ -1968,6 +1954,9 @@ get_numeric_property(zfs_handle_t *zhp, mntopt_on = MNTOPT_NBMAND; mntopt_off = MNTOPT_NONBMAND; break; + + default: + break; } /* @@ -3145,7 +3134,7 @@ create_parents(libzfs_handle_t *hdl, cha * up to the prefixlen-long one. */ for (cp = target + prefixlen + 1; - cp = strchr(cp, '/'); *cp = '/', cp++) { + (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) { *cp = '\0'; @@ -3908,7 +3897,7 @@ int zfs_rename(zfs_handle_t *zhp, const char *source, const char *target, renameflags_t flags) { - int ret; + int ret = 0; zfs_cmd_t zc = { 0 }; char *delim; prop_changelist_t *cl = NULL; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c Tue Oct 11 16:53:50 2016 (r307058) @@ -23,6 +23,7 @@ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2016 Joyent, Inc. + * Copyright 2016 Igor Kozhukhov */ /* @@ -353,7 +354,7 @@ write_inuse_diffs(FILE *fp, differ_info_ int err; for (o = dr->ddr_first; o <= dr->ddr_last; o++) { - if (err = write_inuse_diffs_one(fp, di, o)) + if ((err = write_inuse_diffs_one(fp, di, o)) != 0) return (err); } return (0); Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c Tue Oct 11 16:53:50 2016 (r307058) @@ -22,6 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014 by Delphix. All rights reserved. + * Copyright 2016 Igor Kozhukhov */ /* @@ -475,7 +476,8 @@ zfs_is_shared_proto(zfs_handle_t *zhp, c if (!zfs_is_mounted(zhp, &mountpoint)) return (SHARED_NOT_SHARED); - if (rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) { + if ((rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) + != SHARED_NOT_SHARED) { if (where != NULL) *where = mountpoint; else Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Tue Oct 11 16:53:50 2016 (r307058) @@ -24,6 +24,7 @@ * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. + * Copyright 2016 Igor Kozhukhov */ #include @@ -199,6 +200,9 @@ zpool_state_to_name(vdev_state_t state, return (gettext("DEGRADED")); case VDEV_STATE_HEALTHY: return (gettext("ONLINE")); + + default: + break; } return (gettext("UNKNOWN")); @@ -635,6 +639,11 @@ zpool_valid_proplist(libzfs_handle_t *hd goto error; } break; + + default: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "property '%s'(%d) not defined"), propname, prop); + break; } } @@ -943,6 +952,10 @@ zpool_name_valid(libzfs_handle_t *hdl, b "multiple '@' delimiters in name")); break; + default: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "(%d) not defined"), why); + break; } } return (B_FALSE); Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Tue Oct 11 16:53:50 2016 (r307058) @@ -27,6 +27,7 @@ * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Igor Kozhukhov */ #include @@ -1182,8 +1183,8 @@ dump_snapshot(zfs_handle_t *zhp, void *a pa.pa_fd = sdd->outfd; pa.pa_parsable = sdd->parsable; - if (err = pthread_create(&tid, NULL, - send_progress_thread, &pa)) { + if ((err = pthread_create(&tid, NULL, + send_progress_thread, &pa)) != 0) { zfs_close(zhp); return (err); } @@ -1661,7 +1662,7 @@ zfs_send(zfs_handle_t *zhp, const char * if (flags->dedup && !flags->dryrun) { featureflags |= (DMU_BACKUP_FEATURE_DEDUP | DMU_BACKUP_FEATURE_DEDUPPROPS); - if (err = pipe(pipefd)) { + if ((err = pipe(pipefd)) != 0) { zfs_error_aux(zhp->zfs_hdl, strerror(errno)); return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf)); @@ -1669,7 +1670,7 @@ zfs_send(zfs_handle_t *zhp, const char * dda.outputfd = outfd; dda.inputfd = pipefd[1]; dda.dedup_hdl = zhp->zfs_hdl; - if (err = pthread_create(&tid, NULL, cksummer, &dda)) { + if ((err = pthread_create(&tid, NULL, cksummer, &dda)) != 0) { (void) close(pipefd[0]); (void) close(pipefd[1]); zfs_error_aux(zhp->zfs_hdl, strerror(errno)); Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c Tue Oct 11 16:53:50 2016 (r307058) @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright 2016 Igor Kozhukhov */ /* @@ -1062,6 +1063,10 @@ zprop_print_one_property(const char *nam case ZPROP_SRC_RECEIVED: str = "received"; break; + + default: + str = NULL; + assert(!"unhandled zprop_source_t"); } break; Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c Tue Oct 11 16:52:57 2016 (r307057) +++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c Tue Oct 11 16:53:50 2016 (r307058) @@ -22,6 +22,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright 2016 Igor Kozhukhov */ #include @@ -177,8 +178,9 @@ zfs_deleg_verify_nvlist(nvlist_t *nvp) nvpair_name(perm_name)); if (error) return (-1); - } while (perm_name = nvlist_next_nvpair(perms, perm_name)); - } while (who = nvlist_next_nvpair(nvp, who)); + } while ((perm_name = nvlist_next_nvpair(perms, perm_name)) + != NULL); + } while ((who = nvlist_next_nvpair(nvp, who)) != NULL); return (0); } From owner-svn-src-stable-10@freebsd.org Tue Oct 11 18:51:05 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6F081C0D1C3; Tue, 11 Oct 2016 18:51:05 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3052C18C; Tue, 11 Oct 2016 18:51:05 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9BIp45M069487; Tue, 11 Oct 2016 18:51:04 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9BIp4Rb069029; Tue, 11 Oct 2016 18:51:04 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201610111851.u9BIp4Rb069029@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Tue, 11 Oct 2016 18:51:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307065 - in stable/10: sys/kern tests/sys/kern X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Oct 2016 18:51:05 -0000 Author: jilles Date: Tue Oct 11 18:51:03 2016 New Revision: 307065 URL: https://svnweb.freebsd.org/changeset/base/307065 Log: wait: Do not copyout uninitialized status/rusage/wrusage. If wait4() or wait6() return 0 because of WNOHANG, the status, rusage and wrusage information should not be returned. PR: 212048 Reported by: Casey Lucas Added: stable/10/tests/sys/kern/waitpid_nohang.c - copied unchanged from r305676, head/tests/sys/kern/waitpid_nohang.c Modified: stable/10/sys/kern/kern_exit.c stable/10/tests/sys/kern/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/kern_exit.c ============================================================================== --- stable/10/sys/kern/kern_exit.c Tue Oct 11 18:09:37 2016 (r307064) +++ stable/10/sys/kern/kern_exit.c Tue Oct 11 18:51:03 2016 (r307065) @@ -785,9 +785,9 @@ sys_wait4(struct thread *td, struct wait else rup = NULL; error = kern_wait(td, uap->pid, &status, uap->options, rup); - if (uap->status != NULL && error == 0) + if (uap->status != NULL && error == 0 && td->td_retval[0] != 0) error = copyout(&status, uap->status, sizeof(status)); - if (uap->rusage != NULL && error == 0) + if (uap->rusage != NULL && error == 0 && td->td_retval[0] != 0) error = copyout(&ru, uap->rusage, sizeof(struct rusage)); return (error); } @@ -821,9 +821,9 @@ sys_wait6(struct thread *td, struct wait */ error = kern_wait6(td, idtype, id, &status, uap->options, wrup, sip); - if (uap->status != NULL && error == 0) + if (uap->status != NULL && error == 0 && td->td_retval[0] != 0) error = copyout(&status, uap->status, sizeof(status)); - if (uap->wrusage != NULL && error == 0) + if (uap->wrusage != NULL && error == 0 && td->td_retval[0] != 0) error = copyout(&wru, uap->wrusage, sizeof(wru)); if (uap->info != NULL && error == 0) error = copyout(&si, uap->info, sizeof(si)); Modified: stable/10/tests/sys/kern/Makefile ============================================================================== --- stable/10/tests/sys/kern/Makefile Tue Oct 11 18:09:37 2016 (r307064) +++ stable/10/tests/sys/kern/Makefile Tue Oct 11 18:51:03 2016 (r307065) @@ -11,6 +11,7 @@ ATF_TESTS_C+= ptrace_test ATF_TESTS_C+= unix_seqpacket_test ATF_TESTS_C+= unix_passfd_test TEST_METADATA.unix_seqpacket_test+= timeout="15" +ATF_TESTS_C+= waitpid_nohang LDADD.ptrace_test+= -lpthread LDADD.unix_seqpacket_test+= -lpthread Copied: stable/10/tests/sys/kern/waitpid_nohang.c (from r305676, head/tests/sys/kern/waitpid_nohang.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/tests/sys/kern/waitpid_nohang.c Tue Oct 11 18:51:03 2016 (r307065, copy of r305676, head/tests/sys/kern/waitpid_nohang.c) @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2016 Jilles Tjoelker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include + +ATF_TC_WITHOUT_HEAD(waitpid_nohang); +ATF_TC_BODY(waitpid_nohang, tc) +{ + pid_t child, pid; + int status, r; + + child = fork(); + ATF_REQUIRE(child != -1); + if (child == 0) { + sleep(10); + _exit(1); + } + + status = 42; + pid = waitpid(child, &status, WNOHANG); + ATF_REQUIRE(pid == 0); + ATF_CHECK(status == 42); + + r = kill(child, SIGTERM); + ATF_REQUIRE(r == 0); + r = waitid(P_PID, child, NULL, WEXITED | WNOWAIT); + ATF_REQUIRE(r == 0); + + status = -1; + pid = waitpid(child, &status, WNOHANG); + ATF_REQUIRE(pid == child); + ATF_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, waitpid_nohang); + return (atf_no_error()); +} From owner-svn-src-stable-10@freebsd.org Wed Oct 12 02:03:07 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 72B4FC0D15D; Wed, 12 Oct 2016 02:03:07 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3C27CECB; Wed, 12 Oct 2016 02:03:07 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C236so037774; Wed, 12 Oct 2016 02:03:06 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C2356x037760; Wed, 12 Oct 2016 02:03:05 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120203.u9C2356x037760@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 02:03:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307079 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 02:03:07 -0000 Author: sephe Date: Wed Oct 12 02:03:05 2016 New Revision: 307079 URL: https://svnweb.freebsd.org/changeset/base/307079 Log: MFC 302882-302884 302882 hyperv/vmbus: Function rename And reorder the error prone parameters list. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7191 302883 hyperv/vmbus: Field rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7193 302884 hyperv/vmbus: Factor out macros to do channel packet length conversion. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7194 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:03:05 2016 (r307079) @@ -323,14 +323,6 @@ int hv_vmbus_channel_open( void hv_vmbus_channel_close(hv_vmbus_channel *channel); -int hv_vmbus_channel_send_packet( - hv_vmbus_channel* channel, - void* buffer, - uint32_t buffer_len, - uint64_t request_id, - uint16_t type, - uint16_t flags); - int hv_vmbus_channel_establish_gpadl( hv_vmbus_channel* channel, /* must be phys and virt contiguous */ Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:03:05 2016 (r307079) @@ -59,6 +59,8 @@ struct vmbus_gpa { struct hv_vmbus_channel; +int vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type, + uint16_t flags, void *data, int dlen, uint64_t xactid); int vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:03:05 2016 (r307079) @@ -182,9 +182,9 @@ hv_nv_init_rx_buffer_with_net_vsp(struct /* Send the gpadl notification request */ - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); if (ret != 0) { goto cleanup; } @@ -275,9 +275,9 @@ hv_nv_init_send_buffer_with_net_vsp(stru /* Send the gpadl notification request */ - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt); if (ret != 0) { goto cleanup; } @@ -334,10 +334,9 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id = NETVSC_RECEIVE_BUFFER_ID; - ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, - revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)revoke_pkt, - VMBUS_CHANPKT_TYPE_INBAND, 0); + ret = vmbus_chan_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), + (uint64_t)(uintptr_t)revoke_pkt); /* * If we failed here, we might as well return and have a leak @@ -402,10 +401,10 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id = NETVSC_SEND_BUFFER_ID; - ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan, + ret = vmbus_chan_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)revoke_pkt, - VMBUS_CHANPKT_TYPE_INBAND, 0); + (uint64_t)(uintptr_t)revoke_pkt); /* * If we failed here, we might as well return and have a leak * rather than continue and a bugchk @@ -469,9 +468,9 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver; /* Send the init request */ - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); if (ret != 0) return (-1); @@ -512,9 +511,8 @@ hv_nv_send_ndis_config(struct hn_softc * = 1; /* Send the configuration packet */ - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, 0); + ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); if (ret != 0) return (-EINVAL); @@ -591,9 +589,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc /* Send the init request */ - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, 0); + ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); if (ret != 0) { goto cleanup; } @@ -815,9 +812,9 @@ hv_nv_on_send(struct hv_vmbus_channel *c ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt, &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); } else { - ret = hv_vmbus_channel_send_packet(chan, - &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); } return (ret); @@ -916,8 +913,8 @@ hv_nv_on_receive_completion(struct hv_vm retry_send_cmplt: /* Send the completion */ - ret = hv_vmbus_channel_send_packet(chan, &rx_comp_msg, - sizeof(nvsp_msg), tid, VMBUS_CHANPKT_TYPE_COMP, 0); + ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0, + &rx_comp_msg, sizeof(nvsp_msg), tid); if (ret == 0) { /* success */ /* no-op */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 02:03:05 2016 (r307079) @@ -1167,9 +1167,9 @@ hv_rf_on_device_add(struct hn_softc *sc, init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels = net_dev->num_channel - 1; - ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt, - sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); if (ret != 0) { device_printf(dev, "Fail to allocate subchannel\n"); goto out; Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:03:05 2016 (r307079) @@ -356,13 +356,9 @@ storvsc_send_multichannel_request(struct vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->u.multi_channels_cnt = request_channels_cnt; - ret = hv_vmbus_channel_send_packet( - sc->hs_chan, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hs_chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); /* wait for 5 seconds */ ret = sema_timedwait(&request->synch_sema, 5 * hz); @@ -427,13 +423,9 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet->flags = REQUEST_COMPLETION_FLAG; - ret = hv_vmbus_channel_send_packet( - sc->hs_chan, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hs_chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); if (ret != 0) goto cleanup; @@ -461,13 +453,9 @@ hv_storvsc_channel_init(struct storvsc_s /* revision is only significant for Windows guests */ vstor_packet->u.version.revision = 0; - ret = hv_vmbus_channel_send_packet( - sc->hs_chan, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hs_chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); if (ret != 0) goto cleanup; @@ -504,13 +492,9 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet->operation = VSTOR_OPERATION_QUERYPROPERTIES; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - ret = hv_vmbus_channel_send_packet( - sc->hs_chan, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hs_chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); if ( ret != 0) goto cleanup; @@ -540,13 +524,9 @@ hv_storvsc_channel_init(struct storvsc_s vstor_packet->operation = VSTOR_OPERATION_ENDINITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - ret = hv_vmbus_channel_send_packet( - sc->hs_chan, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(sc->hs_chan, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); if (ret != 0) { goto cleanup; @@ -631,12 +611,10 @@ hv_storvsc_host_reset(struct storvsc_sof vstor_packet->operation = VSTOR_OPERATION_RESETBUS; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - ret = hv_vmbus_channel_send_packet(dev->channel, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)&sc->hs_reset_req, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(dev->channel, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, + (uint64_t)(uintptr_t)&sc->hs_reset_req); if (ret != 0) { goto cleanup; @@ -695,13 +673,9 @@ hv_storvsc_io_request(struct storvsc_sof &request->prp_list.gpa_range, request->prp_cnt, vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); } else { - ret = hv_vmbus_channel_send_packet( - outgoing_channel, - vstor_packet, - VSTOR_PKT_SIZE, - (uint64_t)(uintptr_t)request, - VMBUS_CHANPKT_TYPE_INBAND, - VMBUS_CHANPKT_FLAG_RC); + ret = vmbus_chan_send(outgoing_channel, + VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, + vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); } mtx_lock(&request->softc->hs_lock); Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 02:03:05 2016 (r307079) @@ -87,8 +87,8 @@ hv_heartbeat_cb(void *context) icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_vmbus_channel_send_packet(channel, buf, recvlen, requestid, - VMBUS_CHANPKT_TYPE_INBAND, 0); + vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, + buf, recvlen, requestid); } } Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 02:03:05 2016 (r307079) @@ -575,11 +575,9 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int e hv_icmsg_hdrp->status = error; hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - error = hv_vmbus_channel_send_packet(sc->util_sc.channel, - sc->rcv_buf, - sc->host_msg_len, sc->host_msg_id, - VMBUS_CHANPKT_TYPE_INBAND, 0); - + error = vmbus_chan_send(sc->util_sc.channel, + VMBUS_CHANPKT_TYPE_INBAND, 0, sc->rcv_buf, sc->host_msg_len, + sc->host_msg_id); if (error) hv_kvp_log_info("%s: hv_kvp_respond_host: sendpacket error:%d\n", __func__, error); Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 02:03:05 2016 (r307079) @@ -105,9 +105,8 @@ hv_shutdown_cb(void *context) icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_vmbus_channel_send_packet(channel, buf, - recv_len, request_id, - VMBUS_CHANPKT_TYPE_INBAND, 0); + vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, + buf, recv_len, request_id); } if (execute_shutdown) Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 02:03:05 2016 (r307079) @@ -163,9 +163,8 @@ hv_timesync_cb(void *context) icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_vmbus_channel_send_packet(channel, time_buf, - recvlen, requestId, - VMBUS_CHANPKT_TYPE_INBAND, 0); + vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, + time_buf, recvlen, requestId); } } Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:03:05 2016 (r307079) @@ -622,8 +622,8 @@ hv_vmbus_channel_close(struct hv_vmbus_c } int -hv_vmbus_channel_send_packet(struct hv_vmbus_channel *chan, - void *data, uint32_t dlen, uint64_t xactid, uint16_t type, uint16_t flags) +vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type, uint16_t flags, + void *data, int dlen, uint64_t xactid) { struct vmbus_chanpkt pkt; int pktlen, pad_pktlen, hlen, error; @@ -633,12 +633,12 @@ hv_vmbus_channel_send_packet(struct hv_v hlen = sizeof(pkt); pktlen = hlen + dlen; - pad_pktlen = roundup2(pktlen, VMBUS_CHANPKT_SIZE_ALIGN); + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); pkt.cp_hdr.cph_type = type; pkt.cp_hdr.cph_flags = flags; - pkt.cp_hdr.cph_data_ofs = hlen >> VMBUS_CHANPKT_SIZE_SHIFT; - pkt.cp_hdr.cph_len = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); pkt.cp_hdr.cph_xactid = xactid; iov[0].iov_base = &pkt; @@ -669,12 +669,12 @@ vmbus_chan_send_sglist(struct hv_vmbus_c hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]); pktlen = hlen + dlen; - pad_pktlen = roundup2(pktlen, VMBUS_CHANPKT_SIZE_ALIGN); + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; - pkt.cp_hdr.cph_data_ofs = hlen >> VMBUS_CHANPKT_SIZE_SHIFT; - pkt.cp_hdr.cph_len = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); pkt.cp_hdr.cph_xactid = xactid; pkt.cp_rsvd = 0; pkt.cp_gpa_cnt = sglen; @@ -711,12 +711,12 @@ vmbus_chan_send_prplist(struct hv_vmbus_ hlen = __offsetof(struct vmbus_chanpkt_prplist, cp_range[0].gpa_page[prp_cnt]); pktlen = hlen + dlen; - pad_pktlen = roundup2(pktlen, VMBUS_CHANPKT_SIZE_ALIGN); + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; - pkt.cp_hdr.cph_data_ofs = hlen >> VMBUS_CHANPKT_SIZE_SHIFT; - pkt.cp_hdr.cph_len = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); pkt.cp_hdr.cph_xactid = xactid; pkt.cp_rsvd = 0; pkt.cp_range_cnt = 1; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 01:52:29 2016 (r307078) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 02:03:05 2016 (r307079) @@ -115,10 +115,18 @@ CTASSERT(sizeof(struct vmbus_mnf) == PAG #define VMBUS_CHANPKT_SIZE_SHIFT 3 #define VMBUS_CHANPKT_SIZE_ALIGN (1 << VMBUS_CHANPKT_SIZE_SHIFT) +#define VMBUS_CHANPKT_SETLEN(pktlen, len) \ +do { \ + (pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT; \ +} while (0) + +#define VMBUS_CHANPKT_TOTLEN(tlen) \ + roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN) + struct vmbus_chanpkt_hdr { uint16_t cph_type; - uint16_t cph_data_ofs; /* in 8 bytes */ - uint16_t cph_len; /* in 8 bytes */ + uint16_t cph_hlen; /* header len, in 8 bytes */ + uint16_t cph_tlen; /* total len, in 8 bytes */ uint16_t cph_flags; uint64_t cph_xactid; } __packed; From owner-svn-src-stable-10@freebsd.org Wed Oct 12 02:09:55 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A3B5AC0D4C3; Wed, 12 Oct 2016 02:09:55 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 679321387; Wed, 12 Oct 2016 02:09:55 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C29sWk038148; Wed, 12 Oct 2016 02:09:54 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C29rgs038138; Wed, 12 Oct 2016 02:09:53 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120209.u9C29rgs038138@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 02:09:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307080 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 02:09:55 -0000 Author: sephe Date: Wed Oct 12 02:09:53 2016 New Revision: 307080 URL: https://svnweb.freebsd.org/changeset/base/307080 Log: MFC 302885,302886 302885 hyperv/vmbus: Cleanup channel receiving. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7202 302886 hyperv/vmbus: Cleanup channel packet receiving. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7204 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:09:53 2016 (r307080) @@ -90,28 +90,6 @@ struct hyperv_guid { int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); -typedef struct { - uint16_t type; - uint16_t data_offset8; - uint16_t length8; - uint16_t flags; - uint64_t transaction_id; -} __packed hv_vm_packet_descriptor; - -typedef struct { - uint32_t byte_count; - uint32_t byte_offset; -} __packed hv_vm_transfer_page; - -typedef struct { - hv_vm_packet_descriptor d; - uint16_t transfer_page_set_id; - hv_bool_uint8_t sender_owns_set; - uint8_t reserved; - uint32_t range_count; - hv_vm_transfer_page ranges[1]; -} __packed hv_vm_transfer_page_packet_header; - #define HW_MACADDR_LEN 6 /* @@ -298,20 +276,6 @@ hv_set_channel_read_state(hv_vmbus_chann channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; } -int hv_vmbus_channel_recv_packet( - hv_vmbus_channel* channel, - void* buffer, - uint32_t buffer_len, - uint32_t* buffer_actual_len, - uint64_t* request_id); - -int hv_vmbus_channel_recv_packet_raw( - hv_vmbus_channel* channel, - void* buffer, - uint32_t buffer_len, - uint32_t* buffer_actual_len, - uint64_t* request_id); - int hv_vmbus_channel_open( hv_vmbus_channel* channel, uint32_t send_ring_buffer_size, Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:09:53 2016 (r307080) @@ -47,6 +47,19 @@ struct vmbus_gpa { uint64_t gpa_page; } __packed; +#define VMBUS_CHANPKT_SIZE_SHIFT 3 + +#define VMBUS_CHANPKT_GETLEN(pktlen) \ + (((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT) + +struct vmbus_chanpkt_hdr { + uint16_t cph_type; /* VMBUS_CHANPKT_TYPE_ */ + uint16_t cph_hlen; /* header len, in 8 bytes */ + uint16_t cph_tlen; /* total len, in 8 bytes */ + uint16_t cph_flags; /* VMBUS_CHANPKT_FLAG_ */ + uint64_t cph_xactid; +} __packed; + #define VMBUS_CHANPKT_TYPE_INBAND 0x0006 #define VMBUS_CHANPKT_TYPE_RXBUF 0x0007 #define VMBUS_CHANPKT_TYPE_GPA 0x0009 @@ -54,11 +67,33 @@ struct vmbus_gpa { #define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */ +#define VMBUS_CHANPKT_CONST_DATA(pkt) \ + (const void *)((const uint8_t *)(pkt) + \ + VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen)) + +struct vmbus_rxbuf_desc { + uint32_t rb_len; + uint32_t rb_ofs; +} __packed; + +struct vmbus_chanpkt_rxbuf { + struct vmbus_chanpkt_hdr cp_hdr; + uint16_t cp_rxbuf_id; + uint16_t cp_rsvd; + uint32_t cp_rxbuf_cnt; + struct vmbus_rxbuf_desc cp_rxbuf[]; +} __packed; + #define VMBUS_CHAN_SGLIST_MAX 32 #define VMBUS_CHAN_PRPLIST_MAX 32 struct hv_vmbus_channel; +int vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen, + uint64_t *xactid); +int vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan, + struct vmbus_chanpkt_hdr *pkt, int *pktlen); + int vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type, uint16_t flags, void *data, int dlen, uint64_t xactid); int vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:09:53 2016 (r307080) @@ -63,12 +63,12 @@ static int hv_nv_destroy_send_buffer(ne static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); static int hv_nv_connect_to_vsp(struct hn_softc *sc); static void hv_nv_on_send_completion(netvsc_dev *net_dev, - struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt); + struct hv_vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, uint64_t tid, uint32_t status); static void hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc, struct hv_vmbus_channel *chan, - hv_vm_packet_descriptor *pkt); + const struct vmbus_chanpkt_hdr *pkt); /* * @@ -725,13 +725,12 @@ hv_nv_on_device_remove(struct hn_softc * */ static void hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan, - hv_vm_packet_descriptor *pkt) + const struct vmbus_chanpkt_hdr *pkt) { - nvsp_msg *nvsp_msg_pkt; + const nvsp_msg *nvsp_msg_pkt; netvsc_packet *net_vsc_pkt; - nvsp_msg_pkt = - (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3)); + nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt); if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete || nvsp_msg_pkt->hdr.msg_type @@ -748,7 +747,7 @@ hv_nv_on_send_completion(netvsc_dev *net nvsp_msg_1_type_send_rndis_pkt_complete) { /* Get the send context */ net_vsc_pkt = - (netvsc_packet *)(unsigned long)pkt->transaction_id; + (netvsc_packet *)(unsigned long)pkt->cph_xactid; if (NULL != net_vsc_pkt) { if (net_vsc_pkt->send_buf_section_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) { @@ -828,10 +827,10 @@ hv_nv_on_send(struct hv_vmbus_channel *c */ static void hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc, - struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt) + struct hv_vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) { - hv_vm_transfer_page_packet_header *vm_xfer_page_pkt; - nvsp_msg *nvsp_msg_pkt; + const struct vmbus_chanpkt_rxbuf *pkt; + const nvsp_msg *nvsp_msg_pkt; netvsc_packet vsc_pkt; netvsc_packet *net_vsc_pkt = &vsc_pkt; device_t dev = sc->hn_dev; @@ -839,43 +838,31 @@ hv_nv_on_receive(netvsc_dev *net_dev, st int i = 0; int status = nvsp_status_success; - /* - * All inbound packets other than send completion should be - * xfer page packet. - */ - if (pkt->type != VMBUS_CHANPKT_TYPE_RXBUF) { - device_printf(dev, "packet type %d is invalid!\n", pkt->type); - return; - } - - nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt - + (pkt->data_offset8 << 3)); + nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr); /* Make sure this is a valid nvsp packet */ if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) { - device_printf(dev, "packet hdr type %d is invalid!\n", - pkt->type); + device_printf(dev, "packet hdr type %u is invalid!\n", + nvsp_msg_pkt->hdr.msg_type); return; } - vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt; + pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; - if (vm_xfer_page_pkt->transfer_page_set_id != - NETVSC_RECEIVE_BUFFER_ID) { - device_printf(dev, "transfer_page_set_id %d is invalid!\n", - vm_xfer_page_pkt->transfer_page_set_id); + if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) { + device_printf(dev, "rxbuf_id %d is invalid!\n", + pkt->cp_rxbuf_id); return; } - count = vm_xfer_page_pkt->range_count; + count = pkt->cp_rxbuf_cnt; /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ for (i = 0; i < count; i++) { net_vsc_pkt->status = nvsp_status_success; - net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf + - vm_xfer_page_pkt->ranges[i].byte_offset); - net_vsc_pkt->tot_data_buf_len = - vm_xfer_page_pkt->ranges[i].byte_count; + net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf + + pkt->cp_rxbuf[i].rb_ofs); + net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len; hv_rf_on_receive(net_dev, chan, net_vsc_pkt); if (net_vsc_pkt->status != nvsp_status_success) { @@ -888,8 +875,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st * messages (not just data messages) will trigger a response * message back to the host. */ - hv_nv_on_receive_completion(chan, vm_xfer_page_pkt->d.transaction_id, - status); + hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status); } /* @@ -933,19 +919,19 @@ retry_send_cmplt: * Net VSC receiving vRSS send table from VSP */ static void -hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt) +hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { netvsc_dev *net_dev; - nvsp_msg *nvsp_msg_pkt; + const nvsp_msg *nvsp_msg_pkt; int i; - uint32_t count, *table; + uint32_t count; + const uint32_t *table; net_dev = hv_nv_get_inbound_net_device(sc); if (!net_dev) return; - nvsp_msg_pkt = - (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3)); + nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt); if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg5_type_send_indirection_table) { @@ -961,8 +947,8 @@ hv_nv_send_table(struct hn_softc *sc, hv return; } - table = (uint32_t *) - ((unsigned long)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table + + table = (const uint32_t *) + ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table + nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset); for (i = 0; i < count; i++) @@ -979,44 +965,40 @@ hv_nv_on_channel_callback(void *xchan) device_t dev = chan->ch_dev; struct hn_softc *sc = device_get_softc(dev); netvsc_dev *net_dev; - uint32_t bytes_rxed; - uint64_t request_id; - hv_vm_packet_descriptor *desc; - uint8_t *buffer; + void *buffer; int bufferlen = NETVSC_PACKET_SIZE; - int ret = 0; net_dev = hv_nv_get_inbound_net_device(sc); if (net_dev == NULL) return; buffer = chan->hv_chan_rdbuf; - do { - ret = hv_vmbus_channel_recv_packet_raw(chan, - buffer, bufferlen, &bytes_rxed, &request_id); + struct vmbus_chanpkt_hdr *pkt = buffer; + uint32_t bytes_rxed; + int ret; + + bytes_rxed = bufferlen; + ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); if (ret == 0) { if (bytes_rxed > 0) { - desc = (hv_vm_packet_descriptor *)buffer; - switch (desc->type) { + switch (pkt->cph_type) { case VMBUS_CHANPKT_TYPE_COMP: hv_nv_on_send_completion(net_dev, chan, - desc); + pkt); break; case VMBUS_CHANPKT_TYPE_RXBUF: - hv_nv_on_receive(net_dev, sc, chan, desc); + hv_nv_on_receive(net_dev, sc, chan, pkt); break; case VMBUS_CHANPKT_TYPE_INBAND: - hv_nv_send_table(sc, desc); + hv_nv_send_table(sc, pkt); break; default: device_printf(dev, - "hv_cb recv unknow type %d " - " packet\n", desc->type); + "unknown chan pkt %u\n", + pkt->cph_type); break; } - } else { - break; } } else if (ret == ENOBUFS) { /* Handle large packet */ @@ -1035,6 +1017,9 @@ hv_nv_on_channel_callback(void *xchan) break; } bufferlen = bytes_rxed; + } else { + /* No more packets */ + break; } } while (1); Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:09:53 2016 (r307080) @@ -780,12 +780,10 @@ hv_storvsc_on_channel_callback(void *xch struct hv_storvsc_request *request; struct vstor_packet *vstor_packet; - ret = hv_vmbus_channel_recv_packet( - channel, - packet, - roundup2(VSTOR_PKT_SIZE, 8), - &bytes_recvd, - &request_id); + bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8); + ret = vmbus_chan_recv(channel, packet, &bytes_recvd, &request_id); + KASSERT(ret != ENOBUFS, ("storvsc recvbuf is not large enough")); + /* XXX check bytes_recvd to make sure that it contains enough data */ while ((ret == 0) && (bytes_recvd > 0)) { request = (struct hv_storvsc_request *)(uintptr_t)request_id; @@ -819,12 +817,16 @@ hv_storvsc_on_channel_callback(void *xch break; } } - ret = hv_vmbus_channel_recv_packet( - channel, - packet, - roundup2(VSTOR_PKT_SIZE, 8), - &bytes_recvd, - &request_id); + + bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8), + ret = vmbus_chan_recv(channel, packet, &bytes_recvd, + &request_id); + KASSERT(ret != ENOBUFS, + ("storvsc recvbuf is not large enough")); + /* + * XXX check bytes_recvd to make sure that it contains + * enough data + */ } } Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 02:09:53 2016 (r307080) @@ -52,7 +52,7 @@ hv_heartbeat_cb(void *context) { uint8_t* buf; hv_vmbus_channel* channel; - uint32_t recvlen; + int recvlen; uint64_t requestid; int ret; @@ -64,8 +64,10 @@ hv_heartbeat_cb(void *context) buf = softc->receive_buffer;; channel = softc->channel; - ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen, - &requestid); + recvlen = PAGE_SIZE; + ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid); + KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough")); + /* XXX check recvlen to make sure that it contains enough data */ if ((ret == 0) && recvlen > 0) { Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 02:09:53 2016 (r307080) @@ -626,8 +626,10 @@ hv_kvp_process_request(void *context, in kvp_buf = sc->util_sc.receive_buffer;; channel = sc->util_sc.channel; - ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE, - &recvlen, &requestid); + recvlen = 2 * PAGE_SIZE; + ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid); + KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough")); + /* XXX check recvlen to make sure that it contains enough data */ while ((ret == 0) && (recvlen > 0)) { @@ -691,9 +693,11 @@ hv_kvp_process_request(void *context, in /* * Try reading next buffer */ - recvlen = 0; - ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE, - &recvlen, &requestid); + recvlen = 2 * PAGE_SIZE; + ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid); + KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough")); + /* XXX check recvlen to make sure that it contains enough data */ + hv_kvp_log_info("%s: read: context %p, ret =%d, recvlen=%d\n", __func__, context, ret, recvlen); } Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 02:09:53 2016 (r307080) @@ -67,8 +67,11 @@ hv_shutdown_cb(void *context) softc = (hv_util_sc*)context; buf = softc->receive_buffer;; channel = softc->channel; - ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, - &recv_len, &request_id); + + recv_len = PAGE_SIZE; + ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id); + KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough")); + /* XXX check recv_len to make sure that it contains enough data */ if ((ret == 0) && recv_len > 0) { Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 02:09:53 2016 (r307080) @@ -144,8 +144,10 @@ hv_timesync_cb(void *context) channel = softc->util_sc.channel; time_buf = softc->util_sc.receive_buffer; - ret = hv_vmbus_channel_recv_packet(channel, time_buf, - PAGE_SIZE, &recvlen, &requestId); + recvlen = PAGE_SIZE; + ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId); + KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough")); + /* XXX check recvlen to make sure that it contains enough data */ if ((ret == 0) && recvlen > 0) { icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[ Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:09:53 2016 (r307080) @@ -736,84 +736,60 @@ vmbus_chan_send_prplist(struct hv_vmbus_ return error; } -/** - * @brief Retrieve the user packet on the specified channel - */ int -hv_vmbus_channel_recv_packet( - hv_vmbus_channel* channel, - void* Buffer, - uint32_t buffer_len, - uint32_t* buffer_actual_len, - uint64_t* request_id) +vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen0, + uint64_t *xactid) { - int ret; - uint32_t user_len; - uint32_t packet_len; - hv_vm_packet_descriptor desc; - - *buffer_actual_len = 0; - *request_id = 0; - - ret = hv_ring_buffer_peek(&channel->inbound, &desc, - sizeof(hv_vm_packet_descriptor)); - if (ret != 0) - return (0); + struct vmbus_chanpkt_hdr pkt; + int error, dlen, hlen; - packet_len = desc.length8 << 3; - user_len = packet_len - (desc.data_offset8 << 3); + error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt)); + if (error) + return error; - *buffer_actual_len = user_len; + hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen); + dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen; - if (user_len > buffer_len) - return (EINVAL); + if (*dlen0 < dlen) { + /* Return the size of this packet's data. */ + *dlen0 = dlen; + return ENOBUFS; + } - *request_id = desc.transaction_id; + *xactid = pkt.cph_xactid; + *dlen0 = dlen; - /* Copy over the packet to the user buffer */ - ret = hv_ring_buffer_read(&channel->inbound, Buffer, user_len, - (desc.data_offset8 << 3)); + /* Skip packet header */ + error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen); + KASSERT(!error, ("hv_ring_buffer_read failed")); - return (0); + return 0; } -/** - * @brief Retrieve the raw packet on the specified channel - */ int -hv_vmbus_channel_recv_packet_raw( - hv_vmbus_channel* channel, - void* buffer, - uint32_t buffer_len, - uint32_t* buffer_actual_len, - uint64_t* request_id) +vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan, + struct vmbus_chanpkt_hdr *pkt0, int *pktlen0) { - int ret; - uint32_t packetLen; - hv_vm_packet_descriptor desc; + struct vmbus_chanpkt_hdr pkt; + int error, pktlen; - *buffer_actual_len = 0; - *request_id = 0; + error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt)); + if (error) + return error; + + pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen); + if (*pktlen0 < pktlen) { + /* Return the size of this packet. */ + *pktlen0 = pktlen; + return ENOBUFS; + } + *pktlen0 = pktlen; + + /* Include packet header */ + error = hv_ring_buffer_read(&chan->inbound, pkt0, pktlen, 0); + KASSERT(!error, ("hv_ring_buffer_read failed")); - ret = hv_ring_buffer_peek( - &channel->inbound, &desc, - sizeof(hv_vm_packet_descriptor)); - - if (ret != 0) - return (0); - - packetLen = desc.length8 << 3; - *buffer_actual_len = packetLen; - - if (packetLen > buffer_len) - return (ENOBUFS); - - *request_id = desc.transaction_id; - - /* Copy over the entire packet to the user buffer */ - ret = hv_ring_buffer_read(&channel->inbound, buffer, packetLen, 0); - - return (0); + return 0; } static void Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 02:03:05 2016 (r307079) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 02:09:53 2016 (r307080) @@ -112,7 +112,6 @@ CTASSERT(sizeof(struct vmbus_mnf) == PAG * Channel packets */ -#define VMBUS_CHANPKT_SIZE_SHIFT 3 #define VMBUS_CHANPKT_SIZE_ALIGN (1 << VMBUS_CHANPKT_SIZE_SHIFT) #define VMBUS_CHANPKT_SETLEN(pktlen, len) \ @@ -123,14 +122,6 @@ do { \ #define VMBUS_CHANPKT_TOTLEN(tlen) \ roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN) -struct vmbus_chanpkt_hdr { - uint16_t cph_type; - uint16_t cph_hlen; /* header len, in 8 bytes */ - uint16_t cph_tlen; /* total len, in 8 bytes */ - uint16_t cph_flags; - uint64_t cph_xactid; -} __packed; - struct vmbus_chanpkt { struct vmbus_chanpkt_hdr cp_hdr; } __packed; From owner-svn-src-stable-10@freebsd.org Wed Oct 12 02:15:08 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 756FEC0D749; Wed, 12 Oct 2016 02:15:08 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4FBFA181A; Wed, 12 Oct 2016 02:15:08 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C2F7Of041702; Wed, 12 Oct 2016 02:15:07 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C2F7uI041698; Wed, 12 Oct 2016 02:15:07 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120215.u9C2F7uI041698@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 02:15:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307081 - in stable/10/sys/dev/hyperv: include netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 02:15:08 -0000 Author: sephe Date: Wed Oct 12 02:15:06 2016 New Revision: 307081 URL: https://svnweb.freebsd.org/changeset/base/307081 Log: MFC 302887 hyperv/hn: Busdma-fy rxbuf and chimney sending buffer Nuke unused channel GPADL API. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7211 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/vmbus/hv_channel.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:09:53 2016 (r307080) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:15:06 2016 (r307081) @@ -287,14 +287,6 @@ int hv_vmbus_channel_open( void hv_vmbus_channel_close(hv_vmbus_channel *channel); -int hv_vmbus_channel_establish_gpadl( - hv_vmbus_channel* channel, - /* must be phys and virt contiguous */ - void* contig_buffer, - /* page-size multiple */ - uint32_t size, - uint32_t* gpadl_handle); - int hv_vmbus_channel_teardown_gpdal( hv_vmbus_channel* channel, uint32_t gpadl_handle); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:09:53 2016 (r307080) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:15:06 2016 (r307081) @@ -151,19 +151,27 @@ hv_nv_init_rx_buffer_with_net_vsp(struct return (ENODEV); } - net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC, - M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); + net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), + PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (net_dev->rx_buf == NULL) { + device_printf(sc->hn_dev, "allocate rxbuf failed\n"); + return ENOMEM; + } /* - * Establish the GPADL handle for this buffer on this channel. - * Note: This call uses the vmbus connection rather than the - * channel to establish the gpadl handle. - * GPADL: Guest physical address descriptor list. - */ - ret = hv_vmbus_channel_establish_gpadl( - sc->hn_prichan, net_dev->rx_buf, - net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle); + * Connect the RXBUF GPADL to the primary channel. + * + * NOTE: + * Only primary channel has RXBUF connected to it. Sub-channels + * just share this RXBUF. + */ + ret = vmbus_chan_gpadl_connect(sc->hn_prichan, + net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size, + &net_dev->rx_buf_gpadl_handle); if (ret != 0) { + device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n", + ret); goto cleanup; } @@ -242,22 +250,27 @@ hv_nv_init_send_buffer_with_net_vsp(stru return (ENODEV); } - net_dev->send_buf = contigmalloc(net_dev->send_buf_size, M_NETVSC, - M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); + net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), + PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); if (net_dev->send_buf == NULL) { - ret = ENOMEM; - goto cleanup; + device_printf(sc->hn_dev, "allocate chimney txbuf failed\n"); + return ENOMEM; } /* - * Establish the gpadl handle for this buffer on this channel. - * Note: This call uses the vmbus connection rather than the - * channel to establish the gpadl handle. + * Connect chimney sending buffer GPADL to the primary channel. + * + * NOTE: + * Only primary channel has chimney sending buffer connected to it. + * Sub-channels just share this chimney sending buffer. */ - ret = hv_vmbus_channel_establish_gpadl(sc->hn_prichan, - net_dev->send_buf, net_dev->send_buf_size, + ret = vmbus_chan_gpadl_connect(sc->hn_prichan, + net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size, &net_dev->send_buf_gpadl_handle); if (ret != 0) { + device_printf(sc->hn_dev, "chimney sending buffer gpadl " + "connect failed: %d\n", ret); goto cleanup; } @@ -363,7 +376,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ if (net_dev->rx_buf) { /* Free up the receive buffer */ - contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC); + hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf); net_dev->rx_buf = NULL; } @@ -431,7 +444,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne if (net_dev->send_buf) { /* Free up the receive buffer */ - contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC); + hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf); net_dev->send_buf = NULL; } Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 02:09:53 2016 (r307080) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 02:15:06 2016 (r307081) @@ -57,6 +57,7 @@ #include #include +#include #include #define HN_USE_TXDESC_BUFRING @@ -1075,6 +1076,8 @@ typedef struct netvsc_dev_ { uint32_t num_channel; + struct hyperv_dma rxbuf_dma; + struct hyperv_dma txbuf_dma; uint32_t vrss_send_table[VRSS_SEND_TABLE_SIZE]; } netvsc_dev; Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:09:53 2016 (r307080) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:15:06 2016 (r307081) @@ -337,17 +337,6 @@ failed: return ret; } -/** - * @brief Establish a GPADL for the specified buffer - */ -int -hv_vmbus_channel_establish_gpadl(struct hv_vmbus_channel *channel, - void *contig_buffer, uint32_t size, uint32_t *gpadl) -{ - return vmbus_chan_gpadl_connect(channel, - hv_get_phys_addr(contig_buffer), size, gpadl); -} - int vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, bus_addr_t paddr, int size, uint32_t *gpadl0) From owner-svn-src-stable-10@freebsd.org Wed Oct 12 02:45:32 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 19903C0DE71; Wed, 12 Oct 2016 02:45:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D6D6EB75; Wed, 12 Oct 2016 02:45:31 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C2jVtT053319; Wed, 12 Oct 2016 02:45:31 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C2jUKT053311; Wed, 12 Oct 2016 02:45:30 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120245.u9C2jUKT053311@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 02:45:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307084 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 02:45:32 -0000 Author: sephe Date: Wed Oct 12 02:45:30 2016 New Revision: 307084 URL: https://svnweb.freebsd.org/changeset/base/307084 Log: MFC 302888-302892,302986,303020-303022 302888 hyperv/hn: Busdma-fy rxbuf and chimney sending buffer Nuke unused channel GPADL API. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7211 302889 hyperv/vmbus: Back out r302888 temporarily Committed by accident w/ duplicated commit log Sponsored by: Microsoft OSTC 302890 hyperv/vmbus: Function rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7212 302891 hyperv/vmbus: Cosmetic vmbus channel close cleanup Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7213 302892 hyperv/vmbus: Cleanup channel sysctl tree creation Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7214 302986 hyperv/vmbus: Cosmetic vmbus channel open cleanup Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7217 303020 hyperv/vmbus: Cleanup cpu based channel selection. And create cpu to channel map at device attach time for storvsc(4). Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7229 303021 hyperv/vmbus: Function rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7230 303022 hyperv/vmbus: Temp/internal variable/function rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7231 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/vmbus/hv_channel.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:45:30 2016 (r307084) @@ -267,42 +267,6 @@ typedef struct hv_vmbus_channel { #define VMBUS_CHAN_ST_OPENED_SHIFT 0 #define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) -static inline void -hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on) -{ - if (!on) - channel->ch_flags &= ~VMBUS_CHAN_FLAG_BATCHREAD; - else - channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD; -} - -int hv_vmbus_channel_open( - hv_vmbus_channel* channel, - uint32_t send_ring_buffer_size, - uint32_t recv_ring_buffer_size, - void* user_data, - uint32_t user_data_len, - vmbus_chan_callback_t cb, - void *cbarg); - -void hv_vmbus_channel_close(hv_vmbus_channel *channel); - -int hv_vmbus_channel_teardown_gpdal( - hv_vmbus_channel* channel, - uint32_t gpadl_handle); - -int vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, - bus_addr_t paddr, int size, uint32_t *gpadl); - -struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary); - -void vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu); -void vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan); -struct hv_vmbus_channel ** - vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt); -void vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt); -void vmbus_drain_subchan(struct hv_vmbus_channel *pri_chan); - /** * @brief Get physical address from virtual */ Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:45:30 2016 (r307084) @@ -89,6 +89,27 @@ struct vmbus_chanpkt_rxbuf { struct hv_vmbus_channel; +int vmbus_chan_open(struct hv_vmbus_channel *chan, + int txbr_size, int rxbr_size, const void *udata, int udlen, + vmbus_chan_callback_t cb, void *cbarg); +void vmbus_chan_close(struct hv_vmbus_channel *chan); + +int vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, + bus_addr_t paddr, int size, uint32_t *gpadl); +int vmbus_chan_gpadl_disconnect(struct hv_vmbus_channel *chan, + uint32_t gpadl); + +void vmbus_chan_cpu_set(struct hv_vmbus_channel *chan, int cpu); +void vmbus_chan_cpu_rr(struct hv_vmbus_channel *chan); +struct hv_vmbus_channel * + vmbus_chan_cpu2chan(struct hv_vmbus_channel *chan, int cpu); +void vmbus_chan_set_readbatch(struct hv_vmbus_channel *chan, bool on); + +struct hv_vmbus_channel ** + vmbus_subchan_get(struct hv_vmbus_channel *pri_chan, int subchan_cnt); +void vmbus_subchan_rel(struct hv_vmbus_channel **subchan, int subchan_cnt); +void vmbus_subchan_drain(struct hv_vmbus_channel *pri_chan); + int vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen, uint64_t *xactid); int vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:45:30 2016 (r307084) @@ -362,7 +362,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ /* Tear down the gpadl on the vsp end */ if (net_dev->rx_buf_gpadl_handle) { - ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan, + ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, net_dev->rx_buf_gpadl_handle); /* * If we failed here, we might as well return and have a leak @@ -429,7 +429,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne /* Tear down the gpadl on the vsp end */ if (net_dev->send_buf_gpadl_handle) { - ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan, + ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, net_dev->send_buf_gpadl_handle); /* @@ -644,7 +644,7 @@ hv_nv_subchan_attach(struct hv_vmbus_cha { chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK); - hv_vmbus_channel_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, + vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hv_nv_on_channel_callback, chan); } @@ -674,7 +674,7 @@ hv_nv_on_device_add(struct hn_softc *sc, /* * Open the channel */ - ret = hv_vmbus_channel_open(chan, + ret = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hv_nv_on_channel_callback, chan); if (ret != 0) { @@ -694,7 +694,7 @@ hv_nv_on_device_add(struct hn_softc *sc, close: /* Now, we can close the channel safely */ free(chan->hv_chan_rdbuf, M_NETVSC); - hv_vmbus_channel_close(chan); + vmbus_chan_close(chan); cleanup: /* @@ -725,7 +725,7 @@ hv_nv_on_device_remove(struct hn_softc * /* Now, we can close the channel safely */ free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC); - hv_vmbus_channel_close(sc->hn_prichan); + vmbus_chan_close(sc->hn_prichan); sema_destroy(&net_dev->channel_init_sema); free(net_dev, M_NETVSC); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 02:45:30 2016 (r307084) @@ -1603,7 +1603,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, } /* Wait for subchannels to be destroyed */ - vmbus_drain_subchan(sc->hn_prichan); + vmbus_subchan_drain(sc->hn_prichan); error = hv_rf_on_device_add(sc, &device_info, sc->hn_rx_ring_inuse); @@ -3006,7 +3006,7 @@ hn_channel_attach(struct hn_softc *sc, s } /* Bind channel to a proper CPU */ - vmbus_channel_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus); + vmbus_chan_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus); } static void @@ -3029,7 +3029,7 @@ hn_subchan_setup(struct hn_softc *sc) int i; /* Wait for sub-channels setup to complete. */ - subchan = vmbus_get_subchan(sc->hn_prichan, subchan_cnt); + subchan = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); /* Attach the sub-channels. */ for (i = 0; i < subchan_cnt; ++i) { @@ -3039,7 +3039,7 @@ hn_subchan_setup(struct hn_softc *sc) } /* Release the sub-channels */ - vmbus_rel_subchan(subchan, subchan_cnt); + vmbus_subchan_rel(subchan, subchan_cnt); if_printf(sc->hn_ifp, "%d sub-channels setup done\n", subchan_cnt); } Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:45:30 2016 (r307084) @@ -147,6 +147,8 @@ struct storvsc_softc { struct hv_storvsc_request hs_init_req; struct hv_storvsc_request hs_reset_req; device_t hs_dev; + + struct hv_vmbus_channel *hs_cpu2chan[MAXCPU]; }; @@ -315,8 +317,8 @@ storvsc_subchan_attach(struct storvsc_so memset(&props, 0, sizeof(props)); new_channel->hv_chan_priv1 = sc; - vmbus_channel_cpu_rr(new_channel); - ret = hv_vmbus_channel_open(new_channel, + vmbus_chan_cpu_rr(new_channel); + ret = vmbus_chan_open(new_channel, sc->hs_drv_props->drv_ringbuffer_size, sc->hs_drv_props->drv_ringbuffer_size, (void *)&props, @@ -377,14 +379,14 @@ storvsc_send_multichannel_request(struct } /* Wait for sub-channels setup to complete. */ - subchan = vmbus_get_subchan(sc->hs_chan, request_channels_cnt); + subchan = vmbus_subchan_get(sc->hs_chan, request_channels_cnt); /* Attach the sub-channels. */ for (i = 0; i < request_channels_cnt; ++i) storvsc_subchan_attach(sc, subchan[i]); /* Release the sub-channels. */ - vmbus_rel_subchan(subchan, request_channels_cnt); + vmbus_subchan_rel(subchan, request_channels_cnt); if (bootverbose) printf("Storvsc create multi-channel success!\n"); @@ -574,8 +576,8 @@ hv_storvsc_connect_vsp(struct storvsc_so * Open the channel */ KASSERT(sc->hs_chan->hv_chan_priv1 == sc, ("invalid chan priv1")); - vmbus_channel_cpu_rr(sc->hs_chan); - ret = hv_vmbus_channel_open( + vmbus_chan_cpu_rr(sc->hs_chan); + ret = vmbus_chan_open( sc->hs_chan, sc->hs_drv_props->drv_ringbuffer_size, sc->hs_drv_props->drv_ringbuffer_size, @@ -665,7 +667,7 @@ hv_storvsc_io_request(struct storvsc_sof vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB; - outgoing_channel = vmbus_select_outgoing_channel(sc->hs_chan); + outgoing_channel = sc->hs_cpu2chan[curcpu]; mtx_unlock(&request->softc->hs_lock); if (request->prp_list.gpa_range.gpa_len) { @@ -872,6 +874,20 @@ storvsc_probe(device_t dev) return (ret); } +static void +storvsc_create_cpu2chan(struct storvsc_softc *sc) +{ + int cpu; + + CPU_FOREACH(cpu) { + sc->hs_cpu2chan[cpu] = vmbus_chan_cpu2chan(sc->hs_chan, cpu); + if (bootverbose) { + device_printf(sc->hs_dev, "cpu%d -> chan%u\n", + cpu, sc->hs_cpu2chan[cpu]->ch_id); + } + } +} + /** * @brief StorVSC attach function * @@ -969,6 +985,9 @@ storvsc_attach(device_t dev) goto cleanup; } + /* Construct cpu to channel mapping */ + storvsc_create_cpu2chan(sc); + /* * Create the device queue. * Hyper-V maps each target to one SCSI HBA @@ -1083,7 +1102,7 @@ storvsc_detach(device_t dev) * under the protection of the incoming channel lock. */ - hv_vmbus_channel_close(sc->hs_chan); + vmbus_chan_close(sc->hs_chan); mtx_lock(&sc->hs_lock); while (!LIST_EMPTY(&sc->hs_free_list)) { Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.c Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/utilities/hv_util.c Wed Oct 12 02:45:30 2016 (r307084) @@ -40,6 +40,7 @@ #include #include +#include #include "hv_util.h" void @@ -89,9 +90,9 @@ hv_util_attach(device_t dev) * Turn off batched reading for all util drivers before we open the * channel. */ - hv_set_channel_read_state(softc->channel, FALSE); + vmbus_chan_set_readbatch(softc->channel, false); - ret = hv_vmbus_channel_open(softc->channel, 4 * PAGE_SIZE, + ret = vmbus_chan_open(softc->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0, softc->callback, softc); @@ -110,7 +111,7 @@ hv_util_detach(device_t dev) { struct hv_util_sc *sc = device_get_softc(dev); - hv_vmbus_channel_close(sc->channel); + vmbus_chan_close(sc->channel); free(sc->receive_buffer, M_DEVBUF); return (0); Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:30:33 2016 (r307083) +++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:45:30 2016 (r307084) @@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include -static void vmbus_chan_send_event(hv_vmbus_channel* channel); +static void vmbus_chan_signal_tx(struct hv_vmbus_channel *chan); static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, const struct hv_vmbus_channel *); @@ -81,195 +81,194 @@ vmbus_chan_msgprocs[VMBUS_CHANMSG_TYPE_M * @brief Trigger an event notification on the specified channel */ static void -vmbus_chan_send_event(hv_vmbus_channel *channel) +vmbus_chan_signal_tx(struct hv_vmbus_channel *chan) { - struct vmbus_softc *sc = channel->vmbus_sc; - uint32_t chanid = channel->ch_id; + struct vmbus_softc *sc = chan->vmbus_sc; + uint32_t chanid = chan->ch_id; atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], 1UL << (chanid & VMBUS_EVTFLAG_MASK)); - if (channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { + if (chan->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { atomic_set_int( - &sc->vmbus_mnf2->mnf_trigs[channel->ch_montrig_idx].mt_pending, - channel->ch_montrig_mask); + &sc->vmbus_mnf2->mnf_trigs[chan->ch_montrig_idx].mt_pending, + chan->ch_montrig_mask); } else { - hypercall_signal_event(channel->ch_monprm_dma.hv_paddr); + hypercall_signal_event(chan->ch_monprm_dma.hv_paddr); } } static int -vmbus_channel_sysctl_monalloc(SYSCTL_HANDLER_ARGS) +vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS) { struct hv_vmbus_channel *chan = arg1; - int alloc = 0; + int mnf = 0; if (chan->ch_flags & VMBUS_CHAN_FLAG_HASMNF) - alloc = 1; - return sysctl_handle_int(oidp, &alloc, 0, req); + mnf = 1; + return sysctl_handle_int(oidp, &mnf, 0, req); } static void -vmbus_channel_sysctl_create(hv_vmbus_channel* channel) +vmbus_chan_sysctl_create(struct hv_vmbus_channel *chan) { - device_t dev; - struct sysctl_oid *devch_sysctl; - struct sysctl_oid *devch_id_sysctl, *devch_sub_sysctl; - struct sysctl_oid *devch_id_in_sysctl, *devch_id_out_sysctl; + struct sysctl_oid *ch_tree, *chid_tree, *br_tree; struct sysctl_ctx_list *ctx; uint32_t ch_id; - uint16_t sub_ch_id; char name[16]; - - hv_vmbus_channel* primary_ch = channel->ch_prichan; - if (primary_ch == NULL) { - dev = channel->ch_dev; - ch_id = channel->ch_id; - } else { - dev = primary_ch->ch_dev; - ch_id = primary_ch->ch_id; - sub_ch_id = channel->ch_subidx; - } - ctx = &channel->ch_sysctl_ctx; + /* + * Add sysctl nodes related to this channel to this + * channel's sysctl ctx, so that they can be destroyed + * independently upon close of this channel, which can + * happen even if the device is not detached. + */ + ctx = &chan->ch_sysctl_ctx; sysctl_ctx_init(ctx); - /* This creates dev.DEVNAME.DEVUNIT.channel tree */ - devch_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "channel", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - /* This creates dev.DEVNAME.DEVUNIT.channel.CHANID tree */ + + /* + * Create dev.NAME.UNIT.channel tree. + */ + ch_tree = SYSCTL_ADD_NODE(ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(chan->ch_dev)), + OID_AUTO, "channel", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (ch_tree == NULL) + return; + + /* + * Create dev.NAME.UNIT.channel.CHANID tree. + */ + if (VMBUS_CHAN_ISPRIMARY(chan)) + ch_id = chan->ch_id; + else + ch_id = chan->ch_prichan->ch_id; snprintf(name, sizeof(name), "%d", ch_id); - devch_id_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(devch_sysctl), - OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - - if (primary_ch != NULL) { - devch_sub_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(devch_id_sysctl), - OID_AUTO, "sub", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - snprintf(name, sizeof(name), "%d", sub_ch_id); - devch_id_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(devch_sub_sysctl), - OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), - OID_AUTO, "chanid", CTLFLAG_RD, - &channel->ch_id, 0, "channel id"); - } - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, - "cpu", CTLFLAG_RD, &channel->ch_cpuid, 0, "owner CPU id"); - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO, - "monitor_allocated", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, - channel, 0, vmbus_channel_sysctl_monalloc, "I", - "is monitor allocated to this channel"); - - devch_id_in_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(devch_id_sysctl), - OID_AUTO, - "in", - CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - devch_id_out_sysctl = SYSCTL_ADD_NODE(ctx, - SYSCTL_CHILDREN(devch_id_sysctl), - OID_AUTO, - "out", - CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - hv_ring_buffer_stat(ctx, - SYSCTL_CHILDREN(devch_id_in_sysctl), - &(channel->inbound), - "inbound ring buffer stats"); - hv_ring_buffer_stat(ctx, - SYSCTL_CHILDREN(devch_id_out_sysctl), - &(channel->outbound), - "outbound ring buffer stats"); + chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree), + OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (chid_tree == NULL) + return; + + if (!VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * Create dev.NAME.UNIT.channel.CHANID.sub tree. + */ + ch_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), + OID_AUTO, "sub", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (ch_tree == NULL) + return; + + /* + * Create dev.NAME.UNIT.channel.CHANID.sub.SUBIDX tree. + * + * NOTE: + * chid_tree is changed to this new sysctl tree. + */ + snprintf(name, sizeof(name), "%d", chan->ch_subidx); + chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree), + OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (chid_tree == NULL) + return; + + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "chanid", CTLFLAG_RD, &chan->ch_id, 0, "channel id"); + } + + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "cpu", CTLFLAG_RD, &chan->ch_cpuid, 0, "owner CPU id"); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "mnf", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, + chan, 0, vmbus_chan_sysctl_mnf, "I", + "has monitor notification facilities"); + + /* + * Create sysctl tree for RX bufring. + */ + br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "in", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (br_tree != NULL) { + hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), + &chan->inbound, "inbound ring buffer stats"); + } + + /* + * Create sysctl tree for TX bufring. + */ + br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "out", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (br_tree != NULL) { + hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), + &chan->outbound, "outbound ring buffer stats"); + } } -/** - * @brief Open the specified channel - */ int -hv_vmbus_channel_open( - hv_vmbus_channel* new_channel, - uint32_t send_ring_buffer_size, - uint32_t recv_ring_buffer_size, - void* user_data, - uint32_t user_data_len, - vmbus_chan_callback_t cb, - void *cbarg) +vmbus_chan_open(struct hv_vmbus_channel *chan, int txbr_size, int rxbr_size, + const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg) { - struct vmbus_softc *sc = new_channel->vmbus_sc; + struct vmbus_softc *sc = chan->vmbus_sc; const struct vmbus_chanmsg_chopen_resp *resp; const struct vmbus_message *msg; struct vmbus_chanmsg_chopen *req; struct vmbus_msghc *mh; uint32_t status; - int ret = 0; + int error; uint8_t *br; - if (user_data_len > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { + if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { device_printf(sc->vmbus_dev, - "invalid udata len %u for chan%u\n", - user_data_len, new_channel->ch_id); + "invalid udata len %d for chan%u\n", udlen, chan->ch_id); return EINVAL; } - KASSERT((send_ring_buffer_size & PAGE_MASK) == 0, + KASSERT((txbr_size & PAGE_MASK) == 0, ("send bufring size is not multiple page")); - KASSERT((recv_ring_buffer_size & PAGE_MASK) == 0, + KASSERT((rxbr_size & PAGE_MASK) == 0, ("recv bufring size is not multiple page")); - if (atomic_testandset_int(&new_channel->ch_stflags, + if (atomic_testandset_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED_SHIFT)) - panic("double-open chan%u", new_channel->ch_id); + panic("double-open chan%u", chan->ch_id); - new_channel->ch_cb = cb; - new_channel->ch_cbarg = cbarg; + chan->ch_cb = cb; + chan->ch_cbarg = cbarg; - vmbus_chan_update_evtflagcnt(sc, new_channel); + vmbus_chan_update_evtflagcnt(sc, chan); - new_channel->ch_tq = VMBUS_PCPU_GET(new_channel->vmbus_sc, event_tq, - new_channel->ch_cpuid); - if (new_channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) { - TASK_INIT(&new_channel->ch_task, 0, vmbus_chan_task, - new_channel); - } else { - TASK_INIT(&new_channel->ch_task, 0, vmbus_chan_task_nobatch, - new_channel); - } + chan->ch_tq = VMBUS_PCPU_GET(chan->vmbus_sc, event_tq, chan->ch_cpuid); + if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) + TASK_INIT(&chan->ch_task, 0, vmbus_chan_task, chan); + else + TASK_INIT(&chan->ch_task, 0, vmbus_chan_task_nobatch, chan); /* * Allocate the TX+RX bufrings. * XXX should use ch_dev dtag */ br = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), - PAGE_SIZE, 0, send_ring_buffer_size + recv_ring_buffer_size, - &new_channel->ch_bufring_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); if (br == NULL) { device_printf(sc->vmbus_dev, "bufring allocation failed\n"); - ret = ENOMEM; + error = ENOMEM; goto failed; } - new_channel->ch_bufring = br; + chan->ch_bufring = br; /* TX bufring comes first */ - hv_vmbus_ring_buffer_init(&new_channel->outbound, - br, send_ring_buffer_size); + hv_vmbus_ring_buffer_init(&chan->outbound, br, txbr_size); /* RX bufring immediately follows TX bufring */ - hv_vmbus_ring_buffer_init(&new_channel->inbound, - br + send_ring_buffer_size, recv_ring_buffer_size); + hv_vmbus_ring_buffer_init(&chan->inbound, br + txbr_size, rxbr_size); /* Create sysctl tree for this channel */ - vmbus_channel_sysctl_create(new_channel); + vmbus_chan_sysctl_create(chan); /* * Connect the bufrings, both RX and TX, to this channel. */ - ret = vmbus_chan_gpadl_connect(new_channel, - new_channel->ch_bufring_dma.hv_paddr, - send_ring_buffer_size + recv_ring_buffer_size, - &new_channel->ch_bufring_gpadl); - if (ret != 0) { + error = vmbus_chan_gpadl_connect(chan, chan->ch_bufring_dma.hv_paddr, + txbr_size + rxbr_size, &chan->ch_bufring_gpadl); + if (error) { device_printf(sc->vmbus_dev, - "failed to connect bufring GPADL to chan%u\n", - new_channel->ch_id); + "failed to connect bufring GPADL to chan%u\n", chan->ch_id); goto failed; } @@ -280,26 +279,26 @@ hv_vmbus_channel_open( if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for chopen(chan%u)\n", - new_channel->ch_id); - ret = ENXIO; + chan->ch_id); + error = ENXIO; goto failed; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; - req->chm_chanid = new_channel->ch_id; - req->chm_openid = new_channel->ch_id; - req->chm_gpadl = new_channel->ch_bufring_gpadl; - req->chm_vcpuid = new_channel->ch_vcpuid; - req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; - if (user_data_len) - memcpy(req->chm_udata, user_data, user_data_len); + req->chm_chanid = chan->ch_id; + req->chm_openid = chan->ch_id; + req->chm_gpadl = chan->ch_bufring_gpadl; + req->chm_vcpuid = chan->ch_vcpuid; + req->chm_txbr_pgcnt = txbr_size >> PAGE_SHIFT; + if (udlen > 0) + memcpy(req->chm_udata, udata, udlen); - ret = vmbus_msghc_exec(sc, mh); - if (ret != 0) { + error = vmbus_msghc_exec(sc, mh); + if (error) { device_printf(sc->vmbus_dev, "chopen(chan%u) msg hypercall exec failed: %d\n", - new_channel->ch_id, ret); + chan->ch_id, error); vmbus_msghc_put(sc, mh); goto failed; } @@ -313,28 +312,25 @@ hv_vmbus_channel_open( if (status == 0) { if (bootverbose) { device_printf(sc->vmbus_dev, "chan%u opened\n", - new_channel->ch_id); + chan->ch_id); } return 0; } - device_printf(sc->vmbus_dev, "failed to open chan%u\n", - new_channel->ch_id); - ret = ENXIO; + device_printf(sc->vmbus_dev, "failed to open chan%u\n", chan->ch_id); + error = ENXIO; failed: - if (new_channel->ch_bufring_gpadl) { - hv_vmbus_channel_teardown_gpdal(new_channel, - new_channel->ch_bufring_gpadl); - new_channel->ch_bufring_gpadl = 0; - } - if (new_channel->ch_bufring != NULL) { - hyperv_dmamem_free(&new_channel->ch_bufring_dma, - new_channel->ch_bufring); - new_channel->ch_bufring = NULL; + if (chan->ch_bufring_gpadl) { + vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); + chan->ch_bufring_gpadl = 0; + } + if (chan->ch_bufring != NULL) { + hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); + chan->ch_bufring = NULL; } - atomic_clear_int(&new_channel->ch_stflags, VMBUS_CHAN_ST_OPENED); - return ret; + atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); + return error; } int @@ -468,7 +464,7 @@ vmbus_chan_gpadl_connect(struct hv_vmbus * Disconnect the GPA from the target channel */ int -hv_vmbus_channel_teardown_gpdal(struct hv_vmbus_channel *chan, uint32_t gpadl) +vmbus_chan_gpadl_disconnect(struct hv_vmbus_channel *chan, uint32_t gpadl) { struct vmbus_softc *sc = chan->vmbus_sc; struct vmbus_msghc *mh; @@ -505,41 +501,45 @@ hv_vmbus_channel_teardown_gpdal(struct h } static void -hv_vmbus_channel_close_internal(hv_vmbus_channel *channel) +vmbus_chan_close_internal(struct hv_vmbus_channel *chan) { - struct vmbus_softc *sc = channel->vmbus_sc; + struct vmbus_softc *sc = chan->vmbus_sc; struct vmbus_msghc *mh; struct vmbus_chanmsg_chclose *req; - struct taskqueue *tq = channel->ch_tq; + struct taskqueue *tq = chan->ch_tq; int error; /* TODO: stringent check */ - atomic_clear_int(&channel->ch_stflags, VMBUS_CHAN_ST_OPENED); - - sysctl_ctx_free(&channel->ch_sysctl_ctx); + atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); /* - * Set ch_tq to NULL to avoid more requests be scheduled + * Free this channel's sysctl tree attached to its device's + * sysctl tree. */ - channel->ch_tq = NULL; - taskqueue_drain(tq, &channel->ch_task); - channel->ch_cb = NULL; + sysctl_ctx_free(&chan->ch_sysctl_ctx); - /** - * Send a closing message + /* + * Set ch_tq to NULL to avoid more requests be scheduled. + * XXX pretty broken; need rework. */ + chan->ch_tq = NULL; + taskqueue_drain(tq, &chan->ch_task); + chan->ch_cb = NULL; + /* + * Close this channel. + */ mh = vmbus_msghc_get(sc, sizeof(*req)); if (mh == NULL) { device_printf(sc->vmbus_dev, "can not get msg hypercall for chclose(chan%u)\n", - channel->ch_id); + chan->ch_id); return; } req = vmbus_msghc_dataptr(mh); req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHCLOSE; - req->chm_chanid = channel->ch_id; + req->chm_chanid = chan->ch_id; error = vmbus_msghc_exec_noresult(mh); vmbus_msghc_put(sc, mh); @@ -547,30 +547,28 @@ hv_vmbus_channel_close_internal(hv_vmbus if (error) { device_printf(sc->vmbus_dev, "chclose(chan%u) msg hypercall exec failed: %d\n", - channel->ch_id, error); + chan->ch_id, error); return; } else if (bootverbose) { - device_printf(sc->vmbus_dev, "close chan%u\n", - channel->ch_id); + device_printf(sc->vmbus_dev, "close chan%u\n", chan->ch_id); } - /* Tear down the gpadl for the channel's ring buffer */ - if (channel->ch_bufring_gpadl) { - hv_vmbus_channel_teardown_gpdal(channel, - channel->ch_bufring_gpadl); - channel->ch_bufring_gpadl = 0; + /* + * Disconnect the TX+RX bufrings from this channel. + */ + if (chan->ch_bufring_gpadl) { + vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); + chan->ch_bufring_gpadl = 0; } - /* TODO: Send a msg to release the childRelId */ - - /* cleanup the ring buffers for this channel */ - hv_ring_buffer_cleanup(&channel->outbound); - hv_ring_buffer_cleanup(&channel->inbound); - - if (channel->ch_bufring != NULL) { - hyperv_dmamem_free(&channel->ch_bufring_dma, - channel->ch_bufring); - channel->ch_bufring = NULL; + /* + * Destroy the TX+RX bufrings. + */ + hv_ring_buffer_cleanup(&chan->outbound); + hv_ring_buffer_cleanup(&chan->inbound); + if (chan->ch_bufring != NULL) { + hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); + chan->ch_bufring = NULL; } } @@ -580,7 +578,7 @@ hv_vmbus_channel_close_internal(hv_vmbus * are not being opened. */ void -hv_vmbus_channel_close(struct hv_vmbus_channel *chan) +vmbus_chan_close(struct hv_vmbus_channel *chan) { int subchan_cnt; @@ -600,14 +598,14 @@ hv_vmbus_channel_close(struct hv_vmbus_c struct hv_vmbus_channel **subchan; int i; - subchan = vmbus_get_subchan(chan, subchan_cnt); + subchan = vmbus_subchan_get(chan, subchan_cnt); for (i = 0; i < subchan_cnt; ++i) - hv_vmbus_channel_close_internal(subchan[i]); - vmbus_rel_subchan(subchan, subchan_cnt); + vmbus_chan_close_internal(subchan[i]); + vmbus_subchan_rel(subchan, subchan_cnt); } /* Then close the primary channel. */ - hv_vmbus_channel_close_internal(chan); + vmbus_chan_close_internal(chan); } int @@ -639,7 +637,7 @@ vmbus_chan_send(struct hv_vmbus_channel error = hv_ring_buffer_write(&chan->outbound, iov, 3, &send_evt); if (!error && send_evt) - vmbus_chan_send_event(chan); + vmbus_chan_signal_tx(chan); return error; } @@ -679,7 +677,7 @@ vmbus_chan_send_sglist(struct hv_vmbus_c error = hv_ring_buffer_write(&chan->outbound, iov, 4, &send_evt); if (!error && send_evt) - vmbus_chan_send_event(chan); + vmbus_chan_signal_tx(chan); return error; } @@ -721,7 +719,7 @@ vmbus_chan_send_prplist(struct hv_vmbus_ error = hv_ring_buffer_write(&chan->outbound, iov, 4, &send_evt); if (!error && send_evt) - vmbus_chan_send_event(chan); + vmbus_chan_signal_tx(chan); return error; } @@ -840,20 +838,20 @@ vmbus_event_flags_proc(struct vmbus_soft chid_base = f << VMBUS_EVTFLAG_SHIFT; while ((chid_ofs = ffsl(flags)) != 0) { - struct hv_vmbus_channel *channel; + struct hv_vmbus_channel *chan; --chid_ofs; /* NOTE: ffsl is 1-based */ flags &= ~(1UL << chid_ofs); - channel = sc->vmbus_chmap[chid_base + chid_ofs]; + chan = sc->vmbus_chmap[chid_base + chid_ofs]; /* if channel is closed or closing */ - if (channel == NULL || channel->ch_tq == NULL) + if (chan == NULL || chan->ch_tq == NULL) continue; - if (channel->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) - hv_ring_buffer_read_begin(&channel->inbound); - taskqueue_enqueue(channel->ch_tq, &channel->ch_task); + if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) + hv_ring_buffer_read_begin(&chan->inbound); + taskqueue_enqueue(chan->ch_tq, &chan->ch_task); } } } @@ -1038,7 +1036,7 @@ vmbus_chan_add(struct hv_vmbus_channel * } void -vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu) +vmbus_chan_cpu_set(struct hv_vmbus_channel *chan, int cpu) { KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu %d", cpu)); @@ -1058,13 +1056,13 @@ vmbus_channel_cpu_set(struct hv_vmbus_ch } void -vmbus_channel_cpu_rr(struct hv_vmbus_channel *chan) +vmbus_chan_cpu_rr(struct hv_vmbus_channel *chan) { static uint32_t vmbus_chan_nextcpu; int cpu; cpu = atomic_fetchadd_int(&vmbus_chan_nextcpu, 1) % mp_ncpus; - vmbus_channel_cpu_set(chan, cpu); + vmbus_chan_cpu_set(chan, cpu); } static void @@ -1073,9 +1071,9 @@ vmbus_chan_cpu_default(struct hv_vmbus_c /* * By default, pin the channel to cpu0. Devices having * special channel-cpu mapping requirement should call - * vmbus_channel_cpu_{set,rr}(). + * vmbus_chan_cpu_{set,rr}(). */ - vmbus_channel_cpu_set(chan, 0); + vmbus_chan_cpu_set(chan, 0); } static void @@ -1251,65 +1249,67 @@ vmbus_chan_destroy_all(struct vmbus_soft mtx_unlock(&sc->vmbus_prichan_lock); } -/** - * @brief Select the best outgoing channel - * +/* * The channel whose vcpu binding is closest to the currect vcpu will * be selected. - * If no multi-channel, always select primary channel - * - * @param primary - primary channel + * If no multi-channel, always select primary channel. */ struct hv_vmbus_channel * -vmbus_select_outgoing_channel(struct hv_vmbus_channel *primary) +vmbus_chan_cpu2chan(struct hv_vmbus_channel *prichan, int cpu) { - hv_vmbus_channel *new_channel = NULL; - hv_vmbus_channel *outgoing_channel = primary; - int old_cpu_distance = 0; - int new_cpu_distance = 0; - int cur_vcpu = 0; - int smp_pro_id = PCPU_GET(cpuid); + struct hv_vmbus_channel *sel, *chan; + uint32_t vcpu, sel_dist; - if (TAILQ_EMPTY(&primary->ch_subchans)) { - return outgoing_channel; - } + KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpuid %d", cpu)); + if (TAILQ_EMPTY(&prichan->ch_subchans)) + return prichan; - if (smp_pro_id >= MAXCPU) { - return outgoing_channel; - } + vcpu = VMBUS_PCPU_GET(prichan->vmbus_sc, vcpuid, cpu); - cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); - - /* XXX need lock */ - TAILQ_FOREACH(new_channel, &primary->ch_subchans, ch_sublink) { - if ((new_channel->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0) { - continue; - } +#define CHAN_VCPU_DIST(ch, vcpu) \ + (((ch)->ch_vcpuid > (vcpu)) ? \ + ((ch)->ch_vcpuid - (vcpu)) : ((vcpu) - (ch)->ch_vcpuid)) - if (new_channel->ch_vcpuid == cur_vcpu){ - return new_channel; - } +#define CHAN_SELECT(ch) \ +do { \ + sel = ch; \ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Wed Oct 12 02:55:25 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AE140C0E0F1; Wed, 12 Oct 2016 02:55:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 75CA627B; Wed, 12 Oct 2016 02:55:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C2tOic057045; Wed, 12 Oct 2016 02:55:24 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C2tOwe057041; Wed, 12 Oct 2016 02:55:24 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120255.u9C2tOwe057041@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 02:55:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307086 - in stable/10/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 02:55:25 -0000 Author: sephe Date: Wed Oct 12 02:55:24 2016 New Revision: 307086 URL: https://svnweb.freebsd.org/changeset/base/307086 Log: MFC 303023 hyperv/vmbus: Rename laundered vmbus channel code Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7232 Added: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c - copied unchanged from r303023, head/sys/dev/hyperv/vmbus/vmbus_chan.c Deleted: stable/10/sys/dev/hyperv/vmbus/hv_channel.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Wed Oct 12 02:47:31 2016 (r307085) +++ stable/10/sys/conf/files.amd64 Wed Oct 12 02:55:24 2016 (r307086) @@ -271,11 +271,11 @@ dev/hyperv/utilities/hv_kvp.c optiona dev/hyperv/utilities/hv_shutdown.c optional hyperv dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv -dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv +dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Wed Oct 12 02:47:31 2016 (r307085) +++ stable/10/sys/conf/files.i386 Wed Oct 12 02:55:24 2016 (r307086) @@ -248,11 +248,11 @@ dev/hyperv/utilities/hv_kvp.c optiona dev/hyperv/utilities/hv_shutdown.c optional hyperv dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv -dev/hyperv/vmbus/hv_channel.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv +dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv Copied: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c (from r303023, head/sys/dev/hyperv/vmbus/vmbus_chan.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 02:55:24 2016 (r307086, copy of r303023, head/sys/dev/hyperv/vmbus/vmbus_chan.c) @@ -0,0 +1,1380 @@ +/*- + * Copyright (c) 2009-2012,2016 Microsoft Corp. + * Copyright (c) 2012 NetApp Inc. + * Copyright (c) 2012 Citrix Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void vmbus_chan_signal_tx(struct hv_vmbus_channel *chan); +static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, + const struct hv_vmbus_channel *); + +static void vmbus_chan_task(void *, int); +static void vmbus_chan_task_nobatch(void *, int); +static void vmbus_chan_detach_task(void *, int); + +static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, + const struct vmbus_message *); + +/* + * Vmbus channel message processing. + */ +static const vmbus_chanmsg_proc_t +vmbus_chan_msgprocs[VMBUS_CHANMSG_TYPE_MAX] = { + VMBUS_CHANMSG_PROC(CHOFFER, vmbus_chan_msgproc_choffer), + VMBUS_CHANMSG_PROC(CHRESCIND, vmbus_chan_msgproc_chrescind), + + VMBUS_CHANMSG_PROC_WAKEUP(CHOPEN_RESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_CONNRESP), + VMBUS_CHANMSG_PROC_WAKEUP(GPADL_DISCONNRESP) +}; + +/** + * @brief Trigger an event notification on the specified channel + */ +static void +vmbus_chan_signal_tx(struct hv_vmbus_channel *chan) +{ + struct vmbus_softc *sc = chan->vmbus_sc; + uint32_t chanid = chan->ch_id; + + atomic_set_long(&sc->vmbus_tx_evtflags[chanid >> VMBUS_EVTFLAG_SHIFT], + 1UL << (chanid & VMBUS_EVTFLAG_MASK)); + + if (chan->ch_flags & VMBUS_CHAN_FLAG_HASMNF) { + atomic_set_int( + &sc->vmbus_mnf2->mnf_trigs[chan->ch_montrig_idx].mt_pending, + chan->ch_montrig_mask); + } else { + hypercall_signal_event(chan->ch_monprm_dma.hv_paddr); + } +} + +static int +vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS) +{ + struct hv_vmbus_channel *chan = arg1; + int mnf = 0; + + if (chan->ch_flags & VMBUS_CHAN_FLAG_HASMNF) + mnf = 1; + return sysctl_handle_int(oidp, &mnf, 0, req); +} + +static void +vmbus_chan_sysctl_create(struct hv_vmbus_channel *chan) +{ + struct sysctl_oid *ch_tree, *chid_tree, *br_tree; + struct sysctl_ctx_list *ctx; + uint32_t ch_id; + char name[16]; + + /* + * Add sysctl nodes related to this channel to this + * channel's sysctl ctx, so that they can be destroyed + * independently upon close of this channel, which can + * happen even if the device is not detached. + */ + ctx = &chan->ch_sysctl_ctx; + sysctl_ctx_init(ctx); + + /* + * Create dev.NAME.UNIT.channel tree. + */ + ch_tree = SYSCTL_ADD_NODE(ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(chan->ch_dev)), + OID_AUTO, "channel", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (ch_tree == NULL) + return; + + /* + * Create dev.NAME.UNIT.channel.CHANID tree. + */ + if (VMBUS_CHAN_ISPRIMARY(chan)) + ch_id = chan->ch_id; + else + ch_id = chan->ch_prichan->ch_id; + snprintf(name, sizeof(name), "%d", ch_id); + chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree), + OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (chid_tree == NULL) + return; + + if (!VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * Create dev.NAME.UNIT.channel.CHANID.sub tree. + */ + ch_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), + OID_AUTO, "sub", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (ch_tree == NULL) + return; + + /* + * Create dev.NAME.UNIT.channel.CHANID.sub.SUBIDX tree. + * + * NOTE: + * chid_tree is changed to this new sysctl tree. + */ + snprintf(name, sizeof(name), "%d", chan->ch_subidx); + chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree), + OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (chid_tree == NULL) + return; + + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "chanid", CTLFLAG_RD, &chan->ch_id, 0, "channel id"); + } + + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "cpu", CTLFLAG_RD, &chan->ch_cpuid, 0, "owner CPU id"); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "mnf", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, + chan, 0, vmbus_chan_sysctl_mnf, "I", + "has monitor notification facilities"); + + /* + * Create sysctl tree for RX bufring. + */ + br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "in", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (br_tree != NULL) { + hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), + &chan->inbound, "inbound ring buffer stats"); + } + + /* + * Create sysctl tree for TX bufring. + */ + br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "out", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (br_tree != NULL) { + hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), + &chan->outbound, "outbound ring buffer stats"); + } +} + +int +vmbus_chan_open(struct hv_vmbus_channel *chan, int txbr_size, int rxbr_size, + const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg) +{ + struct vmbus_softc *sc = chan->vmbus_sc; + const struct vmbus_chanmsg_chopen_resp *resp; + const struct vmbus_message *msg; + struct vmbus_chanmsg_chopen *req; + struct vmbus_msghc *mh; + uint32_t status; + int error; + uint8_t *br; + + if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { + device_printf(sc->vmbus_dev, + "invalid udata len %d for chan%u\n", udlen, chan->ch_id); + return EINVAL; + } + KASSERT((txbr_size & PAGE_MASK) == 0, + ("send bufring size is not multiple page")); + KASSERT((rxbr_size & PAGE_MASK) == 0, + ("recv bufring size is not multiple page")); + + if (atomic_testandset_int(&chan->ch_stflags, + VMBUS_CHAN_ST_OPENED_SHIFT)) + panic("double-open chan%u", chan->ch_id); + + chan->ch_cb = cb; + chan->ch_cbarg = cbarg; + + vmbus_chan_update_evtflagcnt(sc, chan); + + chan->ch_tq = VMBUS_PCPU_GET(chan->vmbus_sc, event_tq, chan->ch_cpuid); + if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) + TASK_INIT(&chan->ch_task, 0, vmbus_chan_task, chan); + else + TASK_INIT(&chan->ch_task, 0, vmbus_chan_task_nobatch, chan); + + /* + * Allocate the TX+RX bufrings. + * XXX should use ch_dev dtag + */ + br = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, + BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (br == NULL) { + device_printf(sc->vmbus_dev, "bufring allocation failed\n"); + error = ENOMEM; + goto failed; + } + chan->ch_bufring = br; + + /* TX bufring comes first */ + hv_vmbus_ring_buffer_init(&chan->outbound, br, txbr_size); + /* RX bufring immediately follows TX bufring */ + hv_vmbus_ring_buffer_init(&chan->inbound, br + txbr_size, rxbr_size); + + /* Create sysctl tree for this channel */ + vmbus_chan_sysctl_create(chan); + + /* + * Connect the bufrings, both RX and TX, to this channel. + */ + error = vmbus_chan_gpadl_connect(chan, chan->ch_bufring_dma.hv_paddr, + txbr_size + rxbr_size, &chan->ch_bufring_gpadl); + if (error) { + device_printf(sc->vmbus_dev, + "failed to connect bufring GPADL to chan%u\n", chan->ch_id); + goto failed; + } + + /* + * Open channel w/ the bufring GPADL on the target CPU. + */ + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chopen(chan%u)\n", + chan->ch_id); + error = ENXIO; + goto failed; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; + req->chm_chanid = chan->ch_id; + req->chm_openid = chan->ch_id; + req->chm_gpadl = chan->ch_bufring_gpadl; + req->chm_vcpuid = chan->ch_vcpuid; + req->chm_txbr_pgcnt = txbr_size >> PAGE_SHIFT; + if (udlen > 0) + memcpy(req->chm_udata, udata, udlen); + + error = vmbus_msghc_exec(sc, mh); + if (error) { + device_printf(sc->vmbus_dev, + "chopen(chan%u) msg hypercall exec failed: %d\n", + chan->ch_id, error); + vmbus_msghc_put(sc, mh); + goto failed; + } + + msg = vmbus_msghc_wait_result(sc, mh); + resp = (const struct vmbus_chanmsg_chopen_resp *)msg->msg_data; + status = resp->chm_status; + + vmbus_msghc_put(sc, mh); + + if (status == 0) { + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u opened\n", + chan->ch_id); + } + return 0; + } + + device_printf(sc->vmbus_dev, "failed to open chan%u\n", chan->ch_id); + error = ENXIO; + +failed: + if (chan->ch_bufring_gpadl) { + vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); + chan->ch_bufring_gpadl = 0; + } + if (chan->ch_bufring != NULL) { + hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); + chan->ch_bufring = NULL; + } + atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); + return error; +} + +int +vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, bus_addr_t paddr, + int size, uint32_t *gpadl0) +{ + struct vmbus_softc *sc = chan->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_gpadl_conn *req; + const struct vmbus_message *msg; + size_t reqsz; + uint32_t gpadl, status; + int page_count, range_len, i, cnt, error; + uint64_t page_id; + + /* + * Preliminary checks. + */ + + KASSERT((size & PAGE_MASK) == 0, + ("invalid GPA size %d, not multiple page size", size)); + page_count = size >> PAGE_SHIFT; + + KASSERT((paddr & PAGE_MASK) == 0, + ("GPA is not page aligned %jx", (uintmax_t)paddr)); + page_id = paddr >> PAGE_SHIFT; + + range_len = __offsetof(struct vmbus_gpa_range, gpa_page[page_count]); + /* + * We don't support multiple GPA ranges. + */ + if (range_len > UINT16_MAX) { + device_printf(sc->vmbus_dev, "GPA too large, %d pages\n", + page_count); + return EOPNOTSUPP; + } + + /* + * Allocate GPADL id. + */ + gpadl = vmbus_gpadl_alloc(sc); + *gpadl0 = gpadl; + + /* + * Connect this GPADL to the target channel. + * + * NOTE: + * Since each message can only hold small set of page + * addresses, several messages may be required to + * complete the connection. + */ + if (page_count > VMBUS_CHANMSG_GPADL_CONN_PGMAX) + cnt = VMBUS_CHANMSG_GPADL_CONN_PGMAX; + else + cnt = page_count; + page_count -= cnt; + + reqsz = __offsetof(struct vmbus_chanmsg_gpadl_conn, + chm_range.gpa_page[cnt]); + mh = vmbus_msghc_get(sc, reqsz); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for gpadl->chan%u\n", + chan->ch_id); + return EIO; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_CONN; + req->chm_chanid = chan->ch_id; + req->chm_gpadl = gpadl; + req->chm_range_len = range_len; + req->chm_range_cnt = 1; + req->chm_range.gpa_len = size; + req->chm_range.gpa_ofs = 0; + for (i = 0; i < cnt; ++i) + req->chm_range.gpa_page[i] = page_id++; + + error = vmbus_msghc_exec(sc, mh); + if (error) { + device_printf(sc->vmbus_dev, + "gpadl->chan%u msg hypercall exec failed: %d\n", + chan->ch_id, error); + vmbus_msghc_put(sc, mh); + return error; + } + + while (page_count > 0) { + struct vmbus_chanmsg_gpadl_subconn *subreq; + + if (page_count > VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX) + cnt = VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX; + else + cnt = page_count; + page_count -= cnt; + + reqsz = __offsetof(struct vmbus_chanmsg_gpadl_subconn, + chm_gpa_page[cnt]); + vmbus_msghc_reset(mh, reqsz); + + subreq = vmbus_msghc_dataptr(mh); + subreq->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_SUBCONN; + subreq->chm_gpadl = gpadl; + for (i = 0; i < cnt; ++i) + subreq->chm_gpa_page[i] = page_id++; + + vmbus_msghc_exec_noresult(mh); + } + KASSERT(page_count == 0, ("invalid page count %d", page_count)); + + msg = vmbus_msghc_wait_result(sc, mh); + status = ((const struct vmbus_chanmsg_gpadl_connresp *) + msg->msg_data)->chm_status; + + vmbus_msghc_put(sc, mh); + + if (status != 0) { + device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " + "status %u\n", chan->ch_id, status); + return EIO; + } else { + if (bootverbose) { + device_printf(sc->vmbus_dev, "gpadl->chan%u " + "succeeded\n", chan->ch_id); + } + } + return 0; +} + +/* + * Disconnect the GPA from the target channel + */ +int +vmbus_chan_gpadl_disconnect(struct hv_vmbus_channel *chan, uint32_t gpadl) +{ + struct vmbus_softc *sc = chan->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_gpadl_disconn *req; + int error; + + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for gpa x->chan%u\n", + chan->ch_id); + return EBUSY; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_DISCONN; + req->chm_chanid = chan->ch_id; + req->chm_gpadl = gpadl; + + error = vmbus_msghc_exec(sc, mh); + if (error) { + device_printf(sc->vmbus_dev, + "gpa x->chan%u msg hypercall exec failed: %d\n", + chan->ch_id, error); + vmbus_msghc_put(sc, mh); + return error; + } + + vmbus_msghc_wait_result(sc, mh); + /* Discard result; no useful information */ + vmbus_msghc_put(sc, mh); + + return 0; +} + +static void +vmbus_chan_close_internal(struct hv_vmbus_channel *chan) +{ + struct vmbus_softc *sc = chan->vmbus_sc; + struct vmbus_msghc *mh; + struct vmbus_chanmsg_chclose *req; + struct taskqueue *tq = chan->ch_tq; + int error; + + /* TODO: stringent check */ + atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); + + /* + * Free this channel's sysctl tree attached to its device's + * sysctl tree. + */ + sysctl_ctx_free(&chan->ch_sysctl_ctx); + + /* + * Set ch_tq to NULL to avoid more requests be scheduled. + * XXX pretty broken; need rework. + */ + chan->ch_tq = NULL; + taskqueue_drain(tq, &chan->ch_task); + chan->ch_cb = NULL; + + /* + * Close this channel. + */ + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chclose(chan%u)\n", + chan->ch_id); + return; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHCLOSE; + req->chm_chanid = chan->ch_id; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, + "chclose(chan%u) msg hypercall exec failed: %d\n", + chan->ch_id, error); + return; + } else if (bootverbose) { + device_printf(sc->vmbus_dev, "close chan%u\n", chan->ch_id); + } + + /* + * Disconnect the TX+RX bufrings from this channel. + */ + if (chan->ch_bufring_gpadl) { + vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); + chan->ch_bufring_gpadl = 0; + } + + /* + * Destroy the TX+RX bufrings. + */ + hv_ring_buffer_cleanup(&chan->outbound); + hv_ring_buffer_cleanup(&chan->inbound); + if (chan->ch_bufring != NULL) { + hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); + chan->ch_bufring = NULL; + } +} + +/* + * Caller should make sure that all sub-channels have + * been added to 'chan' and all to-be-closed channels + * are not being opened. + */ +void +vmbus_chan_close(struct hv_vmbus_channel *chan) +{ + int subchan_cnt; + + if (!VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * Sub-channel is closed when its primary channel + * is closed; done. + */ + return; + } + + /* + * Close all sub-channels, if any. + */ + subchan_cnt = chan->ch_subchan_cnt; + if (subchan_cnt > 0) { + struct hv_vmbus_channel **subchan; + int i; + + subchan = vmbus_subchan_get(chan, subchan_cnt); + for (i = 0; i < subchan_cnt; ++i) + vmbus_chan_close_internal(subchan[i]); + vmbus_subchan_rel(subchan, subchan_cnt); + } + + /* Then close the primary channel. */ + vmbus_chan_close_internal(chan); +} + +int +vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type, uint16_t flags, + void *data, int dlen, uint64_t xactid) +{ + struct vmbus_chanpkt pkt; + int pktlen, pad_pktlen, hlen, error; + uint64_t pad = 0; + struct iovec iov[3]; + boolean_t send_evt; + + hlen = sizeof(pkt); + pktlen = hlen + dlen; + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + + pkt.cp_hdr.cph_type = type; + pkt.cp_hdr.cph_flags = flags; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); + pkt.cp_hdr.cph_xactid = xactid; + + iov[0].iov_base = &pkt; + iov[0].iov_len = hlen; + iov[1].iov_base = data; + iov[1].iov_len = dlen; + iov[2].iov_base = &pad; + iov[2].iov_len = pad_pktlen - pktlen; + + error = hv_ring_buffer_write(&chan->outbound, iov, 3, &send_evt); + if (!error && send_evt) + vmbus_chan_signal_tx(chan); + return error; +} + +int +vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, + struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid) +{ + struct vmbus_chanpkt_sglist pkt; + int pktlen, pad_pktlen, hlen, error; + struct iovec iov[4]; + boolean_t send_evt; + uint64_t pad = 0; + + KASSERT(sglen < VMBUS_CHAN_SGLIST_MAX, + ("invalid sglist len %d", sglen)); + + hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]); + pktlen = hlen + dlen; + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + + pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; + pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); + pkt.cp_hdr.cph_xactid = xactid; + pkt.cp_rsvd = 0; + pkt.cp_gpa_cnt = sglen; + + iov[0].iov_base = &pkt; + iov[0].iov_len = sizeof(pkt); + iov[1].iov_base = sg; + iov[1].iov_len = sizeof(struct vmbus_gpa) * sglen; + iov[2].iov_base = data; + iov[2].iov_len = dlen; + iov[3].iov_base = &pad; + iov[3].iov_len = pad_pktlen - pktlen; + + error = hv_ring_buffer_write(&chan->outbound, iov, 4, &send_evt); + if (!error && send_evt) + vmbus_chan_signal_tx(chan); + return error; +} + +int +vmbus_chan_send_prplist(struct hv_vmbus_channel *chan, + struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen, + uint64_t xactid) +{ + struct vmbus_chanpkt_prplist pkt; + int pktlen, pad_pktlen, hlen, error; + struct iovec iov[4]; + boolean_t send_evt; + uint64_t pad = 0; + + KASSERT(prp_cnt < VMBUS_CHAN_PRPLIST_MAX, + ("invalid prplist entry count %d", prp_cnt)); + + hlen = __offsetof(struct vmbus_chanpkt_prplist, + cp_range[0].gpa_page[prp_cnt]); + pktlen = hlen + dlen; + pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + + pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; + pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen); + VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen); + pkt.cp_hdr.cph_xactid = xactid; + pkt.cp_rsvd = 0; + pkt.cp_range_cnt = 1; + + iov[0].iov_base = &pkt; + iov[0].iov_len = sizeof(pkt); + iov[1].iov_base = prp; + iov[1].iov_len = __offsetof(struct vmbus_gpa_range, gpa_page[prp_cnt]); + iov[2].iov_base = data; + iov[2].iov_len = dlen; + iov[3].iov_base = &pad; + iov[3].iov_len = pad_pktlen - pktlen; + + error = hv_ring_buffer_write(&chan->outbound, iov, 4, &send_evt); + if (!error && send_evt) + vmbus_chan_signal_tx(chan); + return error; +} + +int +vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen0, + uint64_t *xactid) +{ + struct vmbus_chanpkt_hdr pkt; + int error, dlen, hlen; + + error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt)); + if (error) + return error; + + hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen); + dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen; + + if (*dlen0 < dlen) { + /* Return the size of this packet's data. */ + *dlen0 = dlen; + return ENOBUFS; + } + + *xactid = pkt.cph_xactid; + *dlen0 = dlen; + + /* Skip packet header */ + error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen); + KASSERT(!error, ("hv_ring_buffer_read failed")); + + return 0; +} + +int +vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan, + struct vmbus_chanpkt_hdr *pkt0, int *pktlen0) +{ + struct vmbus_chanpkt_hdr pkt; + int error, pktlen; + + error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt)); + if (error) + return error; + + pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen); + if (*pktlen0 < pktlen) { + /* Return the size of this packet. */ + *pktlen0 = pktlen; + return ENOBUFS; + } + *pktlen0 = pktlen; + + /* Include packet header */ + error = hv_ring_buffer_read(&chan->inbound, pkt0, pktlen, 0); + KASSERT(!error, ("hv_ring_buffer_read failed")); + + return 0; +} + +static void +vmbus_chan_task(void *xchan, int pending __unused) +{ + struct hv_vmbus_channel *chan = xchan; + vmbus_chan_callback_t cb = chan->ch_cb; + void *cbarg = chan->ch_cbarg; + + /* + * Optimize host to guest signaling by ensuring: + * 1. While reading the channel, we disable interrupts from + * host. + * 2. Ensure that we process all posted messages from the host + * before returning from this callback. + * 3. Once we return, enable signaling from the host. Once this + * state is set we check to see if additional packets are + * available to read. In this case we repeat the process. + * + * NOTE: Interrupt has been disabled in the ISR. + */ + for (;;) { + uint32_t left; + + cb(cbarg); + + left = hv_ring_buffer_read_end(&chan->inbound); + if (left == 0) { + /* No more data in RX bufring; done */ + break; + } + hv_ring_buffer_read_begin(&chan->inbound); + } +} + +static void +vmbus_chan_task_nobatch(void *xchan, int pending __unused) +{ + struct hv_vmbus_channel *chan = xchan; + + chan->ch_cb(chan->ch_cbarg); +} + +static __inline void +vmbus_event_flags_proc(struct vmbus_softc *sc, volatile u_long *event_flags, + int flag_cnt) +{ + int f; + + for (f = 0; f < flag_cnt; ++f) { + uint32_t chid_base; + u_long flags; + int chid_ofs; + + if (event_flags[f] == 0) + continue; + + flags = atomic_swap_long(&event_flags[f], 0); + chid_base = f << VMBUS_EVTFLAG_SHIFT; + + while ((chid_ofs = ffsl(flags)) != 0) { + struct hv_vmbus_channel *chan; + + --chid_ofs; /* NOTE: ffsl is 1-based */ + flags &= ~(1UL << chid_ofs); + + chan = sc->vmbus_chmap[chid_base + chid_ofs]; + + /* if channel is closed or closing */ + if (chan == NULL || chan->ch_tq == NULL) + continue; + + if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) + hv_ring_buffer_read_begin(&chan->inbound); + taskqueue_enqueue(chan->ch_tq, &chan->ch_task); + } + } +} + +void +vmbus_event_proc(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + /* + * On Host with Win8 or above, the event page can be checked directly + * to get the id of the channel that has the pending interrupt. + */ + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + vmbus_event_flags_proc(sc, eventf->evt_flags, + VMBUS_PCPU_GET(sc, event_flags_cnt, cpu)); +} + +void +vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu) +{ + struct vmbus_evtflags *eventf; + + eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE; + if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) { + vmbus_event_flags_proc(sc, sc->vmbus_rx_evtflags, + VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT); + } +} + +static void +vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc, + const struct hv_vmbus_channel *chan) +{ + volatile int *flag_cnt_ptr; + int flag_cnt; + + flag_cnt = (chan->ch_id / VMBUS_EVTFLAG_LEN) + 1; + flag_cnt_ptr = VMBUS_PCPU_PTR(sc, event_flags_cnt, chan->ch_cpuid); + + for (;;) { + int old_flag_cnt; + + old_flag_cnt = *flag_cnt_ptr; + if (old_flag_cnt >= flag_cnt) + break; + if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) { + if (bootverbose) { + device_printf(sc->vmbus_dev, + "channel%u update cpu%d flag_cnt to %d\n", + chan->ch_id, chan->ch_cpuid, flag_cnt); + } + break; + } + } +} + +static struct hv_vmbus_channel * +vmbus_chan_alloc(struct vmbus_softc *sc) +{ + struct hv_vmbus_channel *chan; + + chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO); + + chan->ch_monprm = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), + &chan->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (chan->ch_monprm == NULL) { + device_printf(sc->vmbus_dev, "monprm alloc failed\n"); + free(chan, M_DEVBUF); + return NULL; + } + + chan->vmbus_sc = sc; + mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); + TAILQ_INIT(&chan->ch_subchans); + TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); + + return chan; +} + +static void +vmbus_chan_free(struct hv_vmbus_channel *chan) +{ + /* TODO: assert sub-channel list is empty */ + /* TODO: asset no longer on the primary channel's sub-channel list */ + /* TODO: asset no longer on the vmbus channel list */ + hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); + mtx_destroy(&chan->ch_subchan_lock); + free(chan, M_DEVBUF); +} + +static int +vmbus_chan_add(struct hv_vmbus_channel *newchan) +{ + struct vmbus_softc *sc = newchan->vmbus_sc; + struct hv_vmbus_channel *prichan; + + if (newchan->ch_id == 0) { + /* + * XXX + * Chan0 will neither be processed nor should be offered; + * skip it. + */ + device_printf(sc->vmbus_dev, "got chan0 offer, discard\n"); + return EINVAL; + } else if (newchan->ch_id >= VMBUS_CHAN_MAX) { + device_printf(sc->vmbus_dev, "invalid chan%u offer\n", + newchan->ch_id); + return EINVAL; + } + sc->vmbus_chmap[newchan->ch_id] = newchan; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Wed Oct 12 03:18:19 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C1888C0EA63; Wed, 12 Oct 2016 03:18:19 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4E0867D; Wed, 12 Oct 2016 03:18:19 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C3IIWX065882; Wed, 12 Oct 2016 03:18:18 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C3IHMQ065873; Wed, 12 Oct 2016 03:18:17 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120318.u9C3IHMQ065873@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 03:18:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307096 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 03:18:19 -0000 Author: sephe Date: Wed Oct 12 03:18:17 2016 New Revision: 307096 URL: https://svnweb.freebsd.org/changeset/base/307096 Log: MFC 303066-303072,303127-303129,303131 303066 hyperv/vmbus: Get rid of unnecessary definition. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7240 303067 hyperv/vmbus: Move IC register definition to Hyper-V utilities Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7241 303068 hyperv/vmbus: Channel struct field rename Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7242 303069 hyperv/vmbus: Pass channel as the first argument for channel callback The prepares to kill device private fields in channel struct, which are not flexible and extensible. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7243 303070 hyperv/vmbus: Deprecate the device private data in channel struct They are neither flexible nor extensible. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7244 303071 hyperv/vmbus: Hide channel struct definition. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7245 303072 hyperv/vmbus: Save MNF trigger location instead of MNF trigger index. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7246 303127 hyperv/vmbus: Save event flag location and evet flag mask. This avoids unnecessary access to the vmbus_softc struct on sending path. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7257 303128 hyperv/vmbus: Reorder channel fields. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7258 303129 hyperv/vmbus: Shuffle function declaration and macro definition. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7259 303131 hyperv: hv_vmbus_channel -> vmbus_channel Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7260 Added: stable/10/sys/dev/hyperv/utilities/hv_utilreg.h - copied unchanged from r303067, head/sys/dev/hyperv/utilities/hv_utilreg.h stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h - copied, changed from r303071, head/sys/dev/hyperv/vmbus/vmbus_chanvar.h Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 03:18:17 2016 (r307096) @@ -58,30 +58,6 @@ #include #include -typedef uint8_t hv_bool_uint8_t; - -#define HV_S_OK 0x00000000 -#define HV_E_FAIL 0x80004005 -#define HV_ERROR_NOT_SUPPORTED 0x80070032 -#define HV_ERROR_MACHINE_LOCKED 0x800704F7 - -/* - * VMBUS version is 32 bit, upper 16 bit for major_number and lower - * 16 bit for minor_number. - * - * 0.13 -- Windows Server 2008 - * 1.1 -- Windows 7 - * 2.4 -- Windows 8 - * 3.0 -- Windows 8.1 - */ -#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) -#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) -#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) -#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) - -#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) -#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) - struct hyperv_guid { uint8_t hv_guid[16]; } __packed; @@ -90,183 +66,6 @@ struct hyperv_guid { int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); -#define HW_MACADDR_LEN 6 - -/* - * Common defines for Hyper-V ICs - */ -#define HV_ICMSGTYPE_NEGOTIATE 0 -#define HV_ICMSGTYPE_HEARTBEAT 1 -#define HV_ICMSGTYPE_KVPEXCHANGE 2 -#define HV_ICMSGTYPE_SHUTDOWN 3 -#define HV_ICMSGTYPE_TIMESYNC 4 -#define HV_ICMSGTYPE_VSS 5 - -#define HV_ICMSGHDRFLAG_TRANSACTION 1 -#define HV_ICMSGHDRFLAG_REQUEST 2 -#define HV_ICMSGHDRFLAG_RESPONSE 4 - -typedef struct hv_vmbus_pipe_hdr { - uint32_t flags; - uint32_t msgsize; -} __packed hv_vmbus_pipe_hdr; - -typedef struct hv_vmbus_ic_version { - uint16_t major; - uint16_t minor; -} __packed hv_vmbus_ic_version; - -typedef struct hv_vmbus_icmsg_hdr { - hv_vmbus_ic_version icverframe; - uint16_t icmsgtype; - hv_vmbus_ic_version icvermsg; - uint16_t icmsgsize; - uint32_t status; - uint8_t ictransaction_id; - uint8_t icflags; - uint8_t reserved[2]; -} __packed hv_vmbus_icmsg_hdr; - -typedef struct hv_vmbus_icmsg_negotiate { - uint16_t icframe_vercnt; - uint16_t icmsg_vercnt; - uint32_t reserved; - hv_vmbus_ic_version icversion_data[1]; /* any size array */ -} __packed hv_vmbus_icmsg_negotiate; - -typedef struct hv_vmbus_shutdown_msg_data { - uint32_t reason_code; - uint32_t timeout_seconds; - uint32_t flags; - uint8_t display_message[2048]; -} __packed hv_vmbus_shutdown_msg_data; - -typedef struct hv_vmbus_heartbeat_msg_data { - uint64_t seq_num; - uint32_t reserved[8]; -} __packed hv_vmbus_heartbeat_msg_data; - -typedef struct { - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t write_index; - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t read_index; - /* - * NOTE: The interrupt_mask field is used only for channels, but - * vmbus connection also uses this data structure - */ - volatile uint32_t interrupt_mask; - /* pad it to PAGE_SIZE so that data starts on a page */ - uint8_t reserved[4084]; - - /* - * WARNING: Ring data starts here - * !!! DO NOT place any fields below this !!! - */ - uint8_t buffer[0]; /* doubles as interrupt mask */ -} __packed hv_vmbus_ring_buffer; - -typedef struct { - hv_vmbus_ring_buffer* ring_buffer; - struct mtx ring_lock; - uint32_t ring_data_size; /* ring_size */ -} hv_vmbus_ring_buffer_info; - -typedef void (*vmbus_chan_callback_t)(void *); - -typedef struct hv_vmbus_channel { - device_t ch_dev; - struct vmbus_softc *vmbus_sc; - uint32_t ch_flags; /* VMBUS_CHAN_FLAG_ */ - uint32_t ch_id; /* channel id */ - - /* - * These are based on the offer_msg.monitor_id. - * Save it here for easy access. - */ - int ch_montrig_idx; /* MNF trig index */ - uint32_t ch_montrig_mask;/* MNF trig mask */ - - /* - * send to parent - */ - hv_vmbus_ring_buffer_info outbound; - /* - * receive from parent - */ - hv_vmbus_ring_buffer_info inbound; - - struct taskqueue *ch_tq; - struct task ch_task; - vmbus_chan_callback_t ch_cb; - void *ch_cbarg; - - struct hyperv_mon_param *ch_monprm; - struct hyperv_dma ch_monprm_dma; - - int ch_cpuid; /* owner cpu */ - /* - * Virtual cpuid for ch_cpuid; it is used to communicate cpuid - * related information w/ Hyper-V. If MSR_HV_VP_INDEX does not - * exist, ch_vcpuid will always be 0 for compatibility. - */ - uint32_t ch_vcpuid; - - /* - * If this is a primary channel, ch_subchan* fields - * contain sub-channels belonging to this primary - * channel. - */ - struct mtx ch_subchan_lock; - TAILQ_HEAD(, hv_vmbus_channel) ch_subchans; - int ch_subchan_cnt; - - /* If this is a sub-channel */ - TAILQ_ENTRY(hv_vmbus_channel) ch_sublink; /* sub-channel link */ - struct hv_vmbus_channel *ch_prichan; /* owner primary chan */ - - /* - * Driver private data - */ - void *hv_chan_priv1; - void *hv_chan_priv2; - void *hv_chan_priv3; - - void *ch_bufring; /* TX+RX bufrings */ - struct hyperv_dma ch_bufring_dma; - uint32_t ch_bufring_gpadl; - - struct task ch_detach_task; - TAILQ_ENTRY(hv_vmbus_channel) ch_prilink; /* primary chan link */ - uint32_t ch_subidx; /* subchan index */ - volatile uint32_t ch_stflags; /* atomic-op */ - /* VMBUS_CHAN_ST_ */ - struct hyperv_guid ch_guid_type; - struct hyperv_guid ch_guid_inst; - - struct sysctl_ctx_list ch_sysctl_ctx; -} hv_vmbus_channel; - -#define VMBUS_CHAN_ISPRIMARY(chan) ((chan)->ch_subidx == 0) - -#define VMBUS_CHAN_FLAG_HASMNF 0x0001 -/* - * If this flag is set, this channel's interrupt will be masked in ISR, - * and the RX bufring will be drained before this channel's interrupt is - * unmasked. - * - * This flag is turned on by default. Drivers can turn it off according - * to their own requirement. - */ -#define VMBUS_CHAN_FLAG_BATCHREAD 0x0002 - -#define VMBUS_CHAN_ST_OPENED_SHIFT 0 -#define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) - /** * @brief Get physical address from virtual */ @@ -278,10 +77,4 @@ hv_get_phys_addr(void *virt) return (ret); } -static __inline struct hv_vmbus_channel * -vmbus_get_channel(device_t dev) -{ - return device_get_ivars(dev); -} - #endif /* __HYPERV_H__ */ Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 03:18:17 2016 (r307096) @@ -32,6 +32,23 @@ #include /* + * VMBUS version is 32 bit, upper 16 bit for major_number and lower + * 16 bit for minor_number. + * + * 0.13 -- Windows Server 2008 + * 1.1 -- Windows 7 + * 2.4 -- Windows 8 + * 3.0 -- Windows 8.1 + */ +#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) +#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) +#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) +#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) + +#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) +#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) + +/* * GPA stuffs. */ struct vmbus_gpa_range { @@ -87,41 +104,56 @@ struct vmbus_chanpkt_rxbuf { #define VMBUS_CHAN_SGLIST_MAX 32 #define VMBUS_CHAN_PRPLIST_MAX 32 -struct hv_vmbus_channel; +struct vmbus_channel; +struct hyperv_guid; -int vmbus_chan_open(struct hv_vmbus_channel *chan, +typedef void (*vmbus_chan_callback_t)(struct vmbus_channel *, void *); + +static __inline struct vmbus_channel * +vmbus_get_channel(device_t dev) +{ + return device_get_ivars(dev); +} + +int vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size, const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg); -void vmbus_chan_close(struct hv_vmbus_channel *chan); +void vmbus_chan_close(struct vmbus_channel *chan); -int vmbus_chan_gpadl_connect(struct hv_vmbus_channel *chan, +int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, int size, uint32_t *gpadl); -int vmbus_chan_gpadl_disconnect(struct hv_vmbus_channel *chan, +int vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl); -void vmbus_chan_cpu_set(struct hv_vmbus_channel *chan, int cpu); -void vmbus_chan_cpu_rr(struct hv_vmbus_channel *chan); -struct hv_vmbus_channel * - vmbus_chan_cpu2chan(struct hv_vmbus_channel *chan, int cpu); -void vmbus_chan_set_readbatch(struct hv_vmbus_channel *chan, bool on); - -struct hv_vmbus_channel ** - vmbus_subchan_get(struct hv_vmbus_channel *pri_chan, int subchan_cnt); -void vmbus_subchan_rel(struct hv_vmbus_channel **subchan, int subchan_cnt); -void vmbus_subchan_drain(struct hv_vmbus_channel *pri_chan); +void vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu); +void vmbus_chan_cpu_rr(struct vmbus_channel *chan); +struct vmbus_channel * + vmbus_chan_cpu2chan(struct vmbus_channel *chan, int cpu); +void vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on); + +struct vmbus_channel ** + vmbus_subchan_get(struct vmbus_channel *pri_chan, int subchan_cnt); +void vmbus_subchan_rel(struct vmbus_channel **subchan, int subchan_cnt); +void vmbus_subchan_drain(struct vmbus_channel *pri_chan); -int vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen, +int vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen, uint64_t *xactid); -int vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan, +int vmbus_chan_recv_pkt(struct vmbus_channel *chan, struct vmbus_chanpkt_hdr *pkt, int *pktlen); -int vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type, +int vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, uint16_t flags, void *data, int dlen, uint64_t xactid); -int vmbus_chan_send_sglist(struct hv_vmbus_channel *chan, +int vmbus_chan_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid); -int vmbus_chan_send_prplist(struct hv_vmbus_channel *chan, +int vmbus_chan_send_prplist(struct vmbus_channel *chan, struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen, uint64_t xactid); +uint32_t vmbus_chan_id(const struct vmbus_channel *chan); +uint32_t vmbus_chan_subidx(const struct vmbus_channel *chan); +bool vmbus_chan_is_primary(const struct vmbus_channel *chan); +const struct hyperv_guid * + vmbus_chan_guid_inst(const struct vmbus_channel *chan); + #endif /* !_VMBUS_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 03:18:17 2016 (r307096) @@ -48,26 +48,24 @@ #include "hv_rndis.h" #include "hv_rndis_filter.h" -/* priv1 and priv2 are consumed by the main driver */ -#define hv_chan_rdbuf hv_chan_priv3 - MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); /* * Forward declarations */ -static void hv_nv_on_channel_callback(void *xchan); +static void hv_nv_on_channel_callback(struct vmbus_channel *chan, + void *xrxr); static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev); static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); static int hv_nv_connect_to_vsp(struct hn_softc *sc); static void hv_nv_on_send_completion(netvsc_dev *net_dev, - struct hv_vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); -static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, + struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); +static void hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid, uint32_t status); static void hv_nv_on_receive(netvsc_dev *net_dev, - struct hn_softc *sc, struct hv_vmbus_channel *chan, + struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt); /* @@ -640,13 +638,14 @@ hv_nv_disconnect_from_vsp(netvsc_dev *ne } void -hv_nv_subchan_attach(struct hv_vmbus_channel *chan) +hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr) { - - chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK); + KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), + ("chan%u subidx %u, rxr%d mismatch", + vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, - hv_nv_on_channel_callback, chan); + hv_nv_on_channel_callback, rxr); } /* @@ -655,9 +654,10 @@ hv_nv_subchan_attach(struct hv_vmbus_cha * Callback when the device belonging to this driver is added */ netvsc_dev * -hv_nv_on_device_add(struct hn_softc *sc, void *additional_info) +hv_nv_on_device_add(struct hn_softc *sc, void *additional_info, + struct hn_rx_ring *rxr) { - struct hv_vmbus_channel *chan = sc->hn_prichan; + struct vmbus_channel *chan = sc->hn_prichan; netvsc_dev *net_dev; int ret = 0; @@ -669,18 +669,17 @@ hv_nv_on_device_add(struct hn_softc *sc, sema_init(&net_dev->channel_init_sema, 0, "netdev_sema"); - chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK); - /* * Open the channel */ + KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), + ("chan%u subidx %u, rxr%d mismatch", + vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); ret = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, - NULL, 0, hv_nv_on_channel_callback, chan); - if (ret != 0) { - free(chan->hv_chan_rdbuf, M_NETVSC); + NULL, 0, hv_nv_on_channel_callback, rxr); + if (ret != 0) goto cleanup; - } /* * Connect with the NetVsp @@ -693,7 +692,6 @@ hv_nv_on_device_add(struct hn_softc *sc, close: /* Now, we can close the channel safely */ - free(chan->hv_chan_rdbuf, M_NETVSC); vmbus_chan_close(chan); cleanup: @@ -724,7 +722,6 @@ hv_nv_on_device_remove(struct hn_softc * /* Now, we can close the channel safely */ - free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC); vmbus_chan_close(sc->hn_prichan); sema_destroy(&net_dev->channel_init_sema); @@ -737,7 +734,7 @@ hv_nv_on_device_remove(struct hn_softc * * Net VSC on send completion */ static void -hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan, +hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt) { const nvsp_msg *nvsp_msg_pkt; @@ -801,7 +798,7 @@ hv_nv_on_send_completion(netvsc_dev *net * Returns 0 on success, non-zero on failure. */ int -hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt) +hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt) { nvsp_msg send_msg; int ret; @@ -839,14 +836,13 @@ hv_nv_on_send(struct hv_vmbus_channel *c * with virtual addresses. */ static void -hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc, - struct hv_vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) +hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, + struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) { const struct vmbus_chanpkt_rxbuf *pkt; const nvsp_msg *nvsp_msg_pkt; netvsc_packet vsc_pkt; netvsc_packet *net_vsc_pkt = &vsc_pkt; - device_t dev = sc->hn_dev; int count = 0; int i = 0; int status = nvsp_status_success; @@ -855,7 +851,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st /* Make sure this is a valid nvsp packet */ if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) { - device_printf(dev, "packet hdr type %u is invalid!\n", + if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n", nvsp_msg_pkt->hdr.msg_type); return; } @@ -863,7 +859,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) { - device_printf(dev, "rxbuf_id %d is invalid!\n", + if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n", pkt->cp_rxbuf_id); return; } @@ -877,7 +873,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st pkt->cp_rxbuf[i].rb_ofs); net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len; - hv_rf_on_receive(net_dev, chan, net_vsc_pkt); + hv_rf_on_receive(net_dev, rxr, net_vsc_pkt); if (net_vsc_pkt->status != nvsp_status_success) { status = nvsp_status_failure; } @@ -897,7 +893,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st * Send a receive completion packet to RNDIS device (ie NetVsp) */ static void -hv_nv_on_receive_completion(struct hv_vmbus_channel *chan, uint64_t tid, +hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid, uint32_t status) { nvsp_msg rx_comp_msg; @@ -972,11 +968,10 @@ hv_nv_send_table(struct hn_softc *sc, co * Net VSC on channel callback */ static void -hv_nv_on_channel_callback(void *xchan) +hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr) { - struct hv_vmbus_channel *chan = xchan; - device_t dev = chan->ch_dev; - struct hn_softc *sc = device_get_softc(dev); + struct hn_rx_ring *rxr = xrxr; + struct hn_softc *sc = rxr->hn_ifp->if_softc; netvsc_dev *net_dev; void *buffer; int bufferlen = NETVSC_PACKET_SIZE; @@ -985,7 +980,7 @@ hv_nv_on_channel_callback(void *xchan) if (net_dev == NULL) return; - buffer = chan->hv_chan_rdbuf; + buffer = rxr->hn_rdbuf; do { struct vmbus_chanpkt_hdr *pkt = buffer; uint32_t bytes_rxed; @@ -1001,13 +996,13 @@ hv_nv_on_channel_callback(void *xchan) pkt); break; case VMBUS_CHANPKT_TYPE_RXBUF: - hv_nv_on_receive(net_dev, sc, chan, pkt); + hv_nv_on_receive(net_dev, rxr, chan, pkt); break; case VMBUS_CHANPKT_TYPE_INBAND: hv_nv_send_table(sc, pkt); break; default: - device_printf(dev, + if_printf(rxr->hn_ifp, "unknown chan pkt %u\n", pkt->cph_type); break; @@ -1023,7 +1018,7 @@ hv_nv_on_channel_callback(void *xchan) /* alloc new buffer */ buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); if (buffer == NULL) { - device_printf(dev, + if_printf(rxr->hn_ifp, "hv_cb malloc buffer failed, len=%u\n", bytes_rxed); bufferlen = 0; @@ -1039,5 +1034,5 @@ hv_nv_on_channel_callback(void *xchan) if (bufferlen > NETVSC_PACKET_SIZE) free(buffer, M_NETVSC); - hv_rf_channel_rollup(chan); + hv_rf_channel_rollup(rxr, rxr->hn_txr); } Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 03:18:17 2016 (r307096) @@ -53,6 +53,7 @@ #include #include +#include #include #include @@ -1065,12 +1066,12 @@ typedef struct netvsc_dev_ { nvsp_msg channel_init_packet; nvsp_msg revoke_packet; - /*uint8_t hw_mac_addr[HW_MACADDR_LEN];*/ + /*uint8_t hw_mac_addr[ETHER_ADDR_LEN];*/ /* Holds rndis device info */ void *extension; - hv_bool_uint8_t destroy; + uint8_t destroy; /* Negotiated NVSP version */ uint32_t nvsp_version; @@ -1081,9 +1082,9 @@ typedef struct netvsc_dev_ { uint32_t vrss_send_table[VRSS_SEND_TABLE_SIZE]; } netvsc_dev; -struct hv_vmbus_channel; +struct vmbus_channel; -typedef void (*pfn_on_send_rx_completion)(struct hv_vmbus_channel *, void *); +typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *); #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) @@ -1109,7 +1110,7 @@ typedef void (*pfn_on_send_rx_completion #endif typedef struct netvsc_packet_ { - hv_bool_uint8_t is_data_pkt; /* One byte */ + uint8_t is_data_pkt; /* One byte */ uint16_t vlan_tci; uint32_t status; @@ -1140,7 +1141,7 @@ typedef struct netvsc_packet_ { typedef struct { uint8_t mac_addr[6]; /* Assumption unsigned long */ - hv_bool_uint8_t link_state; + uint8_t link_state; } netvsc_device_info; #ifndef HN_USE_TXDESC_BUFRING @@ -1150,8 +1151,12 @@ SLIST_HEAD(hn_txdesc_list, hn_txdesc); struct buf_ring; #endif +struct hn_tx_ring; + struct hn_rx_ring { struct ifnet *hn_ifp; + struct hn_tx_ring *hn_txr; + void *hn_rdbuf; int hn_rx_idx; /* Trust csum verification on host side */ @@ -1202,7 +1207,7 @@ struct hn_tx_ring { struct mtx hn_tx_lock; struct hn_softc *hn_sc; - struct hv_vmbus_channel *hn_chan; + struct vmbus_channel *hn_chan; int hn_direct_tx_size; int hn_tx_chimney_size; @@ -1242,7 +1247,7 @@ typedef struct hn_softc { /* See hv_netvsc_drv_freebsd.c for rules on how to use */ int temp_unusable; netvsc_dev *net_dev; - struct hv_vmbus_channel *hn_prichan; + struct vmbus_channel *hn_prichan; int hn_rx_ring_cnt; int hn_rx_ring_inuse; @@ -1266,12 +1271,13 @@ extern int hv_promisc_mode; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc, - void *additional_info); + void *additional_info, struct hn_rx_ring *rxr); int hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); -int hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt); +int hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt); int hv_nv_get_next_send_section(netvsc_dev *net_dev); -void hv_nv_subchan_attach(struct hv_vmbus_channel *chan); +void hv_nv_subchan_attach(struct vmbus_channel *chan, + struct hn_rx_ring *rxr); #endif /* __HV_NET_VSC_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 03:18:17 2016 (r307096) @@ -122,9 +122,6 @@ __FBSDID("$FreeBSD$"); #include "hv_rndis_filter.h" #include "vmbus_if.h" -#define hv_chan_rxr hv_chan_priv1 -#define hv_chan_txr hv_chan_priv2 - /* Short for Hyper-V network interface */ #define NETVSC_DEVNAME "hn" @@ -347,8 +344,8 @@ static int hn_encap(struct hn_tx_ring *, static void hn_create_rx_data(struct hn_softc *sc, int); static void hn_destroy_rx_data(struct hn_softc *sc); static void hn_set_tx_chimney_size(struct hn_softc *, int); -static void hn_channel_attach(struct hn_softc *, struct hv_vmbus_channel *); -static void hn_subchan_attach(struct hn_softc *, struct hv_vmbus_channel *); +static void hn_channel_attach(struct hn_softc *, struct vmbus_channel *); +static void hn_subchan_attach(struct hn_softc *, struct vmbus_channel *); static void hn_subchan_setup(struct hn_softc *); static int hn_transmit(struct ifnet *, struct mbuf *); @@ -560,7 +557,8 @@ netvsc_attach(device_t dev) IFCAP_LRO; ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; - error = hv_rf_on_device_add(sc, &device_info, ring_cnt); + error = hv_rf_on_device_add(sc, &device_info, ring_cnt, + &sc->hn_rx_ring[0]); if (error) goto failed; KASSERT(sc->net_dev->num_channel > 0 && @@ -794,7 +792,7 @@ hn_txeof(struct hn_tx_ring *txr) } static void -hn_tx_done(struct hv_vmbus_channel *chan, void *xpkt) +hn_tx_done(struct vmbus_channel *chan, void *xpkt) { netvsc_packet *packet = xpkt; struct hn_txdesc *txd; @@ -805,9 +803,8 @@ hn_tx_done(struct hv_vmbus_channel *chan txr = txd->txr; KASSERT(txr->hn_chan == chan, - ("channel mismatch, on channel%u, should be channel%u", - chan->ch_subidx, - txr->hn_chan->ch_subidx)); + ("channel mismatch, on chan%u, should be chan%u", + vmbus_chan_subidx(chan), vmbus_chan_subidx(txr->hn_chan))); txr->hn_has_txeof = 1; hn_txdesc_put(txr, txd); @@ -821,11 +818,9 @@ hn_tx_done(struct hv_vmbus_channel *chan } void -netvsc_channel_rollup(struct hv_vmbus_channel *chan) +netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { - struct hn_tx_ring *txr = chan->hv_chan_txr; #if defined(INET) || defined(INET6) - struct hn_rx_ring *rxr = chan->hv_chan_rxr; struct lro_ctrl *lro = &rxr->hn_lro; struct lro_entry *queued; @@ -1296,12 +1291,11 @@ hn_lro_rx(struct lro_ctrl *lc, struct mb * Note: This is no longer used as a callback */ int -netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet, +netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet, const rndis_tcp_ip_csum_info *csum_info, const struct rndis_hash_info *hash_info, const struct rndis_hash_value *hash_value) { - struct hn_rx_ring *rxr = chan->hv_chan_rxr; struct ifnet *ifp = rxr->hn_ifp; struct mbuf *m_new; int size, do_lro = 0, do_csum = 1; @@ -1606,7 +1600,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, vmbus_subchan_drain(sc->hn_prichan); error = hv_rf_on_device_add(sc, &device_info, - sc->hn_rx_ring_inuse); + sc->hn_rx_ring_inuse, &sc->hn_rx_ring[0]); if (error) { NV_LOCK(sc); sc->temp_unusable = FALSE; @@ -2269,6 +2263,9 @@ hn_create_rx_data(struct hn_softc *sc, i if (hn_trust_hostip) rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_IP; rxr->hn_ifp = sc->hn_ifp; + if (i < sc->hn_tx_ring_cnt) + rxr->hn_txr = &sc->hn_tx_ring[i]; + rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK); rxr->hn_rx_idx = i; /* @@ -2391,17 +2388,19 @@ hn_create_rx_data(struct hn_softc *sc, i static void hn_destroy_rx_data(struct hn_softc *sc) { -#if defined(INET) || defined(INET6) int i; -#endif if (sc->hn_rx_ring_cnt == 0) return; + for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { + struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; + #if defined(INET) || defined(INET6) - for (i = 0; i < sc->hn_rx_ring_cnt; ++i) - tcp_lro_free(&sc->hn_rx_ring[i].hn_lro); + tcp_lro_free(&rxr->hn_lro); #endif + free(rxr->hn_rdbuf, M_NETVSC); + } free(sc->hn_rx_ring, M_NETVSC); sc->hn_rx_ring = NULL; @@ -2969,12 +2968,12 @@ hn_xmit_txeof_taskfunc(void *xtxr, int p } static void -hn_channel_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan) +hn_channel_attach(struct hn_softc *sc, struct vmbus_channel *chan) { struct hn_rx_ring *rxr; int idx; - idx = chan->ch_subidx; + idx = vmbus_chan_subidx(chan); KASSERT(idx >= 0 && idx < sc->hn_rx_ring_inuse, ("invalid channel index %d, should > 0 && < %d", @@ -2984,10 +2983,9 @@ hn_channel_attach(struct hn_softc *sc, s ("RX ring %d already attached", idx)); rxr->hn_rx_flags |= HN_RX_FLAG_ATTACHED; - chan->hv_chan_rxr = rxr; if (bootverbose) { if_printf(sc->hn_ifp, "link RX ring %d to channel%u\n", - idx, chan->ch_id); + idx, vmbus_chan_id(chan)); } if (idx < sc->hn_tx_ring_inuse) { @@ -2997,11 +2995,10 @@ hn_channel_attach(struct hn_softc *sc, s ("TX ring %d already attached", idx)); txr->hn_tx_flags |= HN_TX_FLAG_ATTACHED; - chan->hv_chan_txr = txr; txr->hn_chan = chan; if (bootverbose) { if_printf(sc->hn_ifp, "link TX ring %d to channel%u\n", - idx, chan->ch_id); + idx, vmbus_chan_id(chan)); } } @@ -3010,36 +3007,36 @@ hn_channel_attach(struct hn_softc *sc, s } static void -hn_subchan_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan) +hn_subchan_attach(struct hn_softc *sc, struct vmbus_channel *chan) { - KASSERT(!VMBUS_CHAN_ISPRIMARY(chan), + KASSERT(!vmbus_chan_is_primary(chan), ("subchannel callback on primary channel")); - KASSERT(chan->ch_subidx > 0, - ("invalid channel subidx %u", - chan->ch_subidx)); hn_channel_attach(sc, chan); } static void hn_subchan_setup(struct hn_softc *sc) { - struct hv_vmbus_channel **subchan; + struct vmbus_channel **subchans; int subchan_cnt = sc->net_dev->num_channel - 1; int i; /* Wait for sub-channels setup to complete. */ - subchan = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); + subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); /* Attach the sub-channels. */ for (i = 0; i < subchan_cnt; ++i) { + struct vmbus_channel *subchan = subchans[i]; + /* NOTE: Calling order is critical. */ - hn_subchan_attach(sc, subchan[i]); - hv_nv_subchan_attach(subchan[i]); + hn_subchan_attach(sc, subchan); + hv_nv_subchan_attach(subchan, + &sc->hn_rx_ring[vmbus_chan_subidx(subchan)]); } /* Release the sub-channels */ - vmbus_subchan_rel(subchan, subchan_cnt); + vmbus_subchan_rel(subchans, subchan_cnt); if_printf(sc->hn_ifp, "%d sub-channels setup done\n", subchan_cnt); } Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Wed Oct 12 03:18:17 2016 (r307096) @@ -1082,13 +1082,14 @@ typedef struct rndismp_rx_bufs_info_ { /* * Externs */ -struct hv_vmbus_channel; +struct hn_rx_ring; +struct hn_tx_ring; -int netvsc_recv(struct hv_vmbus_channel *chan, +int netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet, const rndis_tcp_ip_csum_info *csum_info, const struct rndis_hash_info *hash_info, const struct rndis_hash_value *hash_value); -void netvsc_channel_rollup(struct hv_vmbus_channel *chan); +void netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); void* hv_set_rppi_data(rndis_msg *rndis_mesg, uint32_t rppi_size, Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 03:08:58 2016 (r307095) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 03:18:17 2016 (r307096) @@ -35,7 +35,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -75,8 +77,7 @@ static int hv_rf_send_request(rndis_dev static void hv_rf_receive_response(rndis_device *device, rndis_msg *response); static void hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response); -static void hv_rf_receive_data(rndis_device *device, rndis_msg *message, - struct hv_vmbus_channel *chan, +static void hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message, netvsc_packet *pkt); static int hv_rf_query_device(rndis_device *device, uint32_t oid, void *result, uint32_t *result_size); @@ -86,8 +87,8 @@ static int hv_rf_set_packet_filter(rndi static int hv_rf_init_device(rndis_device *device); static int hv_rf_open_device(rndis_device *device); static int hv_rf_close_device(rndis_device *device); -static void hv_rf_on_send_request_completion(struct hv_vmbus_channel *, void *context); -static void hv_rf_on_send_request_halt_completion(struct hv_vmbus_channel *, void *context); +static void hv_rf_on_send_request_completion(struct vmbus_channel *, void *context); +static void hv_rf_on_send_request_halt_completion(struct vmbus_channel *, void *context); int hv_rf_send_offload_request(struct hn_softc *sc, rndis_offload_params *offloads); @@ -528,12 +529,11 @@ skip: * RNDIS filter receive data */ static void -hv_rf_receive_data(rndis_device *device, rndis_msg *message, - struct hv_vmbus_channel *chan, netvsc_packet *pkt) +hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message, + netvsc_packet *pkt) { rndis_packet *rndis_pkt; uint32_t data_offset; - device_t dev = device->net_dev->sc->hn_dev; struct hv_rf_recvinfo info; rndis_pkt = &message->msg.packet; @@ -549,7 +549,7 @@ hv_rf_receive_data(rndis_device *device, pkt->tot_data_buf_len -= data_offset; if (pkt->tot_data_buf_len < rndis_pkt->data_length) { pkt->status = nvsp_status_failure; - device_printf(dev, + if_printf(rxr->hn_ifp, "total length %u is less than data length %u\n", pkt->tot_data_buf_len, rndis_pkt->data_length); return; @@ -560,7 +560,7 @@ hv_rf_receive_data(rndis_device *device, if (hv_rf_find_recvinfo(rndis_pkt, &info)) { pkt->status = nvsp_status_failure; - device_printf(dev, "recvinfo parsing failed\n"); + if_printf(rxr->hn_ifp, "recvinfo parsing failed\n"); return; } @@ -569,7 +569,7 @@ hv_rf_receive_data(rndis_device *device, else pkt->vlan_tci = 0; - netvsc_recv(chan, pkt, info.csum_info, info.hash_info, info.hash_value); + netvsc_recv(rxr, pkt, info.csum_info, info.hash_info, info.hash_value); } /* @@ -577,7 +577,7 @@ hv_rf_receive_data(rndis_device *device, */ int hv_rf_on_receive(netvsc_dev *net_dev, - struct hv_vmbus_channel *chan, netvsc_packet *pkt) + struct hn_rx_ring *rxr, netvsc_packet *pkt) { rndis_device *rndis_dev; rndis_msg *rndis_hdr; @@ -600,7 +600,7 @@ hv_rf_on_receive(netvsc_dev *net_dev, /* data message */ case REMOTE_NDIS_PACKET_MSG: - hv_rf_receive_data(rndis_dev, rndis_hdr, chan, pkt); + hv_rf_receive_data(rxr, rndis_hdr, pkt); break; /* completion messages */ case REMOTE_NDIS_INITIALIZE_CMPLT: @@ -700,7 +700,7 @@ cleanup: static inline int hv_rf_query_device_mac(rndis_device *device) { - uint32_t size = HW_MACADDR_LEN; + uint32_t size = ETHER_ADDR_LEN; return (hv_rf_query_device(device, RNDIS_OID_802_3_PERMANENT_ADDRESS, device->hw_mac_addr, &size)); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Wed Oct 12 03:32:49 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 917BDC0ECC2; Wed, 12 Oct 2016 03:32:49 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5D114957; Wed, 12 Oct 2016 03:32:49 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C3WmpB073012; Wed, 12 Oct 2016 03:32:48 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C3WmAp073007; Wed, 12 Oct 2016 03:32:48 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120332.u9C3WmAp073007@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 03:32:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307097 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 03:32:49 -0000 Author: sephe Date: Wed Oct 12 03:32:47 2016 New Revision: 307097 URL: https://svnweb.freebsd.org/changeset/base/307097 Log: MFC 303178,303180,303182 303178 hyperv/vmbus: Cosmetic bufring cleanup. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7267 303180 hyperv/vmbus: Cleanup and augment bufring sysctl tree creation Binary state node is added, so that userland programs do not have to parse human readable state string. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7268 303182 hyperv/vmbus: Move vmbus bufring definition to vmbus_reg.h And add more comment about its fields. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7269 Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 03:18:17 2016 (r307096) +++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 03:32:47 2016 (r307097) @@ -35,116 +35,148 @@ __FBSDID("$FreeBSD$"); #include #include "hv_vmbus_priv.h" +#include /* Amount of space to write to */ -#define HV_BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))? \ - ((z) - ((w) - (r))):((r) - (w)) +#define HV_BYTES_AVAIL_TO_WRITE(r, w, z) \ + ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) +static uint32_t copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, + uint32_t start_write_offset, const uint8_t *src, + uint32_t src_len); +static uint32_t copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, + char *dest, uint32_t dest_len, uint32_t start_read_offset); + +static int +vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS) +{ + const hv_vmbus_ring_buffer_info *br = arg1; + uint32_t rindex, windex, intr_mask, ravail, wavail; + char state[256]; + + rindex = br->ring_buffer->br_rindex; + windex = br->ring_buffer->br_windex; + intr_mask = br->ring_buffer->br_imask; + wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size); + ravail = br->ring_data_size - wavail; + + snprintf(state, sizeof(state), + "rindex:%u windex:%u intr_mask:%u ravail:%u wavail:%u", + rindex, windex, intr_mask, ravail, wavail); + return sysctl_handle_string(oidp, state, sizeof(state), req); +} + +/* + * Binary bufring states. + */ static int -hv_rbi_sysctl_stats(SYSCTL_HANDLER_ARGS) +vmbus_br_sysctl_state_bin(SYSCTL_HANDLER_ARGS) { - hv_vmbus_ring_buffer_info* rbi; - uint32_t read_index, write_index, interrupt_mask, sz; - uint32_t read_avail, write_avail; - char rbi_stats[256]; - - rbi = (hv_vmbus_ring_buffer_info*)arg1; - read_index = rbi->ring_buffer->read_index; - write_index = rbi->ring_buffer->write_index; - interrupt_mask = rbi->ring_buffer->interrupt_mask; - sz = rbi->ring_data_size; - write_avail = HV_BYTES_AVAIL_TO_WRITE(read_index, - write_index, sz); - read_avail = sz - write_avail; - snprintf(rbi_stats, sizeof(rbi_stats), - "r_idx:%d " - "w_idx:%d " - "int_mask:%d " - "r_avail:%d " - "w_avail:%d", - read_index, write_index, interrupt_mask, - read_avail, write_avail); +#define BR_STATE_RIDX 0 +#define BR_STATE_WIDX 1 +#define BR_STATE_IMSK 2 +#define BR_STATE_RSPC 3 +#define BR_STATE_WSPC 4 +#define BR_STATE_MAX 5 + + const hv_vmbus_ring_buffer_info *br = arg1; + uint32_t rindex, windex, wavail, state[BR_STATE_MAX]; + + rindex = br->ring_buffer->br_rindex; + windex = br->ring_buffer->br_windex; + wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size); + + state[BR_STATE_RIDX] = rindex; + state[BR_STATE_WIDX] = windex; + state[BR_STATE_IMSK] = br->ring_buffer->br_imask; + state[BR_STATE_WSPC] = wavail; + state[BR_STATE_RSPC] = br->ring_data_size - wavail; - return (sysctl_handle_string(oidp, rbi_stats, - sizeof(rbi_stats), req)); + return sysctl_handle_opaque(oidp, state, sizeof(state), req); } void -hv_ring_buffer_stat( - struct sysctl_ctx_list *ctx, - struct sysctl_oid_list *tree_node, - hv_vmbus_ring_buffer_info *rbi, - const char *desc) -{ - SYSCTL_ADD_PROC(ctx, tree_node, OID_AUTO, - "ring_buffer_stats", - CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, rbi, 0, - hv_rbi_sysctl_stats, "A", desc); +vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, struct sysctl_oid *br_tree, + hv_vmbus_ring_buffer_info *br, const char *name) +{ + struct sysctl_oid *tree; + char desc[64]; + + tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(br_tree), OID_AUTO, + name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (tree == NULL) + return; + + snprintf(desc, sizeof(desc), "%s state", name); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "state", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, + br, 0, vmbus_br_sysctl_state, "A", desc); + + snprintf(desc, sizeof(desc), "%s binary state", name); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "state_bin", + CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, + br, 0, vmbus_br_sysctl_state_bin, "IU", desc); } + /** * @brief Get number of bytes available to read and to write to * for the specified ring buffer */ -static inline void -get_ring_buffer_avail_bytes( - hv_vmbus_ring_buffer_info* rbi, - uint32_t* read, - uint32_t* write) +static __inline void +get_ring_buffer_avail_bytes(hv_vmbus_ring_buffer_info *rbi, uint32_t *read, + uint32_t *write) { uint32_t read_loc, write_loc; /* * Capture the read/write indices before they changed */ - read_loc = rbi->ring_buffer->read_index; - write_loc = rbi->ring_buffer->write_index; + read_loc = rbi->ring_buffer->br_rindex; + write_loc = rbi->ring_buffer->br_windex; - *write = HV_BYTES_AVAIL_TO_WRITE( - read_loc, write_loc, rbi->ring_data_size); + *write = HV_BYTES_AVAIL_TO_WRITE(read_loc, write_loc, + rbi->ring_data_size); *read = rbi->ring_data_size - *write; } /** * @brief Get the next write location for the specified ring buffer */ -static inline uint32_t -get_next_write_location(hv_vmbus_ring_buffer_info* ring_info) +static __inline uint32_t +get_next_write_location(hv_vmbus_ring_buffer_info *ring_info) { - uint32_t next = ring_info->ring_buffer->write_index; - return (next); + return ring_info->ring_buffer->br_windex; } /** * @brief Set the next write location for the specified ring buffer */ -static inline void -set_next_write_location( - hv_vmbus_ring_buffer_info* ring_info, - uint32_t next_write_location) +static __inline void +set_next_write_location(hv_vmbus_ring_buffer_info *ring_info, + uint32_t next_write_location) { - ring_info->ring_buffer->write_index = next_write_location; + ring_info->ring_buffer->br_windex = next_write_location; } /** * @brief Get the next read location for the specified ring buffer */ -static inline uint32_t -get_next_read_location(hv_vmbus_ring_buffer_info* ring_info) +static __inline uint32_t +get_next_read_location(hv_vmbus_ring_buffer_info *ring_info) { - uint32_t next = ring_info->ring_buffer->read_index; - return (next); + return ring_info->ring_buffer->br_rindex; } /** * @brief Get the next read location + offset for the specified ring buffer. * This allows the caller to skip. */ -static inline uint32_t -get_next_read_location_with_offset( - hv_vmbus_ring_buffer_info* ring_info, - uint32_t offset) +static __inline uint32_t +get_next_read_location_with_offset(hv_vmbus_ring_buffer_info *ring_info, + uint32_t offset) { - uint32_t next = ring_info->ring_buffer->read_index; + uint32_t next = ring_info->ring_buffer->br_rindex; + next += offset; next %= ring_info->ring_data_size; return (next); @@ -153,28 +185,27 @@ get_next_read_location_with_offset( /** * @brief Set the next read location for the specified ring buffer */ -static inline void -set_next_read_location( - hv_vmbus_ring_buffer_info* ring_info, - uint32_t next_read_location) +static __inline void +set_next_read_location(hv_vmbus_ring_buffer_info *ring_info, + uint32_t next_read_location) { - ring_info->ring_buffer->read_index = next_read_location; + ring_info->ring_buffer->br_rindex = next_read_location; } /** * @brief Get the start of the ring buffer */ -static inline void * -get_ring_buffer(hv_vmbus_ring_buffer_info* ring_info) +static __inline void * +get_ring_buffer(hv_vmbus_ring_buffer_info *ring_info) { - return (void *) ring_info->ring_buffer->buffer; + return ring_info->ring_buffer->br_data; } /** * @brief Get the size of the ring buffer. */ -static inline uint32_t -get_ring_buffer_size(hv_vmbus_ring_buffer_info* ring_info) +static __inline uint32_t +get_ring_buffer_size(hv_vmbus_ring_buffer_info *ring_info) { return ring_info->ring_data_size; } @@ -182,27 +213,25 @@ get_ring_buffer_size(hv_vmbus_ring_buffe /** * Get the read and write indices as uint64_t of the specified ring buffer. */ -static inline uint64_t -get_ring_buffer_indices(hv_vmbus_ring_buffer_info* ring_info) +static __inline uint64_t +get_ring_buffer_indices(hv_vmbus_ring_buffer_info *ring_info) { - return (uint64_t) ring_info->ring_buffer->write_index << 32; + return ((uint64_t)ring_info->ring_buffer->br_windex) << 32; } void -hv_ring_buffer_read_begin( - hv_vmbus_ring_buffer_info* ring_info) +hv_ring_buffer_read_begin(hv_vmbus_ring_buffer_info *ring_info) { - ring_info->ring_buffer->interrupt_mask = 1; + ring_info->ring_buffer->br_imask = 1; mb(); } uint32_t -hv_ring_buffer_read_end( - hv_vmbus_ring_buffer_info* ring_info) +hv_ring_buffer_read_end(hv_vmbus_ring_buffer_info *ring_info) { - uint32_t read, write; + uint32_t read, write; - ring_info->ring_buffer->interrupt_mask = 0; + ring_info->ring_buffer->br_imask = 0; mb(); /* @@ -211,7 +240,6 @@ hv_ring_buffer_read_end( * incoming messages. */ get_ring_buffer_avail_bytes(ring_info, &read, &write); - return (read); } @@ -231,12 +259,11 @@ hv_ring_buffer_read_end( * arrived. */ static boolean_t -hv_ring_buffer_needsig_on_write( - uint32_t old_write_location, - hv_vmbus_ring_buffer_info* rbi) +hv_ring_buffer_needsig_on_write(uint32_t old_write_location, + hv_vmbus_ring_buffer_info *rbi) { mb(); - if (rbi->ring_buffer->interrupt_mask) + if (rbi->ring_buffer->br_imask) return (FALSE); /* Read memory barrier */ @@ -245,41 +272,26 @@ hv_ring_buffer_needsig_on_write( * This is the only case we need to signal when the * ring transitions from being empty to non-empty. */ - if (old_write_location == rbi->ring_buffer->read_index) + if (old_write_location == rbi->ring_buffer->br_rindex) return (TRUE); return (FALSE); } -static uint32_t copy_to_ring_buffer( - hv_vmbus_ring_buffer_info* ring_info, - uint32_t start_write_offset, - const uint8_t *src, - uint32_t src_len); - -static uint32_t copy_from_ring_buffer( - hv_vmbus_ring_buffer_info* ring_info, - char* dest, - uint32_t dest_len, - uint32_t start_read_offset); - /** * @brief Initialize the ring buffer. */ int -hv_vmbus_ring_buffer_init( - hv_vmbus_ring_buffer_info* ring_info, - void* buffer, - uint32_t buffer_len) +hv_vmbus_ring_buffer_init(hv_vmbus_ring_buffer_info *ring_info, void *buffer, + uint32_t buffer_len) { memset(ring_info, 0, sizeof(hv_vmbus_ring_buffer_info)); - ring_info->ring_buffer = (hv_vmbus_ring_buffer*) buffer; - ring_info->ring_buffer->read_index = - ring_info->ring_buffer->write_index = 0; - - ring_info->ring_data_size = buffer_len - sizeof(hv_vmbus_ring_buffer); + ring_info->ring_buffer = buffer; + ring_info->ring_buffer->br_rindex = 0; + ring_info->ring_buffer->br_windex = 0; + ring_info->ring_data_size = buffer_len - sizeof(struct vmbus_bufring); mtx_init(&ring_info->ring_lock, "vmbus ring buffer", NULL, MTX_SPIN); return (0); @@ -288,7 +300,8 @@ hv_vmbus_ring_buffer_init( /** * @brief Cleanup the ring buffer. */ -void hv_ring_buffer_cleanup(hv_vmbus_ring_buffer_info* ring_info) +void +hv_ring_buffer_cleanup(hv_vmbus_ring_buffer_info *ring_info) { mtx_destroy(&ring_info->ring_lock); } @@ -297,24 +310,19 @@ void hv_ring_buffer_cleanup(hv_vmbus_rin * @brief Write to the ring buffer. */ int -hv_ring_buffer_write( - hv_vmbus_ring_buffer_info* out_ring_info, - const struct iovec iov[], - uint32_t iovlen, - boolean_t *need_sig) +hv_ring_buffer_write(hv_vmbus_ring_buffer_info *out_ring_info, + const struct iovec iov[], uint32_t iovlen, boolean_t *need_sig) { int i = 0; uint32_t byte_avail_to_write; uint32_t byte_avail_to_read; uint32_t old_write_location; uint32_t total_bytes_to_write = 0; - volatile uint32_t next_write_location; uint64_t prev_indices = 0; - for (i = 0; i < iovlen; i++) { - total_bytes_to_write += iov[i].iov_len; - } + for (i = 0; i < iovlen; i++) + total_bytes_to_write += iov[i].iov_len; total_bytes_to_write += sizeof(uint64_t); @@ -328,11 +336,9 @@ hv_ring_buffer_write( * Otherwise, the next time around, we think the ring buffer * is empty since the read index == write index */ - if (byte_avail_to_write <= total_bytes_to_write) { - - mtx_unlock_spin(&out_ring_info->ring_lock); - return (EAGAIN); + mtx_unlock_spin(&out_ring_info->ring_lock); + return (EAGAIN); } /* @@ -343,8 +349,8 @@ hv_ring_buffer_write( old_write_location = next_write_location; for (i = 0; i < iovlen; i++) { - next_write_location = copy_to_ring_buffer(out_ring_info, - next_write_location, iov[i].iov_base, iov[i].iov_len); + next_write_location = copy_to_ring_buffer(out_ring_info, + next_write_location, iov[i].iov_base, iov[i].iov_len); } /* @@ -352,9 +358,8 @@ hv_ring_buffer_write( */ prev_indices = get_ring_buffer_indices(out_ring_info); - next_write_location = copy_to_ring_buffer( - out_ring_info, next_write_location, - (char *) &prev_indices, sizeof(uint64_t)); + next_write_location = copy_to_ring_buffer(out_ring_info, + next_write_location, (char *)&prev_indices, sizeof(uint64_t)); /* * Full memory barrier before upding the write index. @@ -378,10 +383,8 @@ hv_ring_buffer_write( * @brief Read without advancing the read index. */ int -hv_ring_buffer_peek( - hv_vmbus_ring_buffer_info* in_ring_info, - void* buffer, - uint32_t buffer_len) +hv_ring_buffer_peek(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer, + uint32_t buffer_len) { uint32_t bytesAvailToWrite; uint32_t bytesAvailToRead; @@ -390,14 +393,14 @@ hv_ring_buffer_peek( mtx_lock_spin(&in_ring_info->ring_lock); get_ring_buffer_avail_bytes(in_ring_info, &bytesAvailToRead, - &bytesAvailToWrite); + &bytesAvailToWrite); /* * Make sure there is something to read */ if (bytesAvailToRead < buffer_len) { - mtx_unlock_spin(&in_ring_info->ring_lock); - return (EAGAIN); + mtx_unlock_spin(&in_ring_info->ring_lock); + return (EAGAIN); } /* @@ -405,8 +408,8 @@ hv_ring_buffer_peek( */ nextReadLocation = get_next_read_location(in_ring_info); - nextReadLocation = copy_from_ring_buffer( - in_ring_info, (char *)buffer, buffer_len, nextReadLocation); + nextReadLocation = copy_from_ring_buffer(in_ring_info, + (char *)buffer, buffer_len, nextReadLocation); mtx_unlock_spin(&in_ring_info->ring_lock); @@ -417,11 +420,8 @@ hv_ring_buffer_peek( * @brief Read and advance the read index. */ int -hv_ring_buffer_read( - hv_vmbus_ring_buffer_info* in_ring_info, - void* buffer, - uint32_t buffer_len, - uint32_t offset) +hv_ring_buffer_read(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer, + uint32_t buffer_len, uint32_t offset) { uint32_t bytes_avail_to_write; uint32_t bytes_avail_to_read; @@ -429,37 +429,29 @@ hv_ring_buffer_read( uint64_t prev_indices = 0; if (buffer_len <= 0) - return (EINVAL); + return (EINVAL); mtx_lock_spin(&in_ring_info->ring_lock); - get_ring_buffer_avail_bytes( - in_ring_info, &bytes_avail_to_read, + get_ring_buffer_avail_bytes(in_ring_info, &bytes_avail_to_read, &bytes_avail_to_write); /* * Make sure there is something to read */ if (bytes_avail_to_read < buffer_len) { - mtx_unlock_spin(&in_ring_info->ring_lock); - return (EAGAIN); + mtx_unlock_spin(&in_ring_info->ring_lock); + return (EAGAIN); } - next_read_location = get_next_read_location_with_offset( - in_ring_info, + next_read_location = get_next_read_location_with_offset(in_ring_info, offset); - next_read_location = copy_from_ring_buffer( - in_ring_info, - (char *) buffer, - buffer_len, - next_read_location); - - next_read_location = copy_from_ring_buffer( - in_ring_info, - (char *) &prev_indices, - sizeof(uint64_t), - next_read_location); + next_read_location = copy_from_ring_buffer(in_ring_info, (char *)buffer, + buffer_len, next_read_location); + + next_read_location = copy_from_ring_buffer(in_ring_info, + (char *)&prev_indices, sizeof(uint64_t), next_read_location); /* * Make sure all reads are done before we update the read index since @@ -484,23 +476,20 @@ hv_ring_buffer_read( * Assume there is enough room. Handles wrap-around in dest case only! */ static uint32_t -copy_to_ring_buffer( - hv_vmbus_ring_buffer_info* ring_info, - uint32_t start_write_offset, - const uint8_t *src, - uint32_t src_len) +copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, + uint32_t start_write_offset, const uint8_t *src, uint32_t src_len) { char *ring_buffer = get_ring_buffer(ring_info); uint32_t ring_buffer_size = get_ring_buffer_size(ring_info); uint32_t fragLen; - if (src_len > ring_buffer_size - start_write_offset) { - /* wrap-around detected! */ - fragLen = ring_buffer_size - start_write_offset; - memcpy(ring_buffer + start_write_offset, src, fragLen); - memcpy(ring_buffer, src + fragLen, src_len - fragLen); + if (src_len > ring_buffer_size - start_write_offset) { + /* wrap-around detected! */ + fragLen = ring_buffer_size - start_write_offset; + memcpy(ring_buffer + start_write_offset, src, fragLen); + memcpy(ring_buffer, src + fragLen, src_len - fragLen); } else { - memcpy(ring_buffer + start_write_offset, src, src_len); + memcpy(ring_buffer + start_write_offset, src, src_len); } start_write_offset += src_len; @@ -514,24 +503,21 @@ copy_to_ring_buffer( * * Assume there is enough room. Handles wrap-around in src case only! */ -uint32_t -copy_from_ring_buffer( - hv_vmbus_ring_buffer_info* ring_info, - char* dest, - uint32_t dest_len, - uint32_t start_read_offset) +static uint32_t +copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, char *dest, + uint32_t dest_len, uint32_t start_read_offset) { uint32_t fragLen; char *ring_buffer = get_ring_buffer(ring_info); uint32_t ring_buffer_size = get_ring_buffer_size(ring_info); if (dest_len > ring_buffer_size - start_read_offset) { - /* wrap-around detected at the src */ - fragLen = ring_buffer_size - start_read_offset; - memcpy(dest, ring_buffer + start_read_offset, fragLen); - memcpy(dest + fragLen, ring_buffer, dest_len - fragLen); + /* wrap-around detected at the src */ + fragLen = ring_buffer_size - start_read_offset; + memcpy(dest, ring_buffer + start_read_offset, fragLen); + memcpy(dest + fragLen, ring_buffer, dest_len - fragLen); } else { - memcpy(dest, ring_buffer + start_read_offset, dest_len); + memcpy(dest, ring_buffer + start_read_offset, dest_len); } start_read_offset += dest_len; @@ -539,4 +525,3 @@ copy_from_ring_buffer( return (start_read_offset); } - Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Wed Oct 12 03:18:17 2016 (r307096) +++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Wed Oct 12 03:32:47 2016 (r307097) @@ -45,13 +45,11 @@ struct vmbus_softc; * Private, VM Bus functions */ struct sysctl_ctx_list; -struct sysctl_oid_list; +struct sysctl_oid; -void hv_ring_buffer_stat( - struct sysctl_ctx_list *ctx, - struct sysctl_oid_list *tree_node, - hv_vmbus_ring_buffer_info *rbi, - const char *desc); +void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, + struct sysctl_oid *br_tree, hv_vmbus_ring_buffer_info *br, + const char *name); int hv_vmbus_ring_buffer_init( hv_vmbus_ring_buffer_info *ring_info, Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 03:18:17 2016 (r307096) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 03:32:47 2016 (r307097) @@ -171,24 +171,17 @@ vmbus_chan_sysctl_create(struct vmbus_ch chan, 0, vmbus_chan_sysctl_mnf, "I", "has monitor notification facilities"); - /* - * Create sysctl tree for RX bufring. - */ - br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, - "in", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); - if (br_tree != NULL) { - hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), - &chan->ch_rxbr, "inbound ring buffer stats"); - } - - /* - * Create sysctl tree for TX bufring. - */ br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, - "out", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + "br", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); if (br_tree != NULL) { - hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree), - &chan->ch_txbr, "outbound ring buffer stats"); + /* + * Create sysctl tree for RX bufring. + */ + vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr, "rx"); + /* + * Create sysctl tree for TX bufring. + */ + vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr, "tx"); } } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 03:18:17 2016 (r307096) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 03:32:47 2016 (r307097) @@ -41,31 +41,7 @@ #include typedef struct { - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t write_index; - /* - * offset in bytes from the start of ring data below - */ - volatile uint32_t read_index; - /* - * NOTE: The interrupt_mask field is used only for channels, but - * vmbus connection also uses this data structure - */ - volatile uint32_t interrupt_mask; - /* pad it to PAGE_SIZE so that data starts on a page */ - uint8_t reserved[4084]; - - /* - * WARNING: Ring data starts here - * !!! DO NOT place any fields below this !!! - */ - uint8_t buffer[0]; /* doubles as interrupt mask */ -} __packed hv_vmbus_ring_buffer; - -typedef struct { - hv_vmbus_ring_buffer* ring_buffer; + struct vmbus_bufring *ring_buffer; struct mtx ring_lock; uint32_t ring_data_size; /* ring_size */ } hv_vmbus_ring_buffer_info; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 03:18:17 2016 (r307096) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 03:32:47 2016 (r307097) @@ -102,6 +102,37 @@ struct vmbus_mnf { CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE); /* + * Buffer ring + */ +struct vmbus_bufring { + /* + * If br_windex == br_rindex, this bufring is empty; this + * means we can _not_ write data to the bufring, if the + * write is going to make br_windex same as br_rindex. + */ + volatile uint32_t br_windex; + volatile uint32_t br_rindex; + + /* + * Interrupt mask {0,1} + * + * For TX bufring, host set this to 1, when it is processing + * the TX bufring, so that we can safely skip the TX event + * notification to host. + * + * For RX bufring, once this is set to 1 by us, host will not + * further dispatch interrupts to us, even if there are data + * pending on the RX bufring. This effectively disables the + * interrupt of the channel to which this RX bufring is attached. + */ + volatile uint32_t br_imask; + + uint8_t br_rsvd[4084]; + uint8_t br_data[]; +} __packed; +CTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE); + +/* * Channel */ From owner-svn-src-stable-10@freebsd.org Wed Oct 12 03:37:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5A1CFC0EE16; Wed, 12 Oct 2016 03:37:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1E2D4D74; Wed, 12 Oct 2016 03:37:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C3bi7r073414; Wed, 12 Oct 2016 03:37:44 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C3bhjR073407; Wed, 12 Oct 2016 03:37:43 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120337.u9C3bhjR073407@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 03:37:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307099 - in stable/10/sys/dev/hyperv: netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 03:37:45 -0000 Author: sephe Date: Wed Oct 12 03:37:43 2016 New Revision: 307099 URL: https://svnweb.freebsd.org/changeset/base/307099 Log: MFC 303283 hyperv/vmbus: Rename hv_vmbus_priv.h to vmbus_brvar.h It only contains bufring related bits for a while. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7281 Added: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h - copied unchanged from r303283, head/sys/dev/hyperv/vmbus/vmbus_brvar.h Deleted: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Wed Oct 12 03:37:43 2016 (r307099) @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include "hv_net_vsc.h" #include "hv_rndis.h" #include "hv_rndis_filter.h" Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 03:37:43 2016 (r307099) @@ -34,8 +34,8 @@ __FBSDID("$FreeBSD$"); #include #include -#include "hv_vmbus_priv.h" #include +#include /* Amount of space to write to */ #define HV_BYTES_AVAIL_TO_WRITE(r, w, z) \ Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Wed Oct 12 03:37:43 2016 (r307099) @@ -43,12 +43,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -#include #include #include #include +#if 0 #include +#endif #define HYPERV_FREEBSD_BUILD 0ULL #define HYPERV_FREEBSD_VERSION ((uint64_t)__FreeBSD_version) Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h Wed Oct 12 03:37:43 2016 (r307099) @@ -30,6 +30,7 @@ #define _HYPERV_REG_H_ #include +#include /* * Hyper-V Synthetic MSRs Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Wed Oct 12 03:37:43 2016 (r307099) @@ -60,11 +60,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include #include +#include #include #include "acpi_if.h" Copied: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h (from r303283, head/sys/dev/hyperv/vmbus/vmbus_brvar.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Wed Oct 12 03:37:43 2016 (r307099, copy of r303283, head/sys/dev/hyperv/vmbus/vmbus_brvar.h) @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2009-2012,2016 Microsoft Corp. + * Copyright (c) 2012 NetApp Inc. + * Copyright (c) 2012 Citrix Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __HYPERV_PRIV_H__ +#define __HYPERV_PRIV_H__ + +#include +#include +#include +#include +#include + +#include + +struct vmbus_softc; + +/* + * Private, VM Bus functions + */ +struct sysctl_ctx_list; +struct sysctl_oid; + +void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, + struct sysctl_oid *br_tree, hv_vmbus_ring_buffer_info *br, + const char *name); + +int hv_vmbus_ring_buffer_init( + hv_vmbus_ring_buffer_info *ring_info, + void *buffer, + uint32_t buffer_len); + +void hv_ring_buffer_cleanup( + hv_vmbus_ring_buffer_info *ring_info); + +int hv_ring_buffer_write( + hv_vmbus_ring_buffer_info *ring_info, + const struct iovec iov[], + uint32_t iovlen, + boolean_t *need_sig); + +int hv_ring_buffer_peek( + hv_vmbus_ring_buffer_info *ring_info, + void *buffer, + uint32_t buffer_len); + +int hv_ring_buffer_read( + hv_vmbus_ring_buffer_info *ring_info, + void *buffer, + uint32_t buffer_len, + uint32_t offset); + +void hv_ring_buffer_read_begin( + hv_vmbus_ring_buffer_info *ring_info); + +uint32_t hv_ring_buffer_read_end( + hv_vmbus_ring_buffer_info *ring_info); + +#endif /* __HYPERV_PRIV_H__ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 03:36:46 2016 (r307098) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 03:37:43 2016 (r307099) @@ -46,10 +46,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include +#include +#include static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, const struct vmbus_channel *); From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:09:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B5A1DC0D8A6; Wed, 12 Oct 2016 05:09:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 50A0311B1; Wed, 12 Oct 2016 05:09:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C59RPK008406; Wed, 12 Oct 2016 05:09:27 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C59Rjh008401; Wed, 12 Oct 2016 05:09:27 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120509.u9C59Rjh008401@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 05:09:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307103 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:09:28 -0000 Author: sephe Date: Wed Oct 12 05:09:26 2016 New Revision: 307103 URL: https://svnweb.freebsd.org/changeset/base/307103 Log: MFC 303284,303329,303361,303362,303366,303368-303370 303284 hyperv/vmbus: Move bufring info definition to vmbus_brvar.h Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7282 303329 hyperv/vmbus: Nuke unnecessary accessor functions. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7303 303361 hyperv/vmbus: Initialize RX/TX bufring mutex at channel creation time Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7312 303362 hyperv/vmbus: Use different struct for RX/TX bufring. So that they can use suitable MP synchronization mechanism. While I'm here change the bufring init/read/write function names. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7313 303366 hyperv/vmbus: Update comment for bufring Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7314 303368 hyperv/vmbus: Cleanup TX bufring write process. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7315 303369 hyperv/vmbus: Stringent RX bufring data length checks. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7316 303370 hyperv/vmbus: Cleanup RX bufring read process. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7317 Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 05:09:22 2016 (r307102) +++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Wed Oct 12 05:09:26 2016 (r307103) @@ -37,32 +37,29 @@ __FBSDID("$FreeBSD$"); #include #include -/* Amount of space to write to */ -#define HV_BYTES_AVAIL_TO_WRITE(r, w, z) \ - ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) - -static uint32_t copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, - uint32_t start_write_offset, const uint8_t *src, - uint32_t src_len); -static uint32_t copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, - char *dest, uint32_t dest_len, uint32_t start_read_offset); +/* Amount of space available for write */ +#define VMBUS_BR_WAVAIL(r, w, z) \ + (((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))) + +/* Increase bufing index */ +#define VMBUS_BR_IDXINC(idx, inc, sz) (((idx) + (inc)) % (sz)) static int vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS) { - const hv_vmbus_ring_buffer_info *br = arg1; - uint32_t rindex, windex, intr_mask, ravail, wavail; + const struct vmbus_br *br = arg1; + uint32_t rindex, windex, imask, ravail, wavail; char state[256]; - rindex = br->ring_buffer->br_rindex; - windex = br->ring_buffer->br_windex; - intr_mask = br->ring_buffer->br_imask; - wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size); - ravail = br->ring_data_size - wavail; + rindex = br->vbr_rindex; + windex = br->vbr_windex; + imask = br->vbr_imask; + wavail = VMBUS_BR_WAVAIL(rindex, windex, br->vbr_dsize); + ravail = br->vbr_dsize - wavail; snprintf(state, sizeof(state), - "rindex:%u windex:%u intr_mask:%u ravail:%u wavail:%u", - rindex, windex, intr_mask, ravail, wavail); + "rindex:%u windex:%u imask:%u ravail:%u wavail:%u", + rindex, windex, imask, ravail, wavail); return sysctl_handle_string(oidp, state, sizeof(state), req); } @@ -79,25 +76,25 @@ vmbus_br_sysctl_state_bin(SYSCTL_HANDLER #define BR_STATE_WSPC 4 #define BR_STATE_MAX 5 - const hv_vmbus_ring_buffer_info *br = arg1; + const struct vmbus_br *br = arg1; uint32_t rindex, windex, wavail, state[BR_STATE_MAX]; - rindex = br->ring_buffer->br_rindex; - windex = br->ring_buffer->br_windex; - wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size); + rindex = br->vbr_rindex; + windex = br->vbr_windex; + wavail = VMBUS_BR_WAVAIL(rindex, windex, br->vbr_dsize); state[BR_STATE_RIDX] = rindex; state[BR_STATE_WIDX] = windex; - state[BR_STATE_IMSK] = br->ring_buffer->br_imask; + state[BR_STATE_IMSK] = br->vbr_imask; state[BR_STATE_WSPC] = wavail; - state[BR_STATE_RSPC] = br->ring_data_size - wavail; + state[BR_STATE_RSPC] = br->vbr_dsize - wavail; return sysctl_handle_opaque(oidp, state, sizeof(state), req); } void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, struct sysctl_oid *br_tree, - hv_vmbus_ring_buffer_info *br, const char *name) + struct vmbus_br *br, const char *name) { struct sysctl_oid *tree; char desc[64]; @@ -118,342 +115,291 @@ vmbus_br_sysctl_create(struct sysctl_ctx br, 0, vmbus_br_sysctl_state_bin, "IU", desc); } -/** - * @brief Get number of bytes available to read and to write to - * for the specified ring buffer - */ -static __inline void -get_ring_buffer_avail_bytes(hv_vmbus_ring_buffer_info *rbi, uint32_t *read, - uint32_t *write) +void +vmbus_rxbr_intr_mask(struct vmbus_rxbr *rbr) { - uint32_t read_loc, write_loc; - - /* - * Capture the read/write indices before they changed - */ - read_loc = rbi->ring_buffer->br_rindex; - write_loc = rbi->ring_buffer->br_windex; - - *write = HV_BYTES_AVAIL_TO_WRITE(read_loc, write_loc, - rbi->ring_data_size); - *read = rbi->ring_data_size - *write; + rbr->rxbr_imask = 1; + mb(); } -/** - * @brief Get the next write location for the specified ring buffer - */ static __inline uint32_t -get_next_write_location(hv_vmbus_ring_buffer_info *ring_info) +vmbus_rxbr_avail(const struct vmbus_rxbr *rbr) { - return ring_info->ring_buffer->br_windex; -} + uint32_t rindex, windex; -/** - * @brief Set the next write location for the specified ring buffer - */ -static __inline void -set_next_write_location(hv_vmbus_ring_buffer_info *ring_info, - uint32_t next_write_location) -{ - ring_info->ring_buffer->br_windex = next_write_location; -} + /* Get snapshot */ + rindex = rbr->rxbr_rindex; + windex = rbr->rxbr_windex; -/** - * @brief Get the next read location for the specified ring buffer - */ -static __inline uint32_t -get_next_read_location(hv_vmbus_ring_buffer_info *ring_info) -{ - return ring_info->ring_buffer->br_rindex; + return (rbr->rxbr_dsize - + VMBUS_BR_WAVAIL(rindex, windex, rbr->rxbr_dsize)); } -/** - * @brief Get the next read location + offset for the specified ring buffer. - * This allows the caller to skip. - */ -static __inline uint32_t -get_next_read_location_with_offset(hv_vmbus_ring_buffer_info *ring_info, - uint32_t offset) +uint32_t +vmbus_rxbr_intr_unmask(struct vmbus_rxbr *rbr) { - uint32_t next = ring_info->ring_buffer->br_rindex; + rbr->rxbr_imask = 0; + mb(); - next += offset; - next %= ring_info->ring_data_size; - return (next); + /* + * Now check to see if the ring buffer is still empty. + * If it is not, we raced and we need to process new + * incoming channel packets. + */ + return vmbus_rxbr_avail(rbr); } -/** - * @brief Set the next read location for the specified ring buffer - */ -static __inline void -set_next_read_location(hv_vmbus_ring_buffer_info *ring_info, - uint32_t next_read_location) +static void +vmbus_br_setup(struct vmbus_br *br, void *buf, int blen) { - ring_info->ring_buffer->br_rindex = next_read_location; + br->vbr = buf; + br->vbr_dsize = blen - sizeof(struct vmbus_bufring); } -/** - * @brief Get the start of the ring buffer - */ -static __inline void * -get_ring_buffer(hv_vmbus_ring_buffer_info *ring_info) +void +vmbus_rxbr_init(struct vmbus_rxbr *rbr) { - return ring_info->ring_buffer->br_data; + mtx_init(&rbr->rxbr_lock, "vmbus_rxbr", NULL, MTX_SPIN); } -/** - * @brief Get the size of the ring buffer. - */ -static __inline uint32_t -get_ring_buffer_size(hv_vmbus_ring_buffer_info *ring_info) +void +vmbus_rxbr_deinit(struct vmbus_rxbr *rbr) { - return ring_info->ring_data_size; + mtx_destroy(&rbr->rxbr_lock); } -/** - * Get the read and write indices as uint64_t of the specified ring buffer. - */ -static __inline uint64_t -get_ring_buffer_indices(hv_vmbus_ring_buffer_info *ring_info) +void +vmbus_rxbr_setup(struct vmbus_rxbr *rbr, void *buf, int blen) { - return ((uint64_t)ring_info->ring_buffer->br_windex) << 32; + vmbus_br_setup(&rbr->rxbr, buf, blen); } void -hv_ring_buffer_read_begin(hv_vmbus_ring_buffer_info *ring_info) +vmbus_txbr_init(struct vmbus_txbr *tbr) { - ring_info->ring_buffer->br_imask = 1; - mb(); + mtx_init(&tbr->txbr_lock, "vmbus_txbr", NULL, MTX_SPIN); } -uint32_t -hv_ring_buffer_read_end(hv_vmbus_ring_buffer_info *ring_info) +void +vmbus_txbr_deinit(struct vmbus_txbr *tbr) { - uint32_t read, write; - - ring_info->ring_buffer->br_imask = 0; - mb(); + mtx_destroy(&tbr->txbr_lock); +} - /* - * Now check to see if the ring buffer is still empty. - * If it is not, we raced and we need to process new - * incoming messages. - */ - get_ring_buffer_avail_bytes(ring_info, &read, &write); - return (read); +void +vmbus_txbr_setup(struct vmbus_txbr *tbr, void *buf, int blen) +{ + vmbus_br_setup(&tbr->txbr, buf, blen); } /* - * When we write to the ring buffer, check if the host needs to - * be signaled. Here is the details of this protocol: - * - * 1. The host guarantees that while it is draining the - * ring buffer, it will set the interrupt_mask to - * indicate it does not need to be interrupted when - * new data is placed. + * When we write to the ring buffer, check if the host needs to be + * signaled. * - * 2. The host guarantees that it will completely drain - * the ring buffer before exiting the read loop. Further, - * once the ring buffer is empty, it will clear the - * interrupt_mask and re-check to see if new data has - * arrived. + * The contract: + * - The host guarantees that while it is draining the TX bufring, + * it will set the br_imask to indicate it does not need to be + * interrupted when new data are added. + * - The host guarantees that it will completely drain the TX bufring + * before exiting the read loop. Further, once the TX bufring is + * empty, it will clear the br_imask and re-check to see if new + * data have arrived. */ -static boolean_t -hv_ring_buffer_needsig_on_write(uint32_t old_write_location, - hv_vmbus_ring_buffer_info *rbi) +static __inline boolean_t +vmbus_txbr_need_signal(const struct vmbus_txbr *tbr, uint32_t old_windex) { mb(); - if (rbi->ring_buffer->br_imask) + if (tbr->txbr_imask) return (FALSE); + /* XXX only compiler fence is needed */ /* Read memory barrier */ rmb(); + /* * This is the only case we need to signal when the * ring transitions from being empty to non-empty. */ - if (old_write_location == rbi->ring_buffer->br_rindex) + if (old_windex == tbr->txbr_rindex) return (TRUE); return (FALSE); } -/** - * @brief Initialize the ring buffer. - */ -int -hv_vmbus_ring_buffer_init(hv_vmbus_ring_buffer_info *ring_info, void *buffer, - uint32_t buffer_len) +static __inline uint32_t +vmbus_txbr_avail(const struct vmbus_txbr *tbr) { - memset(ring_info, 0, sizeof(hv_vmbus_ring_buffer_info)); - - ring_info->ring_buffer = buffer; - ring_info->ring_buffer->br_rindex = 0; - ring_info->ring_buffer->br_windex = 0; + uint32_t rindex, windex; - ring_info->ring_data_size = buffer_len - sizeof(struct vmbus_bufring); - mtx_init(&ring_info->ring_lock, "vmbus ring buffer", NULL, MTX_SPIN); + /* Get snapshot */ + rindex = tbr->txbr_rindex; + windex = tbr->txbr_windex; - return (0); + return VMBUS_BR_WAVAIL(rindex, windex, tbr->txbr_dsize); } -/** - * @brief Cleanup the ring buffer. - */ -void -hv_ring_buffer_cleanup(hv_vmbus_ring_buffer_info *ring_info) +static __inline uint32_t +vmbus_txbr_copyto(const struct vmbus_txbr *tbr, uint32_t windex, + const void *src0, uint32_t cplen) { - mtx_destroy(&ring_info->ring_lock); + const uint8_t *src = src0; + uint8_t *br_data = tbr->txbr_data; + uint32_t br_dsize = tbr->txbr_dsize; + + if (cplen > br_dsize - windex) { + uint32_t fraglen = br_dsize - windex; + + /* Wrap-around detected */ + memcpy(br_data + windex, src, fraglen); + memcpy(br_data, src + fraglen, cplen - fraglen); + } else { + memcpy(br_data + windex, src, cplen); + } + return VMBUS_BR_IDXINC(windex, cplen, br_dsize); } -/** - * @brief Write to the ring buffer. +/* + * Write scattered channel packet to TX bufring. + * + * The offset of this channel packet is written as a 64bits value + * immediately after this channel packet. */ int -hv_ring_buffer_write(hv_vmbus_ring_buffer_info *out_ring_info, - const struct iovec iov[], uint32_t iovlen, boolean_t *need_sig) +vmbus_txbr_write(struct vmbus_txbr *tbr, const struct iovec iov[], int iovlen, + boolean_t *need_sig) { - int i = 0; - uint32_t byte_avail_to_write; - uint32_t byte_avail_to_read; - uint32_t old_write_location; - uint32_t total_bytes_to_write = 0; - volatile uint32_t next_write_location; - uint64_t prev_indices = 0; + uint32_t old_windex, windex, total; + uint64_t save_windex; + int i; + total = 0; for (i = 0; i < iovlen; i++) - total_bytes_to_write += iov[i].iov_len; + total += iov[i].iov_len; + total += sizeof(save_windex); - total_bytes_to_write += sizeof(uint64_t); - - mtx_lock_spin(&out_ring_info->ring_lock); - - get_ring_buffer_avail_bytes(out_ring_info, &byte_avail_to_read, - &byte_avail_to_write); + mtx_lock_spin(&tbr->txbr_lock); /* - * If there is only room for the packet, assume it is full. - * Otherwise, the next time around, we think the ring buffer - * is empty since the read index == write index + * NOTE: + * If this write is going to make br_windex same as br_rindex, + * i.e. the available space for write is same as the write size, + * we can't do it then, since br_windex == br_rindex means that + * the bufring is empty. */ - if (byte_avail_to_write <= total_bytes_to_write) { - mtx_unlock_spin(&out_ring_info->ring_lock); + if (vmbus_txbr_avail(tbr) <= total) { + mtx_unlock_spin(&tbr->txbr_lock); return (EAGAIN); } + /* Save br_windex for later use */ + old_windex = tbr->txbr_windex; + /* - * Write to the ring buffer + * Copy the scattered channel packet to the TX bufring. */ - next_write_location = get_next_write_location(out_ring_info); - - old_write_location = next_write_location; - + windex = old_windex; for (i = 0; i < iovlen; i++) { - next_write_location = copy_to_ring_buffer(out_ring_info, - next_write_location, iov[i].iov_base, iov[i].iov_len); + windex = vmbus_txbr_copyto(tbr, windex, + iov[i].iov_base, iov[i].iov_len); } /* - * Set previous packet start + * Set the offset of the current channel packet. */ - prev_indices = get_ring_buffer_indices(out_ring_info); - - next_write_location = copy_to_ring_buffer(out_ring_info, - next_write_location, (char *)&prev_indices, sizeof(uint64_t)); + save_windex = ((uint64_t)old_windex) << 32; + windex = vmbus_txbr_copyto(tbr, windex, &save_windex, + sizeof(save_windex)); /* + * XXX only compiler fence is needed. * Full memory barrier before upding the write index. */ mb(); /* - * Now, update the write location + * Update the write index _after_ the channel packet + * is copied. */ - set_next_write_location(out_ring_info, next_write_location); + tbr->txbr_windex = windex; - mtx_unlock_spin(&out_ring_info->ring_lock); + mtx_unlock_spin(&tbr->txbr_lock); - *need_sig = hv_ring_buffer_needsig_on_write(old_write_location, - out_ring_info); + *need_sig = vmbus_txbr_need_signal(tbr, old_windex); return (0); } -/** - * @brief Read without advancing the read index. - */ -int -hv_ring_buffer_peek(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer, - uint32_t buffer_len) +static __inline uint32_t +vmbus_rxbr_copyfrom(const struct vmbus_rxbr *rbr, uint32_t rindex, + void *dst0, int cplen) { - uint32_t bytesAvailToWrite; - uint32_t bytesAvailToRead; - uint32_t nextReadLocation = 0; - - mtx_lock_spin(&in_ring_info->ring_lock); + uint8_t *dst = dst0; + const uint8_t *br_data = rbr->rxbr_data; + uint32_t br_dsize = rbr->rxbr_dsize; + + if (cplen > br_dsize - rindex) { + uint32_t fraglen = br_dsize - rindex; + + /* Wrap-around detected. */ + memcpy(dst, br_data + rindex, fraglen); + memcpy(dst + fraglen, br_data, cplen - fraglen); + } else { + memcpy(dst, br_data + rindex, cplen); + } + return VMBUS_BR_IDXINC(rindex, cplen, br_dsize); +} - get_ring_buffer_avail_bytes(in_ring_info, &bytesAvailToRead, - &bytesAvailToWrite); +int +vmbus_rxbr_peek(struct vmbus_rxbr *rbr, void *data, int dlen) +{ + mtx_lock_spin(&rbr->rxbr_lock); /* - * Make sure there is something to read + * The requested data and the 64bits channel packet + * offset should be there at least. */ - if (bytesAvailToRead < buffer_len) { - mtx_unlock_spin(&in_ring_info->ring_lock); + if (vmbus_rxbr_avail(rbr) < dlen + sizeof(uint64_t)) { + mtx_unlock_spin(&rbr->rxbr_lock); return (EAGAIN); } + vmbus_rxbr_copyfrom(rbr, rbr->rxbr_rindex, data, dlen); - /* - * Convert to byte offset - */ - nextReadLocation = get_next_read_location(in_ring_info); - - nextReadLocation = copy_from_ring_buffer(in_ring_info, - (char *)buffer, buffer_len, nextReadLocation); - - mtx_unlock_spin(&in_ring_info->ring_lock); + mtx_unlock_spin(&rbr->rxbr_lock); return (0); } -/** - * @brief Read and advance the read index. +/* + * NOTE: + * We assume (dlen + skip) == sizeof(channel packet). */ int -hv_ring_buffer_read(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer, - uint32_t buffer_len, uint32_t offset) +vmbus_rxbr_read(struct vmbus_rxbr *rbr, void *data, int dlen, uint32_t skip) { - uint32_t bytes_avail_to_write; - uint32_t bytes_avail_to_read; - uint32_t next_read_location = 0; - uint64_t prev_indices = 0; - - if (buffer_len <= 0) - return (EINVAL); + uint32_t rindex, br_dsize = rbr->rxbr_dsize; - mtx_lock_spin(&in_ring_info->ring_lock); + KASSERT(dlen + skip > 0, ("invalid dlen %d, offset %u", dlen, skip)); - get_ring_buffer_avail_bytes(in_ring_info, &bytes_avail_to_read, - &bytes_avail_to_write); + mtx_lock_spin(&rbr->rxbr_lock); - /* - * Make sure there is something to read - */ - if (bytes_avail_to_read < buffer_len) { - mtx_unlock_spin(&in_ring_info->ring_lock); + if (vmbus_rxbr_avail(rbr) < dlen + skip + sizeof(uint64_t)) { + mtx_unlock_spin(&rbr->rxbr_lock); return (EAGAIN); } - next_read_location = get_next_read_location_with_offset(in_ring_info, - offset); - - next_read_location = copy_from_ring_buffer(in_ring_info, (char *)buffer, - buffer_len, next_read_location); + /* + * Copy channel packet from RX bufring. + */ + rindex = VMBUS_BR_IDXINC(rbr->rxbr_rindex, skip, br_dsize); + rindex = vmbus_rxbr_copyfrom(rbr, rindex, data, dlen); - next_read_location = copy_from_ring_buffer(in_ring_info, - (char *)&prev_indices, sizeof(uint64_t), next_read_location); + /* + * Discard this channel packet's 64bits offset, which is useless to us. + */ + rindex = VMBUS_BR_IDXINC(rindex, sizeof(uint64_t), br_dsize); /* + * XXX only compiler fence is needed. * Make sure all reads are done before we update the read index since * the writer may start writing to the read area once the read index * is updated. @@ -461,67 +407,11 @@ hv_ring_buffer_read(hv_vmbus_ring_buffer wmb(); /* - * Update the read index + * Update the read index _after_ the channel packet is fetched. */ - set_next_read_location(in_ring_info, next_read_location); + rbr->rxbr_rindex = rindex; - mtx_unlock_spin(&in_ring_info->ring_lock); + mtx_unlock_spin(&rbr->rxbr_lock); return (0); } - -/** - * @brief Helper routine to copy from source to ring buffer. - * - * Assume there is enough room. Handles wrap-around in dest case only! - */ -static uint32_t -copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, - uint32_t start_write_offset, const uint8_t *src, uint32_t src_len) -{ - char *ring_buffer = get_ring_buffer(ring_info); - uint32_t ring_buffer_size = get_ring_buffer_size(ring_info); - uint32_t fragLen; - - if (src_len > ring_buffer_size - start_write_offset) { - /* wrap-around detected! */ - fragLen = ring_buffer_size - start_write_offset; - memcpy(ring_buffer + start_write_offset, src, fragLen); - memcpy(ring_buffer, src + fragLen, src_len - fragLen); - } else { - memcpy(ring_buffer + start_write_offset, src, src_len); - } - - start_write_offset += src_len; - start_write_offset %= ring_buffer_size; - - return (start_write_offset); -} - -/** - * @brief Helper routine to copy to source from ring buffer. - * - * Assume there is enough room. Handles wrap-around in src case only! - */ -static uint32_t -copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, char *dest, - uint32_t dest_len, uint32_t start_read_offset) -{ - uint32_t fragLen; - char *ring_buffer = get_ring_buffer(ring_info); - uint32_t ring_buffer_size = get_ring_buffer_size(ring_info); - - if (dest_len > ring_buffer_size - start_read_offset) { - /* wrap-around detected at the src */ - fragLen = ring_buffer_size - start_read_offset; - memcpy(dest, ring_buffer + start_read_offset, fragLen); - memcpy(dest + fragLen, ring_buffer, dest_len - fragLen); - } else { - memcpy(dest, ring_buffer + start_read_offset, dest_len); - } - - start_read_offset += dest_len; - start_read_offset %= ring_buffer_size; - - return (start_read_offset); -} Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Wed Oct 12 05:09:22 2016 (r307102) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Wed Oct 12 05:09:26 2016 (r307103) @@ -28,58 +28,66 @@ * $FreeBSD$ */ -#ifndef __HYPERV_PRIV_H__ -#define __HYPERV_PRIV_H__ +#ifndef _VMBUS_BRVAR_H_ +#define _VMBUS_BRVAR_H_ #include #include #include -#include #include -#include +struct vmbus_br { + struct vmbus_bufring *vbr; + uint32_t vbr_dsize; /* total data size */ +}; + +#define vbr_windex vbr->br_windex +#define vbr_rindex vbr->br_rindex +#define vbr_imask vbr->br_imask +#define vbr_data vbr->br_data + +struct vmbus_rxbr { + struct mtx rxbr_lock; + struct vmbus_br rxbr; +}; + +#define rxbr_windex rxbr.vbr_windex +#define rxbr_rindex rxbr.vbr_rindex +#define rxbr_imask rxbr.vbr_imask +#define rxbr_data rxbr.vbr_data +#define rxbr_dsize rxbr.vbr_dsize + +struct vmbus_txbr { + struct mtx txbr_lock; + struct vmbus_br txbr; +}; + +#define txbr_windex txbr.vbr_windex +#define txbr_rindex txbr.vbr_rindex +#define txbr_imask txbr.vbr_imask +#define txbr_data txbr.vbr_data +#define txbr_dsize txbr.vbr_dsize -struct vmbus_softc; - -/* - * Private, VM Bus functions - */ struct sysctl_ctx_list; struct sysctl_oid; -void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, - struct sysctl_oid *br_tree, hv_vmbus_ring_buffer_info *br, - const char *name); - -int hv_vmbus_ring_buffer_init( - hv_vmbus_ring_buffer_info *ring_info, - void *buffer, - uint32_t buffer_len); - -void hv_ring_buffer_cleanup( - hv_vmbus_ring_buffer_info *ring_info); - -int hv_ring_buffer_write( - hv_vmbus_ring_buffer_info *ring_info, - const struct iovec iov[], - uint32_t iovlen, - boolean_t *need_sig); - -int hv_ring_buffer_peek( - hv_vmbus_ring_buffer_info *ring_info, - void *buffer, - uint32_t buffer_len); - -int hv_ring_buffer_read( - hv_vmbus_ring_buffer_info *ring_info, - void *buffer, - uint32_t buffer_len, - uint32_t offset); - -void hv_ring_buffer_read_begin( - hv_vmbus_ring_buffer_info *ring_info); - -uint32_t hv_ring_buffer_read_end( - hv_vmbus_ring_buffer_info *ring_info); +void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, + struct sysctl_oid *br_tree, struct vmbus_br *br, + const char *name); + +void vmbus_rxbr_init(struct vmbus_rxbr *rbr); +void vmbus_rxbr_deinit(struct vmbus_rxbr *rbr); +void vmbus_rxbr_setup(struct vmbus_rxbr *rbr, void *buf, int blen); +int vmbus_rxbr_peek(struct vmbus_rxbr *rbr, void *data, int dlen); +int vmbus_rxbr_read(struct vmbus_rxbr *rbr, void *data, int dlen, + uint32_t skip); +void vmbus_rxbr_intr_mask(struct vmbus_rxbr *rbr); +uint32_t vmbus_rxbr_intr_unmask(struct vmbus_rxbr *rbr); + +void vmbus_txbr_init(struct vmbus_txbr *tbr); +void vmbus_txbr_deinit(struct vmbus_txbr *tbr); +void vmbus_txbr_setup(struct vmbus_txbr *tbr, void *buf, int blen); +int vmbus_txbr_write(struct vmbus_txbr *tbr, + const struct iovec iov[], int iovlen, boolean_t *need_sig); -#endif /* __HYPERV_PRIV_H__ */ +#endif /* _VMBUS_BRVAR_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 05:09:22 2016 (r307102) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 05:09:26 2016 (r307103) @@ -178,11 +178,11 @@ vmbus_chan_sysctl_create(struct vmbus_ch /* * Create sysctl tree for RX bufring. */ - vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr, "rx"); + vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr.rxbr, "rx"); /* * Create sysctl tree for TX bufring. */ - vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr, "tx"); + vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr.txbr, "tx"); } } @@ -239,9 +239,9 @@ vmbus_chan_open(struct vmbus_channel *ch chan->ch_bufring = br; /* TX bufring comes first */ - hv_vmbus_ring_buffer_init(&chan->ch_txbr, br, txbr_size); + vmbus_txbr_setup(&chan->ch_txbr, br, txbr_size); /* RX bufring immediately follows TX bufring */ - hv_vmbus_ring_buffer_init(&chan->ch_rxbr, br + txbr_size, rxbr_size); + vmbus_rxbr_setup(&chan->ch_rxbr, br + txbr_size, rxbr_size); /* Create sysctl tree for this channel */ vmbus_chan_sysctl_create(chan); @@ -549,8 +549,6 @@ vmbus_chan_close_internal(struct vmbus_c /* * Destroy the TX+RX bufrings. */ - hv_ring_buffer_cleanup(&chan->ch_txbr); - hv_ring_buffer_cleanup(&chan->ch_rxbr); if (chan->ch_bufring != NULL) { hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); chan->ch_bufring = NULL; @@ -620,7 +618,7 @@ vmbus_chan_send(struct vmbus_channel *ch iov[2].iov_base = &pad; iov[2].iov_len = pad_pktlen - pktlen; - error = hv_ring_buffer_write(&chan->ch_txbr, iov, 3, &send_evt); + error = vmbus_txbr_write(&chan->ch_txbr, iov, 3, &send_evt); if (!error && send_evt) vmbus_chan_signal_tx(chan); return error; @@ -660,7 +658,7 @@ vmbus_chan_send_sglist(struct vmbus_chan iov[3].iov_base = &pad; iov[3].iov_len = pad_pktlen - pktlen; - error = hv_ring_buffer_write(&chan->ch_txbr, iov, 4, &send_evt); + error = vmbus_txbr_write(&chan->ch_txbr, iov, 4, &send_evt); if (!error && send_evt) vmbus_chan_signal_tx(chan); return error; @@ -702,7 +700,7 @@ vmbus_chan_send_prplist(struct vmbus_cha iov[3].iov_base = &pad; iov[3].iov_len = pad_pktlen - pktlen; - error = hv_ring_buffer_write(&chan->ch_txbr, iov, 4, &send_evt); + error = vmbus_txbr_write(&chan->ch_txbr, iov, 4, &send_evt); if (!error && send_evt) vmbus_chan_signal_tx(chan); return error; @@ -715,7 +713,7 @@ vmbus_chan_recv(struct vmbus_channel *ch struct vmbus_chanpkt_hdr pkt; int error, dlen, hlen; - error = hv_ring_buffer_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); + error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); if (error) return error; @@ -732,8 +730,8 @@ vmbus_chan_recv(struct vmbus_channel *ch *dlen0 = dlen; /* Skip packet header */ - error = hv_ring_buffer_read(&chan->ch_rxbr, data, dlen, hlen); - KASSERT(!error, ("hv_ring_buffer_read failed")); + error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen); + KASSERT(!error, ("vmbus_rxbr_read failed")); return 0; } @@ -745,7 +743,7 @@ vmbus_chan_recv_pkt(struct vmbus_channel struct vmbus_chanpkt_hdr pkt; int error, pktlen; - error = hv_ring_buffer_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); + error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); if (error) return error; @@ -758,8 +756,8 @@ vmbus_chan_recv_pkt(struct vmbus_channel *pktlen0 = pktlen; /* Include packet header */ - error = hv_ring_buffer_read(&chan->ch_rxbr, pkt0, pktlen, 0); - KASSERT(!error, ("hv_ring_buffer_read failed")); + error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0); + KASSERT(!error, ("vmbus_rxbr_read failed")); return 0; } @@ -788,12 +786,12 @@ vmbus_chan_task(void *xchan, int pending cb(chan, cbarg); - left = hv_ring_buffer_read_end(&chan->ch_rxbr); + left = vmbus_rxbr_intr_unmask(&chan->ch_rxbr); if (left == 0) { /* No more data in RX bufring; done */ break; } - hv_ring_buffer_read_begin(&chan->ch_rxbr); + vmbus_rxbr_intr_mask(&chan->ch_rxbr); } } @@ -835,7 +833,7 @@ vmbus_event_flags_proc(struct vmbus_soft continue; if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) - hv_ring_buffer_read_begin(&chan->ch_rxbr); + vmbus_rxbr_intr_mask(&chan->ch_rxbr); taskqueue_enqueue(chan->ch_tq, &chan->ch_task); } } @@ -914,6 +912,8 @@ vmbus_chan_alloc(struct vmbus_softc *sc) mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); TAILQ_INIT(&chan->ch_subchans); TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); + vmbus_rxbr_init(&chan->ch_rxbr); + vmbus_txbr_init(&chan->ch_txbr); return chan; } @@ -926,6 +926,8 @@ vmbus_chan_free(struct vmbus_channel *ch /* TODO: asset no longer on the vmbus channel list */ hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); mtx_destroy(&chan->ch_subchan_lock); + vmbus_rxbr_deinit(&chan->ch_rxbr); + vmbus_txbr_deinit(&chan->ch_txbr); free(chan, M_DEVBUF); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 05:09:22 2016 (r307102) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 05:09:26 2016 (r307103) @@ -39,12 +39,7 @@ #include #include #include - -typedef struct { - struct vmbus_bufring *ring_buffer; - struct mtx ring_lock; - uint32_t ring_data_size; /* ring_size */ -} hv_vmbus_ring_buffer_info; +#include struct vmbus_channel { /* @@ -57,7 +52,7 @@ struct vmbus_channel { /* * RX bufring; immediately following ch_txbr. */ - hv_vmbus_ring_buffer_info ch_rxbr; + struct vmbus_rxbr ch_rxbr; struct taskqueue *ch_tq; struct task ch_task; @@ -76,7 +71,7 @@ struct vmbus_channel { * TX bufring and following MNF/evtflags do _not_ fit in * one 64B cacheline. */ - hv_vmbus_ring_buffer_info ch_txbr __aligned(CACHE_LINE_SIZE); + struct vmbus_txbr ch_txbr __aligned(CACHE_LINE_SIZE); uint32_t ch_txflags; /* VMBUS_CHAN_TXF_ */ /* From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:28:26 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9F651C0E1AF; Wed, 12 Oct 2016 05:28:26 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7703EC5C; Wed, 12 Oct 2016 05:28:26 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5SPJI016937; Wed, 12 Oct 2016 05:28:25 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5SPGp016933; Wed, 12 Oct 2016 05:28:25 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120528.u9C5SPGp016933@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 05:28:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307114 - in stable/10/sys: conf dev/hyperv/vmbus modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:28:26 -0000 Author: sephe Date: Wed Oct 12 05:28:24 2016 New Revision: 307114 URL: https://svnweb.freebsd.org/changeset/base/307114 Log: MFC 303379 hyperv/vmbus: Rename cleaned up bufring code Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7318 Added: stable/10/sys/dev/hyperv/vmbus/vmbus_br.c - copied, changed from r303379, head/sys/dev/hyperv/vmbus/vmbus_br.c Deleted: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Wed Oct 12 05:20:06 2016 (r307113) +++ stable/10/sys/conf/files.amd64 Wed Oct 12 05:28:24 2016 (r307114) @@ -271,10 +271,10 @@ dev/hyperv/utilities/hv_kvp.c optiona dev/hyperv/utilities/hv_shutdown.c optional hyperv dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv -dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv +dev/hyperv/vmbus/vmbus_br.c optional hyperv dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Wed Oct 12 05:20:06 2016 (r307113) +++ stable/10/sys/conf/files.i386 Wed Oct 12 05:28:24 2016 (r307114) @@ -248,10 +248,10 @@ dev/hyperv/utilities/hv_kvp.c optiona dev/hyperv/utilities/hv_shutdown.c optional hyperv dev/hyperv/utilities/hv_timesync.c optional hyperv dev/hyperv/utilities/hv_util.c optional hyperv -dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv +dev/hyperv/vmbus/vmbus_br.c optional hyperv dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv Copied and modified: stable/10/sys/dev/hyperv/vmbus/vmbus_br.c (from r303379, head/sys/dev/hyperv/vmbus/vmbus_br.c) ============================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_br.c Wed Jul 27 09:27:08 2016 (r303379, copy source) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_br.c Wed Oct 12 05:28:24 2016 (r307114) @@ -26,6 +26,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +__FBSDID("$FreeBSD$"); + #include #include #include Modified: stable/10/sys/modules/hyperv/vmbus/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/vmbus/Makefile Wed Oct 12 05:20:06 2016 (r307113) +++ stable/10/sys/modules/hyperv/vmbus/Makefile Wed Oct 12 05:28:24 2016 (r307114) @@ -4,11 +4,11 @@ ${.CURDIR}/../../../dev/hyperv/vmbus/${MACHINE_CPUARCH} KMOD= hv_vmbus -SRCS= hv_ring_buffer.c \ - hyperv.c \ +SRCS= hyperv.c \ hyperv_busdma.c \ hyperv_machdep.c \ vmbus.c \ + vmbus_br.c \ vmbus_chan.c \ vmbus_et.c SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h vmbus_if.h From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:36:56 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E9B70C0E457; Wed, 12 Oct 2016 05:36:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9B0FB2B1; Wed, 12 Oct 2016 05:36:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5atRV021171; Wed, 12 Oct 2016 05:36:55 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5atPW021170; Wed, 12 Oct 2016 05:36:55 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120536.u9C5atPW021170@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:36:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307116 - stable/10/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:36:57 -0000 Author: mav Date: Wed Oct 12 05:36:55 2016 New Revision: 307116 URL: https://svnweb.freebsd.org/changeset/base/307116 Log: MFC r305194: MFV r302642: 6876 Stack corruption after importing a pool with a too-long name illumos/illumos-gate@c971037baa5d64dfecf6d87ed602fc3116ebec41 https://github.com/illumos/illumos-gate/commit/c971037baa5d64dfecf6d87ed602fc3116ebec41 https://www.illumos.org/issues/6876 Calling dsl_dataset_name on a dataset with a 256 byte buffer is asking for trouble. We should check every dataset on import, using a 1024 byte buffer and checking each time to see if the dataset's new name is longer than 256 bytes. Reviewed by: Prakash Surya Reviewed by: Dan Kimmel Reviewed by: George Wilson Reviewed by: Yuri Pankov Approved by: Richard Lowe Author: Paul Dagnelie Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Wed Oct 12 05:35:57 2016 (r307115) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Wed Oct 12 05:36:55 2016 (r307116) @@ -1799,7 +1799,12 @@ zpool_import_props(libzfs_handle_t *hdl, case EEXIST: (void) zpool_standard_error(hdl, error, desc); break; - + case ENAMETOOLONG: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "new name of at least one dataset is longer than " + "the maximum allowable length")); + (void) zfs_error(hdl, EZFS_NAMETOOLONG, desc); + break; default: (void) zpool_standard_error(hdl, error, desc); zpool_explain_recover(hdl, From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:37:56 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 199A1C0E4C3; Wed, 12 Oct 2016 05:37:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E64D6651; Wed, 12 Oct 2016 05:37:55 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5bscu021262; Wed, 12 Oct 2016 05:37:54 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5bsRS021261; Wed, 12 Oct 2016 05:37:54 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120537.u9C5bsRS021261@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:37:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307117 - stable/10/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:37:56 -0000 Author: mav Date: Wed Oct 12 05:37:54 2016 New Revision: 307117 URL: https://svnweb.freebsd.org/changeset/base/307117 Log: MFC r305201: MFV r302653: 6111 zfs send should ignore datasets created after the ending snapshot illumos/illumos-gate@4a20c933b148de8a1c1d3538391c64284e636653 https://github.com/illumos/illumos-gate/commit/4a20c933b148de8a1c1d3538391c64284 e636653 https://www.illumos.org/issues/6111 If you create a zfs child folder, zfs send returns an error when a recursive incremental send is done between two snapshots made prior to the folder creation. The problem can be reproduced with the following steps. root@zfs:/# zfs create pool/test root@zfs:/# zfs snapshot pool/test@snap1 root@zfs:/# zfs snapshot pool/test@snap2 root@zfs:/# zfs create pool/test/child root@zfs:/# zfs send -R -I pool/test@snap1 pool/test@snap2 > /dev/null WARNING: could not send pool/test/child@snap2: does not exist WARNING: could not send pool/test/child@snap2: does not exist root@zfs:/# echo $? 1 root@zfs:/# zfs snapshot -r pool/test@snap3 root@zfs:/# zfs send -R -I pool/test@snap1 pool/test@snap3 > /dev/null root@zfs:/# echo $? 0 root@zfs:/# zfs send -R -I pool/test@snap2 pool/test@snap3 > /dev/null root@zfs:/# echo $? 0 Since pool/test/child was created after snap2, zfs send should not expect snap2 to be in pool/test/child when doing a recursive send. It should examine the compare the creation time of the snapshot and each child folder to decide if the folder will be sent. The next incremental send between snap2 and snap3 would properly create the child folder and snap3 which first appears in the child folder. The problem is identical if '-i' is used instead of '-I'. Reviewed by: Alex Aizman alex.aizman@nexenta.com Reviewed by: Alek Pinchuk alek.pinchuk@nexenta.com Reviewed by: Roman Strashkin roman.strashkin@nexenta.com Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Approved by: Garrett D'Amore Author: Alex Deiter Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:36:55 2016 (r307116) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:37:54 2016 (r307117) @@ -580,13 +580,30 @@ fsavl_create(nvlist_t *fss) * Routines for dealing with the giant nvlist of fs-nvlists, etc. */ typedef struct send_data { + /* + * assigned inside every recursive call, + * restored from *_save on return: + * + * guid of fromsnap snapshot in parent dataset + * txg of fromsnap snapshot in current dataset + * txg of tosnap snapshot in current dataset + */ + uint64_t parent_fromsnap_guid; + uint64_t fromsnap_txg; + uint64_t tosnap_txg; + + /* the nvlists get accumulated during depth-first traversal */ nvlist_t *parent_snaps; nvlist_t *fss; nvlist_t *snapprops; + + /* send-receive configuration, does not change during traversal */ + const char *fsname; const char *fromsnap; const char *tosnap; boolean_t recursive; + boolean_t verbose; /* * The header nvlist is of the following format: @@ -619,11 +636,23 @@ send_iterate_snap(zfs_handle_t *zhp, voi { send_data_t *sd = arg; uint64_t guid = zhp->zfs_dmustats.dds_guid; + uint64_t txg = zhp->zfs_dmustats.dds_creation_txg; char *snapname; nvlist_t *nv; snapname = strrchr(zhp->zfs_name, '@')+1; + if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) { + if (sd->verbose) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "skipping snapshot %s because it was created " + "after the destination snapshot (%s)\n"), + zhp->zfs_name, sd->tosnap); + } + zfs_close(zhp); + return (0); + } + VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid)); /* * NB: if there is no fromsnap here (it's a newly created fs in @@ -717,6 +746,31 @@ send_iterate_prop(zfs_handle_t *zhp, nvl } /* + * returns snapshot creation txg + * and returns 0 if the snapshot does not exist + */ +static uint64_t +get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap) +{ + char name[ZFS_MAXNAMELEN]; + uint64_t txg = 0; + + if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0') + return (txg); + + (void) snprintf(name, sizeof (name), "%s@%s", fs, snap); + if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) { + zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT); + if (zhp != NULL) { + txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG); + zfs_close(zhp); + } + } + + return (txg); +} + +/* * recursively generate nvlists describing datasets. See comment * for the data structure send_data_t above for description of contents * of the nvlist. @@ -728,9 +782,48 @@ send_iterate_fs(zfs_handle_t *zhp, void nvlist_t *nvfs, *nv; int rv = 0; uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid; + uint64_t fromsnap_txg_save = sd->fromsnap_txg; + uint64_t tosnap_txg_save = sd->tosnap_txg; + uint64_t txg = zhp->zfs_dmustats.dds_creation_txg; uint64_t guid = zhp->zfs_dmustats.dds_guid; + uint64_t fromsnap_txg, tosnap_txg; char guidstring[64]; + fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap); + if (fromsnap_txg != 0) + sd->fromsnap_txg = fromsnap_txg; + + tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap); + if (tosnap_txg != 0) + sd->tosnap_txg = tosnap_txg; + + /* + * on the send side, if the current dataset does not have tosnap, + * perform two additional checks: + * + * - skip sending the current dataset if it was created later than + * the parent tosnap + * - return error if the current dataset was created earlier than + * the parent tosnap + */ + if (sd->tosnap != NULL && tosnap_txg == 0) { + if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) { + if (sd->verbose) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "skipping dataset %s: snapshot %s does " + "not exist\n"), zhp->zfs_name, sd->tosnap); + } + } else { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "cannot send %s@%s%s: snapshot %s@%s does not " + "exist\n"), sd->fsname, sd->tosnap, sd->recursive ? + dgettext(TEXT_DOMAIN, " recursively") : "", + zhp->zfs_name, sd->tosnap); + rv = -1; + } + goto out; + } + VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0)); VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name)); VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap", @@ -739,8 +832,10 @@ send_iterate_fs(zfs_handle_t *zhp, void if (zhp->zfs_dmustats.dds_origin[0]) { zfs_handle_t *origin = zfs_open(zhp->zfs_hdl, zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT); - if (origin == NULL) - return (-1); + if (origin == NULL) { + rv = -1; + goto out; + } VERIFY(0 == nvlist_add_uint64(nvfs, "origin", origin->zfs_dmustats.dds_guid)); } @@ -771,7 +866,10 @@ send_iterate_fs(zfs_handle_t *zhp, void if (sd->recursive) rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd); +out: sd->parent_fromsnap_guid = parent_fromsnap_guid_save; + sd->fromsnap_txg = fromsnap_txg_save; + sd->tosnap_txg = tosnap_txg_save; zfs_close(zhp); return (rv); @@ -779,7 +877,8 @@ send_iterate_fs(zfs_handle_t *zhp, void static int gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap, - const char *tosnap, boolean_t recursive, nvlist_t **nvlp, avl_tree_t **avlp) + const char *tosnap, boolean_t recursive, boolean_t verbose, + nvlist_t **nvlp, avl_tree_t **avlp) { zfs_handle_t *zhp; send_data_t sd = { 0 }; @@ -790,9 +889,11 @@ gather_nvlist(libzfs_handle_t *hdl, cons return (EZFS_BADTYPE); VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0)); + sd.fsname = fsname; sd.fromsnap = fromsnap; sd.tosnap = tosnap; sd.recursive = recursive; + sd.verbose = verbose; if ((error = send_iterate_fs(zhp, &sd)) != 0) { nvlist_free(sd.fss); @@ -1700,7 +1801,8 @@ zfs_send(zfs_handle_t *zhp, const char * } err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name, - fromsnap, tosnap, flags->replicate, &fss, &fsavl); + fromsnap, tosnap, flags->replicate, flags->verbose, + &fss, &fsavl); if (err) goto err_out; VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss)); @@ -2316,7 +2418,7 @@ again: VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0)); if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL, - recursive, &local_nv, &local_avl)) != 0) + recursive, B_FALSE, &local_nv, &local_avl)) != 0) return (error); /* @@ -3380,7 +3482,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in */ *cp = '\0'; if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE, - &local_nv, &local_avl) == 0) { + B_FALSE, &local_nv, &local_avl) == 0) { *cp = '@'; fs = fsavl_find(local_avl, drrb->drr_toguid, NULL); fsavl_destroy(local_avl); From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:38:46 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 497B8C0E52A; Wed, 12 Oct 2016 05:38:46 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 17256828; Wed, 12 Oct 2016 05:38:46 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5cj25021345; Wed, 12 Oct 2016 05:38:45 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5cjlf021344; Wed, 12 Oct 2016 05:38:45 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120538.u9C5cjlf021344@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:38:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307118 - stable/10/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:38:46 -0000 Author: mav Date: Wed Oct 12 05:38:44 2016 New Revision: 307118 URL: https://svnweb.freebsd.org/changeset/base/307118 Log: MFC r305202: MFV r302654: 6879 incorrect endianness swap for drr_spill.drr_length in libzfs_sendrecv.c illumos/illumos-gate@20fea7a47472aceb64d3ed48cc2a3ea268bc4795 https://github.com/illumos/illumos-gate/commit/20fea7a47472aceb64d3ed48cc2a3ea26 8bc4795 https://www.illumos.org/issues/6879 In libzfs_sendrecv, there's a typo: case DRR_SPILL: if (byteswap) { drr->drr_u.drr_write.drr_length = BSWAP_64(drr->drr_u.drr_spill.drr_length); } Instead of drr_write.drr_length, we should be assigning the result of the byteswap to drr_spill.drr_length. Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Approved by: Robert Mustacchi Author: Dan Kimmel Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:37:54 2016 (r307117) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:38:44 2016 (r307118) @@ -2968,7 +2968,7 @@ recv_skip(libzfs_handle_t *hdl, int fd, break; case DRR_SPILL: if (byteswap) { - drr->drr_u.drr_write.drr_length = + drr->drr_u.drr_spill.drr_length = BSWAP_64(drr->drr_u.drr_spill.drr_length); } (void) recv_read(hdl, fd, buf, From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:39:30 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AF1D7C0E58C; Wed, 12 Oct 2016 05:39:30 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8040998E; Wed, 12 Oct 2016 05:39:30 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5dTGU021432; Wed, 12 Oct 2016 05:39:29 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5dT6N021431; Wed, 12 Oct 2016 05:39:29 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120539.u9C5dT6N021431@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:39:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307119 - stable/10/cddl/contrib/opensolaris/lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:39:30 -0000 Author: mav Date: Wed Oct 12 05:39:29 2016 New Revision: 307119 URL: https://svnweb.freebsd.org/changeset/base/307119 Log: MFC r305203: MFV r302655: 6873 zfs_destroy_snaps_nvl leaks errlist illumos/illumos-gate@4cde22c29999ffb907ca39d2ebd512812f7e5168 https://github.com/illumos/illumos-gate/commit/4cde22c29999ffb907ca39d2ebd512812 f7e5168 https://www.illumos.org/issues/6873 lzc_destroy_snaps() returns an nvlist in errlist. zfs_destroy_snaps_nvl() should nvlist_free() it before returning. Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Approved by: Dan McDonald Author: Chris Williamson Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:38:44 2016 (r307118) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:39:29 2016 (r307119) @@ -3449,12 +3449,14 @@ int zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer) { int ret; - nvlist_t *errlist; + nvlist_t *errlist = NULL; ret = lzc_destroy_snaps(snaps, defer, &errlist); - if (ret == 0) + if (ret == 0) { + nvlist_free(errlist); return (0); + } if (nvlist_empty(errlist)) { char errbuf[1024]; @@ -3482,6 +3484,7 @@ zfs_destroy_snaps_nvl(libzfs_handle_t *h } } + nvlist_free(errlist); return (ret); } From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:41:12 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1007FC0E63F; Wed, 12 Oct 2016 05:41:12 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C6A35B9A; Wed, 12 Oct 2016 05:41:11 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5fAVr021585; Wed, 12 Oct 2016 05:41:10 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5fAWa021581; Wed, 12 Oct 2016 05:41:10 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120541.u9C5fAWa021581@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:41:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307120 - in stable/10/cddl/contrib/opensolaris: cmd/zfs lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:41:12 -0000 Author: mav Date: Wed Oct 12 05:41:10 2016 New Revision: 307120 URL: https://svnweb.freebsd.org/changeset/base/307120 Log: MFC r305205: MFV r302657: 4521 zfstest is trying to execute evil "zfs unmount -a" illumos/illumos-gate@8808ac5dae118369991f158b6ab736cb2691ecde https://github.com/illumos/illumos-gate/commit/8808ac5dae118369991f158b6ab736cb2 691ecde https://www.illumos.org/issues/4521 zfstest is trying to execute evil "zfs unmount -a", which fails (fortunately, as it would otherwise leave me with my ~ missing): 03:44:11.86 cannot unmount '/export/home/yuri': Device busy cannot unmount '/ export/home': Device busy 03:44:11.86 ERROR: /usr/sbin/zfs unmount -a exited 1 This affects, at least, zfs_mount_009_neg and zfs_mount_all_001_pos, both failing on that step. The pool containing the /export/home hierarchy is included in KEEP variable, but it doesn't seem to affect anything here. Reviewed by: Andriy Gapon Reviewed by: Dan McDonald Reviewed by: Matthew Ahrens Reviewed by: John Kennedy Approved by: Robert Mustacchi Author: Yuri Pankov Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Wed Oct 12 05:39:29 2016 (r307119) +++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Wed Oct 12 05:41:10 2016 (r307120) @@ -27,9 +27,9 @@ * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Igor Kozhukhov . + * Copyright 2016 Nexenta Systems, Inc. */ #include @@ -6469,6 +6469,15 @@ unshare_unmount(int op, int argc, char * continue; } + /* + * Ignore datasets that are excluded/restricted by + * parent pool name. + */ + if (zpool_skip_pool(zfs_get_pool_name(zhp))) { + zfs_close(zhp); + continue; + } + switch (op) { case OP_SHARE: verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Wed Oct 12 05:39:29 2016 (r307119) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Wed Oct 12 05:41:10 2016 (r307120) @@ -26,8 +26,8 @@ * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. */ #ifndef _LIBZFS_H @@ -221,6 +221,7 @@ extern void zpool_free_handles(libzfs_ha */ typedef int (*zpool_iter_f)(zpool_handle_t *, void *); extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *); +extern boolean_t zpool_skip_pool(const char *); /* * Functions to create and destroy pools @@ -411,6 +412,7 @@ extern void zfs_close(zfs_handle_t *); extern zfs_type_t zfs_get_type(const zfs_handle_t *); extern const char *zfs_get_name(const zfs_handle_t *); extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *); +extern const char *zfs_get_pool_name(const zfs_handle_t *); /* * Property management functions. Some functions are shared with the kernel, Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c Wed Oct 12 05:39:29 2016 (r307119) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c Wed Oct 12 05:41:10 2016 (r307120) @@ -27,6 +27,7 @@ /* * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright (c) 2015 by Syneto S.R.L. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. */ /* @@ -338,33 +339,47 @@ zpool_refresh_stats(zpool_handle_t *zhp, } /* - * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over - * pools it lists. + * The following environment variables are undocumented + * and should be used for testing purposes only: * - * This is an undocumented feature for use during testing only. + * __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists + * __ZFS_POOL_RESTRICT - iterate only over the pools it lists * * This function returns B_TRUE if the pool should be skipped * during iteration. */ -static boolean_t -check_restricted(const char *poolname) +boolean_t +zpool_skip_pool(const char *poolname) { static boolean_t initialized = B_FALSE; - static char *restricted = NULL; + static const char *exclude = NULL; + static const char *restricted = NULL; const char *cur, *end; - int len, namelen; + int len; + int namelen = strlen(poolname); if (!initialized) { initialized = B_TRUE; + exclude = getenv("__ZFS_POOL_EXCLUDE"); restricted = getenv("__ZFS_POOL_RESTRICT"); } + if (exclude != NULL) { + cur = exclude; + do { + end = strchr(cur, ' '); + len = (NULL == end) ? strlen(cur) : (end - cur); + if (len == namelen && 0 == strncmp(cur, poolname, len)) + return (B_TRUE); + cur += (len + 1); + } while (NULL != end); + } + if (NULL == restricted) return (B_FALSE); cur = restricted; - namelen = strlen(poolname); do { end = strchr(cur, ' '); len = (NULL == end) ? strlen(cur) : (end - cur); @@ -402,7 +417,7 @@ zpool_iter(libzfs_handle_t *hdl, zpool_i for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL; cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) { - if (check_restricted(cn->cn_name)) + if (zpool_skip_pool(cn->cn_name)) continue; if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) { @@ -440,7 +455,7 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_ for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL; cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) { - if (check_restricted(cn->cn_name)) + if (zpool_skip_pool(cn->cn_name)) continue; if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:39:29 2016 (r307119) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:41:10 2016 (r307120) @@ -27,9 +27,9 @@ * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. * Copyright (c) 2013 Martin Matuska. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Igor Kozhukhov + * Copyright 2016 Nexenta Systems, Inc. */ #include @@ -2945,6 +2945,15 @@ zfs_get_name(const zfs_handle_t *zhp) } /* + * Returns the name of the parent pool for the given zfs handle. + */ +const char * +zfs_get_pool_name(const zfs_handle_t *zhp) +{ + return (zhp->zpool_hdl->zpool_name); +} + +/* * Returns the type of the given zfs handle. */ zfs_type_t From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:42:02 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5A6CCC0E6A0; Wed, 12 Oct 2016 05:42:02 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1C4AAD98; Wed, 12 Oct 2016 05:42:02 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5g1Sa024958; Wed, 12 Oct 2016 05:42:01 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5g0RB024953; Wed, 12 Oct 2016 05:42:00 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120542.u9C5g0RB024953@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:42:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307121 - in stable/10/cddl/contrib/opensolaris: cmd/zpool lib/libzfs/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:42:02 -0000 Author: mav Date: Wed Oct 12 05:42:00 2016 New Revision: 307121 URL: https://svnweb.freebsd.org/changeset/base/307121 Log: MFC r305206: MFV r302658: 6872 zfs libraries should not allow uninitialized variables illumos/illumos-gate@f83b46baf98d276f5f84fa84c8b461f412ac1f5e https://github.com/illumos/illumos-gate/commit/f83b46baf98d276f5f84fa84c8b461f41 2ac1f5e https://www.illumos.org/issues/6872 We compile the zfs libraries with -Wno-uninitialized. We should remove this. Change makefiles, fix new warnings, fix pbchk errors. Reviewed by: Dan Kimmel Reviewed by: George Wilson Reviewed by: Prakash Surya Reviewed by: Yuri Pankov Approved by: Robert Mustacchi Author: Paul Dagnelie Modified: stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c Wed Oct 12 05:41:10 2016 (r307120) +++ stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c Wed Oct 12 05:42:00 2016 (r307121) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright 2016 Igor Kozhukhov . */ @@ -597,7 +597,6 @@ get_replication(nvlist_t *nvroot, boolea verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &top, &toplevels) == 0); - lastrep.zprl_type = NULL; for (t = 0; t < toplevels; t++) { uint64_t is_log = B_FALSE; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:41:10 2016 (r307120) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:42:00 2016 (r307121) @@ -1564,7 +1564,7 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvl libzfs_handle_t *hdl = zhp->zfs_hdl; nvlist_t *nvl; int nvl_len; - int added_resv; + int added_resv = 0; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), @@ -3195,7 +3195,7 @@ zfs_create_ancestors(libzfs_handle_t *hd { int prefix; char *path_copy; - int rc; + int rc = 0; if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0) return (-1); @@ -3837,7 +3837,7 @@ zfs_rollback(zfs_handle_t *zhp, zfs_hand rollback_data_t cb = { 0 }; int err; boolean_t restore_resv = 0; - uint64_t old_volsize, new_volsize; + uint64_t old_volsize = 0, new_volsize; zfs_prop_t resv_prop; assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM || @@ -4054,6 +4054,7 @@ zfs_rename(zfs_handle_t *zhp, const char "child dataset with inherited mountpoint is used " "in a non-global zone")); (void) zfs_error(hdl, EZFS_ZONED, errbuf); + ret = -1; goto error; } Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c Wed Oct 12 05:41:10 2016 (r307120) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c Wed Oct 12 05:42:00 2016 (r307121) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright 2015 RackTop Systems. * Copyright 2016 Nexenta Systems, Inc. */ @@ -440,12 +440,12 @@ get_configs(libzfs_handle_t *hdl, pool_l pool_entry_t *pe; vdev_entry_t *ve; config_entry_t *ce; - nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot; + nvlist_t *ret = NULL, *config = NULL, *tmp = NULL, *nvtop, *nvroot; nvlist_t **spares, **l2cache; uint_t i, nspares, nl2cache; boolean_t config_seen; uint64_t best_txg; - char *name, *hostname; + char *name, *hostname = NULL; uint64_t guid; uint_t children = 0; nvlist_t **child = NULL; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c Wed Oct 12 05:41:10 2016 (r307120) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c Wed Oct 12 05:42:00 2016 (r307121) @@ -1011,7 +1011,7 @@ zprop_print_one_property(const char *nam const char *source, const char *recvd_value) { int i; - const char *str; + const char *str = NULL; char buf[128]; /* From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:43:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8F88CC0E815; Wed, 12 Oct 2016 05:43:28 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2F513BB; Wed, 12 Oct 2016 05:43:28 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5hR70025074; Wed, 12 Oct 2016 05:43:27 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5hPST025057; Wed, 12 Oct 2016 05:43:25 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120543.u9C5hPST025057@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:43:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307122 - in stable/10: cddl/contrib/opensolaris/cmd/zdb cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/cmd/zhack cddl/contrib/opensolaris/cmd/zpool cddl/contrib/opensolaris/... X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:43:28 -0000 Author: mav Date: Wed Oct 12 05:43:25 2016 New Revision: 307122 URL: https://svnweb.freebsd.org/changeset/base/307122 Log: MFC r305209: MFV r302660: 6314 buffer overflow in dsl_dataset_name illumos/illumos-gate@9adfa60d484ce2435f5af77cc99dcd4e692b6660 https://github.com/illumos/illumos-gate/commit/9adfa60d484ce2435f5af77cc99dcd4e6 92b6660 https://www.illumos.org/issues/6314 Callers of dsl_dataset_name pass a buffer of size ZFS_MAXNAMELEN, but dsl_dataset_name copies the datasets' name PLUS the snapshot name to it, resulting in a max of 2 * ZFS_MAXNAMELEN + '@'. Reviewed by: George Wilson Reviewed by: Prakash Surya Reviewed by: Igor Kozhukhov Approved by: Dan McDonald Author: Matthew Ahrens Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c stable/10/cddl/contrib/opensolaris/cmd/zhack/zhack.c stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c stable/10/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Wed Oct 12 05:43:25 2016 (r307122) @@ -60,7 +60,6 @@ #include #include #include -#undef ZFS_MAXNAMELEN #undef verify #include @@ -1946,7 +1945,7 @@ dump_dir(objset_t *os) uint64_t refdbytes, usedobjs, scratch; char numbuf[32]; char blkbuf[BP_SPRINTF_LEN + 20]; - char osname[MAXNAMELEN]; + char osname[ZFS_MAX_DATASET_NAME_LEN]; char *type = "UNKNOWN"; int verbosity = dump_opt['d']; int print_header = 1; @@ -3483,7 +3482,7 @@ find_zpool(char **target, nvlist_t **con nvlist_t *match = NULL; char *name = NULL; char *sepp = NULL; - char sep; + char sep = '\0'; int count = 0; importargs_t args = { 0 }; Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Wed Oct 12 05:43:25 2016 (r307122) @@ -1509,7 +1509,7 @@ get_callback(zfs_handle_t *zhp, void *da char buf[ZFS_MAXPROPLEN]; char rbuf[ZFS_MAXPROPLEN]; zprop_source_t sourcetype; - char source[ZFS_MAXNAMELEN]; + char source[ZFS_MAX_DATASET_NAME_LEN]; zprop_get_cbdata_t *cbp = data; nvlist_t *user_props = zfs_get_user_props(zhp); zprop_list_t *pl = cbp->cb_proplist; @@ -1989,7 +1989,7 @@ typedef struct upgrade_cbdata { uint64_t cb_version; boolean_t cb_newer; boolean_t cb_foundone; - char cb_lastfs[ZFS_MAXNAMELEN]; + char cb_lastfs[ZFS_MAX_DATASET_NAME_LEN]; } upgrade_cbdata_t; static int @@ -2435,7 +2435,7 @@ userspace_cb(void *arg, const char *doma if (domain != NULL && domain[0] != '\0') { /* SMB */ - char sid[ZFS_MAXNAMELEN + 32]; + char sid[MAXNAMELEN + 32]; uid_t id; #ifdef illumos int err; @@ -2572,7 +2572,7 @@ print_us_node(boolean_t scripted, boolea size_t *width, us_node_t *node) { nvlist_t *nvl = node->usn_nvl; - char valstr[ZFS_MAXNAMELEN]; + char valstr[MAXNAMELEN]; boolean_t first = B_TRUE; int cfield = 0; int field; @@ -3471,7 +3471,7 @@ zfs_do_rollback(int argc, char **argv) boolean_t force = B_FALSE; rollback_cbdata_t cb = { 0 }; zfs_handle_t *zhp, *snap; - char parentname[ZFS_MAXNAMELEN]; + char parentname[ZFS_MAX_DATASET_NAME_LEN]; char *delim; /* check options */ @@ -3871,7 +3871,7 @@ zfs_do_send(int argc, char **argv) */ if (strchr(argv[0], '@') == NULL || (fromname && strchr(fromname, '#') != NULL)) { - char frombuf[ZFS_MAXNAMELEN]; + char frombuf[ZFS_MAX_DATASET_NAME_LEN]; enum lzc_send_flags lzc_flags = 0; if (flags.replicate || flags.doall || flags.props || @@ -3923,7 +3923,7 @@ zfs_do_send(int argc, char **argv) * case if they specify the origin. */ if (fromname && (cp = strchr(fromname, '@')) != NULL) { - char origin[ZFS_MAXNAMELEN]; + char origin[ZFS_MAX_DATASET_NAME_LEN]; zprop_source_t src; (void) zfs_prop_get(zhp, ZFS_PROP_ORIGIN, @@ -4057,7 +4057,7 @@ zfs_do_receive(int argc, char **argv) usage(B_FALSE); } - char namebuf[ZFS_MAXNAMELEN]; + char namebuf[ZFS_MAX_DATASET_NAME_LEN]; (void) snprintf(namebuf, sizeof (namebuf), "%s/%%recv", argv[0]); @@ -4915,7 +4915,7 @@ store_allow_perm(zfs_deleg_who_type_t ty { int i; char ld[2] = { '\0', '\0' }; - char who_buf[ZFS_MAXNAMELEN+32]; + char who_buf[MAXNAMELEN + 32]; char base_type = '\0'; char set_type = '\0'; nvlist_t *base_nvl = NULL; @@ -5283,7 +5283,7 @@ static void print_fs_perms(fs_perm_set_t *fspset) { fs_perm_node_t *node = NULL; - char buf[ZFS_MAXNAMELEN+32]; + char buf[MAXNAMELEN + 32]; const char *dsname = buf; for (node = uu_list_first(fspset->fsps_list); node != NULL; @@ -5292,7 +5292,7 @@ print_fs_perms(fs_perm_set_t *fspset) uu_avl_t *uge_avl = node->fspn_fsperm.fsp_uge_avl; int left = 0; - (void) snprintf(buf, ZFS_MAXNAMELEN+32, + (void) snprintf(buf, sizeof (buf), gettext("---- Permissions on %s "), node->fspn_fsperm.fsp_name); (void) printf(dsname); @@ -5489,7 +5489,7 @@ zfs_do_hold_rele_impl(int argc, char **a for (i = 0; i < argc; ++i) { zfs_handle_t *zhp; - char parent[ZFS_MAXNAMELEN]; + char parent[ZFS_MAX_DATASET_NAME_LEN]; const char *delim; char *path = argv[i]; @@ -5617,7 +5617,7 @@ holds_callback(zfs_handle_t *zhp, void * nvlist_t *nvl = NULL; nvpair_t *nvp = NULL; const char *zname = zfs_get_name(zhp); - size_t znamelen = strnlen(zname, ZFS_MAXNAMELEN); + size_t znamelen = strlen(zname); if (cbp->cb_recursive) { const char *snapname; @@ -5638,7 +5638,7 @@ holds_callback(zfs_handle_t *zhp, void * while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { const char *tag = nvpair_name(nvp); - size_t taglen = strnlen(tag, MAXNAMELEN); + size_t taglen = strlen(tag); if (taglen > cbp->cb_max_taglen) cbp->cb_max_taglen = taglen; } @@ -6967,7 +6967,7 @@ zfs_do_diff(int argc, char **argv) static int zfs_do_bookmark(int argc, char **argv) { - char snapname[ZFS_MAXNAMELEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; zfs_handle_t *zhp; nvlist_t *nvl; int ret = 0; Modified: stable/10/cddl/contrib/opensolaris/cmd/zhack/zhack.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zhack/zhack.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/cmd/zhack/zhack.c Wed Oct 12 05:43:25 2016 (r307122) @@ -48,7 +48,6 @@ #include #include #include -#undef ZFS_MAXNAMELEN #undef verify #include Modified: stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c Wed Oct 12 05:43:25 2016 (r307122) @@ -4540,7 +4540,7 @@ zpool_do_status(int argc, char **argv) typedef struct upgrade_cbdata { boolean_t cb_first; boolean_t cb_unavail; - char cb_poolname[ZPOOL_MAXNAMELEN]; + char cb_poolname[ZFS_MAX_DATASET_NAME_LEN]; int cb_argc; uint64_t cb_version; char **cb_argv; Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Wed Oct 12 05:43:25 2016 (r307122) @@ -141,8 +141,8 @@ typedef struct ztest_shared_hdr { static ztest_shared_hdr_t *ztest_shared_hdr; typedef struct ztest_shared_opts { - char zo_pool[MAXNAMELEN]; - char zo_dir[MAXNAMELEN]; + char zo_pool[ZFS_MAX_DATASET_NAME_LEN]; + char zo_dir[ZFS_MAX_DATASET_NAME_LEN]; char zo_alt_ztest[MAXNAMELEN]; char zo_alt_libpath[MAXNAMELEN]; uint64_t zo_vdevs; @@ -268,7 +268,7 @@ typedef struct ztest_od { uint64_t od_crblocksize; uint64_t od_gen; uint64_t od_crgen; - char od_name[MAXNAMELEN]; + char od_name[ZFS_MAX_DATASET_NAME_LEN]; } ztest_od_t; /* @@ -280,7 +280,7 @@ typedef struct ztest_ds { rwlock_t zd_zilog_lock; zilog_t *zd_zilog; ztest_od_t *zd_od; /* debugging aid */ - char zd_name[MAXNAMELEN]; + char zd_name[ZFS_MAX_DATASET_NAME_LEN]; mutex_t zd_dirobj_lock; rll_t zd_object_lock[ZTEST_OBJECT_LOCKS]; rll_t zd_range_lock[ZTEST_RANGE_LOCKS]; @@ -3227,7 +3227,7 @@ ztest_objset_destroy_cb(const char *name static boolean_t ztest_snapshot_create(char *osname, uint64_t id) { - char snapname[MAXNAMELEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; int error; (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id); @@ -3247,10 +3247,10 @@ ztest_snapshot_create(char *osname, uint static boolean_t ztest_snapshot_destroy(char *osname, uint64_t id) { - char snapname[MAXNAMELEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; int error; - (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname, + (void) snprintf(snapname, sizeof (snapname), "%s@%llu", osname, (u_longlong_t)id); error = dsl_destroy_snapshot(snapname, B_FALSE); @@ -3267,12 +3267,12 @@ ztest_dmu_objset_create_destroy(ztest_ds int iters; int error; objset_t *os, *os2; - char name[MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; zilog_t *zilog; (void) rw_rdlock(&ztest_name_lock); - (void) snprintf(name, MAXNAMELEN, "%s/temp_%llu", + (void) snprintf(name, sizeof (name), "%s/temp_%llu", ztest_opts.zo_pool, (u_longlong_t)id); /* @@ -3378,18 +3378,23 @@ ztest_dmu_snapshot_create_destroy(ztest_ void ztest_dsl_dataset_cleanup(char *osname, uint64_t id) { - char snap1name[MAXNAMELEN]; - char clone1name[MAXNAMELEN]; - char snap2name[MAXNAMELEN]; - char clone2name[MAXNAMELEN]; - char snap3name[MAXNAMELEN]; + char snap1name[ZFS_MAX_DATASET_NAME_LEN]; + char clone1name[ZFS_MAX_DATASET_NAME_LEN]; + char snap2name[ZFS_MAX_DATASET_NAME_LEN]; + char clone2name[ZFS_MAX_DATASET_NAME_LEN]; + char snap3name[ZFS_MAX_DATASET_NAME_LEN]; int error; - (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu", osname, id); - (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu", osname, id); - (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu", clone1name, id); - (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id); - (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id); + (void) snprintf(snap1name, sizeof (snap1name), + "%s@s1_%llu", osname, id); + (void) snprintf(clone1name, sizeof (clone1name), + "%s/c1_%llu", osname, id); + (void) snprintf(snap2name, sizeof (snap2name), + "%s@s2_%llu", clone1name, id); + (void) snprintf(clone2name, sizeof (clone2name), + "%s/c2_%llu", osname, id); + (void) snprintf(snap3name, sizeof (snap3name), + "%s@s3_%llu", clone1name, id); error = dsl_destroy_head(clone2name); if (error && error != ENOENT) @@ -3415,11 +3420,11 @@ void ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) { objset_t *os; - char snap1name[MAXNAMELEN]; - char clone1name[MAXNAMELEN]; - char snap2name[MAXNAMELEN]; - char clone2name[MAXNAMELEN]; - char snap3name[MAXNAMELEN]; + char snap1name[ZFS_MAX_DATASET_NAME_LEN]; + char clone1name[ZFS_MAX_DATASET_NAME_LEN]; + char snap2name[ZFS_MAX_DATASET_NAME_LEN]; + char clone2name[ZFS_MAX_DATASET_NAME_LEN]; + char snap3name[ZFS_MAX_DATASET_NAME_LEN]; char *osname = zd->zd_name; int error; @@ -3427,11 +3432,16 @@ ztest_dsl_dataset_promote_busy(ztest_ds_ ztest_dsl_dataset_cleanup(osname, id); - (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu", osname, id); - (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu", osname, id); - (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu", clone1name, id); - (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id); - (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id); + (void) snprintf(snap1name, sizeof (snap1name), + "%s@s1_%llu", osname, id); + (void) snprintf(clone1name, sizeof (clone1name), + "%s/c1_%llu", osname, id); + (void) snprintf(snap2name, sizeof (snap2name), + "%s@s2_%llu", clone1name, id); + (void) snprintf(clone2name, sizeof (clone2name), + "%s/c2_%llu", osname, id); + (void) snprintf(snap3name, sizeof (snap3name), + "%s@s3_%llu", clone1name, id); error = dmu_objset_snapshot_one(osname, strchr(snap1name, '@') + 1); if (error && error != EEXIST) { @@ -4249,7 +4259,7 @@ ztest_fzap(ztest_ds_t *zd, uint64_t id) * 2050 entries we should see ptrtbl growth and leaf-block split. */ for (int i = 0; i < 2050; i++) { - char name[MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; uint64_t value = i; dmu_tx_t *tx; int error; @@ -4654,7 +4664,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, char fullname[100]; char clonename[100]; char tag[100]; - char osname[MAXNAMELEN]; + char osname[ZFS_MAX_DATASET_NAME_LEN]; nvlist_t *holds; (void) rw_rdlock(&ztest_name_lock); @@ -5450,13 +5460,13 @@ ztest_thread(void *arg) static void ztest_dataset_name(char *dsname, char *pool, int d) { - (void) snprintf(dsname, MAXNAMELEN, "%s/ds_%d", pool, d); + (void) snprintf(dsname, ZFS_MAX_DATASET_NAME_LEN, "%s/ds_%d", pool, d); } static void ztest_dataset_destroy(int d) { - char name[MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; ztest_dataset_name(name, ztest_opts.zo_pool, d); @@ -5505,7 +5515,7 @@ ztest_dataset_open(int d) uint64_t committed_seq = ZTEST_GET_SHARED_DS(d)->zd_seq; objset_t *os; zilog_t *zilog; - char name[MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; int error; ztest_dataset_name(name, ztest_opts.zo_pool, d); @@ -5728,8 +5738,8 @@ ztest_run(ztest_shared_t *zs) * different name. */ if (ztest_random(2) == 0) { - char name[MAXNAMELEN]; - (void) snprintf(name, MAXNAMELEN, "%s_import", + char name[ZFS_MAX_DATASET_NAME_LEN]; + (void) snprintf(name, sizeof (name), "%s_import", ztest_opts.zo_pool); ztest_spa_import_export(ztest_opts.zo_pool, name); ztest_spa_import_export(name, ztest_opts.zo_pool); @@ -6297,7 +6307,7 @@ main(int argc, char **argv) if (spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0) { spa_close(spa, FTAG); } else { - char tmpname[MAXNAMELEN]; + char tmpname[ZFS_MAX_DATASET_NAME_LEN]; kernel_fini(); kernel_init(FREAD | FWRITE); (void) snprintf(tmpname, sizeof (tmpname), "%s_tmp", Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h Wed Oct 12 05:43:25 2016 (r307122) @@ -51,8 +51,6 @@ extern "C" { /* * Miscellaneous ZFS constants */ -#define ZFS_MAXNAMELEN MAXNAMELEN -#define ZPOOL_MAXNAMELEN MAXNAMELEN #define ZFS_MAXPROPLEN MAXPATHLEN #define ZPOOL_MAXPROPLEN MAXPATHLEN Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c Wed Oct 12 05:43:25 2016 (r307122) @@ -26,6 +26,7 @@ * Portions Copyright 2007 Ramprakash Jelari * Copyright (c) 2011 Pawel Jakub Dawidek . * All rights reserved. + * Copyright (c) 2014, 2015 by Delphix. All rights reserved. * Copyright 2016 Igor Kozhukhov */ @@ -296,7 +297,7 @@ void changelist_rename(prop_changelist_t *clp, const char *src, const char *dst) { prop_changenode_t *cn; - char newname[ZFS_MAXNAMELEN]; + char newname[ZFS_MAX_DATASET_NAME_LEN]; for (cn = uu_list_first(clp->cl_list); cn != NULL; cn = uu_list_next(clp->cl_list, cn)) { Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c Wed Oct 12 05:43:25 2016 (r307122) @@ -554,7 +554,7 @@ zfs_bookmark_exists(const char *path) { nvlist_t *bmarks; nvlist_t *props; - char fsname[ZFS_MAXNAMELEN]; + char fsname[ZFS_MAX_DATASET_NAME_LEN]; char *bmark_name; char *pound; int err; @@ -2175,7 +2175,7 @@ struct get_clones_arg { uint64_t numclones; nvlist_t *value; const char *origin; - char buf[ZFS_MAXNAMELEN]; + char buf[ZFS_MAX_DATASET_NAME_LEN]; }; int @@ -2230,7 +2230,7 @@ zfs_get_clones_nvl(zfs_handle_t *zhp) if (gca.numclones != 0) { zfs_handle_t *root; - char pool[ZFS_MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; char *cp = pool; /* get the pool name */ @@ -3015,7 +3015,7 @@ check_parents(libzfs_handle_t *hdl, cons boolean_t accept_ancestor, int *prefixlen) { zfs_cmd_t zc = { 0 }; - char parent[ZFS_MAXNAMELEN]; + char parent[ZFS_MAX_DATASET_NAME_LEN]; char *slash; zfs_handle_t *zhp; char errbuf[1024]; @@ -3254,7 +3254,7 @@ zfs_create(libzfs_handle_t *hdl, const c ost = LZC_DATSET_TYPE_ZFS; /* open zpool handle for prop validation */ - char pool_path[MAXNAMELEN]; + char pool_path[ZFS_MAX_DATASET_NAME_LEN]; (void) strlcpy(pool_path, path, sizeof (pool_path)); /* truncate pool_path at first slash */ @@ -3323,7 +3323,7 @@ zfs_create(libzfs_handle_t *hdl, const c /* check for failure */ if (ret != 0) { - char parent[ZFS_MAXNAMELEN]; + char parent[ZFS_MAX_DATASET_NAME_LEN]; (void) parent_name(path, parent, sizeof (parent)); switch (errno) { @@ -3413,7 +3413,7 @@ static int zfs_check_snap_cb(zfs_handle_t *zhp, void *arg) { struct destroydata *dd = arg; - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; int rv = 0; (void) snprintf(name, sizeof (name), @@ -3503,7 +3503,7 @@ zfs_destroy_snaps_nvl(libzfs_handle_t *h int zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) { - char parent[ZFS_MAXNAMELEN]; + char parent[ZFS_MAX_DATASET_NAME_LEN]; int ret; char errbuf[1024]; libzfs_handle_t *hdl = zhp->zfs_hdl; @@ -3633,7 +3633,7 @@ static int zfs_snapshot_cb(zfs_handle_t *zhp, void *arg) { snapdata_t *sd = arg; - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; int rv = 0; if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) { @@ -3682,7 +3682,7 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, n * get pool handle for prop validation. assumes all snaps are in the * same pool, as does lzc_snapshot (below). */ - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; elem = nvlist_next_nvpair(snaps, NULL); (void) strlcpy(pool, nvpair_name(elem), sizeof (pool)); pool[strcspn(pool, "/@")] = '\0'; @@ -3736,7 +3736,7 @@ zfs_snapshot(libzfs_handle_t *hdl, const { int ret; snapdata_t sd = { 0 }; - char fsname[ZFS_MAXNAMELEN]; + char fsname[ZFS_MAX_DATASET_NAME_LEN]; char *cp; zfs_handle_t *zhp; char errbuf[1024]; @@ -3915,7 +3915,7 @@ zfs_rename(zfs_handle_t *zhp, const char prop_changelist_t *cl = NULL; zfs_handle_t *zhrp = NULL; char *parentname = NULL; - char parent[ZFS_MAXNAMELEN]; + char parent[ZFS_MAX_DATASET_NAME_LEN]; char property[ZFS_MAXPROPLEN]; libzfs_handle_t *hdl = zhp->zfs_hdl; char errbuf[1024]; @@ -4429,7 +4429,7 @@ static int zfs_hold_one(zfs_handle_t *zhp, void *arg) { struct holdarg *ha = arg; - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; int rv = 0; (void) snprintf(name, sizeof (name), @@ -4548,7 +4548,7 @@ static int zfs_release_one(zfs_handle_t *zhp, void *arg) { struct holdarg *ha = arg; - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; int rv = 0; nvlist_t *existing_holds; @@ -4677,7 +4677,7 @@ tryagain: zc.zc_nvlist_dst_size = nvsz; zc.zc_nvlist_dst = (uintptr_t)nvbuf; - (void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN); + (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); if (ioctl(hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) { (void) snprintf(errbuf, sizeof (errbuf), Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c Wed Oct 12 05:43:25 2016 (r307122) @@ -22,6 +22,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2015 by Delphix. All rights reserved. * Copyright 2016 Joyent, Inc. * Copyright 2016 Igor Kozhukhov */ @@ -618,7 +619,7 @@ get_snapshot_names(differ_info_t *di, co * not the same dataset name, might be okay if * tosnap is a clone of a fromsnap descendant. */ - char origin[ZFS_MAXNAMELEN]; + char origin[ZFS_MAX_DATASET_NAME_LEN]; zprop_source_t src; zfs_handle_t *zhp; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h Wed Oct 12 05:43:25 2016 (r307122) @@ -22,18 +22,18 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 Martin Matuska . All rights reserved. */ #ifndef _LIBZFS_IMPL_H #define _LIBZFS_IMPL_H -#include #include -#include #include #include +#include +#include #include #include @@ -86,7 +86,7 @@ struct libzfs_handle { struct zfs_handle { libzfs_handle_t *zfs_hdl; zpool_handle_t *zpool_hdl; - char zfs_name[ZFS_MAXNAMELEN]; + char zfs_name[ZFS_MAX_DATASET_NAME_LEN]; zfs_type_t zfs_type; /* type including snapshot */ zfs_type_t zfs_head_type; /* type excluding snapshot */ dmu_objset_stats_t zfs_dmustats; @@ -107,7 +107,7 @@ struct zfs_handle { struct zpool_handle { libzfs_handle_t *zpool_hdl; zpool_handle_t *zpool_next; - char zpool_name[ZPOOL_MAXNAMELEN]; + char zpool_name[ZFS_MAX_DATASET_NAME_LEN]; int zpool_state; size_t zpool_config_size; nvlist_t *zpool_config; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c Wed Oct 12 05:43:25 2016 (r307122) @@ -197,7 +197,7 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zf for (nvpair_t *pair = nvlist_next_nvpair(bmarks, NULL); pair != NULL; pair = nvlist_next_nvpair(bmarks, pair)) { - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; char *bmark_name; nvlist_t *bmark_props; @@ -385,7 +385,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, * exists. */ if (ssa.ssa_last[0] != '\0') { - char snapname[ZFS_MAXNAMELEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; (void) snprintf(snapname, sizeof (snapname), "%s@%s", zfs_get_name(fs_zhp), ssa.ssa_last); @@ -405,7 +405,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, ret = ENOENT; } } else { - char snapname[ZFS_MAXNAMELEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; zfs_handle_t *snap_zhp; (void) snprintf(snapname, sizeof (snapname), "%s@%s", zfs_get_name(fs_zhp), comma_separated); Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c Wed Oct 12 05:43:25 2016 (r307122) @@ -236,7 +236,7 @@ static boolean_t zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, zprop_source_t *source) { - char sourceloc[ZFS_MAXNAMELEN]; + char sourceloc[MAXNAMELEN]; zprop_source_t sourcetype; if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type)) Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c Wed Oct 12 05:43:25 2016 (r307122) @@ -407,7 +407,7 @@ bootfs_name_valid(const char *pool, char boolean_t zpool_is_bootable(zpool_handle_t *zhp) { - char bootfs[ZPOOL_MAXNAMELEN]; + char bootfs[ZFS_MAX_DATASET_NAME_LEN]; return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-", @@ -3803,7 +3803,7 @@ zpool_obj_to_path(zpool_handle_t *zhp, u zfs_cmd_t zc = { 0 }; boolean_t mounted = B_FALSE; char *mntpnt = NULL; - char dsname[MAXNAMELEN]; + char dsname[ZFS_MAX_DATASET_NAME_LEN]; if (dsobj == 0) { /* special case for the MOS */ @@ -4064,7 +4064,7 @@ zvol_check_dump_config(char *arg) uint_t toplevels; libzfs_handle_t *hdl; char errbuf[1024]; - char poolname[ZPOOL_MAXNAMELEN]; + char poolname[ZFS_MAX_DATASET_NAME_LEN]; int pathlen = strlen(ZVOL_FULL_DEV_DIR); int ret = 1; @@ -4087,7 +4087,7 @@ zvol_check_dump_config(char *arg) "malformed dataset name")); (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); return (1); - } else if (p - volname >= ZFS_MAXNAMELEN) { + } else if (p - volname >= ZFS_MAX_DATASET_NAME_LEN) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "dataset name is too long")); (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf); Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c Wed Oct 12 05:43:25 2016 (r307122) @@ -752,7 +752,7 @@ send_iterate_prop(zfs_handle_t *zhp, nvl static uint64_t get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap) { - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; uint64_t txg = 0; if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0') @@ -920,7 +920,7 @@ typedef struct send_dump_data { /* these are all just the short snapname (the part after the @) */ const char *fromsnap; const char *tosnap; - char prevsnap[ZFS_MAXNAMELEN]; + char prevsnap[ZFS_MAX_DATASET_NAME_LEN]; uint64_t prevsnap_obj; boolean_t seenfrom, seento, replicate, doall, fromorigin; boolean_t verbose, dryrun, parsable, progress, embed_data, std_out; @@ -933,7 +933,7 @@ typedef struct send_dump_data { snapfilter_cb_t *filter_cb; void *filter_cb_arg; nvlist_t *debugnv; - char holdtag[ZFS_MAXNAMELEN]; + char holdtag[ZFS_MAX_DATASET_NAME_LEN]; int cleanup_fd; uint64_t size; } send_dump_data_t; @@ -1569,7 +1569,7 @@ zfs_send_resume(libzfs_handle_t *hdl, se uint64_t resumeobj, resumeoff, toguid, fromguid, bytes; zfs_handle_t *zhp; int error = 0; - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; enum lzc_send_flags lzc_flags = 0; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, @@ -2163,8 +2163,8 @@ recv_rename(libzfs_handle_t *hdl, const if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) { seq++; - (void) snprintf(newname, ZFS_MAXNAMELEN, "%.*srecv-%u-%u", - baselen, name, getpid(), seq); + (void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN, + "%.*srecv-%u-%u", baselen, name, getpid(), seq); (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value)); if (flags->verbose) { @@ -2292,7 +2292,7 @@ static int guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid, boolean_t bookmark_ok, char *name) { - char pname[ZFS_MAXNAMELEN]; + char pname[ZFS_MAX_DATASET_NAME_LEN]; guid_to_name_data_t gtnd; gtnd.guid = guid; @@ -2347,7 +2347,7 @@ created_before(libzfs_handle_t *hdl, avl { nvlist_t *nvfs; char *fsname, *snapname; - char buf[ZFS_MAXNAMELEN]; + char buf[ZFS_MAX_DATASET_NAME_LEN]; int rv; zfs_handle_t *guid1hdl, *guid2hdl; uint64_t create1, create2; @@ -2398,7 +2398,7 @@ recv_incremental_replication(libzfs_hand avl_tree_t *local_avl; nvpair_t *fselem, *nextfselem; char *fromsnap; - char newname[ZFS_MAXNAMELEN]; + char newname[ZFS_MAX_DATASET_NAME_LEN]; char guidname[32]; int error; boolean_t needagain, progress, recursive; @@ -2517,7 +2517,7 @@ again: /* check for delete */ if (found == NULL) { - char name[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; if (!flags->force) continue; @@ -2557,8 +2557,8 @@ again: /* check for different snapname */ if (strcmp(nvpair_name(snapelem), stream_snapname) != 0) { - char name[ZFS_MAXNAMELEN]; - char tryname[ZFS_MAXNAMELEN]; + char name[ZFS_MAX_DATASET_NAME_LEN]; + char tryname[ZFS_MAX_DATASET_NAME_LEN]; (void) snprintf(name, sizeof (name), "%s@%s", fsname, nvpair_name(snapelem)); @@ -2640,7 +2640,7 @@ again: ((flags->isprefix || strcmp(tofs, fsname) != 0) && (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) { nvlist_t *parent; - char tryname[ZFS_MAXNAMELEN]; + char tryname[ZFS_MAX_DATASET_NAME_LEN]; parent = fsavl_find(local_avl, stream_parent_fromsnap_guid, NULL); @@ -2708,8 +2708,8 @@ zfs_receive_package(libzfs_handle_t *hdl char *fromsnap = NULL; char *sendsnap = NULL; char *cp; - char tofs[ZFS_MAXNAMELEN]; - char sendfs[ZFS_MAXNAMELEN]; + char tofs[ZFS_MAX_DATASET_NAME_LEN]; + char sendfs[ZFS_MAX_DATASET_NAME_LEN]; char errbuf[1024]; dmu_replay_record_t drre; int error; @@ -2793,7 +2793,7 @@ zfs_receive_package(libzfs_handle_t *hdl nvlist_t *renamed = NULL; nvpair_t *pair = NULL; - (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN); + (void) strlcpy(tofs, destname, sizeof (tofs)); if (flags->isprefix) { struct drr_begin *drrb = &drr->drr_u.drr_begin; int i; @@ -2802,7 +2802,7 @@ zfs_receive_package(libzfs_handle_t *hdl cp = strrchr(drrb->drr_toname, '/'); if (cp == NULL) { (void) strlcat(tofs, "/", - ZFS_MAXNAMELEN); + sizeof (tofs)); i = 0; } else { i = (cp - drrb->drr_toname); @@ -2812,7 +2812,7 @@ zfs_receive_package(libzfs_handle_t *hdl } /* zfs_receive_one() will create_parents() */ (void) strlcat(tofs, &drrb->drr_toname[i], - ZFS_MAXNAMELEN); + sizeof (tofs)); *strchr(tofs, '@') = '\0'; } @@ -2854,7 +2854,7 @@ zfs_receive_package(libzfs_handle_t *hdl * zfs_receive_one(). */ (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname, - ZFS_MAXNAMELEN); + sizeof (sendfs)); if ((cp = strchr(sendfs, '@')) != NULL) { *cp = '\0'; /* @@ -3004,7 +3004,7 @@ static void recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap, boolean_t resumable) { - char target_fs[ZFS_MAXNAMELEN]; + char target_fs[ZFS_MAX_DATASET_NAME_LEN]; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "checksum mismatch or incomplete stream")); @@ -3207,7 +3207,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in if (flags->verbose) (void) printf("found clone origin %s\n", zc.zc_string); } else if (originsnap) { - (void) strncpy(zc.zc_string, originsnap, ZFS_MAXNAMELEN); + (void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string)); if (flags->verbose) (void) printf("using provided clone origin %s\n", zc.zc_string); @@ -3232,7 +3232,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in *cp = '\0'; if (cp && !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { - char suffix[ZFS_MAXNAMELEN]; + char suffix[ZFS_MAX_DATASET_NAME_LEN]; (void) strcpy(suffix, strrchr(zc.zc_value, '/')); if (guid_to_name(hdl, zc.zc_name, parent_snapguid, B_FALSE, zc.zc_value) == 0) { @@ -3259,7 +3259,7 @@ zfs_receive_one(libzfs_handle_t *hdl, in if ((flags->isprefix || (*(chopprefix = drrb->drr_toname + strlen(sendfs)) != '\0' && *chopprefix != '@')) && !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) { - char snap[ZFS_MAXNAMELEN]; + char snap[ZFS_MAX_DATASET_NAME_LEN]; (void) strcpy(snap, strchr(zc.zc_value, '@')); if (guid_to_name(hdl, zc.zc_name, drrb->drr_fromguid, B_FALSE, zc.zc_value) == 0) { @@ -3709,7 +3709,7 @@ zfs_receive_impl(libzfs_handle_t *hdl, c } if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) { - char nonpackage_sendfs[ZFS_MAXNAMELEN]; + char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN]; if (sendfs == NULL) { /* * We were not called from zfs_receive_package(). Get @@ -3717,7 +3717,8 @@ zfs_receive_impl(libzfs_handle_t *hdl, c */ char *cp; (void) strlcpy(nonpackage_sendfs, - drr.drr_u.drr_begin.drr_toname, ZFS_MAXNAMELEN); + drr.drr_u.drr_begin.drr_toname, + sizeof (nonpackage_sendfs)); if ((cp = strchr(nonpackage_sendfs, '@')) != NULL) *cp = '\0'; sendfs = nonpackage_sendfs; Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c Wed Oct 12 05:43:25 2016 (r307122) @@ -265,7 +265,7 @@ lzc_snapshot(nvlist_t *snaps, nvlist_t * nvpair_t *elem; nvlist_t *args; int error; - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; *errlist = NULL; @@ -317,7 +317,7 @@ lzc_destroy_snaps(nvlist_t *snaps, boole nvpair_t *elem; nvlist_t *args; int error; - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; /* determine the pool name */ elem = nvlist_next_nvpair(snaps, NULL); @@ -344,7 +344,7 @@ lzc_snaprange_space(const char *firstsna nvlist_t *args; nvlist_t *result; int err; - char fs[MAXNAMELEN]; + char fs[ZFS_MAX_DATASET_NAME_LEN]; char *atp; /* determine the fs name */ @@ -409,7 +409,7 @@ lzc_exists(const char *dataset) int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist) { - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; nvlist_t *args; nvpair_t *elem; int error; @@ -456,7 +456,7 @@ lzc_hold(nvlist_t *holds, int cleanup_fd int lzc_release(nvlist_t *holds, nvlist_t **errlist) { - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; nvpair_t *elem; /* determine the pool name */ @@ -743,7 +743,7 @@ lzc_bookmark(nvlist_t *bookmarks, nvlist { nvpair_t *elem; int error; - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; /* determine the pool name */ elem = nvlist_next_nvpair(bookmarks, NULL); @@ -805,7 +805,7 @@ lzc_destroy_bookmarks(nvlist_t *bmarks, { nvpair_t *elem; int error; - char pool[MAXNAMELEN]; + char pool[ZFS_MAX_DATASET_NAME_LEN]; /* determine the pool name */ elem = nvlist_next_nvpair(bmarks, NULL); Modified: stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c Wed Oct 12 05:42:00 2016 (r307121) +++ stable/10/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c Wed Oct 12 05:43:25 2016 (r307122) @@ -69,7 +69,7 @@ zfs_component_namecheck(const char *path { const char *loc; - if (strlen(path) >= MAXNAMELEN) { + if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); @@ -140,14 +140,9 @@ dataset_namecheck(const char *path, name /* * Make sure the name is not too long. - * - * ZFS_MAXNAMELEN is the maximum dataset length used in the userland - * which is the same as MAXNAMELEN used in the kernel. - * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all - * places using MAXNAMELEN. */ - if (strlen(path) >= MAXNAMELEN) { + if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); @@ -276,7 +271,7 @@ mountpoint_namecheck(const char *path, n while (*end != '/' && *end != '\0') end++; - if (end - start >= MAXNAMELEN) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:44:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DEE9AC0E8B6; Wed, 12 Oct 2016 05:44:13 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 961B2264; Wed, 12 Oct 2016 05:44:13 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5iCf5025173; Wed, 12 Oct 2016 05:44:12 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5iC4b025172; Wed, 12 Oct 2016 05:44:12 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120544.u9C5iC4b025172@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:44:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307123 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:44:14 -0000 Author: mav Date: Wed Oct 12 05:44:12 2016 New Revision: 307123 URL: https://svnweb.freebsd.org/changeset/base/307123 Log: MFC r305210: MFV r302661: 7082 bptree_iterate() passes wrong args to zfs_dbgmsg() illumos/illumos-gate@10e67aa0db0823d5464aafdd681f3c966155c68e https://github.com/illumos/illumos-gate/commit/10e67aa0db0823d5464aafdd681f3c966 155c68e https://www.illumos.org/issues/7082 upstream DLPX-40542 bptree_iterate() passes wrong args to zfs_dbgmsg() Reviewed by: Dan Kimmel Reviewed by: George Wilson Reviewed by: Igor Kozhukhov Approved by: Dan McDonald Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Wed Oct 12 05:43:25 2016 (r307122) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c Wed Oct 12 05:44:12 2016 (r307123) @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -220,9 +220,10 @@ bptree_iterate(objset_t *os, uint64_t ob if (zfs_free_leak_on_eio) flags |= TRAVERSE_HARD; - zfs_dbgmsg("bptree index %d: traversing from min_txg=%lld " + zfs_dbgmsg("bptree index %lld: traversing from min_txg=%lld " "bookmark %lld/%lld/%lld/%lld", - i, (longlong_t)bte.be_birth_txg, + (longlong_t)i, + (longlong_t)bte.be_birth_txg, (longlong_t)bte.be_zb.zb_objset, (longlong_t)bte.be_zb.zb_object, (longlong_t)bte.be_zb.zb_level, From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:44:55 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 68222C0E93F; Wed, 12 Oct 2016 05:44:55 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 44CD4656; Wed, 12 Oct 2016 05:44:55 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5is35025250; Wed, 12 Oct 2016 05:44:54 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5iswq025248; Wed, 12 Oct 2016 05:44:54 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120544.u9C5iswq025248@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:44:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307124 - in stable/10: cddl/contrib/opensolaris/lib/libnvpair sys/cddl/contrib/opensolaris/common/nvpair X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:44:55 -0000 Author: mav Date: Wed Oct 12 05:44:54 2016 New Revision: 307124 URL: https://svnweb.freebsd.org/changeset/base/307124 Log: MFC r305211: MFV r302662: 6447 handful of nvpair cleanups illumos/illumos-gate@759e89be359f2af635e4122d147df56bce948773 https://github.com/illumos/illumos-gate/commit/759e89be359f2af635e4122d147df56bc e948773 https://www.illumos.org/issues/6447 I got a patch from someone who uses nvpair code outside of illumos. It fixes a couple of gcc warnings/bugs for him. 1. silence uninitialized use warnings 2. add parentheses around assignment used as truth value 3. fix printf format specifier (ll is for integers only) 4. strstr, strspn, strcspn, and strcmp are declared in string.h, not strings.h. 5. avoid scanning integer into boolean variable Reviewed by: Josef 'Jeff' Sipek Reviewed by: Andy Stormont Reviewed by: Garrett D'Amore Approved by: Robert Mustacchi Author: Steve Dougherty Modified: stable/10/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c stable/10/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c Wed Oct 12 05:44:12 2016 (r307123) +++ stable/10/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c Wed Oct 12 05:44:54 2016 (r307124) @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include "libnvpair.h" @@ -1228,7 +1228,8 @@ nvpair_value_match_regex(nvpair_t *nvp, break; } case DATA_TYPE_BOOLEAN_VALUE: { - boolean_t val, val_arg; + int32_t val_arg; + boolean_t val; /* scanf boolean_t from value and check for match */ sr = sscanf(value, "%"SCNi32, &val_arg); @@ -1239,7 +1240,8 @@ nvpair_value_match_regex(nvpair_t *nvp, break; } case DATA_TYPE_BOOLEAN_ARRAY: { - boolean_t *val_array, val_arg; + boolean_t *val_array; + int32_t val_arg; /* check indexed value of array for match */ sr = sscanf(value, "%"SCNi32, &val_arg); Modified: stable/10/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c Wed Oct 12 05:44:12 2016 (r307123) +++ stable/10/sys/cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c Wed Oct 12 05:44:54 2016 (r307124) @@ -1629,6 +1629,8 @@ nvlist_lookup_nvpair_ei_sep(nvlist_t *nv if ((nvl == NULL) || (name == NULL)) return (EINVAL); + sepp = NULL; + idx = 0; /* step through components of name */ for (np = name; np && *np; np = sepp) { /* ensure unique names */ @@ -2386,7 +2388,7 @@ nvlist_xpack(nvlist_t *nvl, char **bufp, */ nv_priv_init(&nvpriv, nva, 0); - if (err = nvlist_size(nvl, &alloc_size, encoding)) + if ((err = nvlist_size(nvl, &alloc_size, encoding))) return (err); if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL) From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:45:42 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2B65DC0E9C7; Wed, 12 Oct 2016 05:45:42 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EEF8C846; Wed, 12 Oct 2016 05:45:41 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5jfA7025337; Wed, 12 Oct 2016 05:45:41 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5jfmT025336; Wed, 12 Oct 2016 05:45:41 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120545.u9C5jfmT025336@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:45:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307125 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:45:42 -0000 Author: mav Date: Wed Oct 12 05:45:40 2016 New Revision: 307125 URL: https://svnweb.freebsd.org/changeset/base/307125 Log: MFC r305221: MFV r302992: 7071 lzc_snapshot does not fill in errlist on ENOENT illumos/illumos-gate@25f7d993adbfb3452ac4625b3791670746d35ae3 https://github.com/illumos/illumos-gate/commit/25f7d993adbfb3452ac4625b379167074 6d35ae3 https://www.illumos.org/issues/7071 upstream DLPX-40482 lzc_snapshot does not fill in errlist on ENOENT Reviewed by: Igor Kozhukhov Reviewed by: George Wilson Reviewed by: Dan Kimmel Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Wed Oct 12 05:44:54 2016 (r307124) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Wed Oct 12 05:45:40 2016 (r307125) @@ -499,6 +499,14 @@ zfs_secpolicy_write_perms(const char *na dsl_dataset_t *ds; dsl_pool_t *dp; + /* + * First do a quick check for root in the global zone, which + * is allowed to do all write_perms. This ensures that zfs_ioc_* + * will get to handle nonexistent datasets. + */ + if (INGLOBALZONE(curthread) && secpolicy_zfs(cr) == 0) + return (0); + error = dsl_pool_hold(name, FTAG, &dp); if (error != 0) return (error); From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:46:22 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DE62EC0EA23; Wed, 12 Oct 2016 05:46:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B7BD59B2; Wed, 12 Oct 2016 05:46:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5kLHs025420; Wed, 12 Oct 2016 05:46:21 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5kL7T025416; Wed, 12 Oct 2016 05:46:21 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120546.u9C5kL7T025416@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:46:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307126 - in stable/10/sys/cddl/contrib/opensolaris/uts/common: fs/zfs fs/zfs/sys sys/fs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:46:23 -0000 Author: mav Date: Wed Oct 12 05:46:21 2016 New Revision: 307126 URL: https://svnweb.freebsd.org/changeset/base/307126 Log: MFC r305222: MFV r302993: 7104 increase indirect block size illumos/illumos-gate@4b5c8e93cab28d3c65ba9d407fd8f46e3be1db1c https://github.com/illumos/illumos-gate/commit/4b5c8e93cab28d3c65ba9d407fd8f46e3 be1db1c https://www.illumos.org/issues/7104 The current default indirect block size is 16KB. We can improve performance by increasing it to 128KB. This is especially helpful for any workload that needs to read most of the metadata, e.g. scrub/resilver, file deletion, filesystem deletion, and zfs send. We also need to fix a few space estimation errors to make the tests pass. Reviewed by: George Wilson Reviewed by: Paul Dagnelie Reviewed by: Dan McDonald Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c Wed Oct 12 05:45:40 2016 (r307125) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c Wed Oct 12 05:46:21 2016 (r307126) @@ -791,11 +791,17 @@ dmu_objset_create_impl(spa_t *spa, dsl_d /* * Determine the number of levels necessary for the meta-dnode - * to contain DN_MAX_OBJECT dnodes. + * to contain DN_MAX_OBJECT dnodes. Note that in order to + * ensure that we do not overflow 64 bits, there has to be + * a nlevels that gives us a number of blocks > DN_MAX_OBJECT + * but < 2^64. Therefore, + * (mdn->dn_indblkshift - SPA_BLKPTRSHIFT) (10) must be + * less than (64 - log2(DN_MAX_OBJECT)) (16). */ - while ((uint64_t)mdn->dn_nblkptr << (mdn->dn_datablkshift + + while ((uint64_t)mdn->dn_nblkptr << + (mdn->dn_datablkshift - DNODE_SHIFT + (levels - 1) * (mdn->dn_indblkshift - SPA_BLKPTRSHIFT)) < - DN_MAX_OBJECT * sizeof (dnode_phys_t)) + DN_MAX_OBJECT) levels++; mdn->dn_next_nlevels[tx->tx_txg & TXG_MASK] = Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Wed Oct 12 05:45:40 2016 (r307125) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Wed Oct 12 05:46:21 2016 (r307126) @@ -411,12 +411,20 @@ zfs_deadman_init() * it is possible to run the pool completely out of space, causing it to * be permanently read-only. * + * Note that on very small pools, the slop space will be larger than + * 3.2%, in an effort to have it be at least spa_min_slop (128MB), + * but we never allow it to be more than half the pool size. + * * See also the comments in zfs_space_check_t. */ int spa_slop_shift = 5; SYSCTL_INT(_vfs_zfs, OID_AUTO, spa_slop_shift, CTLFLAG_RWTUN, &spa_slop_shift, 0, "Shift value of reserved space (1/(2^spa_slop_shift))."); +uint64_t spa_min_slop = 128 * 1024 * 1024; +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, spa_min_slop, CTLFLAG_RWTUN, + &spa_min_slop, 0, + "Minimal value of reserved space"); /* * ========================================================================== @@ -1723,14 +1731,16 @@ spa_get_asize(spa_t *spa, uint64_t lsize /* * Return the amount of slop space in bytes. It is 1/32 of the pool (3.2%), - * or at least 32MB. + * or at least 128MB, unless that would cause it to be more than half the + * pool size. * * See the comment above spa_slop_shift for details. */ uint64_t -spa_get_slop_space(spa_t *spa) { +spa_get_slop_space(spa_t *spa) +{ uint64_t space = spa_get_dspace(spa); - return (MAX(space >> spa_slop_shift, SPA_MINDEVSIZE >> 1)); + return (MAX(space >> spa_slop_shift, MIN(space >> 1, spa_min_slop))); } uint64_t Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h Wed Oct 12 05:45:40 2016 (r307125) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h Wed Oct 12 05:46:21 2016 (r307126) @@ -58,7 +58,7 @@ extern "C" { */ #define DNODE_SHIFT 9 /* 512 bytes */ #define DN_MIN_INDBLKSHIFT 12 /* 4k */ -#define DN_MAX_INDBLKSHIFT 14 /* 16k */ +#define DN_MAX_INDBLKSHIFT 17 /* 128k */ #define DNODE_BLOCK_SHIFT 14 /* 16k */ #define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */ #define DN_MAX_OBJECT_SHIFT 48 /* 256 trillion (zfs_fid_t limit) */ @@ -88,6 +88,11 @@ extern "C" { #define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) #define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) + +/* + * This is inaccurate if the indblkshift of the particular object is not the + * max. But it's only used by userland to calculate the zvol reservation. + */ #define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) #define DNODES_PER_LEVEL (1ULL << DNODES_PER_LEVEL_SHIFT) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Wed Oct 12 05:45:40 2016 (r307125) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Wed Oct 12 05:46:21 2016 (r307126) @@ -607,6 +607,8 @@ typedef struct zpool_rewind_policy { /* * This is needed in userland to report the minimum necessary device size. + * + * Note that the zfs test suite uses 64MB vdevs. */ #define SPA_MINDEVSIZE (64ULL << 20) From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:47:07 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 68483C0EA8C; Wed, 12 Oct 2016 05:47:07 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 29A38B1D; Wed, 12 Oct 2016 05:47:07 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5l6Rc025509; Wed, 12 Oct 2016 05:47:06 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5l6MF025508; Wed, 12 Oct 2016 05:47:06 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120547.u9C5l6MF025508@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:47:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307127 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:47:07 -0000 Author: mav Date: Wed Oct 12 05:47:06 2016 New Revision: 307127 URL: https://svnweb.freebsd.org/changeset/base/307127 Log: MFC r305224: MFV r304158: 7136 ESC_VDEV_REMOVE_AUX ought to always include vdev information 7115 6922 generates ESC_ZFS_VDEV_REMOVE_AUX a bit too often illumos/illumos-gate@b72b6bb10ad55121a1b352c6f68ebdc8e20c9086 https://github.com/illumos/illumos-gate/commit/b72b6bb10ad55121a1b352c6f68ebdc8e 20c9086 https://www.illumos.org/issues/7136 6922 added ESC_ZFS_VDEV_REMOVE_AUX and ESC_ZFS_VDEV_REMOVE_DEV sysevents whenever an aux device gets removed from a pool. However, those sysevents will be created without the vdev_guid and vdev_path fields. It would be better to always populate those fields. https://www.illumos.org/issues/7115 The addition of spa_event_notify in vdev removal code (see #6922) causes event s to be generated even if the spare failed to be removed with EBUSY. Reviewed by: George Wilson Reviewed by: Josef 'Jeff' Sipek Approved by: Robert Mustacchi Author: Alan Somers Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Wed Oct 12 05:46:21 2016 (r307126) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Wed Oct 12 05:47:06 2016 (r307127) @@ -152,6 +152,8 @@ const zio_taskq_info_t zio_taskqs[ZIO_TY { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* IOCTL */ }; +static sysevent_t *spa_event_create(spa_t *spa, vdev_t *vd, const char *name); +static void spa_event_post(sysevent_t *ev); static void spa_sync_version(void *arg, dmu_tx_t *tx); static void spa_sync_props(void *arg, dmu_tx_t *tx); static boolean_t spa_has_active_shared_spare(spa_t *spa); @@ -5645,6 +5647,7 @@ int spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare) { vdev_t *vd; + sysevent_t *ev = NULL; metaslab_group_t *mg; nvlist_t **spares, **l2cache, *nv; uint64_t txg = 0; @@ -5668,6 +5671,9 @@ spa_vdev_remove(spa_t *spa, uint64_t gui * in this pool. */ if (vd == NULL || unspare) { + if (vd == NULL) + vd = spa_lookup_by_guid(spa, guid, B_TRUE); + ev = spa_event_create(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); spa_vdev_remove_aux(spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES, spares, nspares, nv); spa_load_spares(spa); @@ -5675,7 +5681,6 @@ spa_vdev_remove(spa_t *spa, uint64_t gui } else { error = SET_ERROR(EBUSY); } - spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); } else if (spa->spa_l2cache.sav_vdevs != NULL && nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0 && @@ -5683,11 +5688,12 @@ spa_vdev_remove(spa_t *spa, uint64_t gui /* * Cache devices can always be removed. */ + vd = spa_lookup_by_guid(spa, guid, B_TRUE); + ev = spa_event_create(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); spa_vdev_remove_aux(spa->spa_l2cache.sav_config, ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache, nv); spa_load_l2cache(spa); spa->spa_l2cache.sav_sync = B_TRUE; - spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_AUX); } else if (vd != NULL && vd->vdev_islog) { ASSERT(!locked); ASSERT(vd == vd->vdev_top); @@ -5724,9 +5730,9 @@ spa_vdev_remove(spa_t *spa, uint64_t gui /* * Clean up the vdev namespace. */ + ev = spa_event_create(spa, vd, ESC_ZFS_VDEV_REMOVE_DEV); spa_vdev_remove_from_namespace(spa, vd); - spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE_DEV); } else if (vd != NULL) { /* * Normal vdevs cannot be removed (yet). @@ -5742,6 +5748,9 @@ spa_vdev_remove(spa_t *spa, uint64_t gui if (!locked) error = spa_vdev_exit(spa, NULL, txg, error); + if (ev) + spa_event_post(ev); + return (error); } @@ -7019,24 +7028,17 @@ spa_has_active_shared_spare(spa_t *spa) return (B_FALSE); } -/* - * Post a sysevent corresponding to the given event. The 'name' must be one of - * the event definitions in sys/sysevent/eventdefs.h. The payload will be - * filled in from the spa and (optionally) the vdev. This doesn't do anything - * in the userland libzpool, as we don't want consumers to misinterpret ztest - * or zdb as real changes. - */ -void -spa_event_notify(spa_t *spa, vdev_t *vd, const char *name) +static sysevent_t * +spa_event_create(spa_t *spa, vdev_t *vd, const char *name) { + sysevent_t *ev = NULL; #ifdef _KERNEL - sysevent_t *ev; sysevent_attr_list_t *attr = NULL; sysevent_value_t value; - sysevent_id_t eid; ev = sysevent_alloc(EC_ZFS, (char *)name, SUNW_KERN_PUB "zfs", SE_SLEEP); + ASSERT(ev != NULL); value.value_type = SE_DATA_TYPE_STRING; value.value.sv_string = spa_name(spa); @@ -7068,11 +7070,34 @@ spa_event_notify(spa_t *spa, vdev_t *vd, goto done; attr = NULL; - (void) log_sysevent(ev, SE_SLEEP, &eid); - done: if (attr) sysevent_free_attr(attr); + +#endif + return (ev); +} + +static void +spa_event_post(sysevent_t *ev) +{ +#ifdef _KERNEL + sysevent_id_t eid; + + (void) log_sysevent(ev, SE_SLEEP, &eid); sysevent_free(ev); #endif } + +/* + * Post a sysevent corresponding to the given event. The 'name' must be one of + * the event definitions in sys/sysevent/eventdefs.h. The payload will be + * filled in from the spa and (optionally) the vdev. This doesn't do anything + * in the userland libzpool, as we don't want consumers to misinterpret ztest + * or zdb as real changes. + */ +void +spa_event_notify(spa_t *spa, vdev_t *vd, const char *name) +{ + spa_event_post(spa_event_create(spa, vd, name)); +} From owner-svn-src-stable-10@freebsd.org Wed Oct 12 05:50:48 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BBB96C0EB52; Wed, 12 Oct 2016 05:50:48 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8AC02E43; Wed, 12 Oct 2016 05:50:48 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C5olqw027784; Wed, 12 Oct 2016 05:50:47 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C5olvg027783; Wed, 12 Oct 2016 05:50:47 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610120550.u9C5olvg027783@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 12 Oct 2016 05:50:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307129 - stable/10/sys/cam/scsi X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 05:50:48 -0000 Author: mav Date: Wed Oct 12 05:50:47 2016 New Revision: 307129 URL: https://svnweb.freebsd.org/changeset/base/307129 Log: MFC 306699: Do not retry on some security sense codes. Modified: stable/10/sys/cam/scsi/scsi_all.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/scsi/scsi_all.c ============================================================================== --- stable/10/sys/cam/scsi/scsi_all.c Wed Oct 12 05:50:13 2016 (r307128) +++ stable/10/sys/cam/scsi/scsi_all.c Wed Oct 12 05:50:47 2016 (r307129) @@ -3191,10 +3191,10 @@ static struct asc_table_entry asc_table[ { SST(0x74, 0x6F, SS_RDEF, /* XXX TBD */ "External data encryption control error") }, /* DT R M E V */ - { SST(0x74, 0x71, SS_RDEF, /* XXX TBD */ + { SST(0x74, 0x71, SS_FATAL | EACCES, "Logical unit access not authorized") }, /* D */ - { SST(0x74, 0x79, SS_RDEF, /* XXX TBD */ + { SST(0x74, 0x79, SS_FATAL | EACCES, "Security conflict in translated device") } }; From owner-svn-src-stable-10@freebsd.org Wed Oct 12 08:58:06 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C4368C0E498; Wed, 12 Oct 2016 08:58:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 87CB5F66; Wed, 12 Oct 2016 08:58:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C8w5p7096724; Wed, 12 Oct 2016 08:58:05 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C8w491096708; Wed, 12 Oct 2016 08:58:04 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120858.u9C8w491096708@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 08:58:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307133 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 08:58:06 -0000 Author: sephe Date: Wed Oct 12 08:58:03 2016 New Revision: 307133 URL: https://svnweb.freebsd.org/changeset/base/307133 Log: MFC 303421,303422,303470-303473 303421 hyperv/vmbus: Avoid unnecessary mb() Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7333 303422 hyperv/vmbus: Inclusion cleanup Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7334 303470 hyperv/vmbus: Reindent function declarations. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7344 303471 hyperv/vmbus: Forward declare static functions Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7346 303472 hyperv/vmbus: Move driver glue to the beginning of the files Just as most of other drivers do. And move sysinit function close to its SYSINIT. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7347 303473 hyperv/vmbus: Revoke unnecessary exposure of vmbus softc Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7348 Modified: stable/10/sys/dev/hyperv/include/hyperv.h stable/10/sys/dev/hyperv/include/hyperv_busdma.h stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/vmbus/hyperv.c stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_br.c stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_et.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/hyperv.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 08:58:03 2016 (r307133) @@ -28,43 +28,21 @@ * $FreeBSD$ */ -/** - * HyperV definitions for messages that are sent between instances of the - * Channel Management Library in separate partitions, or in some cases, - * back to itself. - */ - -#ifndef __HYPERV_H__ -#define __HYPERV_H__ +#ifndef _HYPERV_H_ +#define _HYPERV_H_ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + #include -#include #include -#include -#include -#include - struct hyperv_guid { uint8_t hv_guid[16]; } __packed; #define HYPERV_GUID_STRLEN 40 -int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); +int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); /** * @brief Get physical address from virtual @@ -77,4 +55,4 @@ hv_get_phys_addr(void *virt) return (ret); } -#endif /* __HYPERV_H__ */ +#endif /* _HYPERV_H_ */ Modified: stable/10/sys/dev/hyperv/include/hyperv_busdma.h ============================================================================== --- stable/10/sys/dev/hyperv/include/hyperv_busdma.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/include/hyperv_busdma.h Wed Oct 12 08:58:03 2016 (r307133) @@ -39,11 +39,11 @@ struct hyperv_dma { bus_dmamap_t hv_dmap; }; -void hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, - int error); -void *hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag, bus_size_t alignment, - bus_addr_t boundary, bus_size_t size, struct hyperv_dma *dma, - int flags); -void hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr); +void hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, + int nseg, int error); +void *hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag, + bus_size_t alignment, bus_addr_t boundary, bus_size_t size, + struct hyperv_dma *dma, int flags); +void hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr); #endif /* !_HYPERV_BUSDMA_H_ */ Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 08:58:03 2016 (r307133) @@ -30,6 +30,8 @@ #define _VMBUS_H_ #include +#include +#include /* * VMBUS version is 32 bit, upper 16 bit for major_number and lower @@ -115,45 +117,47 @@ vmbus_get_channel(device_t dev) return device_get_ivars(dev); } -int vmbus_chan_open(struct vmbus_channel *chan, - int txbr_size, int rxbr_size, const void *udata, int udlen, - vmbus_chan_callback_t cb, void *cbarg); -void vmbus_chan_close(struct vmbus_channel *chan); - -int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, - bus_addr_t paddr, int size, uint32_t *gpadl); -int vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, - uint32_t gpadl); +int vmbus_chan_open(struct vmbus_channel *chan, + int txbr_size, int rxbr_size, const void *udata, int udlen, + vmbus_chan_callback_t cb, void *cbarg); +void vmbus_chan_close(struct vmbus_channel *chan); + +int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, + bus_addr_t paddr, int size, uint32_t *gpadl); +int vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, + uint32_t gpadl); -void vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu); -void vmbus_chan_cpu_rr(struct vmbus_channel *chan); +void vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu); +void vmbus_chan_cpu_rr(struct vmbus_channel *chan); struct vmbus_channel * - vmbus_chan_cpu2chan(struct vmbus_channel *chan, int cpu); -void vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on); + vmbus_chan_cpu2chan(struct vmbus_channel *chan, int cpu); +void vmbus_chan_set_readbatch(struct vmbus_channel *chan, bool on); struct vmbus_channel ** - vmbus_subchan_get(struct vmbus_channel *pri_chan, int subchan_cnt); -void vmbus_subchan_rel(struct vmbus_channel **subchan, int subchan_cnt); -void vmbus_subchan_drain(struct vmbus_channel *pri_chan); - -int vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen, - uint64_t *xactid); -int vmbus_chan_recv_pkt(struct vmbus_channel *chan, - struct vmbus_chanpkt_hdr *pkt, int *pktlen); - -int vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, - uint16_t flags, void *data, int dlen, uint64_t xactid); -int vmbus_chan_send_sglist(struct vmbus_channel *chan, - struct vmbus_gpa sg[], int sglen, void *data, int dlen, - uint64_t xactid); -int vmbus_chan_send_prplist(struct vmbus_channel *chan, - struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen, - uint64_t xactid); - -uint32_t vmbus_chan_id(const struct vmbus_channel *chan); -uint32_t vmbus_chan_subidx(const struct vmbus_channel *chan); -bool vmbus_chan_is_primary(const struct vmbus_channel *chan); + vmbus_subchan_get(struct vmbus_channel *pri_chan, + int subchan_cnt); +void vmbus_subchan_rel(struct vmbus_channel **subchan, + int subchan_cnt); +void vmbus_subchan_drain(struct vmbus_channel *pri_chan); + +int vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen, + uint64_t *xactid); +int vmbus_chan_recv_pkt(struct vmbus_channel *chan, + struct vmbus_chanpkt_hdr *pkt, int *pktlen); + +int vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, + uint16_t flags, void *data, int dlen, uint64_t xactid); +int vmbus_chan_send_sglist(struct vmbus_channel *chan, + struct vmbus_gpa sg[], int sglen, void *data, int dlen, + uint64_t xactid); +int vmbus_chan_send_prplist(struct vmbus_channel *chan, + struct vmbus_gpa_range *prp, int prp_cnt, void *data, + int dlen, uint64_t xactid); + +uint32_t vmbus_chan_id(const struct vmbus_channel *chan); +uint32_t vmbus_chan_subidx(const struct vmbus_channel *chan); +bool vmbus_chan_is_primary(const struct vmbus_channel *chan); const struct hyperv_guid * - vmbus_chan_guid_inst(const struct vmbus_channel *chan); + vmbus_chan_guid_inst(const struct vmbus_channel *chan); #endif /* !_VMBUS_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 08:58:03 2016 (r307133) @@ -44,6 +44,7 @@ #include #include #include +#include #include #include Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 08:58:03 2016 (r307133) @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 08:58:03 2016 (r307133) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 08:58:03 2016 (r307133) @@ -33,6 +33,7 @@ #include #include #include +#include #include #include Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 08:58:03 2016 (r307133) @@ -38,6 +38,7 @@ #include #include #include +#include #include #include Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 08:58:03 2016 (r307133) @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/hyperv.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/hyperv.c Wed Oct 12 08:58:03 2016 (r307133) @@ -34,23 +34,14 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include +#include #include -#include -#include -#include -#include -#include #include #include #include #include #include -#if 0 -#include -#endif #define HYPERV_FREEBSD_BUILD 0ULL #define HYPERV_FREEBSD_VERSION ((uint64_t)__FreeBSD_version) @@ -76,13 +67,15 @@ struct hypercall_ctx { struct hyperv_dma hc_dma; }; -static u_int hyperv_get_timecount(struct timecounter *tc); +static u_int hyperv_get_timecount(struct timecounter *); +static bool hyperv_identify(void); +static void hypercall_memfree(void); -u_int hyperv_features; -u_int hyperv_recommends; +u_int hyperv_features; +u_int hyperv_recommends; -static u_int hyperv_pm_features; -static u_int hyperv_features3; +static u_int hyperv_pm_features; +static u_int hyperv_features3; static struct timecounter hyperv_timecounter = { .tc_get_timecount = hyperv_get_timecount, Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Wed Oct 12 08:58:03 2016 (r307133) @@ -38,26 +38,18 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include -#include #include -#include -#include -#include #include -#include -#include -#include -#include - -#include #include -#include -#include -#include #include +#include + +#include #include #include @@ -66,7 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include "acpi_if.h" #include "vmbus_if.h" @@ -92,6 +83,17 @@ struct vmbus_msghc_ctx { #define VMBUS_MSGHC_CTXF_DESTROY 0x0001 +static int vmbus_probe(device_t); +static int vmbus_attach(device_t); +static int vmbus_detach(device_t); +static int vmbus_read_ivar(device_t, device_t, int, + uintptr_t *); +static int vmbus_child_pnpinfo_str(device_t, device_t, + char *, size_t); +static uint32_t vmbus_get_version_method(device_t, device_t); +static int vmbus_probe_guid_method(device_t, device_t, + const struct hyperv_guid *); + static int vmbus_init(struct vmbus_softc *); static int vmbus_connect(struct vmbus_softc *, uint32_t); static int vmbus_req_channels(struct vmbus_softc *sc); @@ -104,8 +106,17 @@ static void vmbus_scan_done(struct vmb const struct vmbus_message *); static void vmbus_chanmsg_handle(struct vmbus_softc *, const struct vmbus_message *); - +static void vmbus_msg_task(void *, int); +static void vmbus_synic_setup(void *); +static void vmbus_synic_teardown(void *); static int vmbus_sysctl_version(SYSCTL_HANDLER_ARGS); +static int vmbus_dma_alloc(struct vmbus_softc *); +static void vmbus_dma_free(struct vmbus_softc *); +static int vmbus_intr_setup(struct vmbus_softc *); +static void vmbus_intr_teardown(struct vmbus_softc *); +static int vmbus_doattach(struct vmbus_softc *); +static void vmbus_event_proc_dummy(struct vmbus_softc *, + int); static struct vmbus_msghc_ctx *vmbus_msghc_ctx_create(bus_dma_tag_t); static void vmbus_msghc_ctx_destroy( @@ -116,7 +127,7 @@ static void vmbus_msghc_free(struct vm static struct vmbus_msghc *vmbus_msghc_get1(struct vmbus_msghc_ctx *, uint32_t); -struct vmbus_softc *vmbus_sc; +static struct vmbus_softc *vmbus_sc; extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr); @@ -133,6 +144,46 @@ vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYP VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) }; +static device_method_t vmbus_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, vmbus_probe), + DEVMETHOD(device_attach, vmbus_attach), + DEVMETHOD(device_detach, vmbus_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_add_child, bus_generic_add_child), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, vmbus_read_ivar), + DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), + + /* Vmbus interface */ + DEVMETHOD(vmbus_get_version, vmbus_get_version_method), + DEVMETHOD(vmbus_probe_guid, vmbus_probe_guid_method), + + DEVMETHOD_END +}; + +static driver_t vmbus_driver = { + "vmbus", + vmbus_methods, + sizeof(struct vmbus_softc) +}; + +static devclass_t vmbus_devclass; + +DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL); +MODULE_DEPEND(vmbus, acpi, 1, 1, 1); +MODULE_VERSION(vmbus, 1); + +static __inline struct vmbus_softc * +vmbus_get_softc(void) +{ + return vmbus_sc; +} + static struct vmbus_msghc * vmbus_msghc_alloc(bus_dma_tag_t parent_dtag) { @@ -1316,24 +1367,6 @@ vmbus_attach(device_t dev) return (0); } -static void -vmbus_sysinit(void *arg __unused) -{ - struct vmbus_softc *sc = vmbus_get_softc(); - - if (vm_guest != VM_GUEST_HV || sc == NULL) - return; - - /* - * If the system has already booted and thread - * scheduling is possible, as indicated by the - * global cold set to zero, we just call the driver - * initialization directly. - */ - if (!cold) - vmbus_doattach(sc); -} - static int vmbus_detach(device_t dev) { @@ -1363,44 +1396,26 @@ vmbus_detach(device_t dev) return (0); } -static device_method_t vmbus_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, vmbus_probe), - DEVMETHOD(device_attach, vmbus_attach), - DEVMETHOD(device_detach, vmbus_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_add_child, bus_generic_add_child), - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_read_ivar, vmbus_read_ivar), - DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), - - /* Vmbus interface */ - DEVMETHOD(vmbus_get_version, vmbus_get_version_method), - DEVMETHOD(vmbus_probe_guid, vmbus_probe_guid_method), - - DEVMETHOD_END -}; - -static driver_t vmbus_driver = { - "vmbus", - vmbus_methods, - sizeof(struct vmbus_softc) -}; - -static devclass_t vmbus_devclass; +static void +vmbus_sysinit(void *arg __unused) +{ + struct vmbus_softc *sc = vmbus_get_softc(); -DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL); -MODULE_DEPEND(vmbus, acpi, 1, 1, 1); -MODULE_VERSION(vmbus, 1); + if (vm_guest != VM_GUEST_HV || sc == NULL) + return; + /* + * If the system has already booted and thread + * scheduling is possible, as indicated by the + * global cold set to zero, we just call the driver + * initialization directly. + */ + if (!cold) + vmbus_doattach(sc); +} /* * NOTE: * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is * initialized. */ SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL); - Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_br.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_br.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_br.c Wed Oct 12 08:58:03 2016 (r307133) @@ -44,6 +44,10 @@ __FBSDID("$FreeBSD$"); /* Increase bufing index */ #define VMBUS_BR_IDXINC(idx, inc, sz) (((idx) + (inc)) % (sz)) +static int vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS); +static int vmbus_br_sysctl_state_bin(SYSCTL_HANDLER_ARGS); +static void vmbus_br_setup(struct vmbus_br *, void *, int); + static int vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS) { @@ -212,9 +216,7 @@ vmbus_txbr_need_signal(const struct vmbu if (tbr->txbr_imask) return (FALSE); - /* XXX only compiler fence is needed */ - /* Read memory barrier */ - rmb(); + __compiler_membar(); /* * This is the only case we need to signal when the @@ -311,15 +313,10 @@ vmbus_txbr_write(struct vmbus_txbr *tbr, sizeof(save_windex)); /* - * XXX only compiler fence is needed. - * Full memory barrier before upding the write index. - */ - mb(); - - /* * Update the write index _after_ the channel packet * is copied. */ + __compiler_membar(); tbr->txbr_windex = windex; mtx_unlock_spin(&tbr->txbr_lock); @@ -399,16 +396,9 @@ vmbus_rxbr_read(struct vmbus_rxbr *rbr, rindex = VMBUS_BR_IDXINC(rindex, sizeof(uint64_t), br_dsize); /* - * XXX only compiler fence is needed. - * Make sure all reads are done before we update the read index since - * the writer may start writing to the read area once the read index - * is updated. - */ - wmb(); - - /* * Update the read index _after_ the channel packet is fetched. */ + __compiler_membar(); rbr->rxbr_rindex = rindex; mtx_unlock_spin(&rbr->rxbr_lock); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 08:58:03 2016 (r307133) @@ -31,19 +31,14 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include #include +#include #include +#include #include +#include #include -#include - -#include -#include -#include #include #include @@ -52,17 +47,28 @@ __FBSDID("$FreeBSD$"); #include #include -static void vmbus_chan_update_evtflagcnt(struct vmbus_softc *, - const struct vmbus_channel *); - -static void vmbus_chan_task(void *, int); -static void vmbus_chan_task_nobatch(void *, int); -static void vmbus_chan_detach_task(void *, int); - -static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, - const struct vmbus_message *); -static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *, - const struct vmbus_message *); +static void vmbus_chan_update_evtflagcnt( + struct vmbus_softc *, + const struct vmbus_channel *); +static void vmbus_chan_close_internal( + struct vmbus_channel *); +static int vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS); +static void vmbus_chan_sysctl_create( + struct vmbus_channel *); +static struct vmbus_channel *vmbus_chan_alloc(struct vmbus_softc *); +static void vmbus_chan_free(struct vmbus_channel *); +static int vmbus_chan_add(struct vmbus_channel *); +static void vmbus_chan_cpu_default(struct vmbus_channel *); + +static void vmbus_chan_task(void *, int); +static void vmbus_chan_task_nobatch(void *, int); +static void vmbus_chan_detach_task(void *, int); + +static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, + const struct vmbus_message *); +static void vmbus_chan_msgproc_chrescind( + struct vmbus_softc *, + const struct vmbus_message *); /* * Vmbus channel message processing. Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Wed Oct 12 08:58:03 2016 (r307133) @@ -155,9 +155,10 @@ struct vmbus_channel { struct vmbus_softc; struct vmbus_message; -void vmbus_event_proc(struct vmbus_softc *, int); -void vmbus_event_proc_compat(struct vmbus_softc *, int); -void vmbus_chan_msgproc(struct vmbus_softc *, const struct vmbus_message *); -void vmbus_chan_destroy_all(struct vmbus_softc *); +void vmbus_event_proc(struct vmbus_softc *, int); +void vmbus_event_proc_compat(struct vmbus_softc *, int); +void vmbus_chan_msgproc(struct vmbus_softc *, + const struct vmbus_message *); +void vmbus_chan_destroy_all(struct vmbus_softc *); #endif /* !_VMBUS_CHANVAR_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_et.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_et.c Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_et.c Wed Oct 12 08:58:03 2016 (r307133) @@ -32,9 +32,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include -#include +#include #include #include @@ -59,8 +58,35 @@ __FBSDID("$FreeBSD$"); CPUID_HV_MSR_SYNIC | \ CPUID_HV_MSR_SYNTIMER) +static void vmbus_et_identify(driver_t *, device_t); +static int vmbus_et_probe(device_t); +static int vmbus_et_attach(device_t); +static int vmbus_et_detach(device_t); +static int vmbus_et_start(struct eventtimer *, sbintime_t, + sbintime_t); + static struct eventtimer vmbus_et; +static device_method_t vmbus_et_methods[] = { + DEVMETHOD(device_identify, vmbus_et_identify), + DEVMETHOD(device_probe, vmbus_et_probe), + DEVMETHOD(device_attach, vmbus_et_attach), + DEVMETHOD(device_detach, vmbus_et_detach), + + DEVMETHOD_END +}; + +static driver_t vmbus_et_driver = { + VMBUS_ET_NAME, + vmbus_et_methods, + 0 +}; + +static devclass_t vmbus_et_devclass; + +DRIVER_MODULE(hv_et, vmbus, vmbus_et_driver, vmbus_et_devclass, NULL, NULL); +MODULE_VERSION(hv_et, 1); + static __inline uint64_t hyperv_sbintime2count(sbintime_t time) { @@ -177,22 +203,3 @@ vmbus_et_detach(device_t dev) { return (et_deregister(&vmbus_et)); } - -static device_method_t vmbus_et_methods[] = { - DEVMETHOD(device_identify, vmbus_et_identify), - DEVMETHOD(device_probe, vmbus_et_probe), - DEVMETHOD(device_attach, vmbus_et_attach), - DEVMETHOD(device_detach, vmbus_et_detach), - - DEVMETHOD_END -}; - -static driver_t vmbus_et_driver = { - VMBUS_ET_NAME, - vmbus_et_methods, - 0 -}; - -static devclass_t vmbus_et_devclass; -DRIVER_MODULE(hv_et, vmbus, vmbus_et_driver, vmbus_et_devclass, NULL, NULL); -MODULE_VERSION(hv_et, 1); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Wed Oct 12 08:25:13 2016 (r307132) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Wed Oct 12 08:58:03 2016 (r307133) @@ -120,20 +120,6 @@ struct vmbus_softc { #define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */ #define VMBUS_FLAG_SYNIC 0x0002 /* SynIC was setup */ -extern struct vmbus_softc *vmbus_sc; - -static __inline struct vmbus_softc * -vmbus_get_softc(void) -{ - return vmbus_sc; -} - -static __inline device_t -vmbus_get_device(void) -{ - return vmbus_sc->vmbus_dev; -} - #define VMBUS_PCPU_GET(sc, field, cpu) (sc)->vmbus_pcpu[(cpu)].field #define VMBUS_PCPU_PTR(sc, field, cpu) &(sc)->vmbus_pcpu[(cpu)].field @@ -142,20 +128,23 @@ struct trapframe; struct vmbus_message; struct vmbus_msghc; -void vmbus_handle_intr(struct trapframe *); -int vmbus_add_child(struct vmbus_channel *); -int vmbus_delete_child(struct vmbus_channel *); -void vmbus_et_intr(struct trapframe *); -uint32_t vmbus_gpadl_alloc(struct vmbus_softc *); - -struct vmbus_msghc *vmbus_msghc_get(struct vmbus_softc *, size_t); -void vmbus_msghc_put(struct vmbus_softc *, struct vmbus_msghc *); -void *vmbus_msghc_dataptr(struct vmbus_msghc *); -int vmbus_msghc_exec_noresult(struct vmbus_msghc *); -int vmbus_msghc_exec(struct vmbus_softc *, struct vmbus_msghc *); -const struct vmbus_message *vmbus_msghc_wait_result(struct vmbus_softc *, - struct vmbus_msghc *); -void vmbus_msghc_wakeup(struct vmbus_softc *, const struct vmbus_message *); -void vmbus_msghc_reset(struct vmbus_msghc *, size_t); +void vmbus_handle_intr(struct trapframe *); +int vmbus_add_child(struct vmbus_channel *); +int vmbus_delete_child(struct vmbus_channel *); +void vmbus_et_intr(struct trapframe *); +uint32_t vmbus_gpadl_alloc(struct vmbus_softc *); + +struct vmbus_msghc * + vmbus_msghc_get(struct vmbus_softc *, size_t); +void vmbus_msghc_put(struct vmbus_softc *, struct vmbus_msghc *); +void *vmbus_msghc_dataptr(struct vmbus_msghc *); +int vmbus_msghc_exec_noresult(struct vmbus_msghc *); +int vmbus_msghc_exec(struct vmbus_softc *, struct vmbus_msghc *); +const struct vmbus_message * + vmbus_msghc_wait_result(struct vmbus_softc *, + struct vmbus_msghc *); +void vmbus_msghc_wakeup(struct vmbus_softc *, + const struct vmbus_message *); +void vmbus_msghc_reset(struct vmbus_msghc *, size_t); #endif /* !_VMBUS_VAR_H_ */ From owner-svn-src-stable-10@freebsd.org Wed Oct 12 09:13:17 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 73285C0EA2E; Wed, 12 Oct 2016 09:13:17 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 425FED9C; Wed, 12 Oct 2016 09:13:17 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C9DGeN004707; Wed, 12 Oct 2016 09:13:16 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C9DG2l004706; Wed, 12 Oct 2016 09:13:16 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120913.u9C9DG2l004706@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 09:13:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307134 - stable/10/sys/dev/hyperv/storvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 09:13:17 -0000 Author: sephe Date: Wed Oct 12 09:13:16 2016 New Revision: 307134 URL: https://svnweb.freebsd.org/changeset/base/307134 Log: MFC 303474 hyperv/storvsc: Use busdma(9) and enable PIM_UNMAPPED by default. The UNMAPPED I/O greatly improves userland direct disk I/O performance by 35% ~ 135%. Submitted by: Hongjiang Zhang Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7195 Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 08:58:03 2016 (r307133) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 09:13:16 2016 (r307134) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -87,7 +88,10 @@ __FBSDID("$FreeBSD$"); #define VSTOR_PKT_SIZE (sizeof(struct vstor_packet) - vmscsi_size_delta) -#define HV_ALIGN(x, a) roundup2(x, a) +#define STORVSC_DATA_SEGCNT_MAX VMBUS_CHAN_PRPLIST_MAX +#define STORVSC_DATA_SEGSZ_MAX PAGE_SIZE +#define STORVSC_DATA_SIZE_MAX \ + (STORVSC_DATA_SEGCNT_MAX * STORVSC_DATA_SEGSZ_MAX) struct storvsc_softc; @@ -102,7 +106,7 @@ struct hv_sgl_page_pool{ boolean_t is_init; } g_hv_sgl_page_pool; -#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * VMBUS_CHAN_PRPLIST_MAX +#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * STORVSC_DATA_SEGCNT_MAX enum storvsc_request_type { WRITE_TYPE, @@ -110,26 +114,41 @@ enum storvsc_request_type { UNKNOWN_TYPE }; -struct hvs_gpa_range { +SYSCTL_NODE(_hw, OID_AUTO, storvsc, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, + "Hyper-V storage interface"); + +static u_int hv_storvsc_use_pim_unmapped = 1; +SYSCTL_INT(_hw_storvsc, OID_AUTO, use_pim_unmapped, CTLFLAG_RDTUN, + &hv_storvsc_use_pim_unmapped, 0, + "Optimize storvsc by using unmapped I/O"); + +struct hv_storvsc_sysctl { + u_long data_bio_cnt; + u_long data_vaddr_cnt; + u_long data_sg_cnt; +}; + +struct storvsc_gpa_range { struct vmbus_gpa_range gpa_range; - uint64_t gpa_page[VMBUS_CHAN_PRPLIST_MAX]; + uint64_t gpa_page[STORVSC_DATA_SEGCNT_MAX]; } __packed; struct hv_storvsc_request { - LIST_ENTRY(hv_storvsc_request) link; - struct vstor_packet vstor_packet; - int prp_cnt; - struct hvs_gpa_range prp_list; - void *sense_data; - uint8_t sense_info_len; - uint8_t retries; - union ccb *ccb; - struct storvsc_softc *softc; - struct callout callout; - struct sema synch_sema; /*Synchronize the request/response if needed */ - struct sglist *bounce_sgl; - unsigned int bounce_sgl_count; - uint64_t not_aligned_seg_bits; + LIST_ENTRY(hv_storvsc_request) link; + struct vstor_packet vstor_packet; + int prp_cnt; + struct storvsc_gpa_range prp_list; + void *sense_data; + uint8_t sense_info_len; + uint8_t retries; + union ccb *ccb; + struct storvsc_softc *softc; + struct callout callout; + struct sema synch_sema; /*Synchronize the request/response if needed */ + struct sglist *bounce_sgl; + unsigned int bounce_sgl_count; + uint64_t not_aligned_seg_bits; + bus_dmamap_t data_dmap; }; struct storvsc_softc { @@ -148,6 +167,8 @@ struct storvsc_softc { struct hv_storvsc_request hs_init_req; struct hv_storvsc_request hs_reset_req; device_t hs_dev; + bus_dma_tag_t storvsc_req_dtag; + struct hv_storvsc_sysctl sysctl_data; struct vmbus_channel *hs_cpu2chan[MAXCPU]; }; @@ -884,6 +905,77 @@ storvsc_create_cpu2chan(struct storvsc_s } } +static int +storvsc_init_requests(device_t dev) +{ + struct storvsc_softc *sc = device_get_softc(dev); + struct hv_storvsc_request *reqp; + int error, i; + + LIST_INIT(&sc->hs_free_list); + + error = bus_dma_tag_create( + bus_get_dma_tag(dev), /* parent */ + 1, /* alignment */ + PAGE_SIZE, /* boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + STORVSC_DATA_SIZE_MAX, /* maxsize */ + STORVSC_DATA_SEGCNT_MAX, /* nsegments */ + STORVSC_DATA_SEGSZ_MAX, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockfuncarg */ + &sc->storvsc_req_dtag); + if (error) { + device_printf(dev, "failed to create storvsc dma tag\n"); + return (error); + } + + for (i = 0; i < sc->hs_drv_props->drv_max_ios_per_target; ++i) { + reqp = malloc(sizeof(struct hv_storvsc_request), + M_DEVBUF, M_WAITOK|M_ZERO); + reqp->softc = sc; + error = bus_dmamap_create(sc->storvsc_req_dtag, 0, + &reqp->data_dmap); + if (error) { + device_printf(dev, "failed to allocate storvsc " + "data dmamap\n"); + goto cleanup; + } + LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link); + } + return (0); + +cleanup: + while ((reqp = LIST_FIRST(&sc->hs_free_list)) != NULL) { + LIST_REMOVE(reqp, link); + bus_dmamap_destroy(sc->storvsc_req_dtag, reqp->data_dmap); + free(reqp, M_DEVBUF); + } + return (error); +} + +static void +storvsc_sysctl(device_t dev) +{ + struct sysctl_oid_list *child; + struct sysctl_ctx_list *ctx; + struct storvsc_softc *sc; + + sc = device_get_softc(dev); + ctx = device_get_sysctl_ctx(dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "data_bio_cnt", CTLFLAG_RW, + &sc->sysctl_data.data_bio_cnt, "# of bio data block"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "data_vaddr_cnt", CTLFLAG_RW, + &sc->sysctl_data.data_vaddr_cnt, "# of vaddr data block"); + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "data_sg_cnt", CTLFLAG_RW, + &sc->sysctl_data.data_sg_cnt, "# of sg data block"); +} + /** * @brief StorVSC attach function * @@ -928,16 +1020,11 @@ storvsc_attach(device_t dev) sc->hs_unit = device_get_unit(dev); sc->hs_dev = dev; - LIST_INIT(&sc->hs_free_list); mtx_init(&sc->hs_lock, "hvslck", NULL, MTX_DEF); - for (i = 0; i < sc->hs_drv_props->drv_max_ios_per_target; ++i) { - reqp = malloc(sizeof(struct hv_storvsc_request), - M_DEVBUF, M_WAITOK|M_ZERO); - reqp->softc = sc; - - LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link); - } + ret = storvsc_init_requests(dev); + if (ret != 0) + goto cleanup; /* create sg-list page pool */ if (FALSE == g_hv_sgl_page_pool.is_init) { @@ -947,7 +1034,7 @@ storvsc_attach(device_t dev) /* * Pre-create SG list, each SG list with - * VMBUS_CHAN_PRPLIST_MAX segments, each + * STORVSC_DATA_SEGCNT_MAX segments, each * segment has one page buffer */ for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) { @@ -955,10 +1042,10 @@ storvsc_attach(device_t dev) M_DEVBUF, M_WAITOK|M_ZERO); sgl_node->sgl_data = - sglist_alloc(VMBUS_CHAN_PRPLIST_MAX, + sglist_alloc(STORVSC_DATA_SEGCNT_MAX, M_WAITOK|M_ZERO); - for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) { + for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++) { tmp_buff = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK|M_ZERO); @@ -1033,6 +1120,8 @@ storvsc_attach(device_t dev) mtx_unlock(&sc->hs_lock); + storvsc_sysctl(dev); + root_mount_rel(root_mount_token); return (0); @@ -1042,13 +1131,14 @@ cleanup: while (!LIST_EMPTY(&sc->hs_free_list)) { reqp = LIST_FIRST(&sc->hs_free_list); LIST_REMOVE(reqp, link); + bus_dmamap_destroy(sc->storvsc_req_dtag, reqp->data_dmap); free(reqp, M_DEVBUF); } while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); - for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) { + for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++) { if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); @@ -1103,7 +1193,7 @@ storvsc_detach(device_t dev) while (!LIST_EMPTY(&sc->hs_free_list)) { reqp = LIST_FIRST(&sc->hs_free_list); LIST_REMOVE(reqp, link); - + bus_dmamap_destroy(sc->storvsc_req_dtag, reqp->data_dmap); free(reqp, M_DEVBUF); } mtx_unlock(&sc->hs_lock); @@ -1111,7 +1201,7 @@ storvsc_detach(device_t dev) while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); LIST_REMOVE(sgl_node, link); - for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++){ + for (j = 0; j < STORVSC_DATA_SEGCNT_MAX; j++){ if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); @@ -1296,6 +1386,8 @@ storvsc_action(struct cam_sim *sim, unio cpi->hba_inquiry = PI_TAG_ABLE|PI_SDTR_ABLE; cpi->target_sprt = 0; cpi->hba_misc = PIM_NOBUSRESET; + if (hv_storvsc_use_pim_unmapped) + cpi->hba_misc |= PIM_UNMAPPED; cpi->hba_eng_cnt = 0; cpi->max_target = STORVSC_MAX_TARGETS; cpi->max_lun = sc->hs_drv_props->drv_max_luns_per_target; @@ -1370,6 +1462,7 @@ storvsc_action(struct cam_sim *sim, unio case XPT_SCSI_IO: case XPT_IMMED_NOTIFY: { struct hv_storvsc_request *reqp = NULL; + bus_dmamap_t dmap_saved; if (ccb->csio.cdb_len == 0) { panic("cdl_len is 0\n"); @@ -1388,7 +1481,14 @@ storvsc_action(struct cam_sim *sim, unio reqp = LIST_FIRST(&sc->hs_free_list); LIST_REMOVE(reqp, link); + /* Save the data_dmap before reset request */ + dmap_saved = reqp->data_dmap; + + /* XXX this is ugly */ bzero(reqp, sizeof(struct hv_storvsc_request)); + + /* Restore necessary bits */ + reqp->data_dmap = dmap_saved; reqp->softc = sc; ccb->ccb_h.status |= CAM_SIM_QUEUED; @@ -1644,6 +1744,35 @@ storvsc_check_bounce_buffer_sgl(bus_dma_ } /** + * Copy bus_dma segments to multiple page buffer, which requires + * the pages are compact composed except for the 1st and last pages. + */ +static void +storvsc_xferbuf_prepare(void *arg, bus_dma_segment_t *segs, int nsegs, int error) +{ + struct hv_storvsc_request *reqp = arg; + union ccb *ccb = reqp->ccb; + struct ccb_scsiio *csio = &ccb->csio; + struct storvsc_gpa_range *prplist; + int i; + + prplist = &reqp->prp_list; + prplist->gpa_range.gpa_len = csio->dxfer_len; + prplist->gpa_range.gpa_ofs = segs[0].ds_addr & PAGE_MASK; + + for (i = 0; i < nsegs; i++) { + prplist->gpa_page[i] = atop(segs[i].ds_addr); +#ifdef INVARIANTS + if (i != 0 && i != nsegs - 1) { + KASSERT((segs[i].ds_addr & PAGE_MASK) == 0 && + segs[i].ds_len == PAGE_SIZE, ("not a full page")); + } +#endif + } + reqp->prp_cnt = nsegs; +} + +/** * @brief Fill in a request structure based on a CAM control block * * Fills in a request structure based on the contents of a CAM control @@ -1658,11 +1787,9 @@ create_storvsc_request(union ccb *ccb, s { struct ccb_scsiio *csio = &ccb->csio; uint64_t phys_addr; - uint32_t bytes_to_copy = 0; - uint32_t pfn_num = 0; uint32_t pfn; uint64_t not_aligned_seg_bits = 0; - struct hvs_gpa_range *prplist; + int error; /* refer to struct vmscsi_req for meanings of these two fields */ reqp->vstor_packet.u.vm_srb.port = @@ -1706,36 +1833,26 @@ create_storvsc_request(union ccb *ccb, s return (0); } - prplist = &reqp->prp_list; - prplist->gpa_range.gpa_len = csio->dxfer_len; - switch (ccb->ccb_h.flags & CAM_DATA_MASK) { + case CAM_DATA_BIO: case CAM_DATA_VADDR: - { - bytes_to_copy = csio->dxfer_len; - phys_addr = vtophys(csio->data_ptr); - prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK; - - while (bytes_to_copy != 0) { - int bytes, page_offset; - phys_addr = - vtophys(&csio->data_ptr[prplist->gpa_range.gpa_len - - bytes_to_copy]); - pfn = phys_addr >> PAGE_SHIFT; - prplist->gpa_page[pfn_num] = pfn; - page_offset = phys_addr & PAGE_MASK; - - bytes = min(PAGE_SIZE - page_offset, bytes_to_copy); - - bytes_to_copy -= bytes; - pfn_num++; + error = bus_dmamap_load_ccb(reqp->softc->storvsc_req_dtag, + reqp->data_dmap, ccb, storvsc_xferbuf_prepare, reqp, + BUS_DMA_NOWAIT); + if (error) { + xpt_print(ccb->ccb_h.path, + "bus_dmamap_load_ccb failed: %d\n", error); + return (error); } - reqp->prp_cnt = pfn_num; + if ((ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) + reqp->softc->sysctl_data.data_bio_cnt++; + else + reqp->softc->sysctl_data.data_vaddr_cnt++; break; - } case CAM_DATA_SG: { + struct storvsc_gpa_range *prplist; int i = 0; int offset = 0; int ret; @@ -1744,13 +1861,16 @@ create_storvsc_request(union ccb *ccb, s (bus_dma_segment_t *)ccb->csio.data_ptr; u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt; + prplist = &reqp->prp_list; + prplist->gpa_range.gpa_len = csio->dxfer_len; + printf("Storvsc: get SG I/O operation, %d\n", reqp->vstor_packet.u.vm_srb.data_in); - if (storvsc_sg_count > VMBUS_CHAN_PRPLIST_MAX){ + if (storvsc_sg_count > STORVSC_DATA_SEGCNT_MAX){ printf("Storvsc: %d segments is too much, " "only support %d segments\n", - storvsc_sg_count, VMBUS_CHAN_PRPLIST_MAX); + storvsc_sg_count, STORVSC_DATA_SEGCNT_MAX); return (EINVAL); } @@ -1847,6 +1967,7 @@ create_storvsc_request(union ccb *ccb, s reqp->bounce_sgl_count = 0; } + reqp->softc->sysctl_data.data_sg_cnt++; break; } default: From owner-svn-src-stable-10@freebsd.org Wed Oct 12 09:27:41 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2D521C0EDA9; Wed, 12 Oct 2016 09:27:41 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E0869981; Wed, 12 Oct 2016 09:27:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9C9Re1Z008942; Wed, 12 Oct 2016 09:27:40 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9C9Rd0F008936; Wed, 12 Oct 2016 09:27:39 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610120927.u9C9Rd0F008936@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Wed, 12 Oct 2016 09:27:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307137 - in stable/10/sys/dev/hyperv: include netvsc storvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 09:27:41 -0000 Author: sephe Date: Wed Oct 12 09:27:39 2016 New Revision: 307137 URL: https://svnweb.freebsd.org/changeset/base/307137 Log: MFC 303603-303605,303764 303603 hyperv/vmbus: Remove the artificial entry limit of SG and PRP list. Just make sure that the total channel packet size does not exceed 1/2 data size of the TX bufring. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7359 303604 hyperv/storvsc: Set maxio to 128KB. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7360 303605 hyperv/storvsc: Stringent PRP list assertions Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7361 303764 hyperv/vmbus: Only make sure the TX bufring will not be closed. KVP can write data, whose size is > 1/2 TX bufring size. Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7414 Modified: stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 09:27:39 2016 (r307137) @@ -103,9 +103,6 @@ struct vmbus_chanpkt_rxbuf { struct vmbus_rxbuf_desc cp_rxbuf[]; } __packed; -#define VMBUS_CHAN_SGLIST_MAX 32 -#define VMBUS_CHAN_PRPLIST_MAX 32 - struct vmbus_channel; struct hyperv_guid; Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Wed Oct 12 09:27:39 2016 (r307137) @@ -1088,6 +1088,7 @@ struct vmbus_channel; typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *); #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) +#define NETVSC_PACKET_MAXPAGE 32 #define NETVSC_VLAN_PRIO_MASK 0xe000 #define NETVSC_VLAN_PRIO_SHIFT 13 @@ -1137,7 +1138,7 @@ typedef struct netvsc_packet_ { uint32_t tot_data_buf_len; void *data; uint32_t gpa_cnt; - struct vmbus_gpa gpa[VMBUS_CHAN_SGLIST_MAX]; + struct vmbus_gpa gpa[NETVSC_PACKET_MAXPAGE]; } netvsc_packet; typedef struct { Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Wed Oct 12 09:27:39 2016 (r307137) @@ -154,7 +154,7 @@ __FBSDID("$FreeBSD$"); #define HN_TX_DATA_MAXSIZE IP_MAXPACKET #define HN_TX_DATA_SEGSIZE PAGE_SIZE #define HN_TX_DATA_SEGCNT_MAX \ - (VMBUS_CHAN_SGLIST_MAX - HV_RF_NUM_TX_RESERVED_PAGE_BUFS) + (NETVSC_PACKET_MAXPAGE - HV_RF_NUM_TX_RESERVED_PAGE_BUFS) #define HN_DIRECT_TX_SIZE_DEF 128 Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 09:27:39 2016 (r307137) @@ -88,10 +88,25 @@ __FBSDID("$FreeBSD$"); #define VSTOR_PKT_SIZE (sizeof(struct vstor_packet) - vmscsi_size_delta) -#define STORVSC_DATA_SEGCNT_MAX VMBUS_CHAN_PRPLIST_MAX +/* + * 33 segments are needed to allow 128KB maxio, in case the data + * in the first page is _not_ PAGE_SIZE aligned, e.g. + * + * |<----------- 128KB ----------->| + * | | + * 0 2K 4K 8K 16K 124K 128K 130K + * | | | | | | | | + * +--+--+-----+-----+.......+-----+--+--+ + * | | | | | | | | | DATA + * | | | | | | | | | + * +--+--+-----+-----+.......------+--+--+ + * | | | | + * | 1| 31 | 1| ...... # of segments + */ +#define STORVSC_DATA_SEGCNT_MAX 33 #define STORVSC_DATA_SEGSZ_MAX PAGE_SIZE #define STORVSC_DATA_SIZE_MAX \ - (STORVSC_DATA_SEGCNT_MAX * STORVSC_DATA_SEGSZ_MAX) + ((STORVSC_DATA_SEGCNT_MAX - 1) * STORVSC_DATA_SEGSZ_MAX) struct storvsc_softc; @@ -1388,6 +1403,7 @@ storvsc_action(struct cam_sim *sim, unio cpi->hba_misc = PIM_NOBUSRESET; if (hv_storvsc_use_pim_unmapped) cpi->hba_misc |= PIM_UNMAPPED; + cpi->maxio = STORVSC_DATA_SIZE_MAX; cpi->hba_eng_cnt = 0; cpi->max_target = STORVSC_MAX_TARGETS; cpi->max_lun = sc->hs_drv_props->drv_max_luns_per_target; @@ -1761,13 +1777,28 @@ storvsc_xferbuf_prepare(void *arg, bus_d prplist->gpa_range.gpa_ofs = segs[0].ds_addr & PAGE_MASK; for (i = 0; i < nsegs; i++) { - prplist->gpa_page[i] = atop(segs[i].ds_addr); #ifdef INVARIANTS - if (i != 0 && i != nsegs - 1) { - KASSERT((segs[i].ds_addr & PAGE_MASK) == 0 && - segs[i].ds_len == PAGE_SIZE, ("not a full page")); + if (nsegs > 1) { + if (i == 0) { + KASSERT((segs[i].ds_addr & PAGE_MASK) + + segs[i].ds_len == PAGE_SIZE, + ("invalid 1st page, ofs 0x%jx, len %zu", + (uintmax_t)segs[i].ds_addr, + segs[i].ds_len)); + } else if (i == nsegs - 1) { + KASSERT((segs[i].ds_addr & PAGE_MASK) == 0, + ("invalid last page, ofs 0x%jx", + (uintmax_t)segs[i].ds_addr)); + } else { + KASSERT((segs[i].ds_addr & PAGE_MASK) == 0 && + segs[i].ds_len == PAGE_SIZE, + ("not a full page, ofs 0x%jx, len %zu", + (uintmax_t)segs[i].ds_addr, + segs[i].ds_len)); + } } #endif + prplist->gpa_page[i] = atop(segs[i].ds_addr); } reqp->prp_cnt = nsegs; } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Wed Oct 12 09:27:39 2016 (r307137) @@ -71,6 +71,17 @@ struct vmbus_txbr { struct sysctl_ctx_list; struct sysctl_oid; +static __inline int +vmbus_txbr_maxpktsz(const struct vmbus_txbr *tbr) +{ + /* + * - 64 bits for the trailing start index (- sizeof(uint64_t)). + * - The rindex and windex can't be same (- 1). See + * the comment near vmbus_bufring.br_{r,w}index. + */ + return (tbr->txbr_dsize - sizeof(uint64_t) - 1); +} + void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, struct sysctl_oid *br_tree, struct vmbus_br *br, const char *name); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 09:17:41 2016 (r307136) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Wed Oct 12 09:27:39 2016 (r307137) @@ -610,6 +610,8 @@ vmbus_chan_send(struct vmbus_channel *ch hlen = sizeof(pkt); pktlen = hlen + dlen; pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr), + ("invalid packet size %d", pad_pktlen)); pkt.cp_hdr.cph_type = type; pkt.cp_hdr.cph_flags = flags; @@ -640,12 +642,11 @@ vmbus_chan_send_sglist(struct vmbus_chan boolean_t send_evt; uint64_t pad = 0; - KASSERT(sglen < VMBUS_CHAN_SGLIST_MAX, - ("invalid sglist len %d", sglen)); - hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]); pktlen = hlen + dlen; pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr), + ("invalid packet size %d", pad_pktlen)); pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; @@ -681,13 +682,12 @@ vmbus_chan_send_prplist(struct vmbus_cha boolean_t send_evt; uint64_t pad = 0; - KASSERT(prp_cnt < VMBUS_CHAN_PRPLIST_MAX, - ("invalid prplist entry count %d", prp_cnt)); - hlen = __offsetof(struct vmbus_chanpkt_prplist, cp_range[0].gpa_page[prp_cnt]); pktlen = hlen + dlen; pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen); + KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr), + ("invalid packet size %d", pad_pktlen)); pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; From owner-svn-src-stable-10@freebsd.org Wed Oct 12 10:28:58 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2291EC0D92A; Wed, 12 Oct 2016 10:28:58 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E2ADC7AC; Wed, 12 Oct 2016 10:28:57 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9CASvw0034541; Wed, 12 Oct 2016 10:28:57 GMT (envelope-from mm@FreeBSD.org) Received: (from mm@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9CAStPB034520; Wed, 12 Oct 2016 10:28:55 GMT (envelope-from mm@FreeBSD.org) Message-Id: <201610121028.u9CAStPB034520@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mm set sender to mm@FreeBSD.org using -f From: Martin Matuska Date: Wed, 12 Oct 2016 10:28:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307139 - in stable/10: contrib/libarchive/cat/test contrib/libarchive/cpio/test contrib/libarchive/libarchive contrib/libarchive/libarchive/test contrib/libarchive/tar contrib/libarchi... X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 10:28:58 -0000 Author: mm Date: Wed Oct 12 10:28:54 2016 New Revision: 307139 URL: https://svnweb.freebsd.org/changeset/base/307139 Log: MFC r306670: Sync libarchive with vendor including security fixes. Important vendor bugfixes (relevant to FreeBSD): #747: Out of bounds read in mtree parser #761: heap-based buffer overflow in read_Header (7-zip) #794: Invalid file on bsdtar command line results in internal errors (1) PR: 213092 (1) Added: stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c - copied unchanged from r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu - copied unchanged from r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu Modified: stable/10/contrib/libarchive/cat/test/main.c stable/10/contrib/libarchive/cat/test/test.h stable/10/contrib/libarchive/cpio/test/main.c stable/10/contrib/libarchive/cpio/test/test.h stable/10/contrib/libarchive/libarchive/archive_read_support_format_7zip.c stable/10/contrib/libarchive/libarchive/archive_read_support_format_mtree.c stable/10/contrib/libarchive/libarchive/test/main.c stable/10/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c stable/10/contrib/libarchive/libarchive/test/test_read_set_format.c stable/10/contrib/libarchive/tar/subst.c stable/10/contrib/libarchive/tar/test/main.c stable/10/contrib/libarchive/tar/test/test.h stable/10/contrib/libarchive/tar/test/test_option_H_upper.c stable/10/contrib/libarchive/tar/test/test_option_L_upper.c stable/10/contrib/libarchive/tar/test/test_option_U_upper.c stable/10/contrib/libarchive/tar/test/test_option_n.c stable/10/contrib/libarchive/tar/write.c stable/10/lib/libarchive/tests/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/contrib/libarchive/cat/test/main.c ============================================================================== --- stable/10/contrib/libarchive/cat/test/main.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/cat/test/main.c Wed Oct 12 10:28:54 2016 (r307139) @@ -1360,6 +1360,31 @@ assertion_file_birthtime_recent(const ch return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); } +/* Verify mode of 'pathname'. */ +int +assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) +{ + int mode; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + failure_start(file, line, "assertFileMode not yet implemented for Windows"); +#else + { + struct stat st; + r = lstat(pathname, &st); + mode = (int)(st.st_mode & 0777); + } + if (r == 0 && mode == expected_mode) + return (1); + failure_start(file, line, "File %s has mode %o, expected %o", + pathname, mode, expected_mode); +#endif + failure_finish(NULL); + return (0); +} + /* Verify mtime of 'pathname'. */ int assertion_file_mtime(const char *file, int line, @@ -1578,8 +1603,12 @@ assertion_make_dir(const char *file, int if (0 == _mkdir(dirname)) return (1); #else - if (0 == mkdir(dirname, mode)) - return (1); + if (0 == mkdir(dirname, mode)) { + if (0 == chmod(dirname, mode)) { + assertion_file_mode(file, line, dirname, mode); + return (1); + } + } #endif failure_start(file, line, "Could not create directory %s", dirname); failure_finish(NULL); @@ -1628,6 +1657,11 @@ assertion_make_file(const char *file, in failure_finish(NULL); return (0); } + if (0 != chmod(path, mode)) { + failure_start(file, line, "Could not chmod %s", path); + failure_finish(NULL); + return (0); + } if (contents != NULL) { ssize_t wsize; @@ -1644,6 +1678,7 @@ assertion_make_file(const char *file, in } } close(fd); + assertion_file_mode(file, line, path, mode); return (1); #endif } Modified: stable/10/contrib/libarchive/cat/test/test.h ============================================================================== --- stable/10/contrib/libarchive/cat/test/test.h Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/cat/test/test.h Wed Oct 12 10:28:54 2016 (r307139) @@ -241,6 +241,7 @@ int assertion_file_birthtime_recent(cons int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); +int assertion_file_mode(const char *, int, const char *, int); int assertion_file_mtime(const char *, int, const char *, long, long); int assertion_file_mtime_recent(const char *, int, const char *); int assertion_file_nlinks(const char *, int, const char *, int); Modified: stable/10/contrib/libarchive/cpio/test/main.c ============================================================================== --- stable/10/contrib/libarchive/cpio/test/main.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/cpio/test/main.c Wed Oct 12 10:28:54 2016 (r307139) @@ -1361,6 +1361,31 @@ assertion_file_birthtime_recent(const ch return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); } +/* Verify mode of 'pathname'. */ +int +assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) +{ + int mode; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + failure_start(file, line, "assertFileMode not yet implemented for Windows"); +#else + { + struct stat st; + r = lstat(pathname, &st); + mode = (int)(st.st_mode & 0777); + } + if (r == 0 && mode == expected_mode) + return (1); + failure_start(file, line, "File %s has mode %o, expected %o", + pathname, mode, expected_mode); +#endif + failure_finish(NULL); + return (0); +} + /* Verify mtime of 'pathname'. */ int assertion_file_mtime(const char *file, int line, @@ -1579,8 +1604,12 @@ assertion_make_dir(const char *file, int if (0 == _mkdir(dirname)) return (1); #else - if (0 == mkdir(dirname, mode)) - return (1); + if (0 == mkdir(dirname, mode)) { + if (0 == chmod(dirname, mode)) { + assertion_file_mode(file, line, dirname, mode); + return (1); + } + } #endif failure_start(file, line, "Could not create directory %s", dirname); failure_finish(NULL); @@ -1629,6 +1658,11 @@ assertion_make_file(const char *file, in failure_finish(NULL); return (0); } + if (0 != chmod(path, mode)) { + failure_start(file, line, "Could not chmod %s", path); + failure_finish(NULL); + return (0); + } if (contents != NULL) { ssize_t wsize; @@ -1645,6 +1679,7 @@ assertion_make_file(const char *file, in } } close(fd); + assertion_file_mode(file, line, path, mode); return (1); #endif } Modified: stable/10/contrib/libarchive/cpio/test/test.h ============================================================================== --- stable/10/contrib/libarchive/cpio/test/test.h Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/cpio/test/test.h Wed Oct 12 10:28:54 2016 (r307139) @@ -241,6 +241,7 @@ int assertion_file_birthtime_recent(cons int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); +int assertion_file_mode(const char *, int, const char *, int); int assertion_file_mtime(const char *, int, const char *, long, long); int assertion_file_mtime_recent(const char *, int, const char *); int assertion_file_nlinks(const char *, int, const char *, int); Modified: stable/10/contrib/libarchive/libarchive/archive_read_support_format_7zip.c ============================================================================== --- stable/10/contrib/libarchive/libarchive/archive_read_support_format_7zip.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/libarchive/archive_read_support_format_7zip.c Wed Oct 12 10:28:54 2016 (r307139) @@ -2431,6 +2431,8 @@ read_Header(struct archive_read *a, stru switch (type) { case kEmptyStream: + if (h->emptyStreamBools != NULL) + return (-1); h->emptyStreamBools = calloc((size_t)zip->numFiles, sizeof(*h->emptyStreamBools)); if (h->emptyStreamBools == NULL) @@ -2451,6 +2453,8 @@ read_Header(struct archive_read *a, stru return (-1); break; } + if (h->emptyFileBools != NULL) + return (-1); h->emptyFileBools = calloc(empty_streams, sizeof(*h->emptyFileBools)); if (h->emptyFileBools == NULL) @@ -2465,6 +2469,8 @@ read_Header(struct archive_read *a, stru return (-1); break; } + if (h->antiBools != NULL) + return (-1); h->antiBools = calloc(empty_streams, sizeof(*h->antiBools)); if (h->antiBools == NULL) @@ -2491,6 +2497,8 @@ read_Header(struct archive_read *a, stru if ((ll & 1) || ll < zip->numFiles * 4) return (-1); + if (zip->entry_names != NULL) + return (-1); zip->entry_names = malloc(ll); if (zip->entry_names == NULL) return (-1); @@ -2543,6 +2551,8 @@ read_Header(struct archive_read *a, stru if ((p = header_bytes(a, 2)) == NULL) return (-1); allAreDefined = *p; + if (h->attrBools != NULL) + return (-1); h->attrBools = calloc((size_t)zip->numFiles, sizeof(*h->attrBools)); if (h->attrBools == NULL) Modified: stable/10/contrib/libarchive/libarchive/archive_read_support_format_mtree.c ============================================================================== --- stable/10/contrib/libarchive/libarchive/archive_read_support_format_mtree.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/libarchive/archive_read_support_format_mtree.c Wed Oct 12 10:28:54 2016 (r307139) @@ -301,6 +301,15 @@ get_line_size(const char *b, ssize_t ava return (avail); } +/* + * <---------------- ravail ---------------------> + * <-- diff ------> <--- avail -----------------> + * <---- len -----------> + * | Previous lines | line being parsed nl extra | + * ^ + * b + * + */ static ssize_t next_line(struct archive_read *a, const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl) @@ -339,7 +348,7 @@ next_line(struct archive_read *a, *b += diff; *avail -= diff; tested = len;/* Skip some bytes we already determinated. */ - len = get_line_size(*b, *avail, nl); + len = get_line_size(*b + len, *avail - len, nl); if (len >= 0) len += tested; } Modified: stable/10/contrib/libarchive/libarchive/test/main.c ============================================================================== --- stable/10/contrib/libarchive/libarchive/test/main.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/libarchive/test/main.c Wed Oct 12 10:28:54 2016 (r307139) @@ -1607,8 +1607,12 @@ assertion_make_dir(const char *file, int if (0 == _mkdir(dirname)) return (1); #else - if (0 == mkdir(dirname, mode)) - return (1); + if (0 == mkdir(dirname, mode)) { + if (0 == chmod(dirname, mode)) { + assertion_file_mode(file, line, dirname, mode); + return (1); + } + } #endif failure_start(file, line, "Could not create directory %s", dirname); failure_finish(NULL); @@ -1657,6 +1661,11 @@ assertion_make_file(const char *file, in failure_finish(NULL); return (0); } + if (0 != chmod(path, mode)) { + failure_start(file, line, "Could not chmod %s", path); + failure_finish(NULL); + return (0); + } if (contents != NULL) { ssize_t wsize; @@ -1673,6 +1682,7 @@ assertion_make_file(const char *file, in } } close(fd); + assertion_file_mode(file, line, path, mode); return (1); #endif } Modified: stable/10/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c ============================================================================== --- stable/10/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c Wed Oct 12 10:28:54 2016 (r307139) @@ -93,7 +93,7 @@ static struct myacl_t acls_reg[] = { static struct myacl_t acls_dir[] = { /* For this test, we need to be able to read and write the ACL. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, + { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL, ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, /* An entry for each type. */ Copied: stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c (from r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c Wed Oct 12 10:28:54 2016 (r307139, copy of r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c) @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2003-2016 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" + + +/* + * Reproduce the crash reported in Github Issue #747. + */ +DEFINE_TEST(test_read_format_mtree_crash747) +{ + const char *reffile = "test_read_format_mtree_crash747.mtree.bz2"; + struct archive *a; + + extract_reference_file(reffile); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_bzip2(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_filename(a, reffile, 10240)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + Copied: stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu (from r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu Wed Oct 12 10:28:54 2016 (r307139, copy of r306670, head/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu) @@ -0,0 +1,6 @@ +begin 600 test_read_format_mtree_crash747.mtree.bz2 +M0EIH.3%!62936:OH@(@``'/[@,`0`@!``'^```)A@9\`$`@@`'4)049!IIH! +MM021-0,F@&@6````9%>$(K!GIC*XFR0`$```J0+:$XP```!D-F)H[#SE9+2' +4+E"L=ASXUI%R(I"HD'ZA(5?1`Q`` +` +end Modified: stable/10/contrib/libarchive/libarchive/test/test_read_set_format.c ============================================================================== --- stable/10/contrib/libarchive/libarchive/test/test_read_set_format.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/libarchive/test/test_read_set_format.c Wed Oct 12 10:28:54 2016 (r307139) @@ -204,7 +204,7 @@ DEFINE_TEST(test_read_append_filter_wron /* * If we have "bunzip2 -q", try using that. */ - if (!canRunCommand("bunzip2 -V")) { + if (!canRunCommand("bunzip2 -h")) { skipping("Can't run bunzip2 program on this platform"); return; } Modified: stable/10/contrib/libarchive/tar/subst.c ============================================================================== --- stable/10/contrib/libarchive/tar/subst.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/subst.c Wed Oct 12 10:28:54 2016 (r307139) @@ -84,6 +84,7 @@ add_substitution(struct bsdtar *bsdtar, if (rule == NULL) lafe_errc(1, errno, "Out of memory"); rule->next = NULL; + rule->result = NULL; if (subst->last_rule == NULL) subst->first_rule = rule; Modified: stable/10/contrib/libarchive/tar/test/main.c ============================================================================== --- stable/10/contrib/libarchive/tar/test/main.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/main.c Wed Oct 12 10:28:54 2016 (r307139) @@ -130,6 +130,13 @@ __FBSDID("$FreeBSD$"); # include #endif +mode_t umasked(mode_t expected_mode) +{ + mode_t mode = umask(0); + umask(mode); + return expected_mode & ~mode; +} + /* Path to working directory for current test */ const char *testworkdir; #ifdef PROGRAM @@ -1361,6 +1368,31 @@ assertion_file_birthtime_recent(const ch return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); } +/* Verify mode of 'pathname'. */ +int +assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) +{ + int mode; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + failure_start(file, line, "assertFileMode not yet implemented for Windows"); +#else + { + struct stat st; + r = lstat(pathname, &st); + mode = (int)(st.st_mode & 0777); + } + if (r == 0 && mode == expected_mode) + return (1); + failure_start(file, line, "File %s has mode %o, expected %o", + pathname, mode, expected_mode); +#endif + failure_finish(NULL); + return (0); +} + /* Verify mtime of 'pathname'. */ int assertion_file_mtime(const char *file, int line, @@ -1579,8 +1611,12 @@ assertion_make_dir(const char *file, int if (0 == _mkdir(dirname)) return (1); #else - if (0 == mkdir(dirname, mode)) - return (1); + if (0 == mkdir(dirname, mode)) { + if (0 == chmod(dirname, mode)) { + assertion_file_mode(file, line, dirname, mode); + return (1); + } + } #endif failure_start(file, line, "Could not create directory %s", dirname); failure_finish(NULL); @@ -1629,6 +1665,11 @@ assertion_make_file(const char *file, in failure_finish(NULL); return (0); } + if (0 != chmod(path, mode)) { + failure_start(file, line, "Could not chmod %s", path); + failure_finish(NULL); + return (0); + } if (contents != NULL) { ssize_t wsize; @@ -1645,6 +1686,7 @@ assertion_make_file(const char *file, in } } close(fd); + assertion_file_mode(file, line, path, mode); return (1); #endif } Modified: stable/10/contrib/libarchive/tar/test/test.h ============================================================================== --- stable/10/contrib/libarchive/tar/test/test.h Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/test.h Wed Oct 12 10:28:54 2016 (r307139) @@ -241,6 +241,7 @@ int assertion_file_birthtime_recent(cons int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); +int assertion_file_mode(const char *, int, const char *, int); int assertion_file_mtime(const char *, int, const char *, long, long); int assertion_file_mtime_recent(const char *, int, const char *); int assertion_file_nlinks(const char *, int, const char *, int); @@ -326,6 +327,9 @@ void copy_reference_file(const char *); */ void extract_reference_files(const char **); +/* Subtract umask from mode */ +mode_t umasked(mode_t expected_mode); + /* Path to working directory for current test */ extern const char *testworkdir; Modified: stable/10/contrib/libarchive/tar/test/test_option_H_upper.c ============================================================================== --- stable/10/contrib/libarchive/tar/test/test_option_H_upper.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/test_option_H_upper.c Wed Oct 12 10:28:54 2016 (r307139) @@ -83,10 +83,10 @@ DEFINE_TEST(test_option_H_upper) assertChdir("test3"); assertEqualInt(0, systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", 0755); + assertIsDir("ld1", umasked(0755)); assertIsSymlink("d1/linkX", "fileX"); assertIsSymlink("d1/link1", "file1"); - assertIsReg("link2", 0644); + assertIsReg("link2", umasked(0644)); assertIsSymlink("linkY", "d1/fileY"); assertChdir(".."); } Modified: stable/10/contrib/libarchive/tar/test/test_option_L_upper.c ============================================================================== --- stable/10/contrib/libarchive/tar/test/test_option_L_upper.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/test_option_L_upper.c Wed Oct 12 10:28:54 2016 (r307139) @@ -69,10 +69,10 @@ DEFINE_TEST(test_option_L_upper) assertChdir("test2"); assertEqualInt(0, systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", 0755); - assertIsReg("d1/link1", 0644); + assertIsDir("ld1", umasked(0755)); + assertIsReg("d1/link1", umasked(0644)); assertIsSymlink("d1/linkX", "fileX"); - assertIsReg("link2", 0644); + assertIsReg("link2", umasked(0644)); assertIsSymlink("linkY", "d1/fileY"); assertChdir(".."); @@ -83,10 +83,10 @@ DEFINE_TEST(test_option_L_upper) assertChdir("test3"); assertEqualInt(0, systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", 0755); - assertIsReg("d1/link1", 0644); + assertIsDir("ld1", umasked(0755)); + assertIsReg("d1/link1", umasked(0644)); assertIsSymlink("d1/linkX", "fileX"); - assertIsReg("link2", 0644); + assertIsReg("link2", umasked(0644)); assertIsSymlink("linkY", "d1/fileY"); assertChdir(".."); } Modified: stable/10/contrib/libarchive/tar/test/test_option_U_upper.c ============================================================================== --- stable/10/contrib/libarchive/tar/test/test_option_U_upper.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/test_option_U_upper.c Wed Oct 12 10:28:54 2016 (r307139) @@ -135,7 +135,7 @@ DEFINE_TEST(test_option_U_upper) assertMakeSymlink("d1/file1", "d1/realfile1"); assertEqualInt(0, systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsReg("d1/file1", 0644); + assertIsReg("d1/file1", umasked(0644)); assertFileContents("d1/file1", 8, "d1/file1"); assertFileContents("realfile1", 9, "d1/realfile1"); assertEmptyFile("test.out"); @@ -150,7 +150,7 @@ DEFINE_TEST(test_option_U_upper) assertMakeSymlink("d1/file1", "d1/realfile1"); assertEqualInt(0, systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsReg("d1/file1", 0644); + assertIsReg("d1/file1", umasked(0644)); assertFileContents("d1/file1", 8, "d1/file1"); assertFileContents("realfile1", 9, "d1/realfile1"); assertEmptyFile("test.out"); Modified: stable/10/contrib/libarchive/tar/test/test_option_n.c ============================================================================== --- stable/10/contrib/libarchive/tar/test/test_option_n.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/test/test_option_n.c Wed Oct 12 10:28:54 2016 (r307139) @@ -55,7 +55,7 @@ DEFINE_TEST(test_option_n) systemf("%s -xf archive.tar >x.out 2>x.err", testprog)); assertEmptyFile("x.out"); assertEmptyFile("x.err"); - assertIsDir("d1", 0755); + assertIsDir("d1", umasked(0755)); assertFileNotExists("d1/file1"); assertChdir(".."); } Modified: stable/10/contrib/libarchive/tar/write.c ============================================================================== --- stable/10/contrib/libarchive/tar/write.c Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/contrib/libarchive/tar/write.c Wed Oct 12 10:28:54 2016 (r307139) @@ -886,6 +886,8 @@ write_hierarchy(struct bsdtar *bsdtar, s "%s", archive_error_string(disk)); if (r == ARCHIVE_FATAL || r == ARCHIVE_FAILED) { bsdtar->return_value = 1; + archive_entry_free(entry); + archive_read_close(disk); return; } else if (r < ARCHIVE_WARN) continue; Modified: stable/10/lib/libarchive/tests/Makefile ============================================================================== --- stable/10/lib/libarchive/tests/Makefile Wed Oct 12 10:28:22 2016 (r307138) +++ stable/10/lib/libarchive/tests/Makefile Wed Oct 12 10:28:54 2016 (r307139) @@ -150,6 +150,7 @@ TESTS_SRCS= \ test_read_format_lha_bugfix_0.c \ test_read_format_lha_filename.c \ test_read_format_mtree.c \ + test_read_format_mtree_crash747.c \ test_read_format_pax_bz2.c \ test_read_format_rar.c \ test_read_format_rar_encryption_data.c \ @@ -466,6 +467,7 @@ FILES+= test_read_format_lha_lh6.lzh.uu FILES+= test_read_format_lha_lh7.lzh.uu FILES+= test_read_format_lha_withjunk.lzh.uu FILES+= test_read_format_mtree.mtree.uu +FILES+= test_read_format_mtree_crash747.mtree.bz2.uu FILES+= test_read_format_mtree_nomagic.mtree.uu FILES+= test_read_format_mtree_nomagic2.mtree.uu FILES+= test_read_format_mtree_nomagic3.mtree.uu From owner-svn-src-stable-10@freebsd.org Wed Oct 12 11:48:49 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4A8C7C0EE88; Wed, 12 Oct 2016 11:48:49 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 16E543D8; Wed, 12 Oct 2016 11:48:49 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9CBmmm9064520; Wed, 12 Oct 2016 11:48:48 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9CBmm8M064519; Wed, 12 Oct 2016 11:48:48 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201610121148.u9CBmm8M064519@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Wed, 12 Oct 2016 11:48:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307143 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 11:48:49 -0000 Author: avg Date: Wed Oct 12 11:48:47 2016 New Revision: 307143 URL: https://svnweb.freebsd.org/changeset/base/307143 Log: MFC r306665: zfs: fix a wrong assertion for extended attributes PR: 213112 Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Oct 12 11:48:14 2016 (r307142) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Wed Oct 12 11:48:47 2016 (r307143) @@ -1454,7 +1454,8 @@ zfs_lookup_lock(vnode_t *dvp, vnode_t *v ASSERT_VOP_LOCKED(dvp, __func__); #ifdef DIAGNOSTIC - ASSERT(!RRM_LOCK_HELD(&zfsvfs->z_teardown_lock)); + if ((zdp->z_pflags & ZFS_XATTR) == 0) + VERIFY(!RRM_LOCK_HELD(&zfsvfs->z_teardown_lock)); #endif if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) { @@ -6017,13 +6018,15 @@ zfs_lock(ap) vp = ap->a_vp; flags = ap->a_flags; if ((flags & LK_INTERLOCK) == 0 && (flags & LK_NOWAIT) == 0 && - (vp->v_iflag & VI_DOOMED) == 0 && (zp = vp->v_data) != NULL) { + (vp->v_iflag & VI_DOOMED) == 0 && (zp = vp->v_data) != NULL && + (zp->z_pflags & ZFS_XATTR) == 0) { zfsvfs = zp->z_zfsvfs; VERIFY(!RRM_LOCK_HELD(&zfsvfs->z_teardown_lock)); } err = vop_stdlock(ap); if ((flags & LK_INTERLOCK) != 0 && (flags & LK_NOWAIT) == 0 && - (vp->v_iflag & VI_DOOMED) == 0 && (zp = vp->v_data) != NULL) { + (vp->v_iflag & VI_DOOMED) == 0 && (zp = vp->v_data) != NULL && + (zp->z_pflags & ZFS_XATTR) == 0) { zfsvfs = zp->z_zfsvfs; VERIFY(!RRM_LOCK_HELD(&zfsvfs->z_teardown_lock)); } From owner-svn-src-stable-10@freebsd.org Wed Oct 12 20:19:34 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C7F30C0F9B5; Wed, 12 Oct 2016 20:19:34 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7CB1A2B1; Wed, 12 Oct 2016 20:19:34 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9CKJXvC058681; Wed, 12 Oct 2016 20:19:33 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9CKJXT9058679; Wed, 12 Oct 2016 20:19:33 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201610122019.u9CKJXT9058679@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Wed, 12 Oct 2016 20:19:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307155 - stable/10/lib/libc/sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Oct 2016 20:19:34 -0000 Author: jilles Date: Wed Oct 12 20:19:33 2016 New Revision: 307155 URL: https://svnweb.freebsd.org/changeset/base/307155 Log: MFC r305628: intro(2),_exit(2): Update for reaper (procctl(PROC_REAP_ACQUIRE)). Modified: stable/10/lib/libc/sys/_exit.2 stable/10/lib/libc/sys/intro.2 Directory Properties: stable/10/ (props changed) Modified: stable/10/lib/libc/sys/_exit.2 ============================================================================== --- stable/10/lib/libc/sys/_exit.2 Wed Oct 12 19:53:10 2016 (r307154) +++ stable/10/lib/libc/sys/_exit.2 Wed Oct 12 20:19:33 2016 (r307155) @@ -28,7 +28,7 @@ .\" @(#)_exit.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd September 8, 2016 .Dt EXIT 2 .Os .Sh NAME @@ -64,9 +64,11 @@ is set as defined by .Xr wait 2 . .It The parent process-ID of all of the calling process's existing child -processes are set to 1; the initialization process +processes are set to the process-ID of the calling process's reaper; +the reaper (normally the initialization process) inherits each of these processes (see +.Xr procctl 2 , .Xr init 8 and the .Sx DEFINITIONS Modified: stable/10/lib/libc/sys/intro.2 ============================================================================== --- stable/10/lib/libc/sys/intro.2 Wed Oct 12 19:53:10 2016 (r307154) +++ stable/10/lib/libc/sys/intro.2 Wed Oct 12 20:19:33 2016 (r307155) @@ -28,7 +28,7 @@ .\" @(#)intro.2 8.5 (Berkeley) 2/27/95 .\" $FreeBSD$ .\" -.Dd May 4, 2013 +.Dd September 8, 2016 .Dt INTRO 2 .Os .Sh NAME @@ -486,7 +486,10 @@ A new process is created by a currently .Xr fork 2 ) . The parent process ID of a process is initially the process ID of its creator. If the creating process exits, -the parent process ID of each child is set to the ID of a system process, +the parent process ID of each child is set to the ID of the calling process's +reaper (see +.Xr procctl 2 ) , +normally .Xr init 8 . .It Process Group Each active process is a member of a process group that is identified by @@ -535,7 +538,7 @@ when none of its members has a parent pr as the group, but is in a different process group. Note that when a process exits, the parent process for its children -is changed to be +is normally changed to be .Xr init 8 , which is in a separate session. Not all members of an orphaned process group are necessarily orphaned From owner-svn-src-stable-10@freebsd.org Thu Oct 13 01:43:17 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 429B8C0EA1A; Thu, 13 Oct 2016 01:43:17 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1D350D21; Thu, 13 Oct 2016 01:43:17 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D1hG5K084232; Thu, 13 Oct 2016 01:43:16 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D1hFAb084225; Thu, 13 Oct 2016 01:43:15 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130143.u9D1hFAb084225@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 01:43:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307160 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 01:43:17 -0000 Author: sephe Date: Thu Oct 13 01:43:15 2016 New Revision: 307160 URL: https://svnweb.freebsd.org/changeset/base/307160 Log: MFC 303822-303824 303822 hyperv/ic: Remove never used second parameter of hv_negotiate_version() Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7422 303823 hyperv/ic: Expose the receive buffer length for callers to use. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7423 303824 hyperv/ic: Pass the channel callback to hv_util_attach() The saved channel callback in util softc is actually never used. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7424 Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 01:43:15 2016 (r307160) @@ -64,7 +64,7 @@ hv_heartbeat_cb(struct vmbus_channel *ch softc = (hv_util_sc*)context; buf = softc->receive_buffer;; - recvlen = PAGE_SIZE; + recvlen = softc->ic_buflen; ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid); KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough")); /* XXX check recvlen to make sure that it contains enough data */ @@ -75,8 +75,7 @@ hv_heartbeat_cb(struct vmbus_channel *ch &buf[sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, NULL, buf); - + hv_negotiate_version(icmsghdrp, buf); } else { heartbeat_msg = (struct hv_vmbus_heartbeat_msg_data *) @@ -110,11 +109,7 @@ hv_heartbeat_probe(device_t dev) static int hv_heartbeat_attach(device_t dev) { - hv_util_sc *softc = (hv_util_sc*)device_get_softc(dev); - - softc->callback = hv_heartbeat_cb; - - return hv_util_attach(dev); + return hv_util_attach(dev, hv_heartbeat_cb); } static device_method_t heartbeat_methods[] = { Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 01:43:15 2016 (r307160) @@ -629,7 +629,7 @@ hv_kvp_process_request(void *context, in kvp_buf = sc->util_sc.receive_buffer;; channel = vmbus_get_channel(sc->dev); - recvlen = 2 * PAGE_SIZE; + recvlen = sc->util_sc.ic_buflen; ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid); KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough")); /* XXX check recvlen to make sure that it contains enough data */ @@ -696,7 +696,7 @@ hv_kvp_process_request(void *context, in /* * Try reading next buffer */ - recvlen = 2 * PAGE_SIZE; + recvlen = sc->util_sc.ic_buflen; ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid); KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough")); /* XXX check recvlen to make sure that it contains enough data */ @@ -892,7 +892,6 @@ hv_kvp_attach(device_t dev) hv_kvp_sc *sc = (hv_kvp_sc*)device_get_softc(dev); - sc->util_sc.callback = hv_kvp_callback; sc->dev = dev; sema_init(&sc->dev_sema, 0, "hv_kvp device semaphore"); mtx_init(&sc->pending_mutex, "hv-kvp pending mutex", @@ -920,7 +919,7 @@ hv_kvp_attach(device_t dev) return (error); sc->hv_kvp_dev->si_drv1 = sc; - return hv_util_attach(dev); + return hv_util_attach(dev, hv_kvp_callback); } static int Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 01:43:15 2016 (r307160) @@ -68,7 +68,7 @@ hv_shutdown_cb(struct vmbus_channel *cha softc = (hv_util_sc*)context; buf = softc->receive_buffer;; - recv_len = PAGE_SIZE; + recv_len = softc->ic_buflen; ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id); KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough")); /* XXX check recv_len to make sure that it contains enough data */ @@ -79,8 +79,7 @@ hv_shutdown_cb(struct vmbus_channel *cha &buf[sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, NULL, buf); - + hv_negotiate_version(icmsghdrp, buf); } else { shutdown_msg = (struct hv_vmbus_shutdown_msg_data *) @@ -132,11 +131,7 @@ hv_shutdown_probe(device_t dev) static int hv_shutdown_attach(device_t dev) { - hv_util_sc *softc = (hv_util_sc*)device_get_softc(dev); - - softc->callback = hv_shutdown_cb; - - return hv_util_attach(dev); + return hv_util_attach(dev, hv_shutdown_cb); } static device_method_t shutdown_methods[] = { Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 01:43:15 2016 (r307160) @@ -145,7 +145,7 @@ hv_timesync_cb(struct vmbus_channel *cha softc = (hv_timesync_sc*)context; time_buf = softc->util_sc.receive_buffer; - recvlen = PAGE_SIZE; + recvlen = softc->util_sc.ic_buflen; ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId); KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough")); /* XXX check recvlen to make sure that it contains enough data */ @@ -155,7 +155,7 @@ hv_timesync_cb(struct vmbus_channel *cha sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, NULL, time_buf); + hv_negotiate_version(icmsghdrp, time_buf); } else { timedatap = (struct hv_ictimesync_data *) &time_buf[ sizeof(struct hv_vmbus_pipe_hdr) + @@ -189,18 +189,16 @@ hv_timesync_attach(device_t dev) { hv_timesync_sc *softc = device_get_softc(dev); - softc->util_sc.callback = hv_timesync_cb; TASK_INIT(&softc->task, 1, hv_set_host_time, softc); - - return hv_util_attach(dev); + return hv_util_attach(dev, hv_timesync_cb); } static int hv_timesync_detach(device_t dev) { hv_timesync_sc *softc = device_get_softc(dev); - taskqueue_drain(taskqueue_thread, &softc->task); + taskqueue_drain(taskqueue_thread, &softc->task); return hv_util_detach(dev); } Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.c Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 01:43:15 2016 (r307160) @@ -44,12 +44,13 @@ #include #include "hv_util.h" +#define VMBUS_IC_BRSIZE (4 * PAGE_SIZE) + void -hv_negotiate_version( - struct hv_vmbus_icmsg_hdr* icmsghdrp, - struct hv_vmbus_icmsg_negotiate* negop, - uint8_t* buf) +hv_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf) { + struct hv_vmbus_icmsg_negotiate *negop; + icmsghdrp->icmsgsize = 0x10; negop = (struct hv_vmbus_icmsg_negotiate *)&buf[ @@ -74,16 +75,15 @@ hv_negotiate_version( } int -hv_util_attach(device_t dev) +hv_util_attach(device_t dev, vmbus_chan_callback_t cb) { - struct hv_util_sc* softc; - struct vmbus_channel *chan; - int ret; - - softc = device_get_softc(dev); - softc->receive_buffer = - malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO); - chan = vmbus_get_channel(dev); + struct hv_util_sc *sc = device_get_softc(dev); + struct vmbus_channel *chan = vmbus_get_channel(dev); + int error; + + sc->ic_buflen = VMBUS_IC_BRSIZE; + sc->receive_buffer = malloc(VMBUS_IC_BRSIZE, M_DEVBUF, + M_WAITOK | M_ZERO); /* * These services are not performance critical and do not need @@ -94,17 +94,13 @@ hv_util_attach(device_t dev) */ vmbus_chan_set_readbatch(chan, false); - ret = vmbus_chan_open(chan, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0, - softc->callback, softc); - - if (ret) - goto error0; - + error = vmbus_chan_open(chan, VMBUS_IC_BRSIZE, VMBUS_IC_BRSIZE, NULL, 0, + cb, sc); + if (error) { + free(sc->receive_buffer, M_DEVBUF); + return (error); + } return (0); - -error0: - free(softc->receive_buffer, M_DEVBUF); - return (ret); } int Modified: stable/10/sys/dev/hyperv/utilities/hv_util.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.h Wed Oct 12 20:50:17 2016 (r307159) +++ stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 01:43:15 2016 (r307160) @@ -31,23 +31,20 @@ #ifndef _HVUTIL_H_ #define _HVUTIL_H_ +#include + /** * hv_util related structures * */ typedef struct hv_util_sc { - /* - * function to process Hyper-V messages - */ - void (*callback)(struct vmbus_channel *, void *); uint8_t *receive_buffer; + int ic_buflen; } hv_util_sc; -void hv_negotiate_version( - struct hv_vmbus_icmsg_hdr* icmsghdrp, - struct hv_vmbus_icmsg_negotiate* negop, - uint8_t* buf); +void hv_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf); -int hv_util_attach(device_t dev); +int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); int hv_util_detach(device_t dev); + #endif From owner-svn-src-stable-10@freebsd.org Thu Oct 13 01:51:51 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0FF45C0EC27; Thu, 13 Oct 2016 01:51:51 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D34A3210; Thu, 13 Oct 2016 01:51:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D1po5W086309; Thu, 13 Oct 2016 01:51:50 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D1pnIG086303; Thu, 13 Oct 2016 01:51:49 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130151.u9D1pnIG086303@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 01:51:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307161 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 01:51:51 -0000 Author: sephe Date: Thu Oct 13 01:51:49 2016 New Revision: 307161 URL: https://svnweb.freebsd.org/changeset/base/307161 Log: MFC 303867,303901 303867 hyperv/hn: Move gpa array out of netvsc_packet. Prepare to deprecate the netvsc_packet. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7436 303901 hyperv/hn: Reorganize send done callback. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7450 Added: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h - copied unchanged from r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 01:43:15 2016 (r307160) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 01:51:49 2016 (r307161) @@ -67,6 +67,12 @@ static void hv_nv_on_receive_completion( static void hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt); +static void hn_nvs_sent_none(struct hn_send_ctx *sndc, + struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, + const struct nvsp_msg_ *msg); + +static struct hn_send_ctx hn_send_ctx_none = + HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); /* * @@ -140,6 +146,7 @@ hv_nv_get_next_send_section(netvsc_dev * static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) { + struct hn_send_ctx sndc; netvsc_dev *net_dev; nvsp_msg *init_pkt; int ret = 0; @@ -188,9 +195,10 @@ hv_nv_init_rx_buffer_with_net_vsp(struct /* Send the gpadl notification request */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); if (ret != 0) { goto cleanup; } @@ -239,6 +247,7 @@ exit: static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) { + struct hn_send_ctx sndc; netvsc_dev *net_dev; nvsp_msg *init_pkt; int ret = 0; @@ -286,9 +295,10 @@ hv_nv_init_send_buffer_with_net_vsp(stru /* Send the gpadl notification request */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); if (ret != 0) { goto cleanup; } @@ -347,8 +357,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ ret = vmbus_chan_send(net_dev->sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)revoke_pkt); - + (uint64_t)(uintptr_t)&hn_send_ctx_none); /* * If we failed here, we might as well return and have a leak * rather than continue and a bugchk @@ -413,9 +422,8 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne NETVSC_SEND_BUFFER_ID; ret = vmbus_chan_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, 0, - revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)revoke_pkt); + VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), + (uint64_t)(uintptr_t)&hn_send_ctx_none); /* * If we failed here, we might as well return and have a leak * rather than continue and a bugchk @@ -465,6 +473,7 @@ static int hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev, uint32_t nvsp_ver) { + struct hn_send_ctx sndc; nvsp_msg *init_pkt; int ret; @@ -479,9 +488,10 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver; /* Send the init request */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); if (ret != 0) return (-1); @@ -523,7 +533,7 @@ hv_nv_send_ndis_config(struct hn_softc * /* Send the configuration packet */ ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none); if (ret != 0) return (-EINVAL); @@ -601,7 +611,7 @@ hv_nv_connect_to_vsp(struct hn_softc *sc /* Send the init request */ ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none); if (ret != 0) { goto cleanup; } @@ -730,6 +740,43 @@ hv_nv_on_device_remove(struct hn_softc * return (0); } +void +hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused, + struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused, + const struct nvsp_msg_ *msg) +{ + /* Copy the response back */ + memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg)); + sema_post(&net_dev->channel_init_sema); +} + +static void +hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, + struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, + const struct nvsp_msg_ *msg __unused) +{ + /* EMPTY */ +} + +void +hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx) +{ + u_long mask; + uint32_t idx; + + idx = chim_idx / BITS_PER_LONG; + KASSERT(idx < net_dev->bitsmap_words, + ("invalid chimney index 0x%x", chim_idx)); + + mask = 1UL << (chim_idx % BITS_PER_LONG); + KASSERT(net_dev->send_section_bitsmap[idx] & mask, + ("index bitmap 0x%lx, chimney index %u, " + "bitmap idx %d, bitmask 0x%lx", + net_dev->send_section_bitsmap[idx], chim_idx, idx, mask)); + + atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask); +} + /* * Net VSC on send completion */ @@ -737,59 +784,15 @@ static void hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt) { - const nvsp_msg *nvsp_msg_pkt; - netvsc_packet *net_vsc_pkt; + struct hn_send_ctx *sndc; - nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt); - - if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete - || nvsp_msg_pkt->hdr.msg_type - == nvsp_msg_1_type_send_rx_buf_complete - || nvsp_msg_pkt->hdr.msg_type - == nvsp_msg_1_type_send_send_buf_complete - || nvsp_msg_pkt->hdr.msg_type - == nvsp_msg5_type_subchannel) { - /* Copy the response back */ - memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt, - sizeof(nvsp_msg)); - sema_post(&net_dev->channel_init_sema); - } else if (nvsp_msg_pkt->hdr.msg_type == - nvsp_msg_1_type_send_rndis_pkt_complete) { - /* Get the send context */ - net_vsc_pkt = - (netvsc_packet *)(unsigned long)pkt->cph_xactid; - if (NULL != net_vsc_pkt) { - if (net_vsc_pkt->send_buf_section_idx != - NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) { - u_long mask; - int idx; - - idx = net_vsc_pkt->send_buf_section_idx / - BITS_PER_LONG; - KASSERT(idx < net_dev->bitsmap_words, - ("invalid section index %u", - net_vsc_pkt->send_buf_section_idx)); - mask = 1UL << - (net_vsc_pkt->send_buf_section_idx % - BITS_PER_LONG); - - KASSERT(net_dev->send_section_bitsmap[idx] & - mask, - ("index bitmap 0x%lx, section index %u, " - "bitmap idx %d, bitmask 0x%lx", - net_dev->send_section_bitsmap[idx], - net_vsc_pkt->send_buf_section_idx, - idx, mask)); - atomic_clear_long( - &net_dev->send_section_bitsmap[idx], mask); - } - - /* Notify the layer above us */ - net_vsc_pkt->compl.send.on_send_completion(chan, - net_vsc_pkt->compl.send.send_completion_context); - - } - } + sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; + sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt)); + /* + * NOTE: + * 'sndc' CAN NOT be accessed anymore, since it can be freed by + * its callback. + */ } /* @@ -798,13 +801,14 @@ hv_nv_on_send_completion(netvsc_dev *net * Returns 0 on success, non-zero on failure. */ int -hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt) +hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt, + struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) { nvsp_msg send_msg; int ret; send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt; - if (pkt->is_data_pkt) { + if (is_data_pkt) { /* 0 is RMC_DATA */ send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0; } else { @@ -813,17 +817,17 @@ hv_nv_on_send(struct vmbus_channel *chan } send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx = - pkt->send_buf_section_idx; + sndc->hn_chim_idx; send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = - pkt->send_buf_section_size; + sndc->hn_chim_sz; - if (pkt->gpa_cnt) { - ret = vmbus_chan_send_sglist(chan, pkt->gpa, pkt->gpa_cnt, - &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); + if (gpa_cnt) { + ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt, + &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); } else { ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); + &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); } return (ret); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 01:43:15 2016 (r307160) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 01:51:49 2016 (r307161) @@ -1112,33 +1112,10 @@ typedef void (*pfn_on_send_rx_completion #endif typedef struct netvsc_packet_ { - uint8_t is_data_pkt; /* One byte */ - uint16_t vlan_tci; - uint32_t status; - - /* Completion */ - union { - struct { - uint64_t rx_completion_tid; - void *rx_completion_context; - /* This is no longer used */ - pfn_on_send_rx_completion on_rx_completion; - } rx; - struct { - uint64_t send_completion_tid; - void *send_completion_context; - /* Still used in netvsc and filter code */ - pfn_on_send_rx_completion on_send_completion; - } send; - } compl; - uint32_t send_buf_section_idx; - uint32_t send_buf_section_size; - - void *rndis_mesg; + uint16_t vlan_tci; + uint32_t status; uint32_t tot_data_buf_len; void *data; - uint32_t gpa_cnt; - struct vmbus_gpa gpa[NETVSC_PACKET_MAXPAGE]; } netvsc_packet; typedef struct { @@ -1216,6 +1193,9 @@ struct hn_tx_ring { bus_dma_tag_t hn_tx_data_dtag; uint64_t hn_csum_assist; + int hn_gpa_cnt; + struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE]; + u_long hn_no_txdescs; u_long hn_send_failed; u_long hn_txdma_failed; @@ -1270,13 +1250,15 @@ typedef struct hn_softc { * Externs */ extern int hv_promisc_mode; +struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc, void *additional_info, struct hn_rx_ring *rxr); int hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); -int hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt); +int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt, + struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); int hv_nv_get_next_send_section(netvsc_dev *net_dev); void hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 01:43:15 2016 (r307160) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 01:51:49 2016 (r307161) @@ -168,7 +168,7 @@ struct hn_txdesc { struct hn_tx_ring *txr; int refs; uint32_t flags; /* HN_TXD_FLAG_ */ - netvsc_packet netvsc_pkt; /* XXX to be removed */ + struct hn_send_ctx send_ctx; bus_dmamap_t data_dmap; @@ -793,14 +793,14 @@ hn_txeof(struct hn_tx_ring *txr) } static void -hn_tx_done(struct vmbus_channel *chan, void *xpkt) +hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, + struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused) { - netvsc_packet *packet = xpkt; - struct hn_txdesc *txd; + struct hn_txdesc *txd = sndc->hn_cbarg; struct hn_tx_ring *txr; - txd = (struct hn_txdesc *)(uintptr_t) - packet->compl.send.send_completion_tid; + if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) + hn_chim_free(net_dev, sndc->hn_chim_idx); txr = txd->txr; KASSERT(txr->hn_chan == chan, @@ -853,16 +853,14 @@ hn_encap(struct hn_tx_ring *txr, struct bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX]; int error, nsegs, i; struct mbuf *m_head = *m_head0; - netvsc_packet *packet; rndis_msg *rndis_mesg; rndis_packet *rndis_pkt; rndis_per_packet_info *rppi; struct rndis_hash_value *hash_value; - uint32_t rndis_msg_size; + uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx; + int send_buf_section_size; - packet = &txd->netvsc_pkt; - packet->is_data_pkt = TRUE; - packet->tot_data_buf_len = m_head->m_pkthdr.len; + tot_data_buf_len = m_head->m_pkthdr.len; /* * extension points to the area reserved for the @@ -877,7 +875,7 @@ hn_encap(struct hn_tx_ring *txr, struct rndis_pkt = &rndis_mesg->msg.packet; rndis_pkt->data_offset = sizeof(rndis_packet); - rndis_pkt->data_length = packet->tot_data_buf_len; + rndis_pkt->data_length = tot_data_buf_len; rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet); rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); @@ -985,15 +983,14 @@ hn_encap(struct hn_tx_ring *txr, struct } } - rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size; - packet->tot_data_buf_len = rndis_mesg->msg_len; + rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size; + tot_data_buf_len = rndis_mesg->msg_len; /* * Chimney send, if the packet could fit into one chimney buffer. */ - if (packet->tot_data_buf_len < txr->hn_tx_chimney_size) { + if (tot_data_buf_len < txr->hn_tx_chimney_size) { netvsc_dev *net_dev = txr->hn_sc->net_dev; - uint32_t send_buf_section_idx; txr->hn_tx_chimney_tried++; send_buf_section_idx = @@ -1008,10 +1005,8 @@ hn_encap(struct hn_tx_ring *txr, struct dest += rndis_msg_size; m_copydata(m_head, 0, m_head->m_pkthdr.len, dest); - packet->send_buf_section_idx = send_buf_section_idx; - packet->send_buf_section_size = - packet->tot_data_buf_len; - packet->gpa_cnt = 0; + send_buf_section_size = tot_data_buf_len; + txr->hn_gpa_cnt = 0; txr->hn_tx_chimney++; goto done; } @@ -1037,19 +1032,19 @@ hn_encap(struct hn_tx_ring *txr, struct } *m_head0 = m_head; - packet->gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS; + txr->hn_gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS; /* send packet with page buffer */ - packet->gpa[0].gpa_page = atop(txd->rndis_msg_paddr); - packet->gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; - packet->gpa[0].gpa_len = rndis_msg_size; + txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr); + txr->hn_gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; + txr->hn_gpa[0].gpa_len = rndis_msg_size; /* * Fill the page buffers with mbuf info starting at index * HV_RF_NUM_TX_RESERVED_PAGE_BUFS. */ for (i = 0; i < nsegs; ++i) { - struct vmbus_gpa *gpa = &packet->gpa[ + struct vmbus_gpa *gpa = &txr->hn_gpa[ i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS]; gpa->gpa_page = atop(segs[i].ds_addr); @@ -1057,16 +1052,14 @@ hn_encap(struct hn_tx_ring *txr, struct gpa->gpa_len = segs[i].ds_len; } - packet->send_buf_section_idx = - NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; - packet->send_buf_section_size = 0; + send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; + send_buf_section_size = 0; done: txd->m = m_head; /* Set the completion routine */ - packet->compl.send.on_send_completion = hn_tx_done; - packet->compl.send.send_completion_context = packet; - packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)txd; + hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd, + send_buf_section_idx, send_buf_section_size); return 0; } @@ -1086,7 +1079,8 @@ again: * Make sure that txd is not freed before ETHER_BPF_MTAP. */ hn_txdesc_hold(txd); - error = hv_nv_on_send(txr->hn_chan, &txd->netvsc_pkt); + error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx, + txr->hn_gpa, txr->hn_gpa_cnt); if (!error) { ETHER_BPF_MTAP(ifp, txd->m); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 01:43:15 2016 (r307160) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 01:51:49 2016 (r307161) @@ -86,11 +86,17 @@ static int hv_rf_set_packet_filter(rndi static int hv_rf_init_device(rndis_device *device); static int hv_rf_open_device(rndis_device *device); static int hv_rf_close_device(rndis_device *device); -static void hv_rf_on_send_request_completion(struct vmbus_channel *, void *context); -static void hv_rf_on_send_request_halt_completion(struct vmbus_channel *, void *context); int hv_rf_send_offload_request(struct hn_softc *sc, rndis_offload_params *offloads); + +static void hn_rndis_sent_halt(struct hn_send_ctx *sndc, + struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, + const struct nvsp_msg_ *msg); +static void hn_rndis_sent_cb(struct hn_send_ctx *sndc, + struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, + const struct nvsp_msg_ *msg); + /* * Set the Per-Packet-Info with the specified type */ @@ -239,45 +245,36 @@ static int hv_rf_send_request(rndis_device *device, rndis_request *request, uint32_t message_type) { - int ret; - netvsc_packet *packet; netvsc_dev *net_dev = device->net_dev; - int send_buf_section_idx; + uint32_t send_buf_section_idx, tot_data_buf_len; + struct vmbus_gpa gpa[2]; + int gpa_cnt, send_buf_section_size; + hn_sent_callback_t cb; /* Set up the packet to send it */ - packet = &request->pkt; - - packet->is_data_pkt = FALSE; - packet->tot_data_buf_len = request->request_msg.msg_len; - packet->gpa_cnt = 1; - - packet->gpa[0].gpa_page = - hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT; - packet->gpa[0].gpa_len = request->request_msg.msg_len; - packet->gpa[0].gpa_ofs = - (unsigned long)&request->request_msg & (PAGE_SIZE - 1); - - if (packet->gpa[0].gpa_ofs + packet->gpa[0].gpa_len > PAGE_SIZE) { - packet->gpa_cnt = 2; - packet->gpa[0].gpa_len = PAGE_SIZE - packet->gpa[0].gpa_ofs; - packet->gpa[1].gpa_page = - hv_get_phys_addr((char*)&request->request_msg + - packet->gpa[0].gpa_len) >> PAGE_SHIFT; - packet->gpa[1].gpa_ofs = 0; - packet->gpa[1].gpa_len = request->request_msg.msg_len - - packet->gpa[0].gpa_len; - } - - packet->compl.send.send_completion_context = request; /* packet */ - if (message_type != REMOTE_NDIS_HALT_MSG) { - packet->compl.send.on_send_completion = - hv_rf_on_send_request_completion; - } else { - packet->compl.send.on_send_completion = - hv_rf_on_send_request_halt_completion; + tot_data_buf_len = request->request_msg.msg_len; + + gpa_cnt = 1; + gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT; + gpa[0].gpa_len = request->request_msg.msg_len; + gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1); + + if (gpa[0].gpa_ofs + gpa[0].gpa_len > PAGE_SIZE) { + gpa_cnt = 2; + gpa[0].gpa_len = PAGE_SIZE - gpa[0].gpa_ofs; + gpa[1].gpa_page = + hv_get_phys_addr((char*)&request->request_msg + + gpa[0].gpa_len) >> PAGE_SHIFT; + gpa[1].gpa_ofs = 0; + gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len; } - packet->compl.send.send_completion_tid = (unsigned long)device; - if (packet->tot_data_buf_len < net_dev->send_section_size) { + + if (message_type != REMOTE_NDIS_HALT_MSG) + cb = hn_rndis_sent_cb; + else + cb = hn_rndis_sent_halt; + + if (tot_data_buf_len < net_dev->send_section_size) { send_buf_section_idx = hv_nv_get_next_send_section(net_dev); if (send_buf_section_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) { @@ -285,20 +282,20 @@ hv_rf_send_request(rndis_device *device, send_buf_section_idx * net_dev->send_section_size); memcpy(dest, &request->request_msg, request->request_msg.msg_len); - packet->send_buf_section_idx = send_buf_section_idx; - packet->send_buf_section_size = packet->tot_data_buf_len; - packet->gpa_cnt = 0; + send_buf_section_size = tot_data_buf_len; + gpa_cnt = 0; goto sendit; } /* Failed to allocate chimney send buffer; move on */ } - packet->send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; - packet->send_buf_section_size = 0; + send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; + send_buf_section_size = 0; sendit: - ret = hv_nv_on_send(device->net_dev->sc->hn_prichan, packet); - - return (ret); + hn_send_ctx_init(&request->send_ctx, cb, request, + send_buf_section_idx, send_buf_section_size); + return hv_nv_on_send(device->net_dev->sc->hn_prichan, false, + &request->send_ctx, gpa, gpa_cnt); } /* @@ -1060,6 +1057,7 @@ int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan, struct hn_rx_ring *rxr) { + struct hn_send_ctx sndc; int ret; netvsc_dev *net_dev; rndis_device *rndis_dev; @@ -1166,9 +1164,10 @@ hv_rf_on_device_add(struct hn_softc *sc, init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels = net_dev->num_channel - 1; + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt); + init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); if (ret != 0) { device_printf(dev, "Fail to allocate subchannel\n"); goto out; @@ -1239,23 +1238,22 @@ hv_rf_on_close(struct hn_softc *sc) return (hv_rf_close_device((rndis_device *)net_dev->extension)); } -/* - * RNDIS filter on send request completion callback - */ -static void -hv_rf_on_send_request_completion(struct vmbus_channel *chan __unused, - void *context __unused) +static void +hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, + struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused) { + if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) + hn_chim_free(net_dev, sndc->hn_chim_idx); } -/* - * RNDIS filter on send request (halt only) completion callback - */ -static void -hv_rf_on_send_request_halt_completion(struct vmbus_channel *chan __unused, - void *context) +static void +hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, + struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused) { - rndis_request *request = context; + rndis_request *request = sndc->hn_cbarg; + + if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) + hn_chim_free(net_dev, sndc->hn_chim_idx); /* * Notify hv_rf_halt_device() about halt completion. Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 01:43:15 2016 (r307160) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 01:51:49 2016 (r307161) @@ -33,6 +33,7 @@ #include #include +#include /* * Defines @@ -75,7 +76,7 @@ typedef struct rndis_request_ { uint8_t buf_resp[PAGE_SIZE]; /* Simplify allocation by having a netvsc packet inline */ - netvsc_packet pkt; + struct hn_send_ctx send_ctx; /* * The max request size is sizeof(rndis_msg) + PAGE_SIZE. Copied: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h (from r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 01:51:49 2016 (r307161, copy of r303901, head/sys/dev/hyperv/netvsc/if_hnvar.h) @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2016 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IF_HNVAR_H_ +#define _IF_HNVAR_H_ + +#include +#include + +struct netvsc_dev_; +struct nvsp_msg_; + +struct vmbus_channel; +struct hn_send_ctx; + +typedef void (*hn_sent_callback_t) + (struct hn_send_ctx *, struct netvsc_dev_ *, + struct vmbus_channel *, const struct nvsp_msg_ *); + +struct hn_send_ctx { + hn_sent_callback_t hn_cb; + void *hn_cbarg; + uint32_t hn_chim_idx; + int hn_chim_sz; +}; + +#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ +{ \ + .hn_cb = cb, \ + .hn_cbarg = cbarg, \ + .hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \ + .hn_chim_sz = 0 \ +} + +static __inline void +hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, + void *cbarg, uint32_t chim_idx, int chim_sz) +{ + sndc->hn_cb = cb; + sndc->hn_cbarg = cbarg; + sndc->hn_chim_idx = chim_idx; + sndc->hn_chim_sz = chim_sz; +} + +static __inline void +hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb, + void *cbarg) +{ + hn_send_ctx_init(sndc, cb, cbarg, + NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0); +} + +void hn_nvs_sent_wakeup(struct hn_send_ctx *sndc, + struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, + const struct nvsp_msg_ *msg); +void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx); + +#endif /* !_IF_HNVAR_H_ */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 01:58:51 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4C547C0ECAE; Thu, 13 Oct 2016 01:58:51 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 10BE767E; Thu, 13 Oct 2016 01:58:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D1wovB088692; Thu, 13 Oct 2016 01:58:50 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D1wo0I088691; Thu, 13 Oct 2016 01:58:50 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130158.u9D1wo0I088691@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 01:58:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307162 - stable/10/sys/cam/scsi X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 01:58:51 -0000 Author: sephe Date: Thu Oct 13 01:58:49 2016 New Revision: 307162 URL: https://svnweb.freebsd.org/changeset/base/307162 Log: MFC 303944 cam/da: Add quirk for I-O Data USB Flash Disk PR: 211716 Submitted by: Jun Su Reported by: Jun Su Sponsored by: Microsoft Modified: stable/10/sys/cam/scsi/scsi_da.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/scsi/scsi_da.c ============================================================================== --- stable/10/sys/cam/scsi/scsi_da.c Thu Oct 13 01:51:49 2016 (r307161) +++ stable/10/sys/cam/scsi/scsi_da.c Thu Oct 13 01:58:49 2016 (r307162) @@ -713,6 +713,14 @@ static struct da_quirk_entry da_quirk_ta {T_DIRECT, SIP_MEDIA_REMOVABLE, "JetFlash", "Transcend*", "*"}, /*quirks*/ DA_Q_NO_RC16 }, + { + /* + * I-O Data USB Flash Disk + * PR: usb/211716 + */ + {T_DIRECT, SIP_MEDIA_REMOVABLE, "I-O DATA", "USB Flash Disk*", + "*"}, /*quirks*/ DA_Q_NO_RC16 + }, /* ATA/SATA devices over SAS/USB/... */ { /* Hitachi Advanced Format (4k) drives */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 02:28:43 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1E6CDC0F597; Thu, 13 Oct 2016 02:28:43 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A8C1E771; Thu, 13 Oct 2016 02:28:42 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D2SfA4099979; Thu, 13 Oct 2016 02:28:41 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D2SeiU099968; Thu, 13 Oct 2016 02:28:40 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130228.u9D2SeiU099968@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 02:28:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307164 - in stable/10/sys: conf dev/hyperv/include dev/hyperv/netvsc dev/hyperv/vmbus modules/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 02:28:43 -0000 Author: sephe Date: Thu Oct 13 02:28:40 2016 New Revision: 307164 URL: https://svnweb.freebsd.org/changeset/base/307164 Log: MFC 303945,303947-303949,303989,303992,303998,304001,304002,304109,304111 303945 hyperv/vmbus: Add macro to get channel packet data length. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7455 303947 hyperv/vmbus: Add APIs for various types of transactions. Reviewed by: Jun Su Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7456 303948 hyperv/hn: Switch to vmbus xact APIs for NVS initialization Reviewed by: Jun Su Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7457 303949 hyperv/vmbus: Use xact APIs to implement post message Hypercall APIs Avoid code duplication. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7458 303989 hyperv/hn: Simplify NDIS configuration. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7466 303992 hyperv/hn: Simplify NDIS initialization. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7467 303998 hyperv/hn: Switch to vmbus xact APIs for NVS RXBUF connection. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7469 304001 hyperv/hn: Switch to vmbus xact APIs for NVS chimney buffer connection. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7470 304002 hyperv/hn: Simplify RXBUF disconnection. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7472 304109 hyperv/hn: Simplify chimney sending buffer disconnection. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7479 304111 hyperv/hn: Switch to vmbus xact APIs for sub-channel alloc request. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7480 Added: stable/10/sys/dev/hyperv/include/vmbus_xact.h - copied, changed from r303947, head/sys/dev/hyperv/include/vmbus_xact.h stable/10/sys/dev/hyperv/netvsc/if_hnreg.h - copied, changed from r303948, head/sys/dev/hyperv/netvsc/if_hnreg.h stable/10/sys/dev/hyperv/vmbus/vmbus_xact.c - copied, changed from r303947, head/sys/dev/hyperv/vmbus/vmbus_xact.c Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnvar.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_var.h stable/10/sys/modules/hyperv/vmbus/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/conf/files.amd64 Thu Oct 13 02:28:40 2016 (r307164) @@ -278,6 +278,7 @@ dev/hyperv/vmbus/vmbus_br.c optional dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv +dev/hyperv/vmbus/vmbus_xact.c optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/lindev/full.c optional lindev Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/conf/files.i386 Thu Oct 13 02:28:40 2016 (r307164) @@ -255,6 +255,7 @@ dev/hyperv/vmbus/vmbus_br.c optional dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv +dev/hyperv/vmbus/vmbus_xact.c optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/i386/vmbus_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 02:28:40 2016 (r307164) @@ -90,6 +90,11 @@ struct vmbus_chanpkt_hdr { (const void *)((const uint8_t *)(pkt) + \ VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen)) +/* Include padding */ +#define VMBUS_CHANPKT_DATALEN(pkt) \ + (VMBUS_CHANPKT_GETLEN((pkt)->cph_tlen) -\ + VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen)) + struct vmbus_rxbuf_desc { uint32_t rb_len; uint32_t rb_ofs; Copied and modified: stable/10/sys/dev/hyperv/include/vmbus_xact.h (from r303947, head/sys/dev/hyperv/include/vmbus_xact.h) ============================================================================== --- head/sys/dev/hyperv/include/vmbus_xact.h Thu Aug 11 05:49:49 2016 (r303947, copy source) +++ stable/10/sys/dev/hyperv/include/vmbus_xact.h Thu Oct 13 02:28:40 2016 (r307164) @@ -31,12 +31,14 @@ #include #include +#include struct vmbus_xact; struct vmbus_xact_ctx; struct vmbus_xact_ctx *vmbus_xact_ctx_create(bus_dma_tag_t dtag, - size_t req_size, size_t resp_size); + size_t req_size, size_t resp_size, + size_t priv_size); void vmbus_xact_ctx_destroy(struct vmbus_xact_ctx *ctx); struct vmbus_xact *vmbus_xact_get(struct vmbus_xact_ctx *ctx, size_t req_len); @@ -44,11 +46,15 @@ void vmbus_xact_put(struct vmbus_xact void *vmbus_xact_req_data(const struct vmbus_xact *xact); bus_addr_t vmbus_xact_req_paddr(const struct vmbus_xact *xact); +void *vmbus_xact_priv(const struct vmbus_xact *xact, + size_t priv_len); void vmbus_xact_activate(struct vmbus_xact *xact); void vmbus_xact_deactivate(struct vmbus_xact *xact); const void *vmbus_xact_wait(struct vmbus_xact *xact, size_t *resp_len); void vmbus_xact_wakeup(struct vmbus_xact *xact, const void *data, size_t dlen); +void vmbus_xact_ctx_wakeup(struct vmbus_xact_ctx *ctx, + const void *data, size_t dlen); #endif /* !_VMBUS_XACT_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:28:40 2016 (r307164) @@ -44,9 +44,11 @@ #include #include -#include "hv_net_vsc.h" -#include "hv_rndis.h" -#include "hv_rndis_filter.h" +#include +#include +#include +#include +#include MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); @@ -69,7 +71,7 @@ static void hv_nv_on_receive(netvsc_dev const struct vmbus_chanpkt_hdr *pkt); static void hn_nvs_sent_none(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, - const struct nvsp_msg_ *msg); + const struct nvsp_msg_ *msg, int); static struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); @@ -146,10 +148,14 @@ hv_nv_get_next_send_section(netvsc_dev * static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) { + struct vmbus_xact *xact; + struct hn_nvs_rxbuf_conn *conn; + const struct hn_nvs_rxbuf_connresp *resp; + size_t resp_len; struct hn_send_ctx sndc; netvsc_dev *net_dev; - nvsp_msg *init_pkt; - int ret = 0; + uint32_t status; + int error; net_dev = hv_nv_get_outbound_net_device(sc); if (!net_dev) { @@ -161,7 +167,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct BUS_DMA_WAITOK | BUS_DMA_ZERO); if (net_dev->rx_buf == NULL) { device_printf(sc->hn_dev, "allocate rxbuf failed\n"); - return ENOMEM; + return (ENOMEM); } /* @@ -171,74 +177,76 @@ hv_nv_init_rx_buffer_with_net_vsp(struct * Only primary channel has RXBUF connected to it. Sub-channels * just share this RXBUF. */ - ret = vmbus_chan_gpadl_connect(sc->hn_prichan, + error = vmbus_chan_gpadl_connect(sc->hn_prichan, net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle); - if (ret != 0) { - device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n", - ret); + if (error) { + if_printf(sc->hn_ifp, "rxbuf gpadl connect failed: %d\n", + error); goto cleanup; } - - /* sema_wait(&ext->channel_init_sema); KYS CHECK */ - /* Notify the NetVsp of the gpadl handle */ - init_pkt = &net_dev->channel_init_packet; + /* + * Connect RXBUF to NVS. + */ - memset(init_pkt, 0, sizeof(nvsp_msg)); + xact = vmbus_xact_get(sc->hn_xact, sizeof(*conn)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for nvs rxbuf conn\n"); + error = ENXIO; + goto cleanup; + } - init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf; - init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle = - net_dev->rx_buf_gpadl_handle; - init_pkt->msgs.vers_1_msgs.send_rx_buf.id = - NETVSC_RECEIVE_BUFFER_ID; + conn = vmbus_xact_req_data(xact); + conn->nvs_type = HN_NVS_TYPE_RXBUF_CONN; + conn->nvs_gpadl = net_dev->rx_buf_gpadl_handle; + conn->nvs_sig = HN_NVS_RXBUF_SIG; - /* Send the gpadl notification request */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + vmbus_xact_activate(xact); - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); - ret = vmbus_chan_send(sc->hn_prichan, + error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); - if (ret != 0) { + conn, sizeof(*conn), (uint64_t)(uintptr_t)&sndc); + if (error != 0) { + if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n", + error); + vmbus_xact_deactivate(xact); + vmbus_xact_put(xact); goto cleanup; } - sema_wait(&net_dev->channel_init_sema); - - /* Check the response */ - if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status - != nvsp_status_success) { - ret = EINVAL; + resp = vmbus_xact_wait(xact, &resp_len); + if (resp_len < sizeof(*resp)) { + if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n", + resp_len); + vmbus_xact_put(xact); + error = EINVAL; + goto cleanup; + } + if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) { + if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n", + resp->nvs_type); + vmbus_xact_put(xact); + error = EINVAL; goto cleanup; } - net_dev->rx_section_count = - init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections; - - net_dev->rx_sections = malloc(net_dev->rx_section_count * - sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK); - memcpy(net_dev->rx_sections, - init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections, - net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section)); - + status = resp->nvs_status; + vmbus_xact_put(xact); - /* - * For first release, there should only be 1 section that represents - * the entire receive buffer - */ - if (net_dev->rx_section_count != 1 - || net_dev->rx_sections->offset != 0) { - ret = EINVAL; + if (status != HN_NVS_STATUS_OK) { + if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status); + error = EIO; goto cleanup; } + net_dev->rx_section_count = 1; - goto exit; + return (0); cleanup: hv_nv_destroy_rx_buffer(net_dev); - -exit: - return (ret); + return (error); } /* @@ -248,9 +256,13 @@ static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) { struct hn_send_ctx sndc; + struct vmbus_xact *xact; + struct hn_nvs_chim_conn *chim; + const struct hn_nvs_chim_connresp *resp; + size_t resp_len; + uint32_t status, sectsz; netvsc_dev *net_dev; - nvsp_msg *init_pkt; - int ret = 0; + int error; net_dev = hv_nv_get_outbound_net_device(sc); if (!net_dev) { @@ -262,7 +274,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru BUS_DMA_WAITOK | BUS_DMA_ZERO); if (net_dev->send_buf == NULL) { device_printf(sc->hn_dev, "allocate chimney txbuf failed\n"); - return ENOMEM; + return (ENOMEM); } /* @@ -272,48 +284,77 @@ hv_nv_init_send_buffer_with_net_vsp(stru * Only primary channel has chimney sending buffer connected to it. * Sub-channels just share this chimney sending buffer. */ - ret = vmbus_chan_gpadl_connect(sc->hn_prichan, + error = vmbus_chan_gpadl_connect(sc->hn_prichan, net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size, &net_dev->send_buf_gpadl_handle); - if (ret != 0) { - device_printf(sc->hn_dev, "chimney sending buffer gpadl " - "connect failed: %d\n", ret); + if (error) { + if_printf(sc->hn_ifp, "chimney sending buffer gpadl " + "connect failed: %d\n", error); goto cleanup; } - /* Notify the NetVsp of the gpadl handle */ - - init_pkt = &net_dev->channel_init_packet; + /* + * Connect chimney sending buffer to NVS + */ - memset(init_pkt, 0, sizeof(nvsp_msg)); + xact = vmbus_xact_get(sc->hn_xact, sizeof(*chim)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for nvs chim conn\n"); + error = ENXIO; + goto cleanup; + } - init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf; - init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle = - net_dev->send_buf_gpadl_handle; - init_pkt->msgs.vers_1_msgs.send_rx_buf.id = - NETVSC_SEND_BUFFER_ID; + chim = vmbus_xact_req_data(xact); + chim->nvs_type = HN_NVS_TYPE_CHIM_CONN; + chim->nvs_gpadl = net_dev->send_buf_gpadl_handle; + chim->nvs_sig = HN_NVS_CHIM_SIG; - /* Send the gpadl notification request */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + vmbus_xact_activate(xact); - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); - ret = vmbus_chan_send(sc->hn_prichan, + error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); - if (ret != 0) { + chim, sizeof(*chim), (uint64_t)(uintptr_t)&sndc); + if (error) { + if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n", + error); + vmbus_xact_deactivate(xact); + vmbus_xact_put(xact); goto cleanup; } - sema_wait(&net_dev->channel_init_sema); + resp = vmbus_xact_wait(xact, &resp_len); + if (resp_len < sizeof(*resp)) { + if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n", + resp_len); + vmbus_xact_put(xact); + error = EINVAL; + goto cleanup; + } + if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) { + if_printf(sc->hn_ifp, "not chim conn resp, type %u\n", + resp->nvs_type); + vmbus_xact_put(xact); + error = EINVAL; + goto cleanup; + } - /* Check the response */ - if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status - != nvsp_status_success) { - ret = EINVAL; + status = resp->nvs_status; + sectsz = resp->nvs_sectsz; + vmbus_xact_put(xact); + + if (status != HN_NVS_STATUS_OK) { + if_printf(sc->hn_ifp, "chim conn failed: %x\n", status); + error = EIO; goto cleanup; } + if (sectsz == 0) { + if_printf(sc->hn_ifp, "zero chimney sending buffer " + "section size\n"); + return 0; + } - net_dev->send_section_size = - init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size; + net_dev->send_section_size = sectsz; net_dev->send_section_count = net_dev->send_buf_size / net_dev->send_section_size; net_dev->bitsmap_words = howmany(net_dev->send_section_count, @@ -322,13 +363,15 @@ hv_nv_init_send_buffer_with_net_vsp(stru malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC, M_WAITOK | M_ZERO); - goto exit; + if (bootverbose) { + if_printf(sc->hn_ifp, "chimney sending buffer %u/%u\n", + net_dev->send_section_size, net_dev->send_section_count); + } + return 0; cleanup: hv_nv_destroy_send_buffer(net_dev); - -exit: - return (ret); + return (error); } /* @@ -337,34 +380,27 @@ exit: static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev) { - nvsp_msg *revoke_pkt; int ret = 0; - /* - * If we got a section count, it means we received a - * send_rx_buf_complete msg - * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore, - * we need to send a revoke msg here - */ if (net_dev->rx_section_count) { - /* Send the revoke receive buffer */ - revoke_pkt = &net_dev->revoke_packet; - memset(revoke_pkt, 0, sizeof(nvsp_msg)); - - revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf; - revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id = - NETVSC_RECEIVE_BUFFER_ID; + struct hn_nvs_rxbuf_disconn disconn; - ret = vmbus_chan_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)&hn_send_ctx_none); /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk + * Disconnect RXBUF from NVS. */ + memset(&disconn, 0, sizeof(disconn)); + disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN; + disconn.nvs_sig = HN_NVS_RXBUF_SIG; + + ret = vmbus_chan_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), + (uint64_t)(uintptr_t)&hn_send_ctx_none); if (ret != 0) { + if_printf(net_dev->sc->hn_ifp, + "send rxbuf disconn failed: %d\n", ret); return (ret); } + net_dev->rx_section_count = 0; } /* Tear down the gpadl on the vsp end */ @@ -387,12 +423,6 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ net_dev->rx_buf = NULL; } - if (net_dev->rx_sections) { - free(net_dev->rx_sections, M_NETVSC); - net_dev->rx_sections = NULL; - net_dev->rx_section_count = 0; - } - return (ret); } @@ -402,33 +432,24 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev) { - nvsp_msg *revoke_pkt; int ret = 0; - /* - * If we got a section count, it means we received a - * send_rx_buf_complete msg - * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore, - * we need to send a revoke msg here - */ if (net_dev->send_section_size) { - /* Send the revoke send buffer */ - revoke_pkt = &net_dev->revoke_packet; - memset(revoke_pkt, 0, sizeof(nvsp_msg)); - - revoke_pkt->hdr.msg_type = - nvsp_msg_1_type_revoke_send_buf; - revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id = - NETVSC_SEND_BUFFER_ID; + struct hn_nvs_chim_disconn disconn; - ret = vmbus_chan_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg), - (uint64_t)(uintptr_t)&hn_send_ctx_none); /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk + * Disconnect chimney sending buffer from NVS. */ + memset(&disconn, 0, sizeof(disconn)); + disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN; + disconn.nvs_sig = HN_NVS_CHIM_SIG; + + ret = vmbus_chan_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), + (uint64_t)(uintptr_t)&hn_send_ctx_none); if (ret != 0) { + if_printf(net_dev->sc->hn_ifp, + "send chim disconn failed: %d\n", ret); return (ret); } } @@ -461,45 +482,64 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne return (ret); } - -/* - * Attempt to negotiate the caller-specified NVSP version - * - * For NVSP v2, Server 2008 R2 does not set - * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers - * to the negotiated version, so we cannot rely on that. - */ static int hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev, - uint32_t nvsp_ver) + uint32_t nvs_ver) { struct hn_send_ctx sndc; - nvsp_msg *init_pkt; - int ret; - - init_pkt = &net_dev->channel_init_packet; - memset(init_pkt, 0, sizeof(nvsp_msg)); - init_pkt->hdr.msg_type = nvsp_msg_type_init; + struct vmbus_xact *xact; + struct hn_nvs_init *init; + const struct hn_nvs_init_resp *resp; + size_t resp_len; + uint32_t status; + int error; + + xact = vmbus_xact_get(sc->hn_xact, sizeof(*init)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for nvs init\n"); + return (ENXIO); + } + + init = vmbus_xact_req_data(xact); + init->nvs_type = HN_NVS_TYPE_INIT; + init->nvs_ver_min = nvs_ver; + init->nvs_ver_max = nvs_ver; - /* - * Specify parameter as the only acceptable protocol version - */ - init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver; - init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver; + vmbus_xact_activate(xact); + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - /* Send the init request */ - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); - ret = vmbus_chan_send(sc->hn_prichan, + error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); - if (ret != 0) - return (-1); - - sema_wait(&net_dev->channel_init_sema); + init, sizeof(*init), (uint64_t)(uintptr_t)&sndc); + if (error) { + if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error); + vmbus_xact_deactivate(xact); + vmbus_xact_put(xact); + return (error); + } - if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success) + resp = vmbus_xact_wait(xact, &resp_len); + if (resp_len < sizeof(*resp)) { + if_printf(sc->hn_ifp, "invalid init resp length %zu\n", + resp_len); + vmbus_xact_put(xact); + return (EINVAL); + } + if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) { + if_printf(sc->hn_ifp, "not init resp, type %u\n", + resp->nvs_type); + vmbus_xact_put(xact); return (EINVAL); + } + + status = resp->nvs_status; + vmbus_xact_put(xact); + if (status != HN_NVS_STATUS_OK) { + if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n", + nvs_ver); + return (EINVAL); + } return (0); } @@ -511,33 +551,19 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ static int hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu) { - netvsc_dev *net_dev; - nvsp_msg *init_pkt; - int ret; - - net_dev = hv_nv_get_outbound_net_device(sc); - if (!net_dev) - return (-ENODEV); - - /* - * Set up configuration packet, write MTU - * Indicate we are capable of handling VLAN tags - */ - init_pkt = &net_dev->channel_init_packet; - memset(init_pkt, 0, sizeof(nvsp_msg)); - init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config; - init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu; - init_pkt-> - msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q - = 1; - - /* Send the configuration packet */ - ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none); - if (ret != 0) - return (-EINVAL); + struct hn_nvs_ndis_conf conf; + int error; - return (0); + memset(&conf, 0, sizeof(conf)); + conf.nvs_type = HN_NVS_TYPE_NDIS_CONF; + conf.nvs_mtu = mtu; + conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; + + error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, + &conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none); + if (error) + if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); + return (error); } /* @@ -547,8 +573,6 @@ static int hv_nv_connect_to_vsp(struct hn_softc *sc) { netvsc_dev *net_dev; - nvsp_msg *init_pkt; - uint32_t ndis_version; uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, NVSP_PROTOCOL_VERSION_4, @@ -558,6 +582,7 @@ hv_nv_connect_to_vsp(struct hn_softc *sc int ret = 0; device_t dev = sc->hn_dev; struct ifnet *ifp = sc->arpcom.ac_ifp; + struct hn_nvs_ndis_init ndis; net_dev = hv_nv_get_outbound_net_device(sc); @@ -590,37 +615,23 @@ hv_nv_connect_to_vsp(struct hn_softc *sc ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); /* - * Send the NDIS version + * Initialize NDIS. */ - init_pkt = &net_dev->channel_init_packet; - - memset(init_pkt, 0, sizeof(nvsp_msg)); - - if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) { - ndis_version = NDIS_VERSION_6_1; - } else { - ndis_version = NDIS_VERSION_6_30; - } - - init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers; - init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers = - (ndis_version & 0xFFFF0000) >> 16; - init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers = - ndis_version & 0xFFFF; - /* Send the init request */ + memset(&ndis, 0, sizeof(ndis)); + ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; + ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6; + if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) + ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1; + else + ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30; ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none); + &ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none); if (ret != 0) { + if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret); goto cleanup; } - /* - * TODO: BUGBUG - We have to wait for the above msg since the netvsp - * uses KMCL which acknowledges packet (completion packet) - * since our Vmbus always set the VMBUS_CHANPKT_FLAG_RC flag - */ - /* sema_wait(&NetVscChannel->channel_init_sema); */ /* Post the big receive buffer to NetVSP */ if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2) @@ -741,19 +752,18 @@ hv_nv_on_device_remove(struct hn_softc * } void -hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused, - struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused, - const struct nvsp_msg_ *msg) -{ - /* Copy the response back */ - memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg)); - sema_post(&net_dev->channel_init_sema); +hn_nvs_sent_xact(struct hn_send_ctx *sndc, + struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, + const struct nvsp_msg_ *msg, int dlen) +{ + + vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen); } static void hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, - const struct nvsp_msg_ *msg __unused) + const struct nvsp_msg_ *msg __unused, int dlen __unused) { /* EMPTY */ } @@ -787,7 +797,8 @@ hv_nv_on_send_completion(netvsc_dev *net struct hn_send_ctx *sndc; sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; - sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt)); + sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt), + VMBUS_CHANPKT_DATALEN(pkt)); /* * NOTE: * 'sndc' CAN NOT be accessed anymore, since it can be freed by Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:28:40 2016 (r307164) @@ -1060,7 +1060,6 @@ typedef struct netvsc_dev_ { uint32_t rx_buf_size; uint32_t rx_buf_gpadl_handle; uint32_t rx_section_count; - nvsp_1_rx_buf_section *rx_sections; /* Used for NetVSP initialization protocol */ struct sema channel_init_sema; @@ -1244,6 +1243,7 @@ typedef struct hn_softc { struct taskqueue *hn_tx_taskq; struct sysctl_oid *hn_tx_sysctl_tree; struct sysctl_oid *hn_rx_sysctl_tree; + struct vmbus_xact_ctx *hn_xact; } hn_softc_t; /* Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 02:28:40 2016 (r307164) @@ -117,6 +117,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include "hv_net_vsc.h" #include "hv_rndis.h" @@ -126,6 +127,9 @@ __FBSDID("$FreeBSD$"); /* Short for Hyper-V network interface */ #define NETVSC_DEVNAME "hn" +#define HN_XACT_REQ_SIZE (2 * PAGE_SIZE) +#define HN_XACT_RESP_SIZE (2 * PAGE_SIZE) + /* * It looks like offset 0 of buf is reserved to hold the softc pointer. * The sc pointer evidently not needed, and is not presently populated. @@ -558,6 +562,11 @@ netvsc_attach(device_t dev) IFCAP_LRO; ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; + sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev), + HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0); + if (sc->hn_xact == NULL) + goto failed; + error = hv_rf_on_device_add(sc, &device_info, ring_cnt, &sc->hn_rx_ring[0]); if (error) @@ -655,6 +664,7 @@ netvsc_detach(device_t dev) if (sc->hn_tx_taskq != hn_tx_taskq) taskqueue_free(sc->hn_tx_taskq); + vmbus_xact_ctx_destroy(sc->hn_xact); return (0); } @@ -794,7 +804,8 @@ hn_txeof(struct hn_tx_ring *txr) static void hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, - struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused) + struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused, + int dlen __unused) { struct hn_txdesc *txd = sndc->hn_cbarg; struct hn_tx_ring *txr; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 02:28:40 2016 (r307164) @@ -41,6 +41,10 @@ #define NDIS_VERSION_6_1 0x00060001 #define NDIS_VERSION_6_30 0x0006001e +#define NDIS_VERSION_MAJOR_6 6 +#define NDIS_VERSION_MINOR_1 1 +#define NDIS_VERSION_MINOR_30 30 + #define NDIS_VERSION (NDIS_VERSION_5_1) /* Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 02:06:23 2016 (r307163) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 02:28:40 2016 (r307164) @@ -47,9 +47,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include "hv_net_vsc.h" -#include "hv_rndis.h" -#include "hv_rndis_filter.h" +#include +#include +#include +#include +#include struct hv_rf_recvinfo { const ndis_8021q_info *vlan_info; @@ -92,10 +94,10 @@ hv_rf_send_offload_request(struct hn_sof static void hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, - const struct nvsp_msg_ *msg); + const struct nvsp_msg_ *msg, int dlen); static void hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, - const struct nvsp_msg_ *msg); + const struct nvsp_msg_ *msg, int dlen); /* * Set the Per-Packet-Info with the specified type @@ -1061,12 +1063,16 @@ hv_rf_on_device_add(struct hn_softc *sc, int ret; netvsc_dev *net_dev; rndis_device *rndis_dev; - nvsp_msg *init_pkt; rndis_offload_params offloads; struct rndis_recv_scale_cap rsscaps; uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; device_t dev = sc->hn_dev; + struct hn_nvs_subch_req *req; + const struct hn_nvs_subch_resp *resp; + size_t resp_len; + struct vmbus_xact *xact; + uint32_t status, nsubch; rndis_dev = hv_get_rndis_device(); if (rndis_dev == NULL) { @@ -1154,36 +1160,65 @@ hv_rf_on_device_add(struct hn_softc *sc, goto out; } - /* request host to create sub channels */ - init_pkt = &net_dev->channel_init_packet; - memset(init_pkt, 0, sizeof(nvsp_msg)); - - init_pkt->hdr.msg_type = nvsp_msg5_type_subchannel; - init_pkt->msgs.vers_5_msgs.subchannel_request.op = - NVSP_SUBCHANNE_ALLOCATE; - init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels = - net_dev->num_channel - 1; + /* + * Ask NVS to allocate sub-channels. + */ + xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for nvs subch req\n"); + ret = ENXIO; + goto out; + } + + req = vmbus_xact_req_data(xact); + req->nvs_type = HN_NVS_TYPE_SUBCH_REQ; + req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; + req->nvs_nsubch = net_dev->num_channel - 1; + + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + vmbus_xact_activate(xact); - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL); ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc); + req, sizeof(*req), (uint64_t)(uintptr_t)&sndc); if (ret != 0) { - device_printf(dev, "Fail to allocate subchannel\n"); + if_printf(sc->hn_ifp, "send nvs subch req failed: %d\n", ret); + vmbus_xact_deactivate(xact); + vmbus_xact_put(xact); goto out; } - sema_wait(&net_dev->channel_init_sema); - - if (init_pkt->msgs.vers_5_msgs.subchn_complete.status != - nvsp_status_success) { - ret = ENODEV; - device_printf(dev, "sub channel complete error\n"); + resp = vmbus_xact_wait(xact, &resp_len); + if (resp_len < sizeof(*resp)) { + if_printf(sc->hn_ifp, "invalid subch resp length %zu\n", + resp_len); + vmbus_xact_put(xact); + ret = EINVAL; + goto out; + } + if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) { + if_printf(sc->hn_ifp, "not subch resp, type %u\n", + resp->nvs_type); + vmbus_xact_put(xact); + ret = EINVAL; goto out; } - net_dev->num_channel = 1 + - init_pkt->msgs.vers_5_msgs.subchn_complete.num_subchannels; + status = resp->nvs_status; + nsubch = resp->nvs_nsubch; + vmbus_xact_put(xact); + + if (status != HN_NVS_STATUS_OK) { + if_printf(sc->hn_ifp, "subch req failed: %x\n", status); + ret = EIO; + goto out; + } + if (nsubch > net_dev->num_channel - 1) { + if_printf(sc->hn_ifp, "%u subchans are allocated, requested %u\n", + nsubch, net_dev->num_channel - 1); + nsubch = net_dev->num_channel - 1; + } + net_dev->num_channel = nsubch + 1; ret = hv_rf_set_rss_param(rndis_dev, net_dev->num_channel); @@ -1240,7 +1275,8 @@ hv_rf_on_close(struct hn_softc *sc) static void hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, - struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused) + struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused, + int dlen __unused) { if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) hn_chim_free(net_dev, sndc->hn_chim_idx); @@ -1248,7 +1284,8 @@ hn_rndis_sent_cb(struct hn_send_ctx *snd static void hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, - struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused) + struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused, + int dlen __unused) { rndis_request *request = sndc->hn_cbarg; Copied and modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h (from r303948, head/sys/dev/hyperv/netvsc/if_hnreg.h) ============================================================================== --- head/sys/dev/hyperv/netvsc/if_hnreg.h Thu Aug 11 06:14:54 2016 (r303948, copy source) +++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 02:28:40 2016 (r307164) @@ -32,10 +32,23 @@ #include #include +#define HN_NVS_RXBUF_SIG 0xcafe +#define HN_NVS_CHIM_SIG 0xface + #define HN_NVS_STATUS_OK 1 #define HN_NVS_TYPE_INIT 1 #define HN_NVS_TYPE_INIT_RESP 2 +#define HN_NVS_TYPE_NDIS_INIT 100 +#define HN_NVS_TYPE_RXBUF_CONN 101 +#define HN_NVS_TYPE_RXBUF_CONNRESP 102 +#define HN_NVS_TYPE_RXBUF_DISCONN 103 +#define HN_NVS_TYPE_CHIM_CONN 104 +#define HN_NVS_TYPE_CHIM_CONNRESP 105 +#define HN_NVS_TYPE_CHIM_DISCONN 106 +#define HN_NVS_TYPE_NDIS_CONF 125 +#define HN_NVS_TYPE_SUBCH_REQ 133 +#define HN_NVS_TYPE_SUBCH_RESP 133 /* same as SUBCH_REQ */ /* * Any size less than this one will _not_ work, e.g. hn_nvs_init @@ -59,4 +72,94 @@ struct hn_nvs_init_resp { uint32_t nvs_status; /* HN_NVS_STATUS_ */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Thu Oct 13 02:31:33 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9863DC0F725; Thu, 13 Oct 2016 02:31:33 +0000 (UTC) (envelope-from jtl@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 678EBA54; Thu, 13 Oct 2016 02:31:33 +0000 (UTC) (envelope-from jtl@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D2VW0i000290; Thu, 13 Oct 2016 02:31:32 GMT (envelope-from jtl@FreeBSD.org) Received: (from jtl@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D2VWF7000289; Thu, 13 Oct 2016 02:31:32 GMT (envelope-from jtl@FreeBSD.org) Message-Id: <201610130231.u9D2VWF7000289@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jtl set sender to jtl@FreeBSD.org using -f From: "Jonathan T. Looney" Date: Thu, 13 Oct 2016 02:31:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307165 - stable/10/sys/netinet X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 02:31:33 -0000 Author: jtl Date: Thu Oct 13 02:31:32 2016 New Revision: 307165 URL: https://svnweb.freebsd.org/changeset/base/307165 Log: MFC r306766: Remove declaration of un-defined function tcp_seq_subtract(). Modified: stable/10/sys/netinet/tcp_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet/tcp_var.h ============================================================================== --- stable/10/sys/netinet/tcp_var.h Thu Oct 13 02:28:40 2016 (r307164) +++ stable/10/sys/netinet/tcp_var.h Thu Oct 13 02:31:32 2016 (r307165) @@ -764,7 +764,6 @@ struct sackhole *tcp_sack_output(struct void tcp_sack_partialack(struct tcpcb *, struct tcphdr *); void tcp_free_sackholes(struct tcpcb *tp); int tcp_newreno(struct tcpcb *, struct tcphdr *); -u_long tcp_seq_subtract(u_long, u_long ); int tcp_compute_pipe(struct tcpcb *); void cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 02:38:48 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 25CE7C0F899; Thu, 13 Oct 2016 02:38:48 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BB3B9E3F; Thu, 13 Oct 2016 02:38:47 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D2clop003988; Thu, 13 Oct 2016 02:38:47 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D2ckUt003984; Thu, 13 Oct 2016 02:38:46 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130238.u9D2ckUt003984@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 02:38:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307167 - in stable/10/sys/dev/hyperv: include netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 02:38:48 -0000 Author: sephe Date: Thu Oct 13 02:38:46 2016 New Revision: 307167 URL: https://svnweb.freebsd.org/changeset/base/307167 Log: MFC 304204-304206,304252-304256 304204 hyperv/hn: Factor out hn_nvs_send/hn_nvs_send_sglist Avoid unnecessary message type setting and centralize the send context to transaction id cast. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7500 304205 hyperv/hn: Simplify RNDIS NVS message sending. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7501 304206 hyperv/hn: Simplify RNDIS message checks on RX path. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7502 304252 hyperv/hn: Ignore the useless TX table. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7514 304253 hyperv/hn: Simplify RNDIS RX packets acknowledgement. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7515 304254 hyperv/hn: Remove reference to nvsp_msg Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7516 304255 hyperv/hn: Remove reference to nvsp_status Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7517 304256 hyperv/hn: Get rid of unused bits Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7518 Modified: stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnreg.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 02:32:41 2016 (r307166) +++ stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 02:38:46 2016 (r307167) @@ -84,6 +84,7 @@ struct vmbus_chanpkt_hdr { #define VMBUS_CHANPKT_TYPE_GPA 0x0009 #define VMBUS_CHANPKT_TYPE_COMP 0x000b +#define VMBUS_CHANPKT_FLAG_NONE 0 #define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */ #define VMBUS_CHANPKT_CONST_DATA(pkt) \ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:32:41 2016 (r307166) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:38:46 2016 (r307167) @@ -71,7 +71,7 @@ static void hv_nv_on_receive(netvsc_dev const struct vmbus_chanpkt_hdr *pkt); static void hn_nvs_sent_none(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, - const struct nvsp_msg_ *msg, int); + const void *, int); static struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); @@ -117,7 +117,7 @@ hv_nv_get_next_send_section(netvsc_dev * unsigned long bitsmap_words = net_dev->bitsmap_words; unsigned long *bitsmap = net_dev->send_section_bitsmap; unsigned long idx; - int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; + int ret = HN_NVS_CHIM_IDX_INVALID; int i; for (i = 0; i < bitsmap_words; i++) { @@ -205,9 +205,8 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); vmbus_xact_activate(xact); - error = vmbus_chan_send(sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - conn, sizeof(*conn), (uint64_t)(uintptr_t)&sndc); + error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, + conn, sizeof(*conn), &sndc); if (error != 0) { if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n", error); @@ -312,9 +311,8 @@ hv_nv_init_send_buffer_with_net_vsp(stru hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); vmbus_xact_activate(xact); - error = vmbus_chan_send(sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - chim, sizeof(*chim), (uint64_t)(uintptr_t)&sndc); + error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, + chim, sizeof(*chim), &sndc); if (error) { if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n", error); @@ -392,9 +390,10 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN; disconn.nvs_sig = HN_NVS_RXBUF_SIG; - ret = vmbus_chan_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), - (uint64_t)(uintptr_t)&hn_send_ctx_none); + /* NOTE: No response. */ + ret = hn_nvs_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn), + &hn_send_ctx_none); if (ret != 0) { if_printf(net_dev->sc->hn_ifp, "send rxbuf disconn failed: %d\n", ret); @@ -444,9 +443,10 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN; disconn.nvs_sig = HN_NVS_CHIM_SIG; - ret = vmbus_chan_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), - (uint64_t)(uintptr_t)&hn_send_ctx_none); + /* NOTE: No response. */ + ret = hn_nvs_send(net_dev->sc->hn_prichan, + VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn), + &hn_send_ctx_none); if (ret != 0) { if_printf(net_dev->sc->hn_ifp, "send chim disconn failed: %d\n", ret); @@ -508,9 +508,8 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ vmbus_xact_activate(xact); hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - error = vmbus_chan_send(sc->hn_prichan, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - init, sizeof(*init), (uint64_t)(uintptr_t)&sndc); + error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, + init, sizeof(*init), &sndc); if (error) { if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error); vmbus_xact_deactivate(xact); @@ -559,8 +558,9 @@ hv_nv_send_ndis_config(struct hn_softc * conf.nvs_mtu = mtu; conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; - error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - &conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none); + /* NOTE: No response. */ + error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, + &conf, sizeof(conf), &hn_send_ctx_none); if (error) if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); return (error); @@ -626,8 +626,9 @@ hv_nv_connect_to_vsp(struct hn_softc *sc else ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30; - ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, - &ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none); + /* NOTE: No response. */ + ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, + &ndis, sizeof(ndis), &hn_send_ctx_none); if (ret != 0) { if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret); goto cleanup; @@ -688,8 +689,6 @@ hv_nv_on_device_add(struct hn_softc *sc, /* Initialize the NetVSC channel extension */ - sema_init(&net_dev->channel_init_sema, 0, "netdev_sema"); - /* * Open the channel */ @@ -720,7 +719,6 @@ cleanup: * Free the packet buffers on the netvsc device packet queue. * Release other resources. */ - sema_destroy(&net_dev->channel_init_sema); free(net_dev, M_NETVSC); return (NULL); @@ -745,7 +743,6 @@ hv_nv_on_device_remove(struct hn_softc * vmbus_chan_close(sc->hn_prichan); - sema_destroy(&net_dev->channel_init_sema); free(net_dev, M_NETVSC); return (0); @@ -754,16 +751,16 @@ hv_nv_on_device_remove(struct hn_softc * void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, - const struct nvsp_msg_ *msg, int dlen) + const void *data, int dlen) { - vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen); + vmbus_xact_wakeup(sndc->hn_cbarg, data, dlen); } static void hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, - const struct nvsp_msg_ *msg __unused, int dlen __unused) + const void *data __unused, int dlen __unused) { /* EMPTY */ } @@ -812,33 +809,23 @@ hv_nv_on_send_completion(netvsc_dev *net * Returns 0 on success, non-zero on failure. */ int -hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt, +hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) { - nvsp_msg send_msg; + struct hn_nvs_rndis rndis; int ret; - send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt; - if (is_data_pkt) { - /* 0 is RMC_DATA */ - send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0; - } else { - /* 1 is RMC_CONTROL */ - send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1; - } - - send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx = - sndc->hn_chim_idx; - send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = - sndc->hn_chim_sz; + rndis.nvs_type = HN_NVS_TYPE_RNDIS; + rndis.nvs_rndis_mtype = rndis_mtype; + rndis.nvs_chim_idx = sndc->hn_chim_idx; + rndis.nvs_chim_sz = sndc->hn_chim_sz; if (gpa_cnt) { - ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt, - &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); + ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt, + &rndis, sizeof(rndis), sndc); } else { - ret = vmbus_chan_send(chan, - VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, - &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); + ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC, + &rndis, sizeof(rndis), sndc); } return (ret); @@ -855,19 +842,18 @@ hv_nv_on_receive(netvsc_dev *net_dev, st struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) { const struct vmbus_chanpkt_rxbuf *pkt; - const nvsp_msg *nvsp_msg_pkt; + const struct hn_nvs_hdr *nvs_hdr; netvsc_packet vsc_pkt; netvsc_packet *net_vsc_pkt = &vsc_pkt; int count = 0; int i = 0; - int status = nvsp_status_success; - - nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr); + int status = HN_NVS_STATUS_OK; - /* Make sure this is a valid nvsp packet */ - if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) { - if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n", - nvsp_msg_pkt->hdr.msg_type); + /* Make sure that this is a RNDIS message. */ + nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr); + if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) { + if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n", + nvs_hdr->nvs_type); return; } @@ -883,15 +869,16 @@ hv_nv_on_receive(netvsc_dev *net_dev, st /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ for (i = 0; i < count; i++) { - net_vsc_pkt->status = nvsp_status_success; + net_vsc_pkt->status = HN_NVS_STATUS_OK; net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf + pkt->cp_rxbuf[i].rb_ofs); net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len; hv_rf_on_receive(net_dev, rxr, net_vsc_pkt); - if (net_vsc_pkt->status != nvsp_status_success) { - status = nvsp_status_failure; - } + + /* XXX pretty broken; whack it */ + if (net_vsc_pkt->status != HN_NVS_STATUS_OK) + status = HN_NVS_STATUS_FAILED; } /* @@ -911,20 +898,17 @@ static void hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid, uint32_t status) { - nvsp_msg rx_comp_msg; + struct hn_nvs_rndis_ack ack; int retries = 0; int ret = 0; - rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete; - - /* Pass in the status */ - rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status = - status; + ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK; + ack.nvs_status = status; retry_send_cmplt: /* Send the completion */ - ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0, - &rx_comp_msg, sizeof(nvsp_msg), tid); + ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, + VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid); if (ret == 0) { /* success */ /* no-op */ @@ -939,44 +923,17 @@ retry_send_cmplt: } } -/* - * Net VSC receiving vRSS send table from VSP - */ static void -hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) +hn_proc_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { - netvsc_dev *net_dev; - const nvsp_msg *nvsp_msg_pkt; - int i; - uint32_t count; - const uint32_t *table; - - net_dev = hv_nv_get_inbound_net_device(sc); - if (!net_dev) - return; - - nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt); + const struct hn_nvs_hdr *hdr; - if (nvsp_msg_pkt->hdr.msg_type != - nvsp_msg5_type_send_indirection_table) { - printf("Netvsc: !Warning! receive msg type not " - "send_indirection_table. type = %d\n", - nvsp_msg_pkt->hdr.msg_type); + hdr = VMBUS_CHANPKT_CONST_DATA(pkt); + if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) { + /* Useless; ignore */ return; } - - count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count; - if (count != VRSS_SEND_TABLE_SIZE) { - printf("Netvsc: Received wrong send table size: %u\n", count); - return; - } - - table = (const uint32_t *) - ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table + - nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset); - - for (i = 0; i < count; i++) - net_dev->vrss_send_table[i] = table[i]; + if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type); } /* @@ -1014,7 +971,7 @@ hv_nv_on_channel_callback(struct vmbus_c hv_nv_on_receive(net_dev, rxr, chan, pkt); break; case VMBUS_CHANPKT_TYPE_INBAND: - hv_nv_send_table(sc, pkt); + hn_proc_notify(sc, pkt); break; default: if_printf(rxr->hn_ifp, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:32:41 2016 (r307166) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:38:46 2016 (r307167) @@ -177,834 +177,6 @@ typedef struct rndis_recv_scale_param_ { uint32_t processor_masks_entry_size; } rndis_recv_scale_param; -typedef enum nvsp_msg_type_ { - nvsp_msg_type_none = 0, - - /* - * Init Messages - */ - nvsp_msg_type_init = 1, - nvsp_msg_type_init_complete = 2, - - nvsp_version_msg_start = 100, - - /* - * Version 1 Messages - */ - nvsp_msg_1_type_send_ndis_vers = nvsp_version_msg_start, - - nvsp_msg_1_type_send_rx_buf, - nvsp_msg_1_type_send_rx_buf_complete, - nvsp_msg_1_type_revoke_rx_buf, - - nvsp_msg_1_type_send_send_buf, - nvsp_msg_1_type_send_send_buf_complete, - nvsp_msg_1_type_revoke_send_buf, - - nvsp_msg_1_type_send_rndis_pkt, - nvsp_msg_1_type_send_rndis_pkt_complete, - - /* - * Version 2 Messages - */ - nvsp_msg_2_type_send_chimney_delegated_buf, - nvsp_msg_2_type_send_chimney_delegated_buf_complete, - nvsp_msg_2_type_revoke_chimney_delegated_buf, - - nvsp_msg_2_type_resume_chimney_rx_indication, - - nvsp_msg_2_type_terminate_chimney, - nvsp_msg_2_type_terminate_chimney_complete, - - nvsp_msg_2_type_indicate_chimney_event, - - nvsp_msg_2_type_send_chimney_packet, - nvsp_msg_2_type_send_chimney_packet_complete, - - nvsp_msg_2_type_post_chimney_rx_request, - nvsp_msg_2_type_post_chimney_rx_request_complete, - - nvsp_msg_2_type_alloc_rx_buf, - nvsp_msg_2_type_alloc_rx_buf_complete, - - nvsp_msg_2_type_free_rx_buf, - - nvsp_msg_2_send_vmq_rndis_pkt, - nvsp_msg_2_send_vmq_rndis_pkt_complete, - - nvsp_msg_2_type_send_ndis_config, - - nvsp_msg_2_type_alloc_chimney_handle, - nvsp_msg_2_type_alloc_chimney_handle_complete, - - nvsp_msg2_max = nvsp_msg_2_type_alloc_chimney_handle_complete, - - /* - * Version 4 Messages - */ - nvsp_msg4_type_send_vf_association, - nvsp_msg4_type_switch_data_path, - nvsp_msg4_type_uplink_connect_state_deprecated, - - nvsp_msg4_max = nvsp_msg4_type_uplink_connect_state_deprecated, - - /* - * Version 5 Messages - */ - nvsp_msg5_type_oid_query_ex, - nvsp_msg5_type_oid_query_ex_comp, - nvsp_msg5_type_subchannel, - nvsp_msg5_type_send_indirection_table, - - nvsp_msg5_max = nvsp_msg5_type_send_indirection_table, -} nvsp_msg_type; - -typedef enum nvsp_status_ { - nvsp_status_none = 0, - nvsp_status_success, - nvsp_status_failure, - /* Deprecated */ - nvsp_status_prot_vers_range_too_new, - /* Deprecated */ - nvsp_status_prot_vers_range_too_old, - nvsp_status_invalid_rndis_pkt, - nvsp_status_busy, - nvsp_status_max, -} nvsp_status; - -typedef struct nvsp_msg_hdr_ { - uint32_t msg_type; -} __packed nvsp_msg_hdr; - -/* - * Init Messages - */ - -/* - * This message is used by the VSC to initialize the channel - * after the channels has been opened. This message should - * never include anything other then versioning (i.e. this - * message will be the same for ever). - * - * Forever is a long time. The values have been redefined - * in Win7 to indicate major and minor protocol version - * number. - */ -typedef struct nvsp_msg_init_ { - union { - struct { - uint16_t minor_protocol_version; - uint16_t major_protocol_version; - } s; - /* Formerly min_protocol_version */ - uint32_t protocol_version; - } p1; - /* Formerly max_protocol_version */ - uint32_t protocol_version_2; -} __packed nvsp_msg_init; - -/* - * This message is used by the VSP to complete the initialization - * of the channel. This message should never include anything other - * then versioning (i.e. this message will be the same forever). - */ -typedef struct nvsp_msg_init_complete_ { - /* Deprecated */ - uint32_t negotiated_prot_vers; - uint32_t max_mdl_chain_len; - uint32_t status; -} __packed nvsp_msg_init_complete; - -typedef union nvsp_msg_init_uber_ { - nvsp_msg_init init; - nvsp_msg_init_complete init_compl; -} __packed nvsp_msg_init_uber; - -/* - * Version 1 Messages - */ - -/* - * This message is used by the VSC to send the NDIS version - * to the VSP. The VSP can use this information when handling - * OIDs sent by the VSC. - */ -typedef struct nvsp_1_msg_send_ndis_version_ { - uint32_t ndis_major_vers; - /* Deprecated */ - uint32_t ndis_minor_vers; -} __packed nvsp_1_msg_send_ndis_version; - -/* - * This message is used by the VSC to send a receive buffer - * to the VSP. The VSP can then use the receive buffer to - * send data to the VSC. - */ -typedef struct nvsp_1_msg_send_rx_buf_ { - uint32_t gpadl_handle; - uint16_t id; -} __packed nvsp_1_msg_send_rx_buf; - -typedef struct nvsp_1_rx_buf_section_ { - uint32_t offset; - uint32_t sub_allocation_size; - uint32_t num_sub_allocations; - uint32_t end_offset; -} __packed nvsp_1_rx_buf_section; - -/* - * This message is used by the VSP to acknowledge a receive - * buffer send by the VSC. This message must be sent by the - * VSP before the VSP uses the receive buffer. - */ -typedef struct nvsp_1_msg_send_rx_buf_complete_ { - uint32_t status; - uint32_t num_sections; - - /* - * The receive buffer is split into two parts, a large - * suballocation section and a small suballocation - * section. These sections are then suballocated by a - * certain size. - * - * For example, the following break up of the receive - * buffer has 6 large suballocations and 10 small - * suballocations. - * - * | Large Section | | Small Section | - * ------------------------------------------------------------ - * | | | | | | | | | | | | | | | | | | - * | | - * LargeOffset SmallOffset - */ - nvsp_1_rx_buf_section sections[1]; - -} __packed nvsp_1_msg_send_rx_buf_complete; - -/* - * This message is sent by the VSC to revoke the receive buffer. - * After the VSP completes this transaction, the VSP should never - * use the receive buffer again. - */ -typedef struct nvsp_1_msg_revoke_rx_buf_ { - uint16_t id; -} __packed nvsp_1_msg_revoke_rx_buf; - -/* - * This message is used by the VSC to send a send buffer - * to the VSP. The VSC can then use the send buffer to - * send data to the VSP. - */ -typedef struct nvsp_1_msg_send_send_buf_ { - uint32_t gpadl_handle; - uint16_t id; -} __packed nvsp_1_msg_send_send_buf; - -/* - * This message is used by the VSP to acknowledge a send - * buffer sent by the VSC. This message must be sent by the - * VSP before the VSP uses the sent buffer. - */ -typedef struct nvsp_1_msg_send_send_buf_complete_ { - uint32_t status; - - /* - * The VSC gets to choose the size of the send buffer and - * the VSP gets to choose the sections size of the buffer. - * This was done to enable dynamic reconfigurations when - * the cost of GPA-direct buffers decreases. - */ - uint32_t section_size; -} __packed nvsp_1_msg_send_send_buf_complete; - -/* - * This message is sent by the VSC to revoke the send buffer. - * After the VSP completes this transaction, the vsp should never - * use the send buffer again. - */ -typedef struct nvsp_1_msg_revoke_send_buf_ { - uint16_t id; -} __packed nvsp_1_msg_revoke_send_buf; - -/* - * This message is used by both the VSP and the VSC to send - * an RNDIS message to the opposite channel endpoint. - */ -typedef struct nvsp_1_msg_send_rndis_pkt_ { - /* - * This field is specified by RNIDS. They assume there's - * two different channels of communication. However, - * the Network VSP only has one. Therefore, the channel - * travels with the RNDIS packet. - */ - uint32_t chan_type; - - /* - * This field is used to send part or all of the data - * through a send buffer. This values specifies an - * index into the send buffer. If the index is - * 0xFFFFFFFF, then the send buffer is not being used - * and all of the data was sent through other VMBus - * mechanisms. - */ - uint32_t send_buf_section_idx; - uint32_t send_buf_section_size; -} __packed nvsp_1_msg_send_rndis_pkt; - -/* - * This message is used by both the VSP and the VSC to complete - * a RNDIS message to the opposite channel endpoint. At this - * point, the initiator of this message cannot use any resources - * associated with the original RNDIS packet. - */ -typedef struct nvsp_1_msg_send_rndis_pkt_complete_ { - uint32_t status; -} __packed nvsp_1_msg_send_rndis_pkt_complete; - - -/* - * Version 2 Messages - */ - -/* - * This message is used by the VSC to send the NDIS version - * to the VSP. The VSP can use this information when handling - * OIDs sent by the VSC. - */ -typedef struct nvsp_2_netvsc_capabilities_ { - union { - uint64_t as_uint64; - struct { - uint64_t vmq : 1; - uint64_t chimney : 1; - uint64_t sriov : 1; - uint64_t ieee8021q : 1; - uint64_t correlationid : 1; - uint64_t teaming : 1; - } u2; - } u1; -} __packed nvsp_2_netvsc_capabilities; - -typedef struct nvsp_2_msg_send_ndis_config_ { - uint32_t mtu; - uint32_t reserved; - nvsp_2_netvsc_capabilities capabilities; -} __packed nvsp_2_msg_send_ndis_config; - -/* - * NvspMessage2TypeSendChimneyDelegatedBuffer - */ -typedef struct nvsp_2_msg_send_chimney_buf_ -{ - /* - * On WIN7 beta, delegated_obj_max_size is defined as a uint32_t - * Since WIN7 RC, it was split into two uint16_t. To have the same - * struct layout, delegated_obj_max_size shall be the first field. - */ - uint16_t delegated_obj_max_size; - - /* - * The revision # of chimney protocol used between NVSC and NVSP. - * - * This revision is NOT related to the chimney revision between - * NDIS protocol and miniport drivers. - */ - uint16_t revision; - - uint32_t gpadl_handle; -} __packed nvsp_2_msg_send_chimney_buf; - - -/* Unsupported chimney revision 0 (only present in WIN7 beta) */ -#define NVSP_CHIMNEY_REVISION_0 0 - -/* WIN7 Beta Chimney QFE */ -#define NVSP_CHIMNEY_REVISION_1 1 - -/* The chimney revision since WIN7 RC */ -#define NVSP_CHIMNEY_REVISION_2 2 - - -/* - * NvspMessage2TypeSendChimneyDelegatedBufferComplete - */ -typedef struct nvsp_2_msg_send_chimney_buf_complete_ { - uint32_t status; - - /* - * Maximum number outstanding sends and pre-posted receives. - * - * NVSC should not post more than SendQuota/ReceiveQuota packets. - * Otherwise, it can block the non-chimney path for an indefinite - * amount of time. - * (since chimney sends/receives are affected by the remote peer). - * - * Note: NVSP enforces the quota restrictions on a per-VMBCHANNEL - * basis. It doesn't enforce the restriction separately for chimney - * send/receive. If NVSC doesn't voluntarily enforce "SendQuota", - * it may kill its own network connectivity. - */ - uint32_t send_quota; - uint32_t rx_quota; -} __packed nvsp_2_msg_send_chimney_buf_complete; - -/* - * NvspMessage2TypeRevokeChimneyDelegatedBuffer - */ -typedef struct nvsp_2_msg_revoke_chimney_buf_ { - uint32_t gpadl_handle; -} __packed nvsp_2_msg_revoke_chimney_buf; - - -#define NVSP_CHIMNEY_OBJECT_TYPE_NEIGHBOR 0 -#define NVSP_CHIMNEY_OBJECT_TYPE_PATH4 1 -#define NVSP_CHIMNEY_OBJECT_TYPE_PATH6 2 -#define NVSP_CHIMNEY_OBJECT_TYPE_TCP 3 - -/* - * NvspMessage2TypeAllocateChimneyHandle - */ -typedef struct nvsp_2_msg_alloc_chimney_handle_ { - uint64_t vsc_context; - uint32_t object_type; -} __packed nvsp_2_msg_alloc_chimney_handle; - -/* - * NvspMessage2TypeAllocateChimneyHandleComplete - */ -typedef struct nvsp_2_msg_alloc_chimney_handle_complete_ { - uint32_t vsp_handle; -} __packed nvsp_2_msg_alloc_chimney_handle_complete; - - -/* - * NvspMessage2TypeResumeChimneyRXIndication - */ -typedef struct nvsp_2_msg_resume_chimney_rx_indication { - /* - * Handle identifying the offloaded connection - */ - uint32_t vsp_tcp_handle; -} __packed nvsp_2_msg_resume_chimney_rx_indication; - - -#define NVSP_2_MSG_TERMINATE_CHIMNEY_FLAGS_FIRST_STAGE (0x01u) -#define NVSP_2_MSG_TERMINATE_CHIMNEY_FLAGS_RESERVED (~(0x01u)) - -/* - * NvspMessage2TypeTerminateChimney - */ -typedef struct nvsp_2_msg_terminate_chimney_ { - /* - * Handle identifying the offloaded object - */ - uint32_t vsp_handle; - - /* - * Terminate Offload Flags - * Bit 0: - * When set to 0, terminate the offload at the destination NIC - * Bit 1-31: Reserved, shall be zero - */ - uint32_t flags; - - union { - /* - * This field is valid only when bit 0 of flags is clear. - * It specifies the index into the premapped delegated - * object buffer. The buffer was sent through the - * NvspMessage2TypeSendChimneyDelegatedBuffer - * message at initialization time. - * - * NVSP will write the delegated state into the delegated - * buffer upon upload completion. - */ - uint32_t index; - - /* - * This field is valid only when bit 0 of flags is set. - * - * The seqence number of the most recently accepted RX - * indication when VSC sets its TCP context into - * "terminating" state. - * - * This allows NVSP to determines if there are any in-flight - * RX indications for which the acceptance state is still - * undefined. - */ - uint64_t last_accepted_rx_seq_no; - } f0; -} __packed nvsp_2_msg_terminate_chimney; - - -#define NVSP_TERMINATE_CHIMNEY_COMPLETE_FLAG_DATA_CORRUPTED 0x0000001u - -/* - * NvspMessage2TypeTerminateChimneyComplete - */ -typedef struct nvsp_2_msg_terminate_chimney_complete_ { - uint64_t vsc_context; - uint32_t flags; -} __packed nvsp_2_msg_terminate_chimney_complete; - -/* - * NvspMessage2TypeIndicateChimneyEvent - */ -typedef struct nvsp_2_msg_indicate_chimney_event_ { - /* - * When VscTcpContext is 0, event_type is an NDIS_STATUS event code - * Otherwise, EventType is an TCP connection event (defined in - * NdisTcpOffloadEventHandler chimney DDK document). - */ - uint32_t event_type; - - /* - * When VscTcpContext is 0, EventType is an NDIS_STATUS event code - * Otherwise, EventType is an TCP connection event specific information - * (defined in NdisTcpOffloadEventHandler chimney DDK document). - */ - uint32_t event_specific_info; - - /* - * If not 0, the event is per-TCP connection event. This field - * contains the VSC's TCP context. - * If 0, the event indication is global. - */ - uint64_t vsc_tcp_context; -} __packed nvsp_2_msg_indicate_chimney_event; - - -#define NVSP_1_CHIMNEY_SEND_INVALID_OOB_INDEX 0xffffu -#define NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX 0xffffffff - -/* - * NvspMessage2TypeSendChimneyPacket - */ -typedef struct nvsp_2_msg_send_chimney_pkt_ { - /* - * Identify the TCP connection for which this chimney send is - */ - uint32_t vsp_tcp_handle; - - /* - * This field is used to send part or all of the data - * through a send buffer. This values specifies an - * index into the send buffer. If the index is - * 0xFFFF, then the send buffer is not being used - * and all of the data was sent through other VMBus - * mechanisms. - */ - uint16_t send_buf_section_index; - uint16_t send_buf_section_size; - - /* - * OOB Data Index - * This an index to the OOB data buffer. If the index is 0xFFFFFFFF, - * then there is no OOB data. - * - * This field shall be always 0xFFFFFFFF for now. It is reserved for - * the future. - */ - uint16_t oob_data_index; - - /* - * DisconnectFlags = 0 - * Normal chimney send. See MiniportTcpOffloadSend for details. - * - * DisconnectFlags = TCP_DISCONNECT_GRACEFUL_CLOSE (0x01) - * Graceful disconnect. See MiniportTcpOffloadDisconnect for details. - * - * DisconnectFlags = TCP_DISCONNECT_ABORTIVE_CLOSE (0x02) - * Abortive disconnect. See MiniportTcpOffloadDisconnect for details. - */ - uint16_t disconnect_flags; - - uint32_t seq_no; -} __packed nvsp_2_msg_send_chimney_pkt; - -/* - * NvspMessage2TypeSendChimneyPacketComplete - */ -typedef struct nvsp_2_msg_send_chimney_pkt_complete_ { - /* - * The NDIS_STATUS for the chimney send - */ - uint32_t status; - - /* - * Number of bytes that have been sent to the peer (and ACKed by the peer). - */ - uint32_t bytes_transferred; -} __packed nvsp_2_msg_send_chimney_pkt_complete; - - -#define NVSP_1_CHIMNEY_RECV_FLAG_NO_PUSH 0x0001u -#define NVSP_1_CHIMNEY_RECV_INVALID_OOB_INDEX 0xffffu - -/* - * NvspMessage2TypePostChimneyRecvRequest - */ -typedef struct nvsp_2_msg_post_chimney_rx_request_ { - /* - * Identify the TCP connection which this chimney receive request - * is for. - */ - uint32_t vsp_tcp_handle; - - /* - * OOB Data Index - * This an index to the OOB data buffer. If the index is 0xFFFFFFFF, - * then there is no OOB data. - * - * This field shall be always 0xFFFFFFFF for now. It is reserved for - * the future. - */ - uint32_t oob_data_index; - - /* - * Bit 0 - * When it is set, this is a "no-push" receive. - * When it is clear, this is a "push" receive. - * - * Bit 1-15: Reserved and shall be zero - */ - uint16_t flags; - - /* - * For debugging and diagnoses purpose. - * The SeqNo is per TCP connection and starts from 0. - */ - uint32_t seq_no; -} __packed nvsp_2_msg_post_chimney_rx_request; - -/* - * NvspMessage2TypePostChimneyRecvRequestComplete - */ -typedef struct nvsp_2_msg_post_chimney_rx_request_complete_ { - /* - * The NDIS_STATUS for the chimney send - */ - uint32_t status; - - /* - * Number of bytes that have been sent to the peer (and ACKed by - * the peer). - */ - uint32_t bytes_xferred; -} __packed nvsp_2_msg_post_chimney_rx_request_complete; - -/* - * NvspMessage2TypeAllocateReceiveBuffer - */ -typedef struct nvsp_2_msg_alloc_rx_buf_ { - /* - * Allocation ID to match the allocation request and response - */ - uint32_t allocation_id; - - /* - * Length of the VM shared memory receive buffer that needs to - * be allocated - */ - uint32_t length; -} __packed nvsp_2_msg_alloc_rx_buf; - -/* - * NvspMessage2TypeAllocateReceiveBufferComplete - */ -typedef struct nvsp_2_msg_alloc_rx_buf_complete_ { - /* - * The NDIS_STATUS code for buffer allocation - */ - uint32_t status; - - /* - * Allocation ID from NVSP_2_MESSAGE_ALLOCATE_RECEIVE_BUFFER - */ - uint32_t allocation_id; - - /* - * GPADL handle for the allocated receive buffer - */ - uint32_t gpadl_handle; - - /* - * Receive buffer ID that is further used in *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Thu Oct 13 02:45:10 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 964AAC0FA34; Thu, 13 Oct 2016 02:45:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 65B4E23F; Thu, 13 Oct 2016 02:45:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D2j9mN007786; Thu, 13 Oct 2016 02:45:09 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D2j8cS007779; Thu, 13 Oct 2016 02:45:08 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130245.u9D2j8cS007779@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 02:45:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307168 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 02:45:10 -0000 Author: sephe Date: Thu Oct 13 02:45:08 2016 New Revision: 307168 URL: https://svnweb.freebsd.org/changeset/base/307168 Log: MFC 304270,304273 304270 hyperv/util: Don't reference hn_softc in KVP hn_softc is private data struct. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7519 304273 hyperv/util: Factor out helper for IC device_probe DEVMETHOD Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7530 Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_kvp.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 02:45:08 2016 (r307168) @@ -41,10 +41,15 @@ #include "hv_util.h" #include "vmbus_if.h" -/* Heartbeat Service */ -static const struct hyperv_guid service_guid = { .hv_guid = - {0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, - 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} }; +static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = { + { + .ic_guid = { .hv_guid = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} }, + .ic_desc = "Hyper-V Heartbeat" + }, + VMBUS_IC_DESC_END +}; /** * Process heartbeat message @@ -96,14 +101,8 @@ hv_heartbeat_cb(struct vmbus_channel *ch static int hv_heartbeat_probe(device_t dev) { - if (resource_disabled("hvheartbeat", 0)) - return ENXIO; - if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) { - device_set_desc(dev, "Hyper-V Heartbeat Service"); - return BUS_PROBE_DEFAULT; - } - return ENXIO; + return (vmbus_ic_probe(dev, vmbus_heartbeat_descs)); } static int Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 02:45:08 2016 (r307168) @@ -54,17 +54,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include -#include -#include -#include - #include -#include #include #include "hv_util.h" @@ -91,9 +87,15 @@ static int hv_kvp_log = 0; log(LOG_INFO, "hv_kvp: " __VA_ARGS__); \ } while (0) -static const struct hyperv_guid service_guid = { .hv_guid = - {0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, - 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6} }; +static const struct vmbus_ic_desc vmbus_kvp_descs[] = { + { + .ic_guid = { .hv_guid = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 } }, + .ic_desc = "Hyper-V KVP" + }, + VMBUS_IC_DESC_END +}; /* character device prototypes */ static d_open_t hv_kvp_dev_open; @@ -333,13 +335,11 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(stru for (devcnt = devcnt - 1; devcnt >= 0; devcnt--) { /* XXX access other driver's softc? are you kidding? */ device_t dev = devs[devcnt]; - struct hn_softc *sc = device_get_softc(dev); struct vmbus_channel *chan; char buf[HYPERV_GUID_STRLEN]; /* * Trying to find GUID of Network Device - * TODO: need vmbus interface. */ chan = vmbus_get_channel(dev); hyperv_guid2str(vmbus_chan_guid_inst(chan), @@ -348,7 +348,7 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(stru if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id, HYPERV_GUID_STRLEN - 1) == 0) { strlcpy((char *)umsg->body.kvp_ip_val.adapter_id, - sc->hn_ifp->if_xname, MAX_ADAPTER_ID_SIZE); + device_get_nameunit(dev), MAX_ADAPTER_ID_SIZE); break; } } @@ -873,14 +873,8 @@ hv_kvp_dev_daemon_poll(struct cdev *dev, static int hv_kvp_probe(device_t dev) { - if (resource_disabled("hvkvp", 0)) - return ENXIO; - if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) { - device_set_desc(dev, "Hyper-V KVP Service"); - return BUS_PROBE_DEFAULT; - } - return ENXIO; + return (vmbus_ic_probe(dev, vmbus_kvp_descs)); } static int Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 02:45:08 2016 (r307168) @@ -46,9 +46,15 @@ #include "hv_util.h" #include "vmbus_if.h" -static const struct hyperv_guid service_guid = { .hv_guid = - {0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, - 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB} }; +static const struct vmbus_ic_desc vmbus_shutdown_descs[] = { + { + .ic_guid = { .hv_guid = { + 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb } }, + .ic_desc = "Hyper-V Shutdown" + }, + VMBUS_IC_DESC_END +}; /** * Shutdown @@ -118,14 +124,8 @@ hv_shutdown_cb(struct vmbus_channel *cha static int hv_shutdown_probe(device_t dev) { - if (resource_disabled("hvshutdown", 0)) - return ENXIO; - if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) { - device_set_desc(dev, "Hyper-V Shutdown Service"); - return BUS_PROBE_DEFAULT; - } - return ENXIO; + return (vmbus_ic_probe(dev, vmbus_shutdown_descs)); } static int Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 02:45:08 2016 (r307168) @@ -58,10 +58,15 @@ typedef struct { uint64_t data; } time_sync_data; - /* Time Synch Service */ -static const struct hyperv_guid service_guid = {.hv_guid = - {0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } }; +static const struct vmbus_ic_desc vmbus_timesync_descs[] = { + { + .ic_guid = { .hv_guid = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } }, + .ic_desc = "Hyper-V Timesync" + }, + VMBUS_IC_DESC_END +}; struct hv_ictimesync_data { uint64_t parenttime; @@ -174,14 +179,8 @@ hv_timesync_cb(struct vmbus_channel *cha static int hv_timesync_probe(device_t dev) { - if (resource_disabled("hvtimesync", 0)) - return ENXIO; - if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) { - device_set_desc(dev, "Hyper-V Time Synch Service"); - return BUS_PROBE_DEFAULT; - } - return ENXIO; + return (vmbus_ic_probe(dev, vmbus_timesync_descs)); } static int Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 02:45:08 2016 (r307168) @@ -42,7 +42,9 @@ #include #include #include -#include "hv_util.h" +#include + +#include "vmbus_if.h" #define VMBUS_IC_BRSIZE (4 * PAGE_SIZE) @@ -75,6 +77,24 @@ hv_negotiate_version(struct hv_vmbus_icm } int +vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]) +{ + device_t bus = device_get_parent(dev); + const struct vmbus_ic_desc *d; + + if (resource_disabled(device_get_name(dev), 0)) + return (ENXIO); + + for (d = descs; d->ic_desc != NULL; ++d) { + if (VMBUS_PROBE_GUID(bus, dev, &d->ic_guid) == 0) { + device_set_desc(dev, d->ic_desc); + return (BUS_PROBE_DEFAULT); + } + } + return (ENXIO); +} + +int hv_util_attach(device_t dev, vmbus_chan_callback_t cb) { struct hv_util_sc *sc = device_get_softc(dev); Modified: stable/10/sys/dev/hyperv/utilities/hv_util.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 02:38:46 2016 (r307167) +++ stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 02:45:08 2016 (r307168) @@ -31,6 +31,7 @@ #ifndef _HVUTIL_H_ #define _HVUTIL_H_ +#include #include /** @@ -42,9 +43,17 @@ typedef struct hv_util_sc { int ic_buflen; } hv_util_sc; +struct vmbus_ic_desc { + const struct hyperv_guid ic_guid; + const char *ic_desc; +}; + +#define VMBUS_IC_DESC_END { .ic_desc = NULL } + void hv_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf); -int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); -int hv_util_detach(device_t dev); +int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); +int hv_util_detach(device_t dev); +int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]); #endif From owner-svn-src-stable-10@freebsd.org Thu Oct 13 02:58:55 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 63976C0FDEA; Thu, 13 Oct 2016 02:58:55 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1F61FAF7; Thu, 13 Oct 2016 02:58:55 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D2wsp9011679; Thu, 13 Oct 2016 02:58:54 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D2wrZw011671; Thu, 13 Oct 2016 02:58:53 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130258.u9D2wrZw011671@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 02:58:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307169 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 02:58:55 -0000 Author: sephe Date: Thu Oct 13 02:58:53 2016 New Revision: 307169 URL: https://svnweb.freebsd.org/changeset/base/307169 Log: MFC 304327,304329,304330 304327 hyperv/hn: Pass RX packet info to netvsc_recv. This paves to nuke netvsc_packet, which does not serves much purpose now. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7541 304329 hyperv/hn: Constify RNDIS messages on RX path. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7542 304330 hyperv/hn: Get rid of the useless netvsc_packet Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7544 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 02:58:53 2016 (r307169) @@ -65,7 +65,7 @@ static int hv_nv_connect_to_vsp(struct static void hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); static void hv_nv_on_receive_completion(struct vmbus_channel *chan, - uint64_t tid, uint32_t status); + uint64_t tid); static void hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt); @@ -843,11 +843,8 @@ hv_nv_on_receive(netvsc_dev *net_dev, st { const struct vmbus_chanpkt_rxbuf *pkt; const struct hn_nvs_hdr *nvs_hdr; - netvsc_packet vsc_pkt; - netvsc_packet *net_vsc_pkt = &vsc_pkt; int count = 0; int i = 0; - int status = HN_NVS_STATUS_OK; /* Make sure that this is a RNDIS message. */ nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr); @@ -869,16 +866,9 @@ hv_nv_on_receive(netvsc_dev *net_dev, st /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ for (i = 0; i < count; i++) { - net_vsc_pkt->status = HN_NVS_STATUS_OK; - net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf + - pkt->cp_rxbuf[i].rb_ofs); - net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len; - - hv_rf_on_receive(net_dev, rxr, net_vsc_pkt); - - /* XXX pretty broken; whack it */ - if (net_vsc_pkt->status != HN_NVS_STATUS_OK) - status = HN_NVS_STATUS_FAILED; + hv_rf_on_receive(net_dev, rxr, + (const uint8_t *)net_dev->rx_buf + pkt->cp_rxbuf[i].rb_ofs, + pkt->cp_rxbuf[i].rb_len); } /* @@ -886,7 +876,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st * messages (not just data messages) will trigger a response * message back to the host. */ - hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status); + hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid); } /* @@ -895,15 +885,14 @@ hv_nv_on_receive(netvsc_dev *net_dev, st * Send a receive completion packet to RNDIS device (ie NetVsp) */ static void -hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid, - uint32_t status) +hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid) { struct hn_nvs_rndis_ack ack; int retries = 0; int ret = 0; ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK; - ack.nvs_status = status; + ack.nvs_status = HN_NVS_STATUS_OK; retry_send_cmplt: /* Send the completion */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 02:58:53 2016 (r307169) @@ -274,13 +274,6 @@ typedef void (*pfn_on_send_rx_completion #define BITS_PER_LONG 32 #endif -typedef struct netvsc_packet_ { - uint16_t vlan_tci; - uint32_t status; - uint32_t tot_data_buf_len; - void *data; -} netvsc_packet; - typedef struct { uint8_t mac_addr[6]; /* Assumption unsigned long */ uint8_t link_state; Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 02:58:53 2016 (r307169) @@ -1295,10 +1295,8 @@ hn_lro_rx(struct lro_ctrl *lc, struct mb * Note: This is no longer used as a callback */ int -netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet, - const rndis_tcp_ip_csum_info *csum_info, - const struct rndis_hash_info *hash_info, - const struct rndis_hash_value *hash_value) +netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, + const struct hn_recvinfo *info) { struct ifnet *ifp = rxr->hn_ifp; struct mbuf *m_new; @@ -1310,17 +1308,16 @@ netvsc_recv(struct hn_rx_ring *rxr, netv /* * Bail out if packet contains more data than configured MTU. */ - if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) { + if (dlen > (ifp->if_mtu + ETHER_HDR_LEN)) { return (0); - } else if (packet->tot_data_buf_len <= MHLEN) { + } else if (dlen <= MHLEN) { m_new = m_gethdr(M_NOWAIT, MT_DATA); if (m_new == NULL) { if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); return (0); } - memcpy(mtod(m_new, void *), packet->data, - packet->tot_data_buf_len); - m_new->m_pkthdr.len = m_new->m_len = packet->tot_data_buf_len; + memcpy(mtod(m_new, void *), data, dlen); + m_new->m_pkthdr.len = m_new->m_len = dlen; rxr->hn_small_pkts++; } else { /* @@ -1330,7 +1327,7 @@ netvsc_recv(struct hn_rx_ring *rxr, netv * if looped around to the Hyper-V TX channel, so avoid them. */ size = MCLBYTES; - if (packet->tot_data_buf_len > MCLBYTES) { + if (dlen > MCLBYTES) { /* 4096 */ size = MJUMPAGESIZE; } @@ -1341,7 +1338,7 @@ netvsc_recv(struct hn_rx_ring *rxr, netv return (0); } - hv_m_append(m_new, packet->tot_data_buf_len, packet->data); + hv_m_append(m_new, dlen, data); } m_new->m_pkthdr.rcvif = ifp; @@ -1349,28 +1346,28 @@ netvsc_recv(struct hn_rx_ring *rxr, netv do_csum = 0; /* receive side checksum offload */ - if (csum_info != NULL) { + if (info->csum_info != NULL) { /* IP csum offload */ - if (csum_info->receive.ip_csum_succeeded && do_csum) { + if (info->csum_info->receive.ip_csum_succeeded && do_csum) { m_new->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); rxr->hn_csum_ip++; } /* TCP/UDP csum offload */ - if ((csum_info->receive.tcp_csum_succeeded || - csum_info->receive.udp_csum_succeeded) && do_csum) { + if ((info->csum_info->receive.tcp_csum_succeeded || + info->csum_info->receive.udp_csum_succeeded) && do_csum) { m_new->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); m_new->m_pkthdr.csum_data = 0xffff; - if (csum_info->receive.tcp_csum_succeeded) + if (info->csum_info->receive.tcp_csum_succeeded) rxr->hn_csum_tcp++; else rxr->hn_csum_udp++; } - if (csum_info->receive.ip_csum_succeeded && - csum_info->receive.tcp_csum_succeeded) + if (info->csum_info->receive.ip_csum_succeeded && + info->csum_info->receive.tcp_csum_succeeded) do_lro = 1; } else { const struct ether_header *eh; @@ -1426,21 +1423,20 @@ netvsc_recv(struct hn_rx_ring *rxr, netv } } skip: - if ((packet->vlan_tci != 0) && - (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) { - m_new->m_pkthdr.ether_vtag = packet->vlan_tci; + if (info->vlan_info != NULL) { + m_new->m_pkthdr.ether_vtag = info->vlan_info->u1.s1.vlan_id; m_new->m_flags |= M_VLANTAG; } - if (hash_info != NULL && hash_value != NULL) { + if (info->hash_info != NULL && info->hash_value != NULL) { int hash_type = M_HASHTYPE_OPAQUE; rxr->hn_rss_pkts++; - m_new->m_pkthdr.flowid = hash_value->hash_value; - if ((hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) == + m_new->m_pkthdr.flowid = info->hash_value->hash_value; + if ((info->hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) == NDIS_HASH_FUNCTION_TOEPLITZ) { uint32_t type = - (hash_info->hash_info & NDIS_HASH_TYPE_MASK); + (info->hash_info->hash_info & NDIS_HASH_TYPE_MASK); switch (type) { case NDIS_HASH_IPV4: @@ -1470,8 +1466,8 @@ skip: } M_HASHTYPE_SET(m_new, hash_type); } else { - if (hash_value != NULL) - m_new->m_pkthdr.flowid = hash_value->hash_value; + if (info->hash_value != NULL) + m_new->m_pkthdr.flowid = info->hash_value->hash_value; else m_new->m_pkthdr.flowid = rxr->hn_rx_idx; M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE); Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 02:58:53 2016 (r307169) @@ -1088,11 +1088,10 @@ typedef struct rndismp_rx_bufs_info_ { */ struct hn_rx_ring; struct hn_tx_ring; +struct hn_recvinfo; -int netvsc_recv(struct hn_rx_ring *rxr, - netvsc_packet *packet, const rndis_tcp_ip_csum_info *csum_info, - const struct rndis_hash_info *hash_info, - const struct rndis_hash_value *hash_value); +int netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, + const struct hn_recvinfo *info); void netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); void* hv_set_rppi_data(rndis_msg *rndis_mesg, Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 02:58:53 2016 (r307169) @@ -53,13 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include -struct hv_rf_recvinfo { - const ndis_8021q_info *vlan_info; - const rndis_tcp_ip_csum_info *csum_info; - const struct rndis_hash_info *hash_info; - const struct rndis_hash_value *hash_value; -}; - #define HV_RF_RECVINFO_VLAN 0x1 #define HV_RF_RECVINFO_CSUM 0x2 #define HV_RF_RECVINFO_HASHINF 0x4 @@ -75,11 +68,12 @@ struct hv_rf_recvinfo { */ static int hv_rf_send_request(rndis_device *device, rndis_request *request, uint32_t message_type); -static void hv_rf_receive_response(rndis_device *device, rndis_msg *response); +static void hv_rf_receive_response(rndis_device *device, + const rndis_msg *response); static void hv_rf_receive_indicate_status(rndis_device *device, - rndis_msg *response); -static void hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message, - netvsc_packet *pkt); + const rndis_msg *response); +static void hv_rf_receive_data(struct hn_rx_ring *rxr, + const void *data, int dlen); static int hv_rf_query_device(rndis_device *device, uint32_t oid, void *result, uint32_t *result_size); static inline int hv_rf_query_device_mac(rndis_device *device); @@ -303,7 +297,7 @@ sendit: * RNDIS filter receive response */ static void -hv_rf_receive_response(rndis_device *device, rndis_msg *response) +hv_rf_receive_response(rndis_device *device, const rndis_msg *response) { rndis_request *request = NULL; rndis_request *next_request; @@ -425,9 +419,9 @@ cleanup: * RNDIS filter receive indicate status */ static void -hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response) +hv_rf_receive_indicate_status(rndis_device *device, const rndis_msg *response) { - rndis_indicate_status *indicate = &response->msg.indicate_status; + const rndis_indicate_status *indicate = &response->msg.indicate_status; switch(indicate->status) { case RNDIS_STATUS_MEDIA_CONNECT: @@ -445,7 +439,7 @@ hv_rf_receive_indicate_status(rndis_devi } static int -hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hv_rf_recvinfo *info) +hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info) { const rndis_per_packet_info *ppi; uint32_t mask, len; @@ -526,12 +520,12 @@ skip: * RNDIS filter receive data */ static void -hv_rf_receive_data(struct hn_rx_ring *rxr, rndis_msg *message, - netvsc_packet *pkt) +hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen) { - rndis_packet *rndis_pkt; + const rndis_msg *message = data; + const rndis_packet *rndis_pkt; uint32_t data_offset; - struct hv_rf_recvinfo info; + struct hn_recvinfo info; rndis_pkt = &message->msg.packet; @@ -543,30 +537,22 @@ hv_rf_receive_data(struct hn_rx_ring *rx /* Remove rndis header, then pass data packet up the stack */ data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; - pkt->tot_data_buf_len -= data_offset; - if (pkt->tot_data_buf_len < rndis_pkt->data_length) { - pkt->status = HN_NVS_STATUS_FAILED; + dlen -= data_offset; + if (dlen < rndis_pkt->data_length) { if_printf(rxr->hn_ifp, "total length %u is less than data length %u\n", - pkt->tot_data_buf_len, rndis_pkt->data_length); + dlen, rndis_pkt->data_length); return; } - pkt->tot_data_buf_len = rndis_pkt->data_length; - pkt->data = (void *)((unsigned long)pkt->data + data_offset); + dlen = rndis_pkt->data_length; + data = (const uint8_t *)data + data_offset; if (hv_rf_find_recvinfo(rndis_pkt, &info)) { - pkt->status = HN_NVS_STATUS_FAILED; if_printf(rxr->hn_ifp, "recvinfo parsing failed\n"); return; } - - if (info.vlan_info != NULL) - pkt->vlan_tci = info.vlan_info->u1.s1.vlan_id; - else - pkt->vlan_tci = 0; - - netvsc_recv(rxr, pkt, info.csum_info, info.hash_info, info.hash_value); + netvsc_recv(rxr, data, dlen, &info); } /* @@ -574,30 +560,25 @@ hv_rf_receive_data(struct hn_rx_ring *rx */ int hv_rf_on_receive(netvsc_dev *net_dev, - struct hn_rx_ring *rxr, netvsc_packet *pkt) + struct hn_rx_ring *rxr, const void *data, int dlen) { rndis_device *rndis_dev; - rndis_msg *rndis_hdr; + const rndis_msg *rndis_hdr; /* Make sure the rndis device state is initialized */ - if (net_dev->extension == NULL) { - pkt->status = HN_NVS_STATUS_FAILED; + if (net_dev->extension == NULL) return (ENODEV); - } rndis_dev = (rndis_device *)net_dev->extension; - if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { - pkt->status = HN_NVS_STATUS_FAILED; + if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) return (EINVAL); - } - - rndis_hdr = pkt->data; + rndis_hdr = data; switch (rndis_hdr->ndis_msg_type) { /* data message */ case REMOTE_NDIS_PACKET_MSG: - hv_rf_receive_data(rxr, rndis_hdr, pkt); + hv_rf_receive_data(rxr, data, dlen); break; /* completion messages */ case REMOTE_NDIS_INITIALIZE_CMPLT: Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 02:58:53 2016 (r307169) @@ -115,8 +115,8 @@ typedef struct rndis_device_ { struct hn_softc; struct hn_rx_ring; -int hv_rf_on_receive(netvsc_dev *net_dev, - struct hn_rx_ring *rxr, netvsc_packet *pkt); +int hv_rf_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, + const void *data, int dlen); void hv_rf_receive_rollup(netvsc_dev *net_dev); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int nchan, Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 02:45:08 2016 (r307168) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 02:58:53 2016 (r307169) @@ -35,7 +35,6 @@ #include struct netvsc_dev_; -struct nvsp_msg_; struct vmbus_channel; struct hn_send_ctx; @@ -51,6 +50,18 @@ struct hn_send_ctx { int hn_chim_sz; }; +struct rndis_hash_info; +struct rndix_hash_value; +struct ndis_8021q_info_; +struct rndis_tcp_ip_csum_info_; + +struct hn_recvinfo { + const struct ndis_8021q_info_ *vlan_info; + const struct rndis_tcp_ip_csum_info_ *csum_info; + const struct rndis_hash_info *hash_info; + const struct rndis_hash_value *hash_value; +}; + #define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ { \ .hn_cb = cb, \ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 03:00:57 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A93C6C0FECB; Thu, 13 Oct 2016 03:00:57 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7843BD36; Thu, 13 Oct 2016 03:00:57 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D30uJv011856; Thu, 13 Oct 2016 03:00:56 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D30uEG011855; Thu, 13 Oct 2016 03:00:56 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130300.u9D30uEG011855@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 03:00:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307170 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 03:00:57 -0000 Author: sephe Date: Thu Oct 13 03:00:56 2016 New Revision: 307170 URL: https://svnweb.freebsd.org/changeset/base/307170 Log: MFC 304331 hyperv/kvp: Remove unnecessary function parameter. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7550 Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 02:58:53 2016 (r307169) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 03:00:56 2016 (r307170) @@ -217,10 +217,9 @@ hv_kvp_transaction_init(hv_kvp_sc *sc, u * hv_kvp - version neogtiation function */ static void -hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, - struct hv_vmbus_icmsg_negotiate *negop, - uint8_t *buf) +hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf) { + struct hv_vmbus_icmsg_negotiate *negop; int icframe_vercnt; int icmsg_vercnt; @@ -641,7 +640,7 @@ hv_kvp_process_request(void *context, in hv_kvp_transaction_init(sc, recvlen, requestid, kvp_buf); if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_kvp_negotiate_version(icmsghdrp, NULL, kvp_buf); + hv_kvp_negotiate_version(icmsghdrp, kvp_buf); hv_kvp_respond_host(sc, ret); /* From owner-svn-src-stable-10@freebsd.org Thu Oct 13 03:16:17 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 22FDEC0E6F3; Thu, 13 Oct 2016 03:16:17 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DF5EE1C68; Thu, 13 Oct 2016 03:16:16 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D3GGM8020061; Thu, 13 Oct 2016 03:16:16 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D3GFQ0020057; Thu, 13 Oct 2016 03:16:15 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130316.u9D3GFQ0020057@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 03:16:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307174 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 03:16:17 -0000 Author: sephe Date: Thu Oct 13 03:16:15 2016 New Revision: 307174 URL: https://svnweb.freebsd.org/changeset/base/307174 Log: MFC 304441,304444,304446,304447,304591,304593-304595 304441 hyperv/hn: Move NVS version to softc Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7553 304444 hyperv/hn: Remove assign-only struct field Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7554 304446 hyperv/hn: Remove the useless num_channel Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7555 304447 hyperv/hn: Move RXBUF to hn_softc And don't recreate RXBUF for each primary channel open, it is now created in device_attach DEVMETHOD and destroyed in device_detach DEVMETHOD. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7556 304591 hyperv/hn: Move chimney sending buffer to hn_softc And don't recreate chimney sending buffer for each primary channel open, it is now created in device_attach DEVMETHOD and destroyed in device_detach DEVMETHOD. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7574 304593 hyperv/hn: Get rid of netvsc_dev Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7575 304594 hyperv/hn: Factor out function to execute NVS transactions. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7577 304595 hyperv/hn: Factor out function to simplify NVS request sending Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7578 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 03:10:04 2016 (r307173) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 03:16:15 2016 (r307174) @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -58,85 +59,78 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper static void hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr); static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); -static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); -static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev); -static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); +static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *, int); +static int hv_nv_destroy_send_buffer(struct hn_softc *sc); +static int hv_nv_destroy_rx_buffer(struct hn_softc *sc); static int hv_nv_connect_to_vsp(struct hn_softc *sc); -static void hv_nv_on_send_completion(netvsc_dev *net_dev, +static void hv_nv_on_send_completion(struct hn_softc *sc, struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); static void hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid); -static void hv_nv_on_receive(netvsc_dev *net_dev, +static void hv_nv_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt); static void hn_nvs_sent_none(struct hn_send_ctx *sndc, - struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, + struct hn_softc *, struct vmbus_channel *chan, const void *, int); +static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc, + struct vmbus_channel *, const void *, int); static struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); -/* - * - */ -static inline netvsc_dev * -hv_nv_alloc_net_device(struct hn_softc *sc) +uint32_t +hn_chim_alloc(struct hn_softc *sc) { - netvsc_dev *net_dev; + int i, bmap_cnt = sc->hn_chim_bmap_cnt; + u_long *bmap = sc->hn_chim_bmap; + uint32_t ret = HN_NVS_CHIM_IDX_INVALID; - net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO); + for (i = 0; i < bmap_cnt; ++i) { + int idx; - net_dev->sc = sc; - net_dev->destroy = FALSE; - sc->net_dev = net_dev; + idx = ffsl(~bmap[i]); + if (idx == 0) + continue; - return (net_dev); -} + --idx; /* ffsl is 1-based */ + KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt, + ("invalid i %d and idx %d", i, idx)); -/* - * XXX unnecessary; nuke it. - */ -static inline netvsc_dev * -hv_nv_get_outbound_net_device(struct hn_softc *sc) -{ - return sc->net_dev; -} + if (atomic_testandset_long(&bmap[i], idx)) + continue; -/* - * XXX unnecessary; nuke it. - */ -static inline netvsc_dev * -hv_nv_get_inbound_net_device(struct hn_softc *sc) -{ - return sc->net_dev; + ret = i * LONG_BIT + idx; + break; + } + return (ret); } -int -hv_nv_get_next_send_section(netvsc_dev *net_dev) +const void * +hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, + void *req, int reqlen, size_t *resp_len) { - unsigned long bitsmap_words = net_dev->bitsmap_words; - unsigned long *bitsmap = net_dev->send_section_bitsmap; - unsigned long idx; - int ret = HN_NVS_CHIM_IDX_INVALID; - int i; - - for (i = 0; i < bitsmap_words; i++) { - idx = ffsl(~bitsmap[i]); - if (0 == idx) - continue; - - idx--; - KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count, - ("invalid i %d and idx %lu", i, idx)); + struct hn_send_ctx sndc; + int error; - if (atomic_testandset_long(&bitsmap[i], idx)) - continue; + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + vmbus_xact_activate(xact); - ret = i * BITS_PER_LONG + idx; - break; + error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, + req, reqlen, &sndc); + if (error) { + vmbus_xact_deactivate(xact); + return NULL; } + return (vmbus_xact_wait(xact, resp_len)); +} - return (ret); +static __inline int +hn_nvs_req_send(struct hn_softc *sc, void *req, int reqlen) +{ + + return (hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, + req, reqlen, &hn_send_ctx_none)); } /* @@ -146,29 +140,17 @@ hv_nv_get_next_send_section(netvsc_dev * * Hyper-V extensible switch and the synthetic data path. */ static int -hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) +hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size) { - struct vmbus_xact *xact; + struct vmbus_xact *xact = NULL; struct hn_nvs_rxbuf_conn *conn; const struct hn_nvs_rxbuf_connresp *resp; size_t resp_len; - struct hn_send_ctx sndc; - netvsc_dev *net_dev; uint32_t status; int error; - net_dev = hv_nv_get_outbound_net_device(sc); - if (!net_dev) { - return (ENODEV); - } - - net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), - PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma, - BUS_DMA_WAITOK | BUS_DMA_ZERO); - if (net_dev->rx_buf == NULL) { - device_printf(sc->hn_dev, "allocate rxbuf failed\n"); - return (ENOMEM); - } + KASSERT(rxbuf_size <= NETVSC_RECEIVE_BUFFER_SIZE, + ("invalid rxbuf size %d", rxbuf_size)); /* * Connect the RXBUF GPADL to the primary channel. @@ -178,8 +160,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct * just share this RXBUF. */ error = vmbus_chan_gpadl_connect(sc->hn_prichan, - net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size, - &net_dev->rx_buf_gpadl_handle); + sc->hn_rxbuf_dma.hv_paddr, rxbuf_size, &sc->hn_rxbuf_gpadl); if (error) { if_printf(sc->hn_ifp, "rxbuf gpadl connect failed: %d\n", error); @@ -196,55 +177,47 @@ hv_nv_init_rx_buffer_with_net_vsp(struct error = ENXIO; goto cleanup; } - conn = vmbus_xact_req_data(xact); conn->nvs_type = HN_NVS_TYPE_RXBUF_CONN; - conn->nvs_gpadl = net_dev->rx_buf_gpadl_handle; + conn->nvs_gpadl = sc->hn_rxbuf_gpadl; conn->nvs_sig = HN_NVS_RXBUF_SIG; - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - vmbus_xact_activate(xact); - - error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, - conn, sizeof(*conn), &sndc); - if (error != 0) { - if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n", - error); - vmbus_xact_deactivate(xact); - vmbus_xact_put(xact); + resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len); + if (resp == NULL) { + if_printf(sc->hn_ifp, "exec rxbuf conn failed\n"); + error = EIO; goto cleanup; } - - resp = vmbus_xact_wait(xact, &resp_len); if (resp_len < sizeof(*resp)) { if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n", resp_len); - vmbus_xact_put(xact); error = EINVAL; goto cleanup; } if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) { if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n", resp->nvs_type); - vmbus_xact_put(xact); error = EINVAL; goto cleanup; } status = resp->nvs_status; vmbus_xact_put(xact); + xact = NULL; if (status != HN_NVS_STATUS_OK) { if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status); error = EIO; goto cleanup; } - net_dev->rx_section_count = 1; + sc->hn_flags |= HN_FLAG_RXBUF_CONNECTED; return (0); cleanup: - hv_nv_destroy_rx_buffer(net_dev); + if (xact != NULL) + vmbus_xact_put(xact); + hv_nv_destroy_rx_buffer(sc); return (error); } @@ -254,28 +227,13 @@ cleanup: static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) { - struct hn_send_ctx sndc; - struct vmbus_xact *xact; + struct vmbus_xact *xact = NULL; struct hn_nvs_chim_conn *chim; const struct hn_nvs_chim_connresp *resp; size_t resp_len; uint32_t status, sectsz; - netvsc_dev *net_dev; int error; - net_dev = hv_nv_get_outbound_net_device(sc); - if (!net_dev) { - return (ENODEV); - } - - net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), - PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma, - BUS_DMA_WAITOK | BUS_DMA_ZERO); - if (net_dev->send_buf == NULL) { - device_printf(sc->hn_dev, "allocate chimney txbuf failed\n"); - return (ENOMEM); - } - /* * Connect chimney sending buffer GPADL to the primary channel. * @@ -284,8 +242,8 @@ hv_nv_init_send_buffer_with_net_vsp(stru * Sub-channels just share this chimney sending buffer. */ error = vmbus_chan_gpadl_connect(sc->hn_prichan, - net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size, - &net_dev->send_buf_gpadl_handle); + sc->hn_chim_dma.hv_paddr, NETVSC_SEND_BUFFER_SIZE, + &sc->hn_chim_gpadl); if (error) { if_printf(sc->hn_ifp, "chimney sending buffer gpadl " "connect failed: %d\n", error); @@ -302,37 +260,26 @@ hv_nv_init_send_buffer_with_net_vsp(stru error = ENXIO; goto cleanup; } - chim = vmbus_xact_req_data(xact); chim->nvs_type = HN_NVS_TYPE_CHIM_CONN; - chim->nvs_gpadl = net_dev->send_buf_gpadl_handle; + chim->nvs_gpadl = sc->hn_chim_gpadl; chim->nvs_sig = HN_NVS_CHIM_SIG; - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - vmbus_xact_activate(xact); - - error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, - chim, sizeof(*chim), &sndc); - if (error) { - if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n", - error); - vmbus_xact_deactivate(xact); - vmbus_xact_put(xact); + resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len); + if (resp == NULL) { + if_printf(sc->hn_ifp, "exec chim conn failed\n"); + error = EIO; goto cleanup; } - - resp = vmbus_xact_wait(xact, &resp_len); if (resp_len < sizeof(*resp)) { if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n", resp_len); - vmbus_xact_put(xact); error = EINVAL; goto cleanup; } if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) { if_printf(sc->hn_ifp, "not chim conn resp, type %u\n", resp->nvs_type); - vmbus_xact_put(xact); error = EINVAL; goto cleanup; } @@ -340,6 +287,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru status = resp->nvs_status; sectsz = resp->nvs_sectsz; vmbus_xact_put(xact); + xact = NULL; if (status != HN_NVS_STATUS_OK) { if_printf(sc->hn_ifp, "chim conn failed: %x\n", status); @@ -352,23 +300,33 @@ hv_nv_init_send_buffer_with_net_vsp(stru return 0; } - net_dev->send_section_size = sectsz; - net_dev->send_section_count = - net_dev->send_buf_size / net_dev->send_section_size; - net_dev->bitsmap_words = howmany(net_dev->send_section_count, - BITS_PER_LONG); - net_dev->send_section_bitsmap = - malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC, - M_WAITOK | M_ZERO); + sc->hn_chim_szmax = sectsz; + sc->hn_chim_cnt = NETVSC_SEND_BUFFER_SIZE / sc->hn_chim_szmax; + if (NETVSC_SEND_BUFFER_SIZE % sc->hn_chim_szmax != 0) { + if_printf(sc->hn_ifp, "chimney sending sections are " + "not properly aligned\n"); + } + if (sc->hn_chim_cnt % LONG_BIT != 0) { + if_printf(sc->hn_ifp, "discard %d chimney sending sections\n", + sc->hn_chim_cnt % LONG_BIT); + } + + sc->hn_chim_bmap_cnt = sc->hn_chim_cnt / LONG_BIT; + sc->hn_chim_bmap = malloc(sc->hn_chim_bmap_cnt * sizeof(u_long), + M_NETVSC, M_WAITOK | M_ZERO); + /* Done! */ + sc->hn_flags |= HN_FLAG_CHIM_CONNECTED; if (bootverbose) { - if_printf(sc->hn_ifp, "chimney sending buffer %u/%u\n", - net_dev->send_section_size, net_dev->send_section_count); + if_printf(sc->hn_ifp, "chimney sending buffer %d/%d\n", + sc->hn_chim_szmax, sc->hn_chim_cnt); } return 0; cleanup: - hv_nv_destroy_send_buffer(net_dev); + if (xact != NULL) + vmbus_xact_put(xact); + hv_nv_destroy_send_buffer(sc); return (error); } @@ -376,11 +334,11 @@ cleanup: * Net VSC destroy receive buffer */ static int -hv_nv_destroy_rx_buffer(netvsc_dev *net_dev) +hv_nv_destroy_rx_buffer(struct hn_softc *sc) { int ret = 0; - if (net_dev->rx_section_count) { + if (sc->hn_flags & HN_FLAG_RXBUF_CONNECTED) { struct hn_nvs_rxbuf_disconn disconn; /* @@ -391,37 +349,28 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ disconn.nvs_sig = HN_NVS_RXBUF_SIG; /* NOTE: No response. */ - ret = hn_nvs_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn), - &hn_send_ctx_none); + ret = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); if (ret != 0) { - if_printf(net_dev->sc->hn_ifp, + if_printf(sc->hn_ifp, "send rxbuf disconn failed: %d\n", ret); return (ret); } - net_dev->rx_section_count = 0; + sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED; } - /* Tear down the gpadl on the vsp end */ - if (net_dev->rx_buf_gpadl_handle) { - ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, - net_dev->rx_buf_gpadl_handle); + if (sc->hn_rxbuf_gpadl != 0) { /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk + * Disconnect RXBUF from primary channel. */ + ret = vmbus_chan_gpadl_disconnect(sc->hn_prichan, + sc->hn_rxbuf_gpadl); if (ret != 0) { + if_printf(sc->hn_ifp, + "rxbuf disconn failed: %d\n", ret); return (ret); } - net_dev->rx_buf_gpadl_handle = 0; - } - - if (net_dev->rx_buf) { - /* Free up the receive buffer */ - hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf); - net_dev->rx_buf = NULL; + sc->hn_rxbuf_gpadl = 0; } - return (ret); } @@ -429,11 +378,11 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_ * Net VSC destroy send buffer */ static int -hv_nv_destroy_send_buffer(netvsc_dev *net_dev) +hv_nv_destroy_send_buffer(struct hn_softc *sc) { int ret = 0; - if (net_dev->send_section_size) { + if (sc->hn_flags & HN_FLAG_CHIM_CONNECTED) { struct hn_nvs_chim_disconn disconn; /* @@ -444,80 +393,62 @@ hv_nv_destroy_send_buffer(netvsc_dev *ne disconn.nvs_sig = HN_NVS_CHIM_SIG; /* NOTE: No response. */ - ret = hn_nvs_send(net_dev->sc->hn_prichan, - VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn), - &hn_send_ctx_none); + ret = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); if (ret != 0) { - if_printf(net_dev->sc->hn_ifp, + if_printf(sc->hn_ifp, "send chim disconn failed: %d\n", ret); return (ret); } + sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED; } - /* Tear down the gpadl on the vsp end */ - if (net_dev->send_buf_gpadl_handle) { - ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, - net_dev->send_buf_gpadl_handle); - + if (sc->hn_chim_gpadl != 0) { /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk + * Disconnect chimney sending buffer from primary channel. */ + ret = vmbus_chan_gpadl_disconnect(sc->hn_prichan, + sc->hn_chim_gpadl); if (ret != 0) { + if_printf(sc->hn_ifp, + "chim disconn failed: %d\n", ret); return (ret); } - net_dev->send_buf_gpadl_handle = 0; - } - - if (net_dev->send_buf) { - /* Free up the receive buffer */ - hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf); - net_dev->send_buf = NULL; + sc->hn_chim_gpadl = 0; } - if (net_dev->send_section_bitsmap) { - free(net_dev->send_section_bitsmap, M_NETVSC); + if (sc->hn_chim_bmap != NULL) { + free(sc->hn_chim_bmap, M_NETVSC); + sc->hn_chim_bmap = NULL; } return (ret); } static int -hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev, - uint32_t nvs_ver) +hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, uint32_t nvs_ver) { - struct hn_send_ctx sndc; struct vmbus_xact *xact; struct hn_nvs_init *init; const struct hn_nvs_init_resp *resp; size_t resp_len; uint32_t status; - int error; xact = vmbus_xact_get(sc->hn_xact, sizeof(*init)); if (xact == NULL) { if_printf(sc->hn_ifp, "no xact for nvs init\n"); return (ENXIO); } - init = vmbus_xact_req_data(xact); init->nvs_type = HN_NVS_TYPE_INIT; init->nvs_ver_min = nvs_ver; init->nvs_ver_max = nvs_ver; - vmbus_xact_activate(xact); - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - - error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, - init, sizeof(*init), &sndc); - if (error) { - if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error); - vmbus_xact_deactivate(xact); + resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len); + if (resp == NULL) { + if_printf(sc->hn_ifp, "exec init failed\n"); vmbus_xact_put(xact); - return (error); + return (EIO); } - - resp = vmbus_xact_wait(xact, &resp_len); if (resp_len < sizeof(*resp)) { if_printf(sc->hn_ifp, "invalid init resp length %zu\n", resp_len); @@ -559,8 +490,7 @@ hv_nv_send_ndis_config(struct hn_softc * conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; /* NOTE: No response. */ - error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, - &conf, sizeof(conf), &hn_send_ctx_none); + error = hn_nvs_req_send(sc, &conf, sizeof(conf)); if (error) if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); return (error); @@ -572,7 +502,6 @@ hv_nv_send_ndis_config(struct hn_softc * static int hv_nv_connect_to_vsp(struct hn_softc *sc) { - netvsc_dev *net_dev; uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, NVSP_PROTOCOL_VERSION_4, @@ -583,19 +512,18 @@ hv_nv_connect_to_vsp(struct hn_softc *sc device_t dev = sc->hn_dev; struct ifnet *ifp = sc->arpcom.ac_ifp; struct hn_nvs_ndis_init ndis; - - net_dev = hv_nv_get_outbound_net_device(sc); + int rxbuf_size; /* * Negotiate the NVSP version. Try the latest NVSP first. */ for (i = protocol_number - 1; i >= 0; i--) { - if (hv_nv_negotiate_nvsp_protocol(sc, net_dev, - protocol_list[i]) == 0) { - net_dev->nvsp_version = protocol_list[i]; - if (bootverbose) - device_printf(dev, "Netvsc: got version 0x%x\n", - net_dev->nvsp_version); + if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { + sc->hn_nvs_ver = protocol_list[i]; + if (bootverbose) { + device_printf(dev, "NVS version 0x%x\n", + sc->hn_nvs_ver); + } break; } } @@ -611,7 +539,7 @@ hv_nv_connect_to_vsp(struct hn_softc *sc * Set the MTU if supported by this NVSP protocol version * This needs to be right after the NVSP init message per Haiyang */ - if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) + if (sc->hn_nvs_ver >= NVSP_PROTOCOL_VERSION_2) ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); /* @@ -621,27 +549,25 @@ hv_nv_connect_to_vsp(struct hn_softc *sc memset(&ndis, 0, sizeof(ndis)); ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6; - if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) + if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1; else ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30; /* NOTE: No response. */ - ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, - &ndis, sizeof(ndis), &hn_send_ctx_none); + ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); if (ret != 0) { if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret); goto cleanup; } /* Post the big receive buffer to NetVSP */ - if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2) - net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; + if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_2) + rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; else - net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; - net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE; + rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE; - ret = hv_nv_init_rx_buffer_with_net_vsp(sc); + ret = hv_nv_init_rx_buffer_with_net_vsp(sc, rxbuf_size); if (ret == 0) ret = hv_nv_init_send_buffer_with_net_vsp(sc); @@ -653,10 +579,10 @@ cleanup: * Net VSC disconnect from VSP */ static void -hv_nv_disconnect_from_vsp(netvsc_dev *net_dev) +hv_nv_disconnect_from_vsp(struct hn_softc *sc) { - hv_nv_destroy_rx_buffer(net_dev); - hv_nv_destroy_send_buffer(net_dev); + hv_nv_destroy_rx_buffer(sc); + hv_nv_destroy_send_buffer(sc); } void @@ -675,20 +601,12 @@ hv_nv_subchan_attach(struct vmbus_channe * * Callback when the device belonging to this driver is added */ -netvsc_dev * -hv_nv_on_device_add(struct hn_softc *sc, void *additional_info, - struct hn_rx_ring *rxr) +int +hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr) { struct vmbus_channel *chan = sc->hn_prichan; - netvsc_dev *net_dev; int ret = 0; - net_dev = hv_nv_alloc_net_device(sc); - if (net_dev == NULL) - return NULL; - - /* Initialize the NetVSC channel extension */ - /* * Open the channel */ @@ -708,20 +626,13 @@ hv_nv_on_device_add(struct hn_softc *sc, if (ret != 0) goto close; - return (net_dev); + return (0); close: /* Now, we can close the channel safely */ vmbus_chan_close(chan); - cleanup: - /* - * Free the packet buffers on the netvsc device packet queue. - * Release other resources. - */ - free(net_dev, M_NETVSC); - - return (NULL); + return (ret); } /* @@ -730,27 +641,19 @@ cleanup: int hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) { - netvsc_dev *net_dev = sc->net_dev;; - /* Stop outbound traffic ie sends and receives completions */ - net_dev->destroy = TRUE; - - hv_nv_disconnect_from_vsp(net_dev); - - /* At this point, no one should be accessing net_dev except in here */ + hv_nv_disconnect_from_vsp(sc); /* Now, we can close the channel safely */ vmbus_chan_close(sc->hn_prichan); - free(net_dev, M_NETVSC); - return (0); } -void +static void hn_nvs_sent_xact(struct hn_send_ctx *sndc, - struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, + struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, const void *data, int dlen) { @@ -759,42 +662,42 @@ hn_nvs_sent_xact(struct hn_send_ctx *snd static void hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, - struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, + struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, const void *data __unused, int dlen __unused) { /* EMPTY */ } void -hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx) +hn_chim_free(struct hn_softc *sc, uint32_t chim_idx) { u_long mask; uint32_t idx; - idx = chim_idx / BITS_PER_LONG; - KASSERT(idx < net_dev->bitsmap_words, + idx = chim_idx / LONG_BIT; + KASSERT(idx < sc->hn_chim_bmap_cnt, ("invalid chimney index 0x%x", chim_idx)); - mask = 1UL << (chim_idx % BITS_PER_LONG); - KASSERT(net_dev->send_section_bitsmap[idx] & mask, + mask = 1UL << (chim_idx % LONG_BIT); + KASSERT(sc->hn_chim_bmap[idx] & mask, ("index bitmap 0x%lx, chimney index %u, " "bitmap idx %d, bitmask 0x%lx", - net_dev->send_section_bitsmap[idx], chim_idx, idx, mask)); + sc->hn_chim_bmap[idx], chim_idx, idx, mask)); - atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask); + atomic_clear_long(&sc->hn_chim_bmap[idx], mask); } /* * Net VSC on send completion */ static void -hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan, +hv_nv_on_send_completion(struct hn_softc *sc, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt) { struct hn_send_ctx *sndc; sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; - sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt), + sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt), VMBUS_CHANPKT_DATALEN(pkt)); /* * NOTE: @@ -838,7 +741,7 @@ hv_nv_on_send(struct vmbus_channel *chan * with virtual addresses. */ static void -hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, +hv_nv_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) { const struct vmbus_chanpkt_rxbuf *pkt; @@ -866,8 +769,8 @@ hv_nv_on_receive(netvsc_dev *net_dev, st /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ for (i = 0; i < count; i++) { - hv_rf_on_receive(net_dev, rxr, - (const uint8_t *)net_dev->rx_buf + pkt->cp_rxbuf[i].rb_ofs, + hv_rf_on_receive(sc, rxr, + rxr->hn_rxbuf + pkt->cp_rxbuf[i].rb_ofs, pkt->cp_rxbuf[i].rb_len); } @@ -933,14 +836,9 @@ hv_nv_on_channel_callback(struct vmbus_c { struct hn_rx_ring *rxr = xrxr; struct hn_softc *sc = rxr->hn_ifp->if_softc; - netvsc_dev *net_dev; void *buffer; int bufferlen = NETVSC_PACKET_SIZE; - net_dev = hv_nv_get_inbound_net_device(sc); - if (net_dev == NULL) - return; - buffer = rxr->hn_rdbuf; do { struct vmbus_chanpkt_hdr *pkt = buffer; @@ -953,11 +851,10 @@ hv_nv_on_channel_callback(struct vmbus_c if (bytes_rxed > 0) { switch (pkt->cph_type) { case VMBUS_CHANPKT_TYPE_COMP: - hv_nv_on_send_completion(net_dev, chan, - pkt); + hv_nv_on_send_completion(sc, chan, pkt); break; case VMBUS_CHANPKT_TYPE_RXBUF: - hv_nv_on_receive(net_dev, rxr, chan, pkt); + hv_nv_on_receive(sc, rxr, chan, pkt); break; case VMBUS_CHANPKT_TYPE_INBAND: hn_proc_notify(sc, pkt); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 03:10:04 2016 (r307173) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 03:16:15 2016 (r307174) @@ -212,40 +212,6 @@ typedef struct rndis_recv_scale_param_ { * Data types */ -/* - * Per netvsc channel-specific - */ -typedef struct netvsc_dev_ { - struct hn_softc *sc; - - /* Send buffer allocated by us but manages by NetVSP */ - void *send_buf; - uint32_t send_buf_size; - uint32_t send_buf_gpadl_handle; - uint32_t send_section_size; - uint32_t send_section_count; - unsigned long bitsmap_words; - unsigned long *send_section_bitsmap; - - /* Receive buffer allocated by us but managed by NetVSP */ - void *rx_buf; - uint32_t rx_buf_size; - uint32_t rx_buf_gpadl_handle; - uint32_t rx_section_count; - - /* Holds rndis device info */ - void *extension; - - uint8_t destroy; - /* Negotiated NVSP version */ - uint32_t nvsp_version; - - uint32_t num_channel; - - struct hyperv_dma rxbuf_dma; - struct hyperv_dma txbuf_dma; -} netvsc_dev; - struct vmbus_channel; typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *); @@ -268,12 +234,6 @@ typedef void (*pfn_on_send_rx_completion #define TRANSPORT_TYPE_IPV6_TCP ((TYPE_IPV6 << 16) | TYPE_TCP) #define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP) -#ifdef __LP64__ -#define BITS_PER_LONG 64 -#else -#define BITS_PER_LONG 32 -#endif - typedef struct { uint8_t mac_addr[6]; /* Assumption unsigned long */ uint8_t link_state; @@ -292,6 +252,7 @@ struct hn_rx_ring { struct ifnet *hn_ifp; struct hn_tx_ring *hn_txr; void *hn_rdbuf; + uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ int hn_rx_idx; /* Trust csum verification on host side */ @@ -345,7 +306,7 @@ struct hn_tx_ring { struct vmbus_channel *hn_chan; int hn_direct_tx_size; - int hn_tx_chimney_size; + int hn_chim_size; bus_dma_tag_t hn_tx_data_dtag; uint64_t hn_csum_assist; @@ -384,7 +345,7 @@ typedef struct hn_softc { int hn_initdone; /* See hv_netvsc_drv_freebsd.c for rules on how to use */ int temp_unusable; - netvsc_dev *net_dev; + struct rndis_device_ *rndis_dev; struct vmbus_channel *hn_prichan; int hn_rx_ring_cnt; @@ -395,14 +356,31 @@ typedef struct hn_softc { int hn_tx_ring_inuse; struct hn_tx_ring *hn_tx_ring; + uint8_t *hn_chim; + u_long *hn_chim_bmap; + int hn_chim_bmap_cnt; + int hn_chim_cnt; + int hn_chim_szmax; + int hn_cpu; - int hn_tx_chimney_max; struct taskqueue *hn_tx_taskq; struct sysctl_oid *hn_tx_sysctl_tree; struct sysctl_oid *hn_rx_sysctl_tree; struct vmbus_xact_ctx *hn_xact; + uint32_t hn_nvs_ver; + + uint32_t hn_flags; + void *hn_rxbuf; + uint32_t hn_rxbuf_gpadl; + struct hyperv_dma hn_rxbuf_dma; + + uint32_t hn_chim_gpadl; + struct hyperv_dma hn_chim_dma; } hn_softc_t; +#define HN_FLAG_RXBUF_CONNECTED 0x0001 +#define HN_FLAG_CHIM_CONNECTED 0x0002 + /* * Externs */ @@ -410,13 +388,11 @@ extern int hv_promisc_mode; struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); -netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc, - void *additional_info, struct hn_rx_ring *rxr); +int hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr); int hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); -int hv_nv_get_next_send_section(netvsc_dev *net_dev); void hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 03:10:04 2016 (r307173) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 03:16:15 2016 (r307174) @@ -328,7 +328,7 @@ static int hn_lro_lenlim_sysctl(SYSCTL_H static int hn_lro_ackcnt_sysctl(SYSCTL_HANDLER_ARGS); #endif static int hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS); -static int hn_tx_chimney_size_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_chim_size_sysctl(SYSCTL_HANDLER_ARGS); #if __FreeBSD_version < 1100095 static int hn_rx_stat_int_sysctl(SYSCTL_HANDLER_ARGS); #else @@ -346,9 +346,9 @@ static void hn_start_taskfunc(void *, in static void hn_start_txeof_taskfunc(void *, int); static void hn_stop_tx_tasks(struct hn_softc *); static int hn_encap(struct hn_tx_ring *, struct hn_txdesc *, struct mbuf **); -static void hn_create_rx_data(struct hn_softc *sc, int); +static int hn_create_rx_data(struct hn_softc *sc, int); static void hn_destroy_rx_data(struct hn_softc *sc); -static void hn_set_tx_chimney_size(struct hn_softc *, int); +static void hn_set_chim_size(struct hn_softc *, int); static void hn_channel_attach(struct hn_softc *, struct vmbus_channel *); static void hn_subchan_attach(struct hn_softc *, struct vmbus_channel *); static void hn_subchan_setup(struct hn_softc *); @@ -520,7 +520,9 @@ netvsc_attach(device_t dev) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Thu Oct 13 03:23:44 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D4FE6C0E9E6; Thu, 13 Oct 2016 03:23:44 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A3330242; Thu, 13 Oct 2016 03:23:44 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D3Nhbc023737; Thu, 13 Oct 2016 03:23:43 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D3Nhwi023734; Thu, 13 Oct 2016 03:23:43 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130323.u9D3Nhwi023734@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 03:23:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307175 - in stable/10/sys: dev/usb/net net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 03:23:44 -0000 Author: sephe Date: Thu Oct 13 03:23:43 2016 New Revision: 307175 URL: https://svnweb.freebsd.org/changeset/base/307175 Log: MFC 304654,304722,304723 304654 net: Split RNDIS protocol structs/macros out of dev/usb/net/if_urndisreg.h So that Hyper-V can leverage them instead of rolling its own definition. Discussed with: hps Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7592 304722 net/rndis: Add canonical RNDIS major/minor version as of today. Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7593 304723 net/rndis: Fix RNDIS_STATUS_PENDING definition. While I'm here, sort the RNDIS status in ascending order. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7594 Added: stable/10/sys/net/rndis.h - copied, changed from r304654, head/sys/net/rndis.h Modified: stable/10/sys/dev/usb/net/if_urndis.c stable/10/sys/dev/usb/net/if_urndisreg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/usb/net/if_urndis.c ============================================================================== --- stable/10/sys/dev/usb/net/if_urndis.c Thu Oct 13 03:16:15 2016 (r307174) +++ stable/10/sys/dev/usb/net/if_urndis.c Thu Oct 13 03:23:43 2016 (r307175) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -79,17 +80,17 @@ static uether_fn_t urndis_setmulti; static uether_fn_t urndis_setpromisc; static uint32_t urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, - struct urndis_query_req *msg, uint16_t len, + struct rndis_query_req *msg, uint16_t len, const void **rbuf, uint16_t *rbufsz); static uint32_t urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, - struct urndis_set_req *msg, uint16_t len); + struct rndis_set_req *msg, uint16_t len); static uint32_t urndis_ctrl_handle_init(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr); + const struct rndis_comp_hdr *hdr); static uint32_t urndis_ctrl_handle_query(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr, const void **buf, + const struct rndis_comp_hdr *hdr, const void **buf, uint16_t *bufsz); static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr); + const struct rndis_comp_hdr *hdr); static uint32_t urndis_ctrl_init(struct urndis_softc *sc); static uint32_t urndis_ctrl_halt(struct urndis_softc *sc); @@ -211,8 +212,8 @@ urndis_attach(device_t dev) { static struct { union { - struct urndis_query_req query; - struct urndis_set_req set; + struct rndis_query_req query; + struct rndis_set_req set; } hdr; union { uint8_t eaddr[ETHER_ADDR_LEN]; @@ -452,10 +453,10 @@ urndis_ctrl_send(struct urndis_softc *sc return (err); } -static struct urndis_comp_hdr * +static struct rndis_comp_hdr * urndis_ctrl_recv(struct urndis_softc *sc) { - struct urndis_comp_hdr *hdr; + struct rndis_comp_hdr *hdr; usb_error_t err; err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE, @@ -465,7 +466,7 @@ urndis_ctrl_recv(struct urndis_softc *sc if (err != USB_ERR_NORMAL_COMPLETION) return (NULL); - hdr = (struct urndis_comp_hdr *)sc->sc_response_buf; + hdr = (struct rndis_comp_hdr *)sc->sc_response_buf; DPRINTF("type 0x%x len %u\n", le32toh(hdr->rm_type), le32toh(hdr->rm_len)); @@ -479,7 +480,7 @@ urndis_ctrl_recv(struct urndis_softc *sc } static uint32_t -urndis_ctrl_handle(struct urndis_softc *sc, struct urndis_comp_hdr *hdr, +urndis_ctrl_handle(struct urndis_softc *sc, struct rndis_comp_hdr *hdr, const void **buf, uint16_t *bufsz) { uint32_t rval; @@ -520,11 +521,11 @@ urndis_ctrl_handle(struct urndis_softc * static uint32_t urndis_ctrl_handle_init(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr) + const struct rndis_comp_hdr *hdr) { - const struct urndis_init_comp *msg; + const struct rndis_init_comp *msg; - msg = (const struct urndis_init_comp *)hdr; + msg = (const struct rndis_init_comp *)hdr; DPRINTF("len %u rid %u status 0x%x " "ver_major %u ver_minor %u devflags 0x%x medium 0x%x pktmaxcnt %u " @@ -563,12 +564,12 @@ urndis_ctrl_handle_init(struct urndis_so static uint32_t urndis_ctrl_handle_query(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr, const void **buf, uint16_t *bufsz) + const struct rndis_comp_hdr *hdr, const void **buf, uint16_t *bufsz) { - const struct urndis_query_comp *msg; + const struct rndis_query_comp *msg; uint64_t limit; - msg = (const struct urndis_query_comp *)hdr; + msg = (const struct rndis_query_comp *)hdr; DPRINTF("len %u rid %u status 0x%x " "buflen %u bufoff %u\n", @@ -608,12 +609,12 @@ urndis_ctrl_handle_query(struct urndis_s static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *sc, - const struct urndis_comp_hdr *hdr) + const struct rndis_comp_hdr *hdr) { - const struct urndis_reset_comp *msg; + const struct rndis_reset_comp *msg; uint32_t rval; - msg = (const struct urndis_reset_comp *)hdr; + msg = (const struct rndis_reset_comp *)hdr; rval = le32toh(msg->rm_status); @@ -629,7 +630,7 @@ urndis_ctrl_handle_reset(struct urndis_s } if (msg->rm_adrreset != 0) { struct { - struct urndis_set_req hdr; + struct rndis_set_req hdr; uint32_t filter; } msg_filter; @@ -649,14 +650,14 @@ urndis_ctrl_handle_reset(struct urndis_s static uint32_t urndis_ctrl_init(struct urndis_softc *sc) { - struct urndis_init_req msg; - struct urndis_comp_hdr *hdr; + struct rndis_init_req msg; + struct rndis_comp_hdr *hdr; uint32_t rval; msg.rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG); msg.rm_len = htole32(sizeof(msg)); msg.rm_rid = 0; - msg.rm_ver_major = htole32(1); + msg.rm_ver_major = htole32(RNDIS_VERSION_MAJOR); msg.rm_ver_minor = htole32(1); msg.rm_max_xfersz = htole32(RNDIS_RX_MAXLEN); @@ -687,7 +688,7 @@ urndis_ctrl_init(struct urndis_softc *sc static uint32_t urndis_ctrl_halt(struct urndis_softc *sc) { - struct urndis_halt_req msg; + struct rndis_halt_req msg; uint32_t rval; msg.rm_type = htole32(REMOTE_NDIS_HALT_MSG); @@ -713,10 +714,10 @@ urndis_ctrl_halt(struct urndis_softc *sc */ static uint32_t urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, - struct urndis_query_req *msg, uint16_t len, const void **rbuf, + struct rndis_query_req *msg, uint16_t len, const void **rbuf, uint16_t *rbufsz) { - struct urndis_comp_hdr *hdr; + struct rndis_comp_hdr *hdr; uint32_t datalen, rval; msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG); @@ -760,9 +761,9 @@ urndis_ctrl_query(struct urndis_softc *s static uint32_t urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, - struct urndis_set_req *msg, uint16_t len) + struct rndis_set_req *msg, uint16_t len) { - struct urndis_comp_hdr *hdr; + struct rndis_comp_hdr *hdr; uint32_t datalen, rval; msg->rm_type = htole32(REMOTE_NDIS_SET_MSG); @@ -812,7 +813,7 @@ urndis_bulk_read_callback(struct usb_xfe struct urndis_softc *sc = usbd_xfer_softc(xfer); struct usb_page_cache *pc = usbd_xfer_get_frame(xfer, 0); struct ifnet *ifp = uether_getifp(&sc->sc_ue); - struct urndis_packet_msg msg; + struct rndis_packet_msg msg; struct mbuf *m; int actlen; int aframes; @@ -872,11 +873,11 @@ urndis_bulk_read_callback(struct usb_xfe "datalen %u\n", msg.rm_datalen, actlen); goto tr_setup; } else if ((msg.rm_dataoffset + msg.rm_datalen + - (uint32_t)__offsetof(struct urndis_packet_msg, + (uint32_t)__offsetof(struct rndis_packet_msg, rm_dataoffset)) > (uint32_t)actlen) { DPRINTF("invalid dataoffset %u larger than %u\n", msg.rm_dataoffset + msg.rm_datalen + - (uint32_t)__offsetof(struct urndis_packet_msg, + (uint32_t)__offsetof(struct rndis_packet_msg, rm_dataoffset), actlen); goto tr_setup; } else if (msg.rm_datalen < (uint32_t)sizeof(struct ether_header)) { @@ -902,7 +903,7 @@ urndis_bulk_read_callback(struct usb_xfe m_adj(m, ETHER_ALIGN); usbd_copy_out(pc, offset + msg.rm_dataoffset + - __offsetof(struct urndis_packet_msg, + __offsetof(struct rndis_packet_msg, rm_dataoffset), m->m_data, msg.rm_datalen); /* enqueue */ @@ -938,7 +939,7 @@ tr_setup: static void urndis_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { - struct urndis_packet_msg msg; + struct rndis_packet_msg msg; struct urndis_softc *sc = usbd_xfer_softc(xfer); struct ifnet *ifp = uether_getifp(&sc->sc_ue); struct mbuf *m; Modified: stable/10/sys/dev/usb/net/if_urndisreg.h ============================================================================== --- stable/10/sys/dev/usb/net/if_urndisreg.h Thu Oct 13 03:16:15 2016 (r307174) +++ stable/10/sys/dev/usb/net/if_urndisreg.h Thu Oct 13 03:23:43 2016 (r307175) @@ -55,242 +55,4 @@ struct urndis_softc { #define URNDIS_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) #define URNDIS_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->sc_mtx, (what)) -#define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005L -#define RNDIS_STATUS_FAILURE 0xC0000001L -#define RNDIS_STATUS_INVALID_DATA 0xC0010015L -#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BL -#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CL -#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBL -#define RNDIS_STATUS_PENDING STATUS_PENDING /* XXX */ -#define RNDIS_STATUS_RESOURCES 0xC000009AL -#define RNDIS_STATUS_SUCCESS 0x00000000L - -#define OID_GEN_SUPPORTED_LIST 0x00010101 -#define OID_GEN_HARDWARE_STATUS 0x00010102 -#define OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define OID_GEN_MEDIA_IN_USE 0x00010104 -#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define OID_GEN_LINK_SPEED 0x00010107 -#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define OID_GEN_VENDOR_ID 0x0001010C -#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define OID_GEN_DRIVER_VERSION 0x00010110 -#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define OID_GEN_MAC_OPTIONS 0x00010113 -#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define OID_GEN_SUPPORTED_GUIDS 0x00010117 -#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define OID_GEN_MACHINE_NAME 0x0001021A -#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B -#define OID_GEN_VLAN_ID 0x0001021C - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 -#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define OID_802_3_MAC_OPTIONS 0x01010105 -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -#define RNDIS_MEDIUM_802_3 0x00000000 - -/* Device flags */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001 -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 - -/* - * RNDIS data message - */ -#define REMOTE_NDIS_PACKET_MSG 0x00000001 - -struct urndis_packet_msg { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_dataoffset; - uint32_t rm_datalen; - uint32_t rm_oobdataoffset; - uint32_t rm_oobdatalen; - uint32_t rm_oobdataelements; - uint32_t rm_pktinfooffset; - uint32_t rm_pktinfolen; - uint32_t rm_vchandle; - uint32_t rm_reserved; -}; - -/* - * RNDIS control messages - */ -struct urndis_comp_hdr { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_status; -}; - -/* Initialize the device. */ -#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002 -#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002 - -struct urndis_init_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_ver_major; - uint32_t rm_ver_minor; - uint32_t rm_max_xfersz; -}; - -struct urndis_init_comp { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_status; - uint32_t rm_ver_major; - uint32_t rm_ver_minor; - uint32_t rm_devflags; - uint32_t rm_medium; - uint32_t rm_pktmaxcnt; - uint32_t rm_pktmaxsz; - uint32_t rm_align; - uint32_t rm_aflistoffset; - uint32_t rm_aflistsz; -}; - -/* Halt the device. No response sent. */ -#define REMOTE_NDIS_HALT_MSG 0x00000003 - -struct urndis_halt_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; -}; - -/* Send a query object. */ -#define REMOTE_NDIS_QUERY_MSG 0x00000004 -#define REMOTE_NDIS_QUERY_CMPLT 0x80000004 - -struct urndis_query_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_oid; - uint32_t rm_infobuflen; - uint32_t rm_infobufoffset; - uint32_t rm_devicevchdl; -}; - -struct urndis_query_comp { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_status; - uint32_t rm_infobuflen; - uint32_t rm_infobufoffset; -}; - -/* Send a set object request. */ -#define REMOTE_NDIS_SET_MSG 0x00000005 -#define REMOTE_NDIS_SET_CMPLT 0x80000005 - -struct urndis_set_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_oid; - uint32_t rm_infobuflen; - uint32_t rm_infobufoffset; - uint32_t rm_devicevchdl; -}; - -struct urndis_set_comp { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_status; -}; - -#define REMOTE_NDIS_SET_PARAM_NUMERIC 0x00000000 -#define REMOTE_NDIS_SET_PARAM_STRING 0x00000002 - -struct urndis_set_parameter { - uint32_t rm_nameoffset; - uint32_t rm_namelen; - uint32_t rm_type; - uint32_t rm_valueoffset; - uint32_t rm_valuelen; -}; - -/* Perform a soft reset on the device. */ -#define REMOTE_NDIS_RESET_MSG 0x00000006 -#define REMOTE_NDIS_RESET_CMPLT 0x80000006 - -struct urndis_reset_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; -}; - -struct urndis_reset_comp { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_status; - uint32_t rm_adrreset; -}; - -/* 802.3 link-state or undefined message error. */ -#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007 - -/* Keepalive messsage. May be sent by device. */ -#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008 -#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008 - -struct urndis_keepalive_req { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; -}; - -struct urndis_keepalive_comp { - uint32_t rm_type; - uint32_t rm_len; - uint32_t rm_rid; - uint32_t rm_status; -}; - -/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ -#define RNDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define RNDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define RNDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define RNDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define RNDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define RNDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define RNDIS_PACKET_TYPE_SMT 0x00000040 -#define RNDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define RNDIS_PACKET_TYPE_GROUP 0x00001000 -#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 -#define RNDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 -#define RNDIS_PACKET_TYPE_MAC_FRAME 0x00008000 - -/* RNDIS offsets */ -#define RNDIS_HEADER_OFFSET 8 /* bytes */ -#define RNDIS_DATA_OFFSET ((uint32_t)(sizeof(struct urndis_packet_msg) - RNDIS_HEADER_OFFSET)) - #endif /* _IF_URNDISREG_H_ */ Copied and modified: stable/10/sys/net/rndis.h (from r304654, head/sys/net/rndis.h) ============================================================================== --- head/sys/net/rndis.h Tue Aug 23 02:54:06 2016 (r304654, copy source) +++ stable/10/sys/net/rndis.h Thu Oct 13 03:23:43 2016 (r307175) @@ -23,15 +23,19 @@ #ifndef _NET_RNDIS_H_ #define _NET_RNDIS_H_ -#define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005L -#define RNDIS_STATUS_FAILURE 0xC0000001L -#define RNDIS_STATUS_INVALID_DATA 0xC0010015L +/* Canonical major/minor version as of 22th Aug. 2016. */ +#define RNDIS_VERSION_MAJOR 0x00000001 +#define RNDIS_VERSION_MINOR 0x00000000 + +#define RNDIS_STATUS_SUCCESS 0x00000000L +#define RNDIS_STATUS_PENDING 0x00000103L #define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BL #define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CL +#define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005L +#define RNDIS_STATUS_FAILURE 0xC0000001L #define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBL -#define RNDIS_STATUS_PENDING STATUS_PENDING /* XXX */ #define RNDIS_STATUS_RESOURCES 0xC000009AL -#define RNDIS_STATUS_SUCCESS 0x00000000L +#define RNDIS_STATUS_INVALID_DATA 0xC0010015L #define OID_GEN_SUPPORTED_LIST 0x00010101 #define OID_GEN_HARDWARE_STATUS 0x00010102 From owner-svn-src-stable-10@freebsd.org Thu Oct 13 04:24:35 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A5C89C0F77D; Thu, 13 Oct 2016 04:24:35 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7F35FD27; Thu, 13 Oct 2016 04:24:35 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D4OYkS046778; Thu, 13 Oct 2016 04:24:34 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D4OY4b046777; Thu, 13 Oct 2016 04:24:34 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130424.u9D4OY4b046777@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 04:24:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307176 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 04:24:35 -0000 Author: sephe Date: Thu Oct 13 04:24:34 2016 New Revision: 307176 URL: https://svnweb.freebsd.org/changeset/base/307176 Log: MFC 304724,304728 304724 hyperv/hn: Remove the redundant rid setting for RNDIS HALT. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7595 304728 hyperv/hn: Log a warning for RESET_CMPLT. RESET is not used by the hn(4) at all, and RESET_CMPLT does not even have a rid to match with the pending requests. So, let's put it onto an independent switch branch and log a warning about it. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7602 Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 03:23:43 2016 (r307175) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 04:24:34 2016 (r307176) @@ -325,16 +325,9 @@ hv_rf_receive_response(rndis_device *dev memcpy(&request->response_msg, response, response->msg_len); } else { - if (response->ndis_msg_type == REMOTE_NDIS_RESET_CMPLT) { - /* Does not have a request id field */ - request->response_msg.msg.reset_complete.status = - STATUS_BUFFER_OVERFLOW; - } else { - request->response_msg.msg.init_complete.status = - STATUS_BUFFER_OVERFLOW; - } + request->response_msg.msg.init_complete.status = + STATUS_BUFFER_OVERFLOW; } - sema_post(&request->wait_sema); } } @@ -567,29 +560,40 @@ hv_rf_on_receive(struct hn_softc *sc, st rndis_hdr = data; switch (rndis_hdr->ndis_msg_type) { - /* data message */ case REMOTE_NDIS_PACKET_MSG: hv_rf_receive_data(rxr, data, dlen); break; + /* completion messages */ case REMOTE_NDIS_INITIALIZE_CMPLT: case REMOTE_NDIS_QUERY_CMPLT: case REMOTE_NDIS_SET_CMPLT: - case REMOTE_NDIS_RESET_CMPLT: case REMOTE_NDIS_KEEPALIVE_CMPLT: hv_rf_receive_response(rndis_dev, rndis_hdr); break; + /* notification message */ case REMOTE_NDIS_INDICATE_STATUS_MSG: hv_rf_receive_indicate_status(rndis_dev, rndis_hdr); break; + + case REMOTE_NDIS_RESET_CMPLT: + /* + * Reset completed, no rid. + * + * NOTE: + * RESET is not issued by hn(4), so this message should + * _not_ be observed. + */ + if_printf(sc->hn_ifp, "RESET CMPLT received\n"); + break; + default: - printf("hv_rf_on_receive(): Unknown msg_type 0x%x\n", + if_printf(sc->hn_ifp, "unknown RNDIS message 0x%x\n", rndis_hdr->ndis_msg_type); break; } - return (0); } @@ -929,7 +933,6 @@ static int hv_rf_halt_device(rndis_device *device) { rndis_request *request; - rndis_halt_request *halt; int i, ret; /* Attempt to do a rndis device halt */ @@ -942,12 +945,6 @@ hv_rf_halt_device(rndis_device *device) /* initialize "poor man's semaphore" */ request->halt_complete_flag = 0; - /* Set up the rndis set */ - halt = &request->request_msg.msg.halt_request; - halt->request_id = atomic_fetchadd_int(&device->new_request_id, 1); - /* Increment to get the new value (call above returns old value) */ - halt->request_id += 1; - ret = hv_rf_send_request(device, request, REMOTE_NDIS_HALT_MSG); if (ret != 0) { return (-1); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 04:32:57 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 526ADC0F907; Thu, 13 Oct 2016 04:32:57 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1008C126; Thu, 13 Oct 2016 04:32:56 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D4WuRJ050592; Thu, 13 Oct 2016 04:32:56 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D4WtqT050586; Thu, 13 Oct 2016 04:32:55 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130432.u9D4WtqT050586@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 04:32:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307177 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 04:32:57 -0000 Author: sephe Date: Thu Oct 13 04:32:55 2016 New Revision: 307177 URL: https://svnweb.freebsd.org/changeset/base/307177 Log: MFC 304730 hyperv/ic: Redefine IC version negotiate message. And stringent input IC version negotiate message checks. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7614 Added: stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h - copied unchanged from r304730, head/sys/dev/hyperv/utilities/vmbus_icreg.h Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 04:24:34 2016 (r307176) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 04:32:55 2016 (r307177) @@ -80,7 +80,11 @@ hv_heartbeat_cb(struct vmbus_channel *ch &buf[sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, buf); + int error; + + error = vmbus_ic_negomsg(softc, buf, recvlen); + if (error) + return; } else { heartbeat_msg = (struct hv_vmbus_heartbeat_msg_data *) Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 04:24:34 2016 (r307176) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 04:32:55 2016 (r307177) @@ -85,7 +85,11 @@ hv_shutdown_cb(struct vmbus_channel *cha &buf[sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, buf); + int error; + + error = vmbus_ic_negomsg(softc, buf, recv_len); + if (error) + return; } else { shutdown_msg = (struct hv_vmbus_shutdown_msg_data *) Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 04:24:34 2016 (r307176) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 04:32:55 2016 (r307177) @@ -160,7 +160,11 @@ hv_timesync_cb(struct vmbus_channel *cha sizeof(struct hv_vmbus_pipe_hdr)]; if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_negotiate_version(icmsghdrp, time_buf); + int error; + + error = vmbus_ic_negomsg(&softc->util_sc, time_buf, recvlen); + if (error) + return; } else { timedatap = (struct hv_ictimesync_data *) &time_buf[ sizeof(struct hv_vmbus_pipe_hdr) + Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 04:24:34 2016 (r307176) +++ stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 04:32:55 2016 (r307177) @@ -36,44 +36,62 @@ #include #include #include +#include #include -#include #include #include -#include #include +#include #include "vmbus_if.h" #define VMBUS_IC_BRSIZE (4 * PAGE_SIZE) -void -hv_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf) +CTASSERT(sizeof(struct vmbus_icmsg_negotiate) < VMBUS_IC_BRSIZE); + +int +vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int dlen) { - struct hv_vmbus_icmsg_negotiate *negop; + struct vmbus_icmsg_negotiate *nego; + int cnt, major; - icmsghdrp->icmsgsize = 0x10; + /* + * Preliminary message size verification + */ + if (dlen < sizeof(*nego)) { + device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n", + dlen); + return EINVAL; + } + nego = data; - negop = (struct hv_vmbus_icmsg_negotiate *)&buf[ - sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; - - if (negop->icframe_vercnt >= 2 && - negop->icversion_data[1].major == 3) { - negop->icversion_data[0].major = 3; - negop->icversion_data[0].minor = 0; - negop->icversion_data[1].major = 3; - negop->icversion_data[1].minor = 0; - } else { - negop->icversion_data[0].major = 1; - negop->icversion_data[0].minor = 0; - negop->icversion_data[1].major = 1; - negop->icversion_data[1].minor = 0; + cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt; + if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) { + device_printf(sc->ic_dev, "ic negotiate does not contain " + "versions %d\n", dlen); + return EINVAL; } - negop->icframe_vercnt = 1; - negop->icmsg_vercnt = 1; + /* Select major version; XXX looks wrong. */ + if (nego->ic_fwver_cnt >= 2 && VMBUS_ICVER_MAJOR(nego->ic_ver[1]) == 3) + major = 3; + else + major = 1; + + /* One framework version */ + nego->ic_fwver_cnt = 1; + nego->ic_ver[0] = VMBUS_IC_VERSION(major, 0); + + /* One message version */ + nego->ic_msgver_cnt = 1; + nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0); + + /* Data contains two versions */ + nego->ic_hdr.ic_dsize = __offsetof(struct vmbus_icmsg_negotiate, + ic_ver[2]) - sizeof(struct vmbus_icmsg_hdr); + + return 0; } int @@ -101,6 +119,7 @@ hv_util_attach(device_t dev, vmbus_chan_ struct vmbus_channel *chan = vmbus_get_channel(dev); int error; + sc->ic_dev = dev; sc->ic_buflen = VMBUS_IC_BRSIZE; sc->receive_buffer = malloc(VMBUS_IC_BRSIZE, M_DEVBUF, M_WAITOK | M_ZERO); Modified: stable/10/sys/dev/hyperv/utilities/hv_util.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 04:24:34 2016 (r307176) +++ stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 04:32:55 2016 (r307177) @@ -39,6 +39,7 @@ * */ typedef struct hv_util_sc { + device_t ic_dev; uint8_t *receive_buffer; int ic_buflen; } hv_util_sc; @@ -50,10 +51,9 @@ struct vmbus_ic_desc { #define VMBUS_IC_DESC_END { .ic_desc = NULL } -void hv_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf); - int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); int hv_util_detach(device_t dev); int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]); +int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int dlen); #endif Copied: stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h (from r304730, head/sys/dev/hyperv/utilities/vmbus_icreg.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Oct 13 04:32:55 2016 (r307177, copy of r304730, head/sys/dev/hyperv/utilities/vmbus_icreg.h) @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2016 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _VMBUS_ICREG_H_ +#define _VMBUS_ICREG_H_ + +#define VMBUS_ICMSG_TYPE_NEGOTIATE 0 +#define VMBUS_ICMSG_TYPE_HEARTBEAT 1 +#define VMBUS_ICMSG_TYPE_KVP 2 +#define VMBUS_ICMSG_TYPE_SHUTDOWN 3 +#define VMBUS_ICMSG_TYPE_TIMESYNC 4 +#define VMBUS_ICMSG_TYPE_VSS 5 + +#define VMBUS_ICMSG_STATUS_OK 0x00000000 +#define VMBUS_ICMSG_STATUS_FAIL 0x80004005 + +#define VMBUS_IC_VERSION(major, minor) ((major) | (((uint32_t)(minor)) << 16)) +#define VMBUS_ICVER_MAJOR(ver) ((ver) & 0xffff) +#define VMBUS_ICVER_MINOR(ver) (((ver) & 0xffff0000) >> 16) + +struct vmbus_pipe_hdr { + uint32_t ph_flags; + uint32_t ph_msgsz; +} __packed; + +struct vmbus_icmsg_hdr { + struct vmbus_pipe_hdr ic_pipe; + uint32_t ic_fwver; /* framework version */ + uint16_t ic_type; + uint32_t ic_msgver; /* message version */ + uint16_t ic_dsize; /* data size */ + uint32_t ic_status; /* VMBUS_ICMSG_STATUS_ */ + uint8_t ic_xactid; + uint8_t ic_flags; /* VMBUS_ICMSG_FLAG_ */ + uint8_t ic_rsvd[2]; +} __packed; + +#define VMBUS_ICMSG_FLAG_XACT 0x0001 +#define VMBUS_ICMSG_FLAG_REQ 0x0002 +#define VMBUS_ICMSG_FLAG_RESP 0x0004 + +/* VMBUS_ICMSG_TYPE_NEGOTIATE */ +struct vmbus_icmsg_negotiate { + struct vmbus_icmsg_hdr ic_hdr; + uint16_t ic_fwver_cnt; + uint16_t ic_msgver_cnt; + uint32_t ic_rsvd; + /* + * This version array contains two set of supported + * versions: + * - The first set consists of #ic_fwver_cnt supported framework + * versions. + * - The second set consists of #ic_msgver_cnt supported message + * versions. + */ + uint32_t ic_ver[]; +} __packed; + +#endif /* !_VMBUS_ICREG_H_ */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 05:20:33 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0D416C0F245; Thu, 13 Oct 2016 05:20:33 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CEB892CC; Thu, 13 Oct 2016 05:20:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D5KWuF065857; Thu, 13 Oct 2016 05:20:32 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D5KVc5065850; Thu, 13 Oct 2016 05:20:31 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130520.u9D5KVc5065850@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 05:20:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307178 - in stable/10/sys: dev/hyperv/netvsc net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 05:20:33 -0000 Author: sephe Date: Thu Oct 13 05:20:31 2016 New Revision: 307178 URL: https://svnweb.freebsd.org/changeset/base/307178 Log: MFC 304783-304785 304783 hyperv/hn: Use definition in net/rndis.h for message type and status code. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7620 304784 hyperv/hn: Add compat code for RNDIS reorganization phase. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7621 304785 hyperv/hn: Use vmbus xact for RNDIS initialize. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7624 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnvar.h stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 05:20:31 2016 (r307178) @@ -76,7 +76,7 @@ static void hn_nvs_sent_none(struct hn_s static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc, struct vmbus_channel *, const void *, int); -static struct hn_send_ctx hn_send_ctx_none = +struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); uint32_t Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 05:20:31 2016 (r307178) @@ -239,6 +239,11 @@ typedef struct { uint8_t link_state; } netvsc_device_info; +#define HN_XACT_REQ_PGCNT 2 +#define HN_XACT_RESP_PGCNT 2 +#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE) +#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE) + #ifndef HN_USE_TXDESC_BUFRING struct hn_txdesc; SLIST_HEAD(hn_txdesc_list, hn_txdesc); @@ -376,6 +381,8 @@ typedef struct hn_softc { uint32_t hn_chim_gpadl; struct hyperv_dma hn_chim_dma; + + uint32_t hn_rndis_rid; } hn_softc_t; #define HN_FLAG_RXBUF_CONNECTED 0x0001 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 05:20:31 2016 (r307178) @@ -127,9 +127,6 @@ __FBSDID("$FreeBSD$"); /* Short for Hyper-V network interface */ #define NETVSC_DEVNAME "hn" -#define HN_XACT_REQ_SIZE (2 * PAGE_SIZE) -#define HN_XACT_RESP_SIZE (2 * PAGE_SIZE) - /* * It looks like offset 0 of buf is reserved to hold the softc pointer. * The sc pointer evidently not needed, and is not presently populated. Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 05:20:31 2016 (r307178) @@ -31,6 +31,7 @@ #ifndef __HV_RNDIS_H__ #define __HV_RNDIS_H__ +#include /* * NDIS protocol version numbers @@ -48,95 +49,6 @@ #define NDIS_VERSION (NDIS_VERSION_5_1) /* - * Status codes - */ - -#define STATUS_SUCCESS (0x00000000L) -#define STATUS_UNSUCCESSFUL (0xC0000001L) -#define STATUS_PENDING (0x00000103L) -#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) -#define STATUS_BUFFER_OVERFLOW (0x80000005L) -#define STATUS_NOT_SUPPORTED (0xC00000BBL) - -#define RNDIS_STATUS_SUCCESS (STATUS_SUCCESS) -#define RNDIS_STATUS_PENDING (STATUS_PENDING) -#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001L) -#define RNDIS_STATUS_NOT_COPIED (0x00010002L) -#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003L) -#define RNDIS_STATUS_CALL_ACTIVE (0x00010007L) - -#define RNDIS_STATUS_ONLINE (0x40010003L) -#define RNDIS_STATUS_RESET_START (0x40010004L) -#define RNDIS_STATUS_RESET_END (0x40010005L) -#define RNDIS_STATUS_RING_STATUS (0x40010006L) -#define RNDIS_STATUS_CLOSED (0x40010007L) -#define RNDIS_STATUS_WAN_LINE_UP (0x40010008L) -#define RNDIS_STATUS_WAN_LINE_DOWN (0x40010009L) -#define RNDIS_STATUS_WAN_FRAGMENT (0x4001000AL) -#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BL) -#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CL) -#define RNDIS_STATUS_HARDWARE_LINE_UP (0x4001000DL) -#define RNDIS_STATUS_HARDWARE_LINE_DOWN (0x4001000EL) -#define RNDIS_STATUS_INTERFACE_UP (0x4001000FL) -#define RNDIS_STATUS_INTERFACE_DOWN (0x40010010L) -#define RNDIS_STATUS_MEDIA_BUSY (0x40010011L) -#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION (0x40010012L) -#define RNDIS_STATUS_WW_INDICATION RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION -#define RNDIS_STATUS_LINK_SPEED_CHANGE (0x40010013L) - -#define RNDIS_STATUS_NOT_RESETTABLE (0x80010001L) -#define RNDIS_STATUS_SOFT_ERRORS (0x80010003L) -#define RNDIS_STATUS_HARD_ERRORS (0x80010004L) -#define RNDIS_STATUS_BUFFER_OVERFLOW (STATUS_BUFFER_OVERFLOW) - -#define RNDIS_STATUS_FAILURE (STATUS_UNSUCCESSFUL) -#define RNDIS_STATUS_RESOURCES (STATUS_INSUFFICIENT_RESOURCES) -#define RNDIS_STATUS_CLOSING (0xC0010002L) -#define RNDIS_STATUS_BAD_VERSION (0xC0010004L) -#define RNDIS_STATUS_BAD_CHARACTERISTICS (0xC0010005L) -#define RNDIS_STATUS_ADAPTER_NOT_FOUND (0xC0010006L) -#define RNDIS_STATUS_OPEN_FAILED (0xC0010007L) -#define RNDIS_STATUS_DEVICE_FAILED (0xC0010008L) -#define RNDIS_STATUS_MULTICAST_FULL (0xC0010009L) -#define RNDIS_STATUS_MULTICAST_EXISTS (0xC001000AL) -#define RNDIS_STATUS_MULTICAST_NOT_FOUND (0xC001000BL) -#define RNDIS_STATUS_REQUEST_ABORTED (0xC001000CL) -#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DL) -#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EL) -#define RNDIS_STATUS_NOT_SUPPORTED (STATUS_NOT_SUPPORTED) -#define RNDIS_STATUS_INVALID_PACKET (0xC001000FL) -#define RNDIS_STATUS_OPEN_LIST_FULL (0xC0010010L) -#define RNDIS_STATUS_ADAPTER_NOT_READY (0xC0010011L) -#define RNDIS_STATUS_ADAPTER_NOT_OPEN (0xC0010012L) -#define RNDIS_STATUS_NOT_INDICATING (0xC0010013L) -#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014L) -#define RNDIS_STATUS_INVALID_DATA (0xC0010015L) -#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016L) -#define RNDIS_STATUS_INVALID_OID (0xC0010017L) -#define RNDIS_STATUS_ADAPTER_REMOVED (0xC0010018L) -#define RNDIS_STATUS_UNSUPPORTED_MEDIA (0xC0010019L) -#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE (0xC001001AL) -#define RNDIS_STATUS_FILE_NOT_FOUND (0xC001001BL) -#define RNDIS_STATUS_ERROR_READING_FILE (0xC001001CL) -#define RNDIS_STATUS_ALREADY_MAPPED (0xC001001DL) -#define RNDIS_STATUS_RESOURCE_CONFLICT (0xC001001EL) -#define RNDIS_STATUS_NO_CABLE (0xC001001FL) - -#define RNDIS_STATUS_INVALID_SAP (0xC0010020L) -#define RNDIS_STATUS_SAP_IN_USE (0xC0010021L) -#define RNDIS_STATUS_INVALID_ADDRESS (0xC0010022L) -#define RNDIS_STATUS_VC_NOT_ACTIVATED (0xC0010023L) -#define RNDIS_STATUS_DEST_OUT_OF_ORDER (0xC0010024L) -#define RNDIS_STATUS_VC_NOT_AVAILABLE (0xC0010025L) -#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE (0xC0010026L) -#define RNDIS_STATUS_INCOMPATABLE_QOS (0xC0010027L) -#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED (0xC0010028L) -#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION (0xC0010029L) - -#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR (0xC0011000L) - - -/* * Object Identifiers used by NdisRequest Query/Set Information */ @@ -289,82 +201,6 @@ */ #define OID_RNDISMP_GET_RECEIVE_BUFFERS 0xFFA0C90D // Query only - -/* - * Remote NDIS message types - */ -#define REMOTE_NDIS_PACKET_MSG 0x00000001 -#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002 -#define REMOTE_NDIS_HALT_MSG 0x00000003 -#define REMOTE_NDIS_QUERY_MSG 0x00000004 -#define REMOTE_NDIS_SET_MSG 0x00000005 -#define REMOTE_NDIS_RESET_MSG 0x00000006 -#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007 -#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008 - -#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001 -#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006 -#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007 - -/* - * Remote NDIS message completion types - */ -#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002 -#define REMOTE_NDIS_QUERY_CMPLT 0x80000004 -#define REMOTE_NDIS_SET_CMPLT 0x80000005 -#define REMOTE_NDIS_RESET_CMPLT 0x80000006 -#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008 - -#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001 -#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006 - -/* - * Reserved message type for private communication between lower-layer - * host driver and remote device, if necessary. - */ -#define REMOTE_NDIS_BUS_MSG 0xff000001 - -/* - * Defines for DeviceFlags in rndis_initialize_complete - */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001 -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 -#define RNDIS_DF_RAW_DATA 0x00000004 - -/* - * Remote NDIS medium types. - */ -#define RNDIS_MEDIUM_802_3 0x00000000 -#define RNDIS_MEDIUM_802_5 0x00000001 -#define RNDIS_MEDIUM_FDDI 0x00000002 -#define RNDIS_MEDIUM_WAN 0x00000003 -#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 -#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 -#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 -#define RNDIS_MEDIUM_ATM 0x00000008 -#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009 -#define RNDIS_MEDIUM_IRDA 0x0000000a -#define RNDIS_MEDIUM_CO_WAN 0x0000000b -/* Not a real medium, defined as an upper bound */ -#define RNDIS_MEDIUM_MAX 0x0000000d - -/* - * Remote NDIS medium connection states. - */ -#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 -#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 - -/* - * Remote NDIS version numbers - */ -#define RNDIS_MAJOR_VERSION 0x00000001 -#define RNDIS_MINOR_VERSION 0x00000000 - - /* * Remote NDIS offload parameters */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 05:20:31 2016 (r307178) @@ -63,6 +63,11 @@ __FBSDID("$FreeBSD$"); HV_RF_RECVINFO_HASHINF | \ HV_RF_RECVINFO_HASHVAL) +#define HN_RNDIS_RID_COMPAT_MASK 0xffff +#define HN_RNDIS_RID_COMPAT_MAX HN_RNDIS_RID_COMPAT_MASK + +#define HN_RNDIS_XFER_SIZE 2048 + /* * Forward declarations */ @@ -93,6 +98,20 @@ static void hn_rndis_sent_cb(struct hn_s struct hn_softc *sc, struct vmbus_channel *chan, const void *data, int dlen); +static __inline uint32_t +hn_rndis_rid(struct hn_softc *sc) +{ + uint32_t rid; + +again: + rid = atomic_fetchadd_int(&sc->hn_rndis_rid, 1); + if (rid == 0) + goto again; + + /* Use upper 16 bits for non-compat RNDIS messages. */ + return ((rid & 0xffff) << 16); +} + /* * Set the Per-Packet-Info with the specified type */ @@ -203,9 +222,8 @@ hv_rndis_request(rndis_device *device, u * as a template. */ set = &rndis_mesg->msg.set_request; - set->request_id = atomic_fetchadd_int(&device->new_request_id, 1); - /* Increment to get the new value (call above returns old value) */ - set->request_id += 1; + set->request_id = atomic_fetchadd_int(&device->new_request_id, 1) & + HN_RNDIS_RID_COMPAT_MASK; /* Add to the request list */ mtx_lock(&device->req_lock); @@ -326,7 +344,7 @@ hv_rf_receive_response(rndis_device *dev response->msg_len); } else { request->response_msg.msg.init_complete.status = - STATUS_BUFFER_OVERFLOW; + RNDIS_STATUS_BUFFER_OVERFLOW; } sema_post(&request->wait_sema); } @@ -390,7 +408,7 @@ hv_rf_send_offload_request(struct hn_sof device_printf(dev, "hv send offload request succeeded\n"); ret = 0; } else { - if (set_complete->status == STATUS_NOT_SUPPORTED) { + if (set_complete->status == RNDIS_STATUS_NOT_SUPPORTED) { device_printf(dev, "HV Not support offload\n"); ret = 0; } else { @@ -553,6 +571,7 @@ hv_rf_on_receive(struct hn_softc *sc, st { rndis_device *rndis_dev; const rndis_msg *rndis_hdr; + const struct rndis_comp_hdr *comp; rndis_dev = sc->rndis_dev; if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) @@ -570,7 +589,13 @@ hv_rf_on_receive(struct hn_softc *sc, st case REMOTE_NDIS_QUERY_CMPLT: case REMOTE_NDIS_SET_CMPLT: case REMOTE_NDIS_KEEPALIVE_CMPLT: - hv_rf_receive_response(rndis_dev, rndis_hdr); + comp = data; + if (comp->rm_rid <= HN_RNDIS_RID_COMPAT_MAX) { + /* Transition time compat code */ + hv_rf_receive_response(rndis_dev, rndis_hdr); + } else { + vmbus_xact_ctx_wakeup(sc->hn_xact, data, dlen); + } break; /* notification message */ @@ -866,62 +891,139 @@ exit: return (ret); } -/* - * RNDIS filter init device - */ -static int -hv_rf_init_device(rndis_device *device) -{ - rndis_request *request; - rndis_initialize_request *init; - rndis_initialize_complete *init_complete; - uint32_t status; - int ret; +static const void * +hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid, + size_t reqlen, size_t min_complen, uint32_t comp_type) +{ + struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT]; + const struct rndis_comp_hdr *comp; + bus_addr_t paddr; + size_t comp_len; + int gpa_cnt, error; + + KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid)); + KASSERT(reqlen <= HN_XACT_REQ_SIZE && reqlen > 0, + ("invalid request length %zu", reqlen)); + KASSERT(min_complen >= sizeof(*comp), + ("invalid minimum complete len %zu", min_complen)); - request = hv_rndis_request(device, REMOTE_NDIS_INITIALIZE_MSG, - RNDIS_MESSAGE_SIZE(rndis_initialize_request)); - if (!request) { - ret = -1; - goto cleanup; + /* + * Setup the SG list. + */ + paddr = vmbus_xact_req_paddr(xact); + KASSERT((paddr & PAGE_MASK) == 0, + ("vmbus xact request is not page aligned 0x%jx", (uintmax_t)paddr)); + for (gpa_cnt = 0; gpa_cnt < HN_XACT_REQ_PGCNT; ++gpa_cnt) { + int len = PAGE_SIZE; + + if (reqlen == 0) + break; + if (reqlen < len) + len = reqlen; + + gpa[gpa_cnt].gpa_page = atop(paddr) + gpa_cnt; + gpa[gpa_cnt].gpa_len = len; + gpa[gpa_cnt].gpa_ofs = 0; + + reqlen -= len; } + KASSERT(reqlen == 0, ("still have %zu request data left", reqlen)); - /* Set up the rndis set */ - init = &request->request_msg.msg.init_request; - init->major_version = RNDIS_MAJOR_VERSION; - init->minor_version = RNDIS_MINOR_VERSION; /* - * Per the RNDIS document, this should be set to the max MTU - * plus the header size. However, 2048 works fine, so leaving - * it as is. + * Send this RNDIS control message and wait for its completion + * message. */ - init->max_xfer_size = 2048; - - device->state = RNDIS_DEV_INITIALIZING; + vmbus_xact_activate(xact); + error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, + &hn_send_ctx_none, gpa, gpa_cnt); + if (error) { + vmbus_xact_deactivate(xact); + if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error); + return (NULL); + } + comp = vmbus_xact_wait(xact, &comp_len); - ret = hv_rf_send_request(device, request, REMOTE_NDIS_INITIALIZE_MSG); - if (ret != 0) { - device->state = RNDIS_DEV_UNINITIALIZED; - goto cleanup; + /* + * Check this RNDIS complete message. + */ + if (comp_len < min_complen) { + if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n", comp_len); + return (NULL); + } + if (comp->rm_len < min_complen) { + if_printf(sc->hn_ifp, "invalid RNDIS comp msglen %u\n", + comp->rm_len); + return (NULL); + } + if (comp->rm_type != comp_type) { + if_printf(sc->hn_ifp, "unexpected RNDIS comp 0x%08x, " + "expect 0x%08x\n", comp->rm_type, comp_type); + return (NULL); + } + if (comp->rm_rid != rid) { + if_printf(sc->hn_ifp, "RNDIS comp rid mismatch %u, " + "expect %u\n", comp->rm_rid, rid); + return (NULL); } + /* All pass! */ + return (comp); +} - sema_wait(&request->wait_sema); +/* + * RNDIS filter init device + */ +static int +hv_rf_init_device(rndis_device *device) +{ + struct hn_softc *sc = device->sc; + struct rndis_init_req *req; + const struct rndis_init_comp *comp; + struct vmbus_xact *xact; + uint32_t rid; + int error; - init_complete = &request->response_msg.msg.init_complete; - status = init_complete->status; - if (status == RNDIS_STATUS_SUCCESS) { - device->state = RNDIS_DEV_INITIALIZED; - ret = 0; - } else { - device->state = RNDIS_DEV_UNINITIALIZED; - ret = -1; - } + /* XXX */ + device->state = RNDIS_DEV_INITIALIZED; -cleanup: - if (request) { - hv_put_rndis_request(device, request); + xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for RNDIS init\n"); + return (ENXIO); + } + rid = hn_rndis_rid(sc); + req = vmbus_xact_req_data(xact); + req->rm_type = REMOTE_NDIS_INITIALIZE_MSG; + req->rm_len = sizeof(*req); + req->rm_rid = rid; + req->rm_ver_major = RNDIS_VERSION_MAJOR; + req->rm_ver_minor = RNDIS_VERSION_MINOR; + req->rm_max_xfersz = HN_RNDIS_XFER_SIZE; + + comp = hn_rndis_xact_execute(sc, xact, rid, sizeof(*req), + RNDIS_INIT_COMP_SIZE_MIN, REMOTE_NDIS_INITIALIZE_CMPLT); + if (comp == NULL) { + if_printf(sc->hn_ifp, "exec RNDIS init failed\n"); + error = EIO; + goto done; + } + + if (comp->rm_status != RNDIS_STATUS_SUCCESS) { + if_printf(sc->hn_ifp, "RNDIS init failed: status 0x%08x\n", + comp->rm_status); + error = EIO; + goto done; + } + if (bootverbose) { + if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u\n", + comp->rm_ver_major, comp->rm_ver_minor, + comp->rm_pktmaxsz, comp->rm_pktmaxcnt); } + error = 0; - return (ret); +done: + if (xact != NULL) + vmbus_xact_put(xact); + return (error); } #define HALT_COMPLETION_WAIT_COUNT 25 Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 05:20:31 2016 (r307178) @@ -115,4 +115,6 @@ const void *hn_nvs_xact_execute(struct h uint32_t hn_chim_alloc(struct hn_softc *sc); void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); +extern struct hn_send_ctx hn_send_ctx_none; + #endif /* !_IF_HNVAR_H_ */ Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 04:32:55 2016 (r307177) +++ stable/10/sys/net/rndis.h Thu Oct 13 05:20:31 2016 (r307178) @@ -146,6 +146,9 @@ struct rndis_init_comp { uint32_t rm_aflistsz; }; +#define RNDIS_INIT_COMP_SIZE_MIN \ + __offsetof(struct rndis_init_comp, rm_aflistsz) + /* Halt the device. No response sent. */ #define REMOTE_NDIS_HALT_MSG 0x00000003 From owner-svn-src-stable-10@freebsd.org Thu Oct 13 05:59:34 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E347EC0F8EC; Thu, 13 Oct 2016 05:59:34 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BABB3221; Thu, 13 Oct 2016 05:59:34 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D5xXlk080941; Thu, 13 Oct 2016 05:59:33 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D5xXT5080935; Thu, 13 Oct 2016 05:59:33 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130559.u9D5xXT5080935@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 05:59:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307179 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 05:59:35 -0000 Author: sephe Date: Thu Oct 13 05:59:33 2016 New Revision: 307179 URL: https://svnweb.freebsd.org/changeset/base/307179 Log: MFC 304786,304788 304786 hyperv/ic: Cleanup heartbeat channel callback. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7626 304788 hyperv/ic: Update total message size if negotiate message size grows. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7627 Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/hv_util.c stable/10/sys/dev/hyperv/utilities/hv_util.h stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 05:59:33 2016 (r307179) @@ -22,23 +22,22 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ +#include +__FBSDID("$FreeBSD$"); + #include -#include #include -#include +#include #include -#include -#include #include #include #include -#include -#include "hv_util.h" +#include +#include + #include "vmbus_if.h" static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = { @@ -51,55 +50,64 @@ static const struct vmbus_ic_desc vmbus_ VMBUS_IC_DESC_END }; -/** - * Process heartbeat message - */ static void -hv_heartbeat_cb(struct vmbus_channel *channel, void *context) +vmbus_heartbeat_cb(struct vmbus_channel *chan, void *xsc) { - uint8_t* buf; - int recvlen; - uint64_t requestid; - int ret; - - struct hv_vmbus_heartbeat_msg_data* heartbeat_msg; - struct hv_vmbus_icmsg_hdr* icmsghdrp; - hv_util_sc *softc; - - softc = (hv_util_sc*)context; - buf = softc->receive_buffer;; - - recvlen = softc->ic_buflen; - ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid); - KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough")); - /* XXX check recvlen to make sure that it contains enough data */ - - if ((ret == 0) && recvlen > 0) { - - icmsghdrp = (struct hv_vmbus_icmsg_hdr *) - &buf[sizeof(struct hv_vmbus_pipe_hdr)]; - - if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - int error; + struct hv_util_sc *sc = xsc; + struct vmbus_icmsg_hdr *hdr; + int dlen, error; + uint64_t xactid; + void *data; + + /* + * Receive request. + */ + data = sc->receive_buffer; + dlen = sc->ic_buflen; + error = vmbus_chan_recv(chan, data, &dlen, &xactid); + KASSERT(error != ENOBUFS, ("icbuf is not large enough")); + if (error) + return; + + if (dlen < sizeof(struct vmbus_icmsg_hdr)) { + device_printf(sc->ic_dev, "invalid data len %d\n", dlen); + return; + } + hdr = data; - error = vmbus_ic_negomsg(softc, buf, recvlen); + /* + * Update request, which will be echoed back as response. + */ + switch (hdr->ic_type) { + case VMBUS_ICMSG_TYPE_NEGOTIATE: + error = vmbus_ic_negomsg(sc, data, &dlen); if (error) return; - } else { - heartbeat_msg = - (struct hv_vmbus_heartbeat_msg_data *) - &buf[sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; - - heartbeat_msg->seq_num += 1; - } + break; - icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | - HV_ICMSGHDRFLAG_RESPONSE; - - vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, - buf, recvlen, requestid); + case VMBUS_ICMSG_TYPE_HEARTBEAT: + /* Only ic_seq is a must */ + if (dlen < VMBUS_ICMSG_HEARTBEAT_SIZE_MIN) { + device_printf(sc->ic_dev, "invalid heartbeat len %d\n", + dlen); + return; + } + ((struct vmbus_icmsg_heartbeat *)data)->ic_seq++; + break; + + default: + device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type); + break; } + + /* + * Send response by echoing the updated request back. + */ + hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP; + error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0, + data, dlen, xactid); + if (error) + device_printf(sc->ic_dev, "resp send failed: %d\n", error); } static int @@ -112,7 +120,8 @@ hv_heartbeat_probe(device_t dev) static int hv_heartbeat_attach(device_t dev) { - return hv_util_attach(dev, hv_heartbeat_cb); + + return (hv_util_attach(dev, vmbus_heartbeat_cb)); } static device_method_t heartbeat_methods[] = { Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 05:59:33 2016 (r307179) @@ -87,7 +87,7 @@ hv_shutdown_cb(struct vmbus_channel *cha if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { int error; - error = vmbus_ic_negomsg(softc, buf, recv_len); + error = vmbus_ic_negomsg(softc, buf, &recv_len); if (error) return; } else { Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 05:59:33 2016 (r307179) @@ -162,7 +162,7 @@ hv_timesync_cb(struct vmbus_channel *cha if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { int error; - error = vmbus_ic_negomsg(&softc->util_sc, time_buf, recvlen); + error = vmbus_ic_negomsg(&softc->util_sc, time_buf, &recvlen); if (error) return; } else { Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/hv_util.c Thu Oct 13 05:59:33 2016 (r307179) @@ -48,13 +48,16 @@ #define VMBUS_IC_BRSIZE (4 * PAGE_SIZE) -CTASSERT(sizeof(struct vmbus_icmsg_negotiate) < VMBUS_IC_BRSIZE); +#define VMBUS_IC_VERCNT 2 +#define VMBUS_IC_NEGOSZ \ + __offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT]) +CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE); int -vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int dlen) +vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0) { struct vmbus_icmsg_negotiate *nego; - int cnt, major; + int cnt, major, dlen = *dlen0; /* * Preliminary message size verification @@ -87,9 +90,13 @@ vmbus_ic_negomsg(struct hv_util_sc *sc, nego->ic_msgver_cnt = 1; nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0); - /* Data contains two versions */ - nego->ic_hdr.ic_dsize = __offsetof(struct vmbus_icmsg_negotiate, - ic_ver[2]) - sizeof(struct vmbus_icmsg_hdr); + /* Update data size */ + nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ - + sizeof(struct vmbus_icmsg_hdr); + + /* Update total size, if necessary */ + if (dlen < VMBUS_IC_NEGOSZ) + *dlen0 = VMBUS_IC_NEGOSZ; return 0; } Modified: stable/10/sys/dev/hyperv/utilities/hv_util.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/hv_util.h Thu Oct 13 05:59:33 2016 (r307179) @@ -54,6 +54,6 @@ struct vmbus_ic_desc { int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); int hv_util_detach(device_t dev); int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]); -int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int dlen); +int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int *dlen); #endif Modified: stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Oct 13 05:20:31 2016 (r307178) +++ stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Oct 13 05:59:33 2016 (r307179) @@ -81,4 +81,14 @@ struct vmbus_icmsg_negotiate { uint32_t ic_ver[]; } __packed; +/* VMBUS_ICMSG_TYPE_HEARTBEAT */ +struct vmbus_icmsg_heartbeat { + struct vmbus_icmsg_hdr ic_hdr; + uint64_t ic_seq; + uint32_t ic_rsvd[8]; +} __packed; + +#define VMBUS_ICMSG_HEARTBEAT_SIZE_MIN \ + __offsetof(struct vmbus_icmsg_heartbeat, ic_rsvd[0]) + #endif /* !_VMBUS_ICREG_H_ */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:09:28 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 03821C0FB3F; Thu, 13 Oct 2016 06:09:28 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BDDE59B6; Thu, 13 Oct 2016 06:09:27 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D69R9J084838; Thu, 13 Oct 2016 06:09:27 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D69QNh084833; Thu, 13 Oct 2016 06:09:26 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130609.u9D69QNh084833@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:09:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307180 - in stable/10/sys/dev/hyperv: include storvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:09:28 -0000 Author: sephe Date: Thu Oct 13 06:09:26 2016 New Revision: 307180 URL: https://svnweb.freebsd.org/changeset/base/307180 Log: MFC 304790,304791 304790 hyperv/vmbus: Add function to calculate max # of elements in a bufring. Sponsored by: Microsoft 304791 hyperv/storvsc: Increase queue depth and rework channel selection. - Increasing queue depth gives ~100% performance improvement for randwrite fio test in Azure. - New channel selection, which takes LUN id and the current cpuid into consideration, gives additional ~20% performance improvement for ranwrite fio test in Azure. Submitted by: Hongzhang Jiang Modified by: sephe Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7622 Modified: stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 05:59:33 2016 (r307179) +++ stable/10/sys/dev/hyperv/include/vmbus.h Thu Oct 13 06:09:26 2016 (r307180) @@ -162,5 +162,7 @@ uint32_t vmbus_chan_subidx(const struct bool vmbus_chan_is_primary(const struct vmbus_channel *chan); const struct hyperv_guid * vmbus_chan_guid_inst(const struct vmbus_channel *chan); +int vmbus_chan_prplist_nelem(int br_size, int prpcnt_max, + int dlen_max); #endif /* !_VMBUS_H_ */ Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Thu Oct 13 05:59:33 2016 (r307179) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Thu Oct 13 06:09:26 2016 (r307180) @@ -75,11 +75,9 @@ __FBSDID("$FreeBSD$"); #include #include - #include "hv_vstorage.h" #include "vmbus_if.h" -#define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE) #define STORVSC_MAX_LUNS_PER_TARGET (64) #define STORVSC_MAX_IO_REQUESTS (STORVSC_MAX_LUNS_PER_TARGET * 2) #define BLKVSC_MAX_IDE_DISKS_PER_TARGET (1) @@ -121,8 +119,6 @@ struct hv_sgl_page_pool{ boolean_t is_init; } g_hv_sgl_page_pool; -#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * STORVSC_DATA_SEGCNT_MAX - enum storvsc_request_type { WRITE_TYPE, READ_TYPE, @@ -130,17 +126,35 @@ enum storvsc_request_type { }; SYSCTL_NODE(_hw, OID_AUTO, storvsc, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, - "Hyper-V storage interface"); + "Hyper-V storage interface"); + +static u_int hv_storvsc_use_win8ext_flags = 1; +SYSCTL_UINT(_hw_storvsc, OID_AUTO, use_win8ext_flags, CTLFLAG_RW, + &hv_storvsc_use_win8ext_flags, 0, + "Use win8 extension flags or not"); static u_int hv_storvsc_use_pim_unmapped = 1; -SYSCTL_INT(_hw_storvsc, OID_AUTO, use_pim_unmapped, CTLFLAG_RDTUN, - &hv_storvsc_use_pim_unmapped, 0, - "Optimize storvsc by using unmapped I/O"); +SYSCTL_UINT(_hw_storvsc, OID_AUTO, use_pim_unmapped, CTLFLAG_RDTUN, + &hv_storvsc_use_pim_unmapped, 0, + "Optimize storvsc by using unmapped I/O"); + +static u_int hv_storvsc_ringbuffer_size = (64 * PAGE_SIZE); +SYSCTL_UINT(_hw_storvsc, OID_AUTO, ringbuffer_size, CTLFLAG_RDTUN, + &hv_storvsc_ringbuffer_size, 0, "Hyper-V storage ringbuffer size"); + +static u_int hv_storvsc_max_io = 512; +SYSCTL_UINT(_hw_storvsc, OID_AUTO, max_io, CTLFLAG_RDTUN, + &hv_storvsc_max_io, 0, "Hyper-V storage max io limit"); + +#define STORVSC_MAX_IO \ + vmbus_chan_prplist_nelem(hv_storvsc_ringbuffer_size, \ + STORVSC_DATA_SEGCNT_MAX, VSTOR_PKT_SIZE) struct hv_storvsc_sysctl { u_long data_bio_cnt; u_long data_vaddr_cnt; u_long data_sg_cnt; + u_long chan_send_cnt[MAXCPU]; }; struct storvsc_gpa_range { @@ -184,10 +198,18 @@ struct storvsc_softc { device_t hs_dev; bus_dma_tag_t storvsc_req_dtag; struct hv_storvsc_sysctl sysctl_data; - - struct vmbus_channel *hs_cpu2chan[MAXCPU]; + uint32_t hs_nchan; + struct vmbus_channel *hs_sel_chan[MAXCPU]; }; +/* + * The size of the vmscsi_request has changed in win8. The + * additional size is for the newly added elements in the + * structure. These elements are valid only when we are talking + * to a win8 host. + * Track the correct size we need to apply. + */ +static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); /** * HyperV storvsc timeout testing cases: @@ -211,7 +233,7 @@ struct storvsc_driver_props { char *drv_name; char *drv_desc; uint8_t drv_max_luns_per_target; - uint8_t drv_max_ios_per_target; + uint32_t drv_max_ios_per_target; uint32_t drv_ringbuffer_size; }; @@ -240,10 +262,10 @@ static const struct hyperv_guid gBlkVscD static struct storvsc_driver_props g_drv_props_table[] = { {"blkvsc", "Hyper-V IDE Storage Interface", BLKVSC_MAX_IDE_DISKS_PER_TARGET, BLKVSC_MAX_IO_REQUESTS, - STORVSC_RINGBUFFER_SIZE}, + 20*PAGE_SIZE}, {"storvsc", "Hyper-V SCSI Storage Interface", STORVSC_MAX_LUNS_PER_TARGET, STORVSC_MAX_IO_REQUESTS, - STORVSC_RINGBUFFER_SIZE} + 20*PAGE_SIZE} }; /* @@ -253,14 +275,6 @@ static struct storvsc_driver_props g_drv static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; /* - * The size of the vmscsi_request has changed in win8. The - * additional size is for the newly added elements in the - * structure. These elements are valid only when we are talking - * to a win8 host. - * Track the correct size we need to apply. - */ -static int vmscsi_size_delta; -/* * The storage protocol version is determined during the * initial exchange with the host. It will indicate which * storage functionality is available in the host. @@ -413,6 +427,9 @@ storvsc_send_multichannel_request(struct return; } + /* Update channel count */ + sc->hs_nchan = request_channels_cnt + 1; + /* Wait for sub-channels setup to complete. */ subchan = vmbus_subchan_get(sc->hs_chan, request_channels_cnt); @@ -585,7 +602,6 @@ hv_storvsc_channel_init(struct storvsc_s */ if (support_multichannel) storvsc_send_multichannel_request(sc, max_chans); - cleanup: sema_destroy(&request->synch_sema); return (ret); @@ -624,7 +640,6 @@ hv_storvsc_connect_vsp(struct storvsc_so } ret = hv_storvsc_channel_init(sc); - return (ret); } @@ -686,7 +701,7 @@ hv_storvsc_io_request(struct storvsc_sof { struct vstor_packet *vstor_packet = &request->vstor_packet; struct vmbus_channel* outgoing_channel = NULL; - int ret = 0; + int ret = 0, ch_sel; vstor_packet->flags |= REQUEST_COMPLETION_FLAG; @@ -700,7 +715,8 @@ hv_storvsc_io_request(struct storvsc_sof vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB; - outgoing_channel = sc->hs_cpu2chan[curcpu]; + ch_sel = (vstor_packet->u.vm_srb.lun + curcpu) % sc->hs_nchan; + outgoing_channel = sc->hs_sel_chan[ch_sel]; mtx_unlock(&request->softc->hs_lock); if (request->prp_list.gpa_range.gpa_len) { @@ -712,6 +728,10 @@ hv_storvsc_io_request(struct storvsc_sof VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request); } + /* statistic for successful request sending on each channel */ + if (!ret) { + sc->sysctl_data.chan_send_cnt[ch_sel]++; + } mtx_lock(&request->softc->hs_lock); if (ret != 0) { @@ -907,17 +927,20 @@ storvsc_probe(device_t dev) } static void -storvsc_create_cpu2chan(struct storvsc_softc *sc) +storvsc_create_chan_sel(struct storvsc_softc *sc) { - int cpu; + struct vmbus_channel **subch; + int i, nsubch; - CPU_FOREACH(cpu) { - sc->hs_cpu2chan[cpu] = vmbus_chan_cpu2chan(sc->hs_chan, cpu); - if (bootverbose) { - device_printf(sc->hs_dev, "cpu%d -> chan%u\n", - cpu, vmbus_chan_id(sc->hs_cpu2chan[cpu])); - } - } + sc->hs_sel_chan[0] = sc->hs_chan; + nsubch = sc->hs_nchan - 1; + if (nsubch == 0) + return; + + subch = vmbus_subchan_get(sc->hs_chan, nsubch); + for (i = 0; i < nsubch; i++) + sc->hs_sel_chan[i + 1] = subch[i]; + vmbus_subchan_rel(subch, nsubch); } static int @@ -977,7 +1000,10 @@ storvsc_sysctl(device_t dev) { struct sysctl_oid_list *child; struct sysctl_ctx_list *ctx; + struct sysctl_oid *ch_tree, *chid_tree; struct storvsc_softc *sc; + char name[16]; + int i; sc = device_get_softc(dev); ctx = device_get_sysctl_ctx(dev); @@ -989,6 +1015,28 @@ storvsc_sysctl(device_t dev) &sc->sysctl_data.data_vaddr_cnt, "# of vaddr data block"); SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "data_sg_cnt", CTLFLAG_RW, &sc->sysctl_data.data_sg_cnt, "# of sg data block"); + + /* dev.storvsc.UNIT.channel */ + ch_tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "channel", + CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (ch_tree == NULL) + return; + + for (i = 0; i < sc->hs_nchan; i++) { + uint32_t ch_id; + + ch_id = vmbus_chan_id(sc->hs_sel_chan[i]); + snprintf(name, sizeof(name), "%d", ch_id); + /* dev.storvsc.UNIT.channel.CHID */ + chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree), + OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); + if (chid_tree == NULL) + return; + /* dev.storvsc.UNIT.channel.CHID.send_req */ + SYSCTL_ADD_ULONG(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO, + "send_req", CTLFLAG_RD, &sc->sysctl_data.chan_send_cnt[i], + "# of request sending from this channel"); + } } /** @@ -1019,6 +1067,7 @@ storvsc_attach(device_t dev) root_mount_token = root_mount_hold("storvsc"); sc = device_get_softc(dev); + sc->hs_nchan = 1; sc->hs_chan = vmbus_get_channel(dev); stor_type = storvsc_get_storage_type(dev); @@ -1030,7 +1079,14 @@ storvsc_attach(device_t dev) /* fill in driver specific properties */ sc->hs_drv_props = &g_drv_props_table[stor_type]; - + sc->hs_drv_props->drv_ringbuffer_size = hv_storvsc_ringbuffer_size; + sc->hs_drv_props->drv_max_ios_per_target = + MIN(STORVSC_MAX_IO, hv_storvsc_max_io); + if (bootverbose) { + printf("storvsc ringbuffer size: %d, max_io: %d\n", + sc->hs_drv_props->drv_ringbuffer_size, + sc->hs_drv_props->drv_max_ios_per_target); + } /* fill in device specific properties */ sc->hs_unit = device_get_unit(dev); sc->hs_dev = dev; @@ -1052,7 +1108,7 @@ storvsc_attach(device_t dev) * STORVSC_DATA_SEGCNT_MAX segments, each * segment has one page buffer */ - for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) { + for (i = 0; i < sc->hs_drv_props->drv_max_ios_per_target; i++) { sgl_node = malloc(sizeof(struct hv_sgl_node), M_DEVBUF, M_WAITOK|M_ZERO); @@ -1083,7 +1139,7 @@ storvsc_attach(device_t dev) } /* Construct cpu to channel mapping */ - storvsc_create_cpu2chan(sc); + storvsc_create_chan_sel(sc); /* * Create the device queue. @@ -1840,19 +1896,37 @@ create_storvsc_request(union ccb *ccb, s csio->cdb_len); } + if (hv_storvsc_use_win8ext_flags) { + reqp->vstor_packet.u.vm_srb.win8_extension.time_out_value = 60; + reqp->vstor_packet.u.vm_srb.win8_extension.srb_flags |= + SRB_FLAGS_DISABLE_SYNCH_TRANSFER; + } switch (ccb->ccb_h.flags & CAM_DIR_MASK) { case CAM_DIR_OUT: - reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE; + reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE; + if (hv_storvsc_use_win8ext_flags) { + reqp->vstor_packet.u.vm_srb.win8_extension.srb_flags |= + SRB_FLAGS_DATA_OUT; + } break; case CAM_DIR_IN: reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE; + if (hv_storvsc_use_win8ext_flags) { + reqp->vstor_packet.u.vm_srb.win8_extension.srb_flags |= + SRB_FLAGS_DATA_IN; + } break; case CAM_DIR_NONE: reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE; + if (hv_storvsc_use_win8ext_flags) { + reqp->vstor_packet.u.vm_srb.win8_extension.srb_flags |= + SRB_FLAGS_NO_DATA_TRANSFER; + } break; default: - reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE; - break; + printf("Error: unexpected data direction: 0x%x\n", + ccb->ccb_h.flags & CAM_DIR_MASK); + return (EINVAL); } reqp->sense_data = &csio->sense_data; Modified: stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h Thu Oct 13 05:59:33 2016 (r307179) +++ stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h Thu Oct 13 06:09:26 2016 (r307180) @@ -253,6 +253,22 @@ struct vstor_packet { #define SRB_STATUS_AUTOSENSE_VALID 0x80 #define SRB_STATUS_INVALID_LUN 0X20 +/* + * SRB Flag Bits + */ + +#define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002 +#define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004 +#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008 +#define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010 +#define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020 +#define SRB_FLAGS_DATA_IN 0x00000040 +#define SRB_FLAGS_DATA_OUT 0x00000080 +#define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000 +#define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) +#define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100 +#define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200 +#define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400 /** * Packet flags */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Thu Oct 13 05:59:33 2016 (r307179) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Thu Oct 13 06:09:26 2016 (r307180) @@ -74,6 +74,7 @@ struct sysctl_oid; static __inline int vmbus_txbr_maxpktsz(const struct vmbus_txbr *tbr) { + /* * - 64 bits for the trailing start index (- sizeof(uint64_t)). * - The rindex and windex can't be same (- 1). See @@ -82,6 +83,17 @@ vmbus_txbr_maxpktsz(const struct vmbus_t return (tbr->txbr_dsize - sizeof(uint64_t) - 1); } +static __inline int +vmbus_br_nelem(int br_size, int elem_size) +{ + + /* Strip bufring header */ + br_size -= sizeof(struct vmbus_bufring); + /* Add per-element trailing index */ + elem_size += sizeof(uint64_t); + return (br_size / elem_size); +} + void vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, struct sysctl_oid *br_tree, struct vmbus_br *br, const char *name); Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 05:59:33 2016 (r307179) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 06:09:26 2016 (r307180) @@ -1411,3 +1411,16 @@ vmbus_chan_guid_inst(const struct vmbus_ { return &chan->ch_guid_inst; } + +int +vmbus_chan_prplist_nelem(int br_size, int prpcnt_max, int dlen_max) +{ + int elem_size; + + elem_size = __offsetof(struct vmbus_chanpkt_prplist, + cp_range[0].gpa_page[prpcnt_max]); + elem_size += dlen_max; + elem_size = VMBUS_CHANPKT_TOTLEN(elem_size); + + return (vmbus_br_nelem(br_size, elem_size)); +} From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:17:35 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 81E9CC0FD99; Thu, 13 Oct 2016 06:17:35 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4A357E62; Thu, 13 Oct 2016 06:17:35 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6HYx2088531; Thu, 13 Oct 2016 06:17:34 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6HXje088523; Thu, 13 Oct 2016 06:17:33 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130617.u9D6HXje088523@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:17:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307181 - in stable/10/sys: dev/hyperv/netvsc net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:17:35 -0000 Author: sephe Date: Thu Oct 13 06:17:33 2016 New Revision: 307181 URL: https://svnweb.freebsd.org/changeset/base/307181 Log: MFC 304832-304834,304972 304832 hyperv/hn: Use vmbus xact for RNDIS query. And switch MAC address query to use new RNDIS query function. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7639 304833 hyperv/hn: Save the adopted NDIS version for RNDIS to use later. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7640 304834 hyperv/hn: Use vmbus xact for RNDIS set. And use new RNDIS set to configure NDIS offloading parameters. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7641 304972 hyperv/hn: Add definition for NDIS media state. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7652 Added: stable/10/sys/dev/hyperv/netvsc/ndis.h - copied, changed from r304834, head/sys/dev/hyperv/netvsc/ndis.h Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:17:33 2016 (r307181) @@ -520,9 +520,15 @@ hv_nv_connect_to_vsp(struct hn_softc *sc for (i = protocol_number - 1; i >= 0; i--) { if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { sc->hn_nvs_ver = protocol_list[i]; + sc->hn_ndis_ver = NDIS_VERSION_6_30; + if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) + sc->hn_ndis_ver = NDIS_VERSION_6_1; if (bootverbose) { - device_printf(dev, "NVS version 0x%x\n", - sc->hn_nvs_ver); + if_printf(sc->hn_ifp, "NVS version 0x%x, " + "NDIS version %u.%u\n", + sc->hn_nvs_ver, + NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } break; } @@ -548,11 +554,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc memset(&ndis, 0, sizeof(ndis)); ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; - ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6; - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) - ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1; - else - ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30; + ndis.nvs_ndis_major = NDIS_VERSION_MAJOR(sc->hn_ndis_ver); + ndis.nvs_ndis_minor = NDIS_VERSION_MINOR(sc->hn_ndis_ver); /* NOTE: No response. */ ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:17:33 2016 (r307181) @@ -383,6 +383,7 @@ typedef struct hn_softc { struct hyperv_dma hn_chim_dma; uint32_t hn_rndis_rid; + uint32_t hn_ndis_ver; } hn_softc_t; #define HN_FLAG_RXBUF_CONNECTED 0x0001 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 06:17:33 2016 (r307181) @@ -119,9 +119,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include "hv_net_vsc.h" -#include "hv_rndis.h" -#include "hv_rndis_filter.h" +#include +#include +#include +#include + #include "vmbus_if.h" /* Short for Hyper-V network interface */ @@ -334,6 +336,7 @@ static int hn_rx_stat_u64_sysctl(SYSCTL_ static int hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS); static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS); static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); static int hn_create_tx_ring(struct hn_softc *, int); static void hn_destroy_tx_ring(struct hn_tx_ring *); @@ -444,6 +447,8 @@ hn_cpuset_setthread_task(void *xmask, in static int netvsc_attach(device_t dev) { + struct sysctl_oid_list *child; + struct sysctl_ctx_list *ctx; netvsc_device_info device_info; hn_softc_t *sc; int unit = device_get_unit(dev); @@ -597,7 +602,7 @@ netvsc_attach(device_t dev) } #endif - if (device_info.link_state == 0) { + if (device_info.link_state == NDIS_MEDIA_STATE_CONNECTED) { sc->hn_carrier = 1; } @@ -620,9 +625,13 @@ netvsc_attach(device_t dev) hn_tx_chimney_size < sc->hn_chim_szmax) hn_set_chim_size(sc, hn_tx_chimney_size); - SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "nvs_version", CTLFLAG_RD, &sc->hn_nvs_ver, 0, "NVS version"); + ctx = device_get_sysctl_ctx(dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD, + &sc->hn_nvs_ver, 0, "NVS version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_ndis_version_sysctl, "A", "NDIS version"); return (0); failed: @@ -2141,6 +2150,18 @@ hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARG } static int +hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char verstr[16]; + + snprintf(verstr, sizeof(verstr), "%u.%u", + NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); +} + +static int hn_check_iplen(const struct mbuf *m, int hoff) { const struct ip *ip; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:17:33 2016 (r307181) @@ -42,11 +42,8 @@ #define NDIS_VERSION_6_1 0x00060001 #define NDIS_VERSION_6_30 0x0006001e -#define NDIS_VERSION_MAJOR_6 6 -#define NDIS_VERSION_MINOR_1 1 -#define NDIS_VERSION_MINOR_30 30 - -#define NDIS_VERSION (NDIS_VERSION_5_1) +#define NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) +#define NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) /* * Object Identifiers used by NdisRequest Query/Set Information Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:17:33 2016 (r307181) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #define HV_RF_RECVINFO_VLAN 0x1 #define HV_RF_RECVINFO_CSUM 0x2 @@ -97,6 +98,11 @@ static void hn_rndis_sent_halt(struct hn static void hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, const void *data, int dlen); +static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, + const void *idata, size_t idlen, void *odata, size_t *odlen0); +static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, + size_t dlen); +static int hn_rndis_conf_offload(struct hn_softc *sc); static __inline uint32_t hn_rndis_rid(struct hn_softc *sc) @@ -696,13 +702,23 @@ cleanup: /* * RNDIS filter query device MAC address */ -static inline int +static int hv_rf_query_device_mac(rndis_device *device) { - uint32_t size = ETHER_ADDR_LEN; + struct hn_softc *sc = device->sc; + size_t hwaddr_len; + int error; - return (hv_rf_query_device(device, - RNDIS_OID_802_3_PERMANENT_ADDRESS, device->hw_mac_addr, &size)); + hwaddr_len = ETHER_ADDR_LEN; + error = hn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0, + device->hw_mac_addr, &hwaddr_len); + if (error) + return error; + if (hwaddr_len != ETHER_ADDR_LEN) { + if_printf(sc->hn_ifp, "invalid hwaddr len %zu\n", hwaddr_len); + return EINVAL; + } + return 0; } /* @@ -893,12 +909,12 @@ exit: static const void * hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid, - size_t reqlen, size_t min_complen, uint32_t comp_type) + size_t reqlen, size_t *comp_len0, uint32_t comp_type) { struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT]; const struct rndis_comp_hdr *comp; bus_addr_t paddr; - size_t comp_len; + size_t comp_len, min_complen = *comp_len0; int gpa_cnt, error; KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid)); @@ -947,7 +963,14 @@ hn_rndis_xact_execute(struct hn_softc *s * Check this RNDIS complete message. */ if (comp_len < min_complen) { - if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n", comp_len); + if (comp_len >= sizeof(*comp)) { + /* rm_status field is valid */ + if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu, " + "status 0x%08x\n", comp_len, comp->rm_status); + } else { + if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n", + comp_len); + } return (NULL); } if (comp->rm_len < min_complen) { @@ -966,9 +989,190 @@ hn_rndis_xact_execute(struct hn_softc *s return (NULL); } /* All pass! */ + *comp_len0 = comp_len; return (comp); } +static int +hn_rndis_query(struct hn_softc *sc, uint32_t oid, + const void *idata, size_t idlen, void *odata, size_t *odlen0) +{ + struct rndis_query_req *req; + const struct rndis_query_comp *comp; + struct vmbus_xact *xact; + size_t reqlen, odlen = *odlen0, comp_len; + int error, ofs; + uint32_t rid; + + reqlen = sizeof(*req) + idlen; + xact = vmbus_xact_get(sc->hn_xact, reqlen); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for RNDIS query 0x%08x\n", oid); + return (ENXIO); + } + rid = hn_rndis_rid(sc); + req = vmbus_xact_req_data(xact); + req->rm_type = REMOTE_NDIS_QUERY_MSG; + req->rm_len = reqlen; + req->rm_rid = rid; + req->rm_oid = oid; + /* + * XXX + * This is _not_ RNDIS Spec conforming: + * "This MUST be set to 0 when there is no input data + * associated with the OID." + * + * If this field was set to 0 according to the RNDIS Spec, + * Hyper-V would set non-SUCCESS status in the query + * completion. + */ + req->rm_infobufoffset = RNDIS_QUERY_REQ_INFOBUFOFFSET; + + if (idlen > 0) { + req->rm_infobuflen = idlen; + /* Input data immediately follows RNDIS query. */ + memcpy(req + 1, idata, idlen); + } + + comp_len = sizeof(*comp) + odlen; + comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len, + REMOTE_NDIS_QUERY_CMPLT); + if (comp == NULL) { + if_printf(sc->hn_ifp, "exec RNDIS query 0x%08x failed\n", oid); + error = EIO; + goto done; + } + + if (comp->rm_status != RNDIS_STATUS_SUCCESS) { + if_printf(sc->hn_ifp, "RNDIS query 0x%08x failed: " + "status 0x%08x\n", oid, comp->rm_status); + error = EIO; + goto done; + } + if (comp->rm_infobuflen == 0 || comp->rm_infobufoffset == 0) { + /* No output data! */ + if_printf(sc->hn_ifp, "RNDIS query 0x%08x, no data\n", oid); + *odlen0 = 0; + error = 0; + goto done; + } + + /* + * Check output data length and offset. + */ + /* ofs is the offset from the beginning of comp. */ + ofs = RNDIS_QUERY_COMP_INFOBUFABS(comp->rm_infobufoffset); + if (ofs < sizeof(*comp) || ofs + comp->rm_infobuflen > comp_len) { + if_printf(sc->hn_ifp, "RNDIS query invalid comp ib off/len, " + "%u/%u\n", comp->rm_infobufoffset, comp->rm_infobuflen); + error = EINVAL; + goto done; + } + + /* + * Save output data. + */ + if (comp->rm_infobuflen < odlen) + odlen = comp->rm_infobuflen; + memcpy(odata, ((const uint8_t *)comp) + ofs, odlen); + *odlen0 = odlen; + + error = 0; +done: + vmbus_xact_put(xact); + return (error); +} + +static int +hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen) +{ + struct rndis_set_req *req; + const struct rndis_set_comp *comp; + struct vmbus_xact *xact; + size_t reqlen, comp_len; + uint32_t rid; + int error; + + KASSERT(dlen > 0, ("invalid dlen %zu", dlen)); + + reqlen = sizeof(*req) + dlen; + xact = vmbus_xact_get(sc->hn_xact, reqlen); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for RNDIS set 0x%08x\n", oid); + return (ENXIO); + } + rid = hn_rndis_rid(sc); + req = vmbus_xact_req_data(xact); + req->rm_type = REMOTE_NDIS_SET_MSG; + req->rm_len = reqlen; + req->rm_rid = rid; + req->rm_oid = oid; + req->rm_infobuflen = dlen; + req->rm_infobufoffset = RNDIS_SET_REQ_INFOBUFOFFSET; + /* Data immediately follows RNDIS set. */ + memcpy(req + 1, data, dlen); + + comp_len = sizeof(*comp); + comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len, + REMOTE_NDIS_SET_CMPLT); + if (comp == NULL) { + if_printf(sc->hn_ifp, "exec RNDIS set 0x%08x failed\n", oid); + error = EIO; + goto done; + } + + if (comp->rm_status != RNDIS_STATUS_SUCCESS) { + if_printf(sc->hn_ifp, "RNDIS set 0x%08x failed: " + "status 0x%08x\n", oid, comp->rm_status); + error = EIO; + goto done; + } + error = 0; +done: + vmbus_xact_put(xact); + return (error); +} + +static int +hn_rndis_conf_offload(struct hn_softc *sc) +{ + struct ndis_offload_params params; + size_t paramsz; + int error; + + /* NOTE: 0 means "no change" */ + memset(¶ms, 0, sizeof(params)); + + params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; + if (sc->hn_ndis_ver < NDIS_VERSION_6_30) { + params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; + paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1; + } else { + params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3; + paramsz = NDIS_OFFLOAD_PARAMS_SIZE; + } + params.ndis_hdr.ndis_size = paramsz; + + params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; + params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; + params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; + if (sc->hn_ndis_ver >= NDIS_VERSION_6_30) { + params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; + params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; + } + params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; + /* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ + + error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); + if (error) { + if_printf(sc->hn_ifp, "offload config failed: %d\n", error); + } else { + if (bootverbose) + if_printf(sc->hn_ifp, "offload config done\n"); + } + return (error); +} + /* * RNDIS filter init device */ @@ -979,6 +1183,7 @@ hv_rf_init_device(rndis_device *device) struct rndis_init_req *req; const struct rndis_init_comp *comp; struct vmbus_xact *xact; + size_t comp_len; uint32_t rid; int error; @@ -999,8 +1204,9 @@ hv_rf_init_device(rndis_device *device) req->rm_ver_minor = RNDIS_VERSION_MINOR; req->rm_max_xfersz = HN_RNDIS_XFER_SIZE; - comp = hn_rndis_xact_execute(sc, xact, rid, sizeof(*req), - RNDIS_INIT_COMP_SIZE_MIN, REMOTE_NDIS_INITIALIZE_CMPLT); + comp_len = RNDIS_INIT_COMP_SIZE_MIN; + comp = hn_rndis_xact_execute(sc, xact, rid, sizeof(*req), &comp_len, + REMOTE_NDIS_INITIALIZE_CMPLT); if (comp == NULL) { if_printf(sc->hn_ifp, "exec RNDIS init failed\n"); error = EIO; @@ -1132,7 +1338,6 @@ hv_rf_on_device_add(struct hn_softc *sc, { int ret; rndis_device *rndis_dev; - rndis_offload_params offloads; struct rndis_recv_scale_cap rsscaps; uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; @@ -1182,21 +1387,8 @@ hv_rf_on_device_add(struct hn_softc *sc, /* TODO: shut down rndis device and the channel */ } - /* config csum offload and send request to host */ - memset(&offloads, 0, sizeof(offloads)); - offloads.ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; - offloads.tcp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; - offloads.udp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; - offloads.tcp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; - offloads.udp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED; - offloads.lso_v2_ipv4 = RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED; - - ret = hv_rf_send_offload_request(sc, &offloads); - if (ret != 0) { - /* TODO: shut down rndis device and the channel */ - device_printf(dev, - "hv_rf_send_offload_request failed, ret=%d\n", ret); - } + /* Configure NDIS offload settings */ + hn_rndis_conf_offload(sc); memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, ETHER_ADDR_LEN); Copied and modified: stable/10/sys/dev/hyperv/netvsc/ndis.h (from r304834, head/sys/dev/hyperv/netvsc/ndis.h) ============================================================================== --- head/sys/dev/hyperv/netvsc/ndis.h Fri Aug 26 05:18:27 2016 (r304834, copy source) +++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 06:17:33 2016 (r307181) @@ -29,6 +29,9 @@ #ifndef _NET_NDIS_H_ #define _NET_NDIS_H_ +#define NDIS_MEDIA_STATE_CONNECTED 0 +#define NDIS_MEDIA_STATE_DISCONNECTED 1 + #define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C #define NDIS_OBJTYPE_DEFAULT 0x80 Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 06:09:26 2016 (r307180) +++ stable/10/sys/net/rndis.h Thu Oct 13 06:17:33 2016 (r307181) @@ -172,6 +172,10 @@ struct rndis_query_req { uint32_t rm_devicevchdl; }; +#define RNDIS_QUERY_REQ_INFOBUFOFFSET \ + (sizeof(struct rndis_query_req) - \ + __offsetof(struct rndis_query_req, rm_rid)) + struct rndis_query_comp { uint32_t rm_type; uint32_t rm_len; @@ -181,6 +185,9 @@ struct rndis_query_comp { uint32_t rm_infobufoffset; }; +#define RNDIS_QUERY_COMP_INFOBUFABS(ofs) \ + ((ofs) + __offsetof(struct rndis_query_req, rm_rid)) + /* Send a set object request. */ #define REMOTE_NDIS_SET_MSG 0x00000005 #define REMOTE_NDIS_SET_CMPLT 0x80000005 @@ -195,6 +202,10 @@ struct rndis_set_req { uint32_t rm_devicevchdl; }; +#define RNDIS_SET_REQ_INFOBUFOFFSET \ + (sizeof(struct rndis_set_req) - \ + __offsetof(struct rndis_set_req, rm_rid)) + struct rndis_set_comp { uint32_t rm_type; uint32_t rm_len; From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:32:22 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BB2A1C0F312; Thu, 13 Oct 2016 06:32:22 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8792FAA1; Thu, 13 Oct 2016 06:32:22 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6WL3o095999; Thu, 13 Oct 2016 06:32:21 GMT (envelope-from np@FreeBSD.org) Received: (from np@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6WLJ4095998; Thu, 13 Oct 2016 06:32:21 GMT (envelope-from np@FreeBSD.org) Message-Id: <201610130632.u9D6WLJ4095998@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: np set sender to np@FreeBSD.org using -f From: Navdeep Parhar Date: Thu, 13 Oct 2016 06:32:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307183 - stable/10/usr.sbin/bhyve X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:32:22 -0000 Author: np Date: Thu Oct 13 06:32:21 2016 New Revision: 307183 URL: https://svnweb.freebsd.org/changeset/base/307183 Log: bhyve(8): Fix typo from r294294 that prevented bhyve from working with vmnet devices. This is a direct commit to stable/10. Modified: stable/10/usr.sbin/bhyve/pci_virtio_net.c Modified: stable/10/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- stable/10/usr.sbin/bhyve/pci_virtio_net.c Thu Oct 13 06:19:54 2016 (r307182) +++ stable/10/usr.sbin/bhyve/pci_virtio_net.c Thu Oct 13 06:32:21 2016 (r307183) @@ -851,7 +851,7 @@ pci_vtnet_init(struct vmctx *ctx, struct if (strncmp(devname, "vale", 4) == 0) pci_vtnet_netmap_setup(sc, devname); if ((strncmp(devname, "tap", 3) == 0) || - (strncmp(devname, "vmmnet", 5) == 0)) + (strncmp(devname, "vmnet", 5) == 0)) pci_vtnet_tap_setup(sc, devname); free(devname); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:34:20 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3FC46C0F3BC; Thu, 13 Oct 2016 06:34:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 03A57C54; Thu, 13 Oct 2016 06:34:19 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6YJs9096142; Thu, 13 Oct 2016 06:34:19 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6YIrt096136; Thu, 13 Oct 2016 06:34:18 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130634.u9D6YIrt096136@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:34:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307184 - in stable/10/sys: dev/hyperv/netvsc dev/usb/net net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:34:20 -0000 Author: sephe Date: Thu Oct 13 06:34:18 2016 New Revision: 307184 URL: https://svnweb.freebsd.org/changeset/base/307184 Log: MFC 304973,304975,304976,304979,305044-305048 304973 hyperv/hn: Switch to new RNDIS query for link status extraction. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7654 304975 hyperv/hn: Switch to new RNDIS query for RSS capabilities extraction. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7656 304976 hyperv/hn: Fix # of channels setting, if RSS is not available. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7657 304979 hyperv/hn: Switch to new RNDIS set for RSS parameters. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7658 305044 hyperv/hn: Move OIDs to net/rndis.h; they are standard NDIS OIDs. Actually all OIDs defined in net/rndis.h are standard NDIS OIDs. While I'm here, use the verbose macro name as in NDIS spec. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7679 305045 hyperv/hn: Indentation and field comment fixup for ndis.h. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7680 305046 net/rndis: Packet types are defined by NDIS; not RNDIS specific. Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7681 305047 hyperv/hn: Switch to new RNDIS set for RX filters. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7683 305048 hyperv/hn: Remove unused function Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7684 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/ndis.h stable/10/sys/dev/usb/net/if_urndis.c stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:32:21 2016 (r307183) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:34:18 2016 (r307184) @@ -62,6 +62,8 @@ #include #include +#include + #define HN_USE_TXDESC_BUFRING MALLOC_DECLARE(M_NETVSC); @@ -384,6 +386,8 @@ typedef struct hn_softc { uint32_t hn_rndis_rid; uint32_t hn_ndis_ver; + + struct ndis_rssprm_toeplitz hn_rss; } hn_softc_t; #define HN_FLAG_RXBUF_CONNECTED 0x0001 Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:32:21 2016 (r307183) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:34:18 2016 (r307184) @@ -536,20 +536,6 @@ struct rndis_hash_info { uint32_t hash_info; } __packed; -#define NDIS_HASH_FUNCTION_MASK 0x000000FF /* see hash function */ -#define NDIS_HASH_TYPE_MASK 0x00FFFF00 /* see hash type */ - -/* hash function */ -#define NDIS_HASH_FUNCTION_TOEPLITZ 0x00000001 - -/* hash type */ -#define NDIS_HASH_IPV4 0x00000100 -#define NDIS_HASH_TCP_IPV4 0x00000200 -#define NDIS_HASH_IPV6 0x00000400 -#define NDIS_HASH_IPV6_EX 0x00000800 -#define NDIS_HASH_TCP_IPV6 0x00001000 -#define NDIS_HASH_TCP_IPV6_EX 0x00002000 - typedef struct rndis_tcp_tso_info_ { union { struct { @@ -903,19 +889,6 @@ typedef struct rndismp_rx_bufs_info_ { #define RNDIS_HEADER_SIZE (sizeof(rndis_msg) - sizeof(rndis_msg_container)) -#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define NDIS_PACKET_TYPE_SMT 0x00000040 -#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define NDIS_PACKET_TYPE_GROUP 0x00000100 -#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 -#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 -#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 - /* * Externs */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:32:21 2016 (r307183) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:34:18 2016 (r307184) @@ -80,17 +80,9 @@ static void hv_rf_receive_indicate_statu const rndis_msg *response); static void hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen); -static int hv_rf_query_device(rndis_device *device, uint32_t oid, - void *result, uint32_t *result_size); static inline int hv_rf_query_device_mac(rndis_device *device); static inline int hv_rf_query_device_link_status(rndis_device *device); -static int hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter); static int hv_rf_init_device(rndis_device *device); -static int hv_rf_open_device(rndis_device *device); -static int hv_rf_close_device(rndis_device *device); -int -hv_rf_send_offload_request(struct hn_softc *sc, - rndis_offload_params *offloads); static void hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, @@ -103,6 +95,8 @@ static int hn_rndis_query(struct hn_soft static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen); static int hn_rndis_conf_offload(struct hn_softc *sc); +static int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt); +static int hn_rndis_conf_rss(struct hn_softc *sc, int nchan); static __inline uint32_t hn_rndis_rid(struct hn_softc *sc) @@ -356,78 +350,6 @@ hv_rf_receive_response(rndis_device *dev } } -int -hv_rf_send_offload_request(struct hn_softc *sc, - rndis_offload_params *offloads) -{ - rndis_request *request; - rndis_set_request *set; - rndis_offload_params *offload_req; - rndis_set_complete *set_complete; - rndis_device *rndis_dev = sc->rndis_dev; - device_t dev = sc->hn_dev; - uint32_t extlen = sizeof(rndis_offload_params); - int ret; - - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) { - extlen = VERSION_4_OFFLOAD_SIZE; - /* On NVSP_PROTOCOL_VERSION_4 and below, we do not support - * UDP checksum offload. - */ - offloads->udp_ipv4_csum = 0; - offloads->udp_ipv6_csum = 0; - } - - request = hv_rndis_request(rndis_dev, REMOTE_NDIS_SET_MSG, - RNDIS_MESSAGE_SIZE(rndis_set_request) + extlen); - if (!request) - return (ENOMEM); - - set = &request->request_msg.msg.set_request; - set->oid = RNDIS_OID_TCP_OFFLOAD_PARAMETERS; - set->info_buffer_length = extlen; - set->info_buffer_offset = sizeof(rndis_set_request); - set->device_vc_handle = 0; - - offload_req = (rndis_offload_params *)((unsigned long)set + - set->info_buffer_offset); - *offload_req = *offloads; - offload_req->header.type = RNDIS_OBJECT_TYPE_DEFAULT; - offload_req->header.revision = RNDIS_OFFLOAD_PARAMETERS_REVISION_3; - offload_req->header.size = extlen; - - ret = hv_rf_send_request(rndis_dev, request, REMOTE_NDIS_SET_MSG); - if (ret != 0) { - device_printf(dev, "hv send offload request failed, ret=%d!\n", - ret); - goto cleanup; - } - - ret = sema_timedwait(&request->wait_sema, 5 * hz); - if (ret != 0) { - device_printf(dev, "hv send offload request timeout\n"); - goto cleanup; - } - - set_complete = &request->response_msg.msg.set_complete; - if (set_complete->status == RNDIS_STATUS_SUCCESS) { - device_printf(dev, "hv send offload request succeeded\n"); - ret = 0; - } else { - if (set_complete->status == RNDIS_STATUS_NOT_SUPPORTED) { - device_printf(dev, "HV Not support offload\n"); - ret = 0; - } else { - ret = set_complete->status; - } - } - -cleanup: - hv_put_rndis_request(rndis_dev, request); - - return (ret); -} - /* * RNDIS filter receive indicate status */ @@ -629,77 +551,6 @@ hv_rf_on_receive(struct hn_softc *sc, st } /* - * RNDIS filter query device - */ -static int -hv_rf_query_device(rndis_device *device, uint32_t oid, void *result, - uint32_t *result_size) -{ - rndis_request *request; - uint32_t in_result_size = *result_size; - rndis_query_request *query; - rndis_query_complete *query_complete; - int ret = 0; - - *result_size = 0; - request = hv_rndis_request(device, REMOTE_NDIS_QUERY_MSG, - RNDIS_MESSAGE_SIZE(rndis_query_request)); - if (request == NULL) { - ret = -1; - goto cleanup; - } - - /* Set up the rndis query */ - query = &request->request_msg.msg.query_request; - query->oid = oid; - query->info_buffer_offset = sizeof(rndis_query_request); - query->info_buffer_length = 0; - query->device_vc_handle = 0; - - if (oid == RNDIS_OID_GEN_RSS_CAPABILITIES) { - struct rndis_recv_scale_cap *cap; - - request->request_msg.msg_len += - sizeof(struct rndis_recv_scale_cap); - query->info_buffer_length = sizeof(struct rndis_recv_scale_cap); - cap = (struct rndis_recv_scale_cap *)((unsigned long)query + - query->info_buffer_offset); - cap->hdr.type = RNDIS_OBJECT_TYPE_RSS_CAPABILITIES; - cap->hdr.rev = RNDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2; - cap->hdr.size = sizeof(struct rndis_recv_scale_cap); - } - - ret = hv_rf_send_request(device, request, REMOTE_NDIS_QUERY_MSG); - if (ret != 0) { - /* Fixme: printf added */ - printf("RNDISFILTER request failed to Send!\n"); - goto cleanup; - } - - sema_wait(&request->wait_sema); - - /* Copy the response back */ - query_complete = &request->response_msg.msg.query_complete; - - if (query_complete->info_buffer_length > in_result_size) { - ret = EINVAL; - goto cleanup; - } - - memcpy(result, (void *)((unsigned long)query_complete + - query_complete->info_buffer_offset), - query_complete->info_buffer_length); - - *result_size = query_complete->info_buffer_length; - -cleanup: - if (request != NULL) - hv_put_rndis_request(device, request); - - return (ret); -} - -/* * RNDIS filter query device MAC address */ static int @@ -713,12 +564,12 @@ hv_rf_query_device_mac(rndis_device *dev error = hn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0, device->hw_mac_addr, &hwaddr_len); if (error) - return error; + return (error); if (hwaddr_len != ETHER_ADDR_LEN) { if_printf(sc->hn_ifp, "invalid hwaddr len %zu\n", hwaddr_len); - return EINVAL; + return (EINVAL); } - return 0; + return (0); } /* @@ -727,13 +578,23 @@ hv_rf_query_device_mac(rndis_device *dev static inline int hv_rf_query_device_link_status(rndis_device *device) { - uint32_t size = sizeof(uint32_t); + struct hn_softc *sc = device->sc; + size_t size; + int error; - return (hv_rf_query_device(device, - RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, &device->link_status, &size)); + size = sizeof(uint32_t); + error = hn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS, NULL, 0, + &device->link_status, &size); + if (error) + return (error); + if (size != sizeof(uint32_t)) { + if_printf(sc->hn_ifp, "invalid link status len %zu\n", size); + return (EINVAL); + } + return (0); } -static uint8_t netvsc_hash_key[HASH_KEYLEN] = { +static uint8_t netvsc_hash_key[NDIS_HASH_KEYSIZE_TOEPLITZ] = { 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, @@ -741,172 +602,6 @@ static uint8_t netvsc_hash_key[HASH_KEYL 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa }; -/* - * RNDIS set vRSS parameters - */ -static int -hv_rf_set_rss_param(rndis_device *device, int num_queue) -{ - rndis_request *request; - rndis_set_request *set; - rndis_set_complete *set_complete; - rndis_recv_scale_param *rssp; - uint32_t extlen = sizeof(rndis_recv_scale_param) + - (4 * ITAB_NUM) + HASH_KEYLEN; - uint32_t *itab, status; - uint8_t *keyp; - int i, ret; - - - request = hv_rndis_request(device, REMOTE_NDIS_SET_MSG, - RNDIS_MESSAGE_SIZE(rndis_set_request) + extlen); - if (request == NULL) { - if (bootverbose) - printf("Netvsc: No memory to set vRSS parameters.\n"); - ret = -1; - goto cleanup; - } - - set = &request->request_msg.msg.set_request; - set->oid = RNDIS_OID_GEN_RSS_PARAMETERS; - set->info_buffer_length = extlen; - set->info_buffer_offset = sizeof(rndis_set_request); - set->device_vc_handle = 0; - - /* Fill out the rssp parameter structure */ - rssp = (rndis_recv_scale_param *)(set + 1); - rssp->hdr.type = RNDIS_OBJECT_TYPE_RSS_PARAMETERS; - rssp->hdr.rev = RNDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2; - rssp->hdr.size = sizeof(rndis_recv_scale_param); - rssp->flag = 0; - rssp->hashinfo = RNDIS_HASH_FUNC_TOEPLITZ | RNDIS_HASH_IPV4 | - RNDIS_HASH_TCP_IPV4 | RNDIS_HASH_IPV6 | RNDIS_HASH_TCP_IPV6; - rssp->indirect_tabsize = 4 * ITAB_NUM; - rssp->indirect_taboffset = sizeof(rndis_recv_scale_param); - rssp->hashkey_size = HASH_KEYLEN; - rssp->hashkey_offset = rssp->indirect_taboffset + - rssp->indirect_tabsize; - - /* Set indirection table entries */ - itab = (uint32_t *)(rssp + 1); - for (i = 0; i < ITAB_NUM; i++) - itab[i] = i % num_queue; - - /* Set hash key values */ - keyp = (uint8_t *)((unsigned long)rssp + rssp->hashkey_offset); - for (i = 0; i < HASH_KEYLEN; i++) - keyp[i] = netvsc_hash_key[i]; - - ret = hv_rf_send_request(device, request, REMOTE_NDIS_SET_MSG); - if (ret != 0) { - goto cleanup; - } - - /* - * Wait for the response from the host. Another thread will signal - * us when the response has arrived. In the failure case, - * sema_timedwait() returns a non-zero status after waiting 5 seconds. - */ - ret = sema_timedwait(&request->wait_sema, 5 * hz); - if (ret == 0) { - /* Response received, check status */ - set_complete = &request->response_msg.msg.set_complete; - status = set_complete->status; - if (status != RNDIS_STATUS_SUCCESS) { - /* Bad response status, return error */ - if (bootverbose) - printf("Netvsc: Failed to set vRSS " - "parameters.\n"); - ret = -2; - } else { - if (bootverbose) - printf("Netvsc: Successfully set vRSS " - "parameters.\n"); - } - } else { - /* - * We cannot deallocate the request since we may still - * receive a send completion for it. - */ - printf("Netvsc: vRSS set timeout, id = %u, ret = %d\n", - request->request_msg.msg.init_request.request_id, ret); - goto exit; - } - -cleanup: - if (request != NULL) { - hv_put_rndis_request(device, request); - } -exit: - return (ret); -} - -/* - * RNDIS filter set packet filter - * Sends an rndis request with the new filter, then waits for a response - * from the host. - * Returns zero on success, non-zero on failure. - */ -static int -hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter) -{ - rndis_request *request; - rndis_set_request *set; - rndis_set_complete *set_complete; - uint32_t status; - int ret; - - request = hv_rndis_request(device, REMOTE_NDIS_SET_MSG, - RNDIS_MESSAGE_SIZE(rndis_set_request) + sizeof(uint32_t)); - if (request == NULL) { - ret = -1; - goto cleanup; - } - - /* Set up the rndis set */ - set = &request->request_msg.msg.set_request; - set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; - set->info_buffer_length = sizeof(uint32_t); - set->info_buffer_offset = sizeof(rndis_set_request); - - memcpy((void *)((unsigned long)set + sizeof(rndis_set_request)), - &new_filter, sizeof(uint32_t)); - - ret = hv_rf_send_request(device, request, REMOTE_NDIS_SET_MSG); - if (ret != 0) { - goto cleanup; - } - - /* - * Wait for the response from the host. Another thread will signal - * us when the response has arrived. In the failure case, - * sema_timedwait() returns a non-zero status after waiting 5 seconds. - */ - ret = sema_timedwait(&request->wait_sema, 5 * hz); - if (ret == 0) { - /* Response received, check status */ - set_complete = &request->response_msg.msg.set_complete; - status = set_complete->status; - if (status != RNDIS_STATUS_SUCCESS) { - /* Bad response status, return error */ - ret = -2; - } - } else { - /* - * We cannot deallocate the request since we may still - * receive a send completion for it. - */ - goto exit; - } - -cleanup: - if (request != NULL) { - hv_put_rndis_request(device, request); - } -exit: - return (ret); -} - static const void * hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid, size_t reqlen, size_t *comp_len0, uint32_t comp_type) @@ -1084,6 +779,51 @@ done: } static int +hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) +{ + struct ndis_rss_caps in, caps; + size_t caps_len; + int error; + + /* + * Only NDIS 6.30+ is supported. + */ + KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); + *rxr_cnt = 0; + + memset(&in, 0, sizeof(in)); + in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS; + in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; + in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; + + caps_len = NDIS_RSS_CAPS_SIZE; + error = hn_rndis_query(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES, + &in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len); + if (error) + return (error); + if (caps_len < NDIS_RSS_CAPS_SIZE_6_0) { + if_printf(sc->hn_ifp, "invalid NDIS RSS caps len %zu", + caps_len); + return (EINVAL); + } + + if (caps.ndis_nrxr == 0) { + if_printf(sc->hn_ifp, "0 RX rings!?\n"); + return (EINVAL); + } + *rxr_cnt = caps.ndis_nrxr; + + if (caps_len == NDIS_RSS_CAPS_SIZE) { + if (bootverbose) { + if_printf(sc->hn_ifp, "RSS indirect table size %u\n", + caps.ndis_nind); + } + } + return (0); +} + +static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen) { struct rndis_set_req *req; @@ -1173,6 +913,72 @@ hn_rndis_conf_offload(struct hn_softc *s return (error); } +static int +hn_rndis_conf_rss(struct hn_softc *sc, int nchan) +{ + struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; + struct ndis_rss_params *prm = &rss->rss_params; + int i, error; + + /* + * Only NDIS 6.30+ is supported. + */ + KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); + + memset(rss, 0, sizeof(*rss)); + prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; + prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; + prm->ndis_hdr.ndis_size = sizeof(*rss); + prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ | + NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | + NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6; + /* TODO: Take ndis_rss_caps.ndis_nind into account */ + prm->ndis_indsize = sizeof(rss->rss_ind); + prm->ndis_indoffset = + __offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]); + prm->ndis_keysize = sizeof(rss->rss_key); + prm->ndis_keyoffset = + __offsetof(struct ndis_rssprm_toeplitz, rss_key[0]); + + /* Setup RSS key */ + memcpy(rss->rss_key, netvsc_hash_key, sizeof(rss->rss_key)); + + /* Setup RSS indirect table */ + /* TODO: Take ndis_rss_caps.ndis_nind into account */ + for (i = 0; i < NDIS_HASH_INDCNT; ++i) + rss->rss_ind[i] = i % nchan; + + error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS, + rss, sizeof(*rss)); + if (error) { + if_printf(sc->hn_ifp, "RSS config failed: %d\n", error); + } else { + if (bootverbose) + if_printf(sc->hn_ifp, "RSS config done\n"); + } + return (error); +} + +static int +hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter) +{ + int error; + + error = hn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER, + &filter, sizeof(filter)); + if (error) { + if_printf(sc->hn_ifp, "set RX filter 0x%08x failed: %d\n", + filter, error); + } else { + if (bootverbose) { + if_printf(sc->hn_ifp, "set RX filter 0x%08x done\n", + filter); + } + } + return (error); +} + /* * RNDIS filter init device */ @@ -1281,55 +1087,6 @@ hv_rf_halt_device(rndis_device *device) } /* - * RNDIS filter open device - */ -static int -hv_rf_open_device(rndis_device *device) -{ - int ret; - - if (device->state != RNDIS_DEV_INITIALIZED) { - return (0); - } - - if (hv_promisc_mode != 1) { - ret = hv_rf_set_packet_filter(device, - NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_ALL_MULTICAST | - NDIS_PACKET_TYPE_DIRECTED); - } else { - ret = hv_rf_set_packet_filter(device, - NDIS_PACKET_TYPE_PROMISCUOUS); - } - - if (ret == 0) { - device->state = RNDIS_DEV_DATAINITIALIZED; - } - - return (ret); -} - -/* - * RNDIS filter close device - */ -static int -hv_rf_close_device(rndis_device *device) -{ - int ret; - - if (device->state != RNDIS_DEV_DATAINITIALIZED) { - return (0); - } - - ret = hv_rf_set_packet_filter(device, 0); - if (ret == 0) { - device->state = RNDIS_DEV_INITIALIZED; - } - - return (ret); -} - -/* * RNDIS filter on device add */ int @@ -1338,8 +1095,6 @@ hv_rf_on_device_add(struct hn_softc *sc, { int ret; rndis_device *rndis_dev; - struct rndis_recv_scale_cap rsscaps; - uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap); netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; device_t dev = sc->hn_dev; struct hn_nvs_subch_req *req; @@ -1348,6 +1103,7 @@ hv_rf_on_device_add(struct hn_softc *sc, struct vmbus_xact *xact = NULL; uint32_t status, nsubch; int nchan = *nchan0; + int rxr_cnt; rndis_dev = hv_get_rndis_device(); if (rndis_dev == NULL) { @@ -1396,22 +1152,29 @@ hv_rf_on_device_add(struct hn_softc *sc, dev_info->link_state = rndis_dev->link_status; - if (sc->hn_nvs_ver < NVSP_PROTOCOL_VERSION_5 || nchan == 1) + if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) { + /* + * Either RSS is not supported, or multiple RX/TX rings + * are not requested. + */ + *nchan0 = 1; return (0); + } - memset(&rsscaps, 0, rsscaps_size); - ret = hv_rf_query_device(rndis_dev, - RNDIS_OID_GEN_RSS_CAPABILITIES, - &rsscaps, &rsscaps_size); - if ((ret != 0) || (rsscaps.num_recv_que < 2)) { - device_printf(dev, "hv_rf_query_device failed or " - "rsscaps.num_recv_que < 2 \n"); - goto out; + /* + * Get RSS capabilities, e.g. # of RX rings, and # of indirect + * table entries. + */ + ret = hn_rndis_get_rsscaps(sc, &rxr_cnt); + if (ret) { + /* No RSS; this is benign. */ + *nchan0 = 1; + return (0); } - device_printf(dev, "channel, offered %u, requested %d\n", - rsscaps.num_recv_que, nchan); - if (nchan > rsscaps.num_recv_que) - nchan = rsscaps.num_recv_que; + if (nchan > rxr_cnt) + nchan = rxr_cnt; + if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n", + rxr_cnt, nchan); if (nchan == 1) { device_printf(dev, "only 1 channel is supported, no vRSS\n"); @@ -1468,8 +1231,11 @@ hv_rf_on_device_add(struct hn_softc *sc, } nchan = nsubch + 1; - ret = hv_rf_set_rss_param(rndis_dev, nchan); - *nchan0 = nchan; + ret = hn_rndis_conf_rss(sc, nchan); + if (ret != 0) + *nchan0 = 1; + else + *nchan0 = nchan; out: if (xact != NULL) vmbus_xact_put(xact); @@ -1503,8 +1269,17 @@ hv_rf_on_device_remove(struct hn_softc * int hv_rf_on_open(struct hn_softc *sc) { + uint32_t filter; - return (hv_rf_open_device(sc->rndis_dev)); + /* XXX */ + if (hv_promisc_mode != 1) { + filter = NDIS_PACKET_TYPE_BROADCAST | + NDIS_PACKET_TYPE_ALL_MULTICAST | + NDIS_PACKET_TYPE_DIRECTED; + } else { + filter = NDIS_PACKET_TYPE_PROMISCUOUS; + } + return (hn_rndis_set_rxfilter(sc, filter)); } /* @@ -1514,7 +1289,7 @@ int hv_rf_on_close(struct hn_softc *sc) { - return (hv_rf_close_device(sc->rndis_dev)); + return (hn_rndis_set_rxfilter(sc, 0)); } static void Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 06:32:21 2016 (r307183) +++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 06:34:18 2016 (r307184) @@ -29,93 +29,178 @@ #ifndef _NET_NDIS_H_ #define _NET_NDIS_H_ -#define NDIS_MEDIA_STATE_CONNECTED 0 -#define NDIS_MEDIA_STATE_DISCONNECTED 1 +#define NDIS_MEDIA_STATE_CONNECTED 0 +#define NDIS_MEDIA_STATE_DISCONNECTED 1 -#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C +#define NDIS_OFFLOAD_SET_NOCHG 0 +#define NDIS_OFFLOAD_SET_ON 1 +#define NDIS_OFFLOAD_SET_OFF 2 -#define NDIS_OBJTYPE_DEFAULT 0x80 +/* a.k.a GRE MAC */ +#define NDIS_ENCAP_TYPE_NVGRE 0x00000001 -/* common_set */ -#define NDIS_OFFLOAD_SET_NOCHG 0 -#define NDIS_OFFLOAD_SET_ON 1 -#define NDIS_OFFLOAD_SET_OFF 2 +#define NDIS_HASH_FUNCTION_MASK 0x000000FF /* see hash function */ +#define NDIS_HASH_TYPE_MASK 0x00FFFF00 /* see hash type */ -/* a.k.a GRE MAC */ -#define NDIS_ENCAP_TYPE_NVGRE 0x00000001 +/* hash function */ +#define NDIS_HASH_FUNCTION_TOEPLITZ 0x00000001 + +/* hash type */ +#define NDIS_HASH_IPV4 0x00000100 +#define NDIS_HASH_TCP_IPV4 0x00000200 +#define NDIS_HASH_IPV6 0x00000400 +#define NDIS_HASH_IPV6_EX 0x00000800 +#define NDIS_HASH_TCP_IPV6 0x00001000 +#define NDIS_HASH_TCP_IPV6_EX 0x00002000 + +#define NDIS_HASH_KEYSIZE_TOEPLITZ 40 +#define NDIS_HASH_INDCNT 128 + +#define NDIS_OBJTYPE_DEFAULT 0x80 +#define NDIS_OBJTYPE_RSS_CAPS 0x88 +#define NDIS_OBJTYPE_RSS_PARAMS 0x89 struct ndis_object_hdr { - uint8_t ndis_type; /* NDIS_OBJTYPE_ */ - uint8_t ndis_rev; /* type specific */ - uint16_t ndis_size; /* incl. this hdr */ + uint8_t ndis_type; /* NDIS_OBJTYPE_ */ + uint8_t ndis_rev; /* type specific */ + uint16_t ndis_size; /* incl. this hdr */ }; -/* OID_TCP_OFFLOAD_PARAMETERS */ +/* + * OID_TCP_OFFLOAD_PARAMETERS + * ndis_type: NDIS_OBJTYPE_DEFAULT + */ struct ndis_offload_params { struct ndis_object_hdr ndis_hdr; - uint8_t ndis_ip4csum; /* param_set */ - uint8_t ndis_tcp4csum; /* param_set */ - uint8_t ndis_udp4csum; /* param_set */ - uint8_t ndis_tcp6csum; /* param_set */ - uint8_t ndis_udp6csum; /* param_set */ - uint8_t ndis_lsov1; /* lsov1_set */ - uint8_t ndis_ipsecv1; /* ipsecv1_set */ - uint8_t ndis_lsov2_ip4; /* lsov2_set */ - uint8_t ndis_lsov2_ip6; /* lsov2_set */ - uint8_t ndis_tcp4conn; /* PARAM_NOCHG */ - uint8_t ndis_tcp6conn; /* PARAM_NOCHG */ - uint32_t ndis_flags; /* 0 */ + uint8_t ndis_ip4csum; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_tcp4csum; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_udp4csum; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_tcp6csum; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_udp6csum; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_lsov1; /* NDIS_OFFLOAD_PARAM_ */ + uint8_t ndis_ipsecv1; /* NDIS_OFFLOAD_IPSECV1_ */ + uint8_t ndis_lsov2_ip4; /* NDIS_OFFLOAD_LSOV2_ */ + uint8_t ndis_lsov2_ip6; /* NDIS_OFFLOAD_LSOV2_ */ + uint8_t ndis_tcp4conn; /* 0 */ + uint8_t ndis_tcp6conn; /* 0 */ + uint32_t ndis_flags; /* 0 */ /* NDIS >= 6.1 */ - uint8_t ndis_ipsecv2; /* ipsecv2_set */ - uint8_t ndis_ipsecv2_ip4; /* ipsecv2_set */ + uint8_t ndis_ipsecv2; /* NDIS_OFFLOAD_IPSECV2_ */ + uint8_t ndis_ipsecv2_ip4;/* NDIS_OFFLOAD_IPSECV2_ */ /* NDIS >= 6.30 */ - uint8_t ndis_rsc_ip4; /* rsc_set */ - uint8_t ndis_rsc_ip6; /* rsc_set */ - uint8_t ndis_encap; /* common_set */ - uint8_t ndis_encap_types; /* NDIS_ENCAP_TYPE_ */ + uint8_t ndis_rsc_ip4; /* NDIS_OFFLOAD_RSC_ */ + uint8_t ndis_rsc_ip6; /* NDIS_OFFLOAD_RSC_ */ + uint8_t ndis_encap; /* NDIS_OFFLOAD_SET_ */ + uint8_t ndis_encap_types;/* NDIS_ENCAP_TYPE_ */ }; -#define NDIS_OFFLOAD_PARAMS_SIZE sizeof(struct ndis_offload_params) -#define NDIS_OFFLOAD_PARAMS_SIZE_6_1 \ +#define NDIS_OFFLOAD_PARAMS_SIZE sizeof(struct ndis_offload_params) +#define NDIS_OFFLOAD_PARAMS_SIZE_6_1 \ __offsetof(struct ndis_offload_params, ndis_rsc_ip4) -#define NDIS_OFFLOAD_PARAMS_REV_2 2 /* NDIS 6.1 */ -#define NDIS_OFFLOAD_PARAMS_REV_3 3 /* NDIS 6.30 */ +#define NDIS_OFFLOAD_PARAMS_REV_2 2 /* NDIS 6.1 */ +#define NDIS_OFFLOAD_PARAMS_REV_3 3 /* NDIS 6.30 */ -/* param_set */ -#define NDIS_OFFLOAD_PARAM_NOCHG 0 /* common to all sets */ -#define NDIS_OFFLOAD_PARAM_OFF 1 -#define NDIS_OFFLOAD_PARAM_TX 2 -#define NDIS_OFFLOAD_PARAM_RX 3 -#define NDIS_OFFLOAD_PARAM_TXRX 4 +#define NDIS_OFFLOAD_PARAM_NOCHG 0 /* common */ +#define NDIS_OFFLOAD_PARAM_OFF 1 +#define NDIS_OFFLOAD_PARAM_TX 2 +#define NDIS_OFFLOAD_PARAM_RX 3 +#define NDIS_OFFLOAD_PARAM_TXRX 4 -/* lsov1_set */ /* NDIS_OFFLOAD_PARAM_NOCHG */ -#define NDIS_OFFLOAD_LSOV1_OFF 1 -#define NDIS_OFFLOAD_LSOV1_ON 2 +#define NDIS_OFFLOAD_LSOV1_OFF 1 +#define NDIS_OFFLOAD_LSOV1_ON 2 -/* ipsecv1_set */ /* NDIS_OFFLOAD_PARAM_NOCHG */ -#define NDIS_OFFLOAD_IPSECV1_OFF 1 -#define NDIS_OFFLOAD_IPSECV1_AH 2 -#define NDIS_OFFLOAD_IPSECV1_ESP 3 -#define NDIS_OFFLOAD_IPSECV1_AH_ESP 4 +#define NDIS_OFFLOAD_IPSECV1_OFF 1 +#define NDIS_OFFLOAD_IPSECV1_AH 2 +#define NDIS_OFFLOAD_IPSECV1_ESP 3 +#define NDIS_OFFLOAD_IPSECV1_AH_ESP 4 -/* lsov2_set */ /* NDIS_OFFLOAD_PARAM_NOCHG */ -#define NDIS_OFFLOAD_LSOV2_OFF 1 -#define NDIS_OFFLOAD_LSOV2_ON 2 +#define NDIS_OFFLOAD_LSOV2_OFF 1 +#define NDIS_OFFLOAD_LSOV2_ON 2 -/* ipsecv2_set */ /* NDIS_OFFLOAD_PARAM_NOCHG */ -#define NDIS_OFFLOAD_IPSECV2_OFF 1 -#define NDIS_OFFLOAD_IPSECV2_AH 2 -#define NDIS_OFFLOAD_IPSECV2_ESP 3 -#define NDIS_OFFLOAD_IPSECV2_AH_ESP 4 +#define NDIS_OFFLOAD_IPSECV2_OFF 1 +#define NDIS_OFFLOAD_IPSECV2_AH 2 +#define NDIS_OFFLOAD_IPSECV2_ESP 3 +#define NDIS_OFFLOAD_IPSECV2_AH_ESP 4 -/* rsc_set */ /* NDIS_OFFLOAD_PARAM_NOCHG */ -#define NDIS_OFFLOAD_RSC_OFF 1 -#define NDIS_OFFLOAD_RSC_ON 2 +#define NDIS_OFFLOAD_RSC_OFF 1 +#define NDIS_OFFLOAD_RSC_ON 2 + +/* + * OID_GEN_RECEIVE_SCALE_CAPABILITIES + * ndis_type: NDIS_OBJTYPE_RSS_CAPS + */ +struct ndis_rss_caps { + struct ndis_object_hdr ndis_hdr; + uint32_t ndis_flags; /* NDIS_RSS_CAP_ */ + uint32_t ndis_nmsi; /* # of MSIs */ + uint32_t ndis_nrxr; /* # of RX rings */ + /* NDIS >= 6.30 */ + uint16_t ndis_nind; /* # of indtbl ent. */ + uint16_t ndis_pad; +}; + +#define NDIS_RSS_CAPS_SIZE \ + __offsetof(struct ndis_rss_caps, ndis_pad) +#define NDIS_RSS_CAPS_SIZE_6_0 \ + __offsetof(struct ndis_rss_caps, ndis_nind) + +#define NDIS_RSS_CAPS_REV_1 1 /* NDIS 6.{0,1,20} */ +#define NDIS_RSS_CAPS_REV_2 2 /* NDIS 6.30 */ + +#define NDIS_RSS_CAP_MSI 0x01000000 +#define NDIS_RSS_CAP_CLASSIFY_ISR 0x02000000 +#define NDIS_RSS_CAP_CLASSIFY_DPC 0x04000000 +#define NDIS_RSS_CAP_MSIX 0x08000000 +#define NDIS_RSS_CAP_IPV4 0x00000100 +#define NDIS_RSS_CAP_IPV6 0x00000200 +#define NDIS_RSS_CAP_IPV6_EX 0x00000400 +#define NDIS_RSS_CAP_HASH_TOEPLITZ 0x00000001 + +/* + * OID_GEN_RECEIVE_SCALE_PARAMETERS + * ndis_type: NDIS_OBJTYPE_RSS_PARAMS + */ +struct ndis_rss_params { + struct ndis_object_hdr ndis_hdr; + uint16_t ndis_flags; /* NDIS_RSS_FLAG_ */ + uint16_t ndis_bcpu; /* base cpu 0 */ + uint32_t ndis_hash; /* NDIS_HASH_ */ + uint16_t ndis_indsize; /* indirect table */ + uint32_t ndis_indoffset; + uint16_t ndis_keysize; /* hash key */ + uint32_t ndis_keyoffset; + /* NDIS >= 6.20 */ + uint32_t ndis_cpumaskoffset; + uint32_t ndis_cpumaskcnt; + uint32_t ndis_cpumaskentsz; +}; + +#define NDIS_RSS_PARAMS_SIZE sizeof(struct ndis_rss_params) +#define NDIS_RSS_PARAMS_SIZE_6_0 \ + __offsetof(struct ndis_rss_params, ndis_cpumaskoffset) + +#define NDIS_RSS_PARAMS_REV_1 1 /* NDIS 6.0 */ +#define NDIS_RSS_PARAMS_REV_2 2 /* NDIS 6.20 */ + +#define NDIS_RSS_FLAG_BCPU_UNCHG 0x0001 +#define NDIS_RSS_FLAG_HASH_UNCHG 0x0002 +#define NDIS_RSS_FLAG_IND_UNCHG 0x0004 +#define NDIS_RSS_FLAG_KEY_UNCHG 0x0008 +#define NDIS_RSS_FLAG_DISABLE 0x0010 + +/* non-standard convenient struct */ +struct ndis_rssprm_toeplitz { + struct ndis_rss_params rss_params; + /* Toeplitz hash key */ + uint8_t rss_key[NDIS_HASH_KEYSIZE_TOEPLITZ]; + /* Indirect table */ + uint32_t rss_ind[NDIS_HASH_INDCNT]; +}; #endif /* !_NET_NDIS_H_ */ Modified: stable/10/sys/dev/usb/net/if_urndis.c ============================================================================== --- stable/10/sys/dev/usb/net/if_urndis.c Thu Oct 13 06:32:21 2016 (r307183) +++ stable/10/sys/dev/usb/net/if_urndis.c Thu Oct 13 06:34:18 2016 (r307184) @@ -291,8 +291,8 @@ urndis_attach(device_t dev) memcpy(&sc->sc_ue.ue_eaddr, buf, ETHER_ADDR_LEN); /* Initialize packet filter */ - sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST | - RNDIS_PACKET_TYPE_ALL_MULTICAST; + sc->sc_filter = NDIS_PACKET_TYPE_BROADCAST | *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:39:07 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C95E2C0F4B7; Thu, 13 Oct 2016 06:39:07 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A497DDF7; Thu, 13 Oct 2016 06:39:07 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6d6Wp096382; Thu, 13 Oct 2016 06:39:06 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6d6OC096379; Thu, 13 Oct 2016 06:39:06 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130639.u9D6d6OC096379@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:39:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307185 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:39:07 -0000 Author: sephe Date: Thu Oct 13 06:39:06 2016 New Revision: 307185 URL: https://svnweb.freebsd.org/changeset/base/307185 Log: MFC 305049,305050 305049 hyperv/hn: Factor out func to exec RNDIS transaction w/o checking result It will be used by RNDIS HALT and RESET. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7685 305050 hyperv/hn: Switch to new RNDIS transaction execution for halt. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7686 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:34:18 2016 (r307184) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:39:06 2016 (r307185) @@ -73,8 +73,6 @@ static void hv_nv_on_receive(struct hn_s static void hn_nvs_sent_none(struct hn_send_ctx *sndc, struct hn_softc *, struct vmbus_channel *chan, const void *, int); -static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc, - struct vmbus_channel *, const void *, int); struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); @@ -654,7 +652,7 @@ hv_nv_on_device_remove(struct hn_softc * return (0); } -static void +void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, const void *data, int dlen) Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:34:18 2016 (r307184) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:39:06 2016 (r307185) @@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$"); /* * Forward declarations */ -static int hv_rf_send_request(rndis_device *device, rndis_request *request, - uint32_t message_type); static void hv_rf_receive_response(rndis_device *device, const rndis_msg *response); static void hv_rf_receive_indicate_status(rndis_device *device, @@ -84,12 +82,6 @@ static inline int hv_rf_query_device_mac static inline int hv_rf_query_device_link_status(rndis_device *device); static int hv_rf_init_device(rndis_device *device); -static void hn_rndis_sent_halt(struct hn_send_ctx *sndc, - struct hn_softc *sc, struct vmbus_channel *chan, - const void *data, int dlen); -static void hn_rndis_sent_cb(struct hn_send_ctx *sndc, - struct hn_softc *sc, struct vmbus_channel *chan, - const void *data, int dlen); static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0); static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, @@ -198,120 +190,6 @@ hv_put_rndis_device(rndis_device *device } /* - * - */ -static inline rndis_request * -hv_rndis_request(rndis_device *device, uint32_t message_type, - uint32_t message_length) -{ - rndis_request *request; - rndis_msg *rndis_mesg; - rndis_set_request *set; - - request = malloc(sizeof(rndis_request), M_NETVSC, M_WAITOK | M_ZERO); - - sema_init(&request->wait_sema, 0, "rndis sema"); - - rndis_mesg = &request->request_msg; - rndis_mesg->ndis_msg_type = message_type; - rndis_mesg->msg_len = message_length; - - /* - * Set the request id. This field is always after the rndis header - * for request/response packet types so we just use the set_request - * as a template. - */ - set = &rndis_mesg->msg.set_request; - set->request_id = atomic_fetchadd_int(&device->new_request_id, 1) & - HN_RNDIS_RID_COMPAT_MASK; - - /* Add to the request list */ - mtx_lock(&device->req_lock); - STAILQ_INSERT_TAIL(&device->myrequest_list, request, mylist_entry); - mtx_unlock(&device->req_lock); - - return (request); -} - -/* - * - */ -static inline void -hv_put_rndis_request(rndis_device *device, rndis_request *request) -{ - mtx_lock(&device->req_lock); - /* Fixme: Has O(n) performance */ - /* - * XXXKYS: Use Doubly linked lists. - */ - STAILQ_REMOVE(&device->myrequest_list, request, rndis_request_, - mylist_entry); - mtx_unlock(&device->req_lock); - - sema_destroy(&request->wait_sema); - free(request, M_NETVSC); -} - -/* - * - */ -static int -hv_rf_send_request(rndis_device *device, rndis_request *request, - uint32_t message_type) -{ - struct hn_softc *sc = device->sc; - uint32_t send_buf_section_idx, tot_data_buf_len; - struct vmbus_gpa gpa[2]; - int gpa_cnt, send_buf_section_size; - hn_sent_callback_t cb; - - /* Set up the packet to send it */ - tot_data_buf_len = request->request_msg.msg_len; - - gpa_cnt = 1; - gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT; - gpa[0].gpa_len = request->request_msg.msg_len; - gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1); - - if (gpa[0].gpa_ofs + gpa[0].gpa_len > PAGE_SIZE) { - gpa_cnt = 2; - gpa[0].gpa_len = PAGE_SIZE - gpa[0].gpa_ofs; - gpa[1].gpa_page = - hv_get_phys_addr((char*)&request->request_msg + - gpa[0].gpa_len) >> PAGE_SHIFT; - gpa[1].gpa_ofs = 0; - gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len; - } - - if (message_type != REMOTE_NDIS_HALT_MSG) - cb = hn_rndis_sent_cb; - else - cb = hn_rndis_sent_halt; - - if (tot_data_buf_len < sc->hn_chim_szmax) { - send_buf_section_idx = hn_chim_alloc(sc); - if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) { - uint8_t *dest = sc->hn_chim + - (send_buf_section_idx * sc->hn_chim_szmax); - - memcpy(dest, &request->request_msg, request->request_msg.msg_len); - send_buf_section_size = tot_data_buf_len; - gpa_cnt = 0; - goto sendit; - } - /* Failed to allocate chimney send buffer; move on */ - } - send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID; - send_buf_section_size = 0; - -sendit: - hn_send_ctx_init(&request->send_ctx, cb, request, - send_buf_section_idx, send_buf_section_size); - return hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, - &request->send_ctx, gpa, gpa_cnt); -} - -/* * RNDIS filter receive response */ static void @@ -603,20 +481,15 @@ static uint8_t netvsc_hash_key[NDIS_HASH }; static const void * -hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid, - size_t reqlen, size_t *comp_len0, uint32_t comp_type) +hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, + struct hn_send_ctx *sndc, size_t *comp_len) { struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT]; - const struct rndis_comp_hdr *comp; - bus_addr_t paddr; - size_t comp_len, min_complen = *comp_len0; int gpa_cnt, error; + bus_addr_t paddr; - KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid)); KASSERT(reqlen <= HN_XACT_REQ_SIZE && reqlen > 0, ("invalid request length %zu", reqlen)); - KASSERT(min_complen >= sizeof(*comp), - ("invalid minimum complete len %zu", min_complen)); /* * Setup the SG list. @@ -645,14 +518,34 @@ hn_rndis_xact_execute(struct hn_softc *s * message. */ vmbus_xact_activate(xact); - error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, - &hn_send_ctx_none, gpa, gpa_cnt); + error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc, + gpa, gpa_cnt); if (error) { vmbus_xact_deactivate(xact); if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error); return (NULL); } - comp = vmbus_xact_wait(xact, &comp_len); + return (vmbus_xact_wait(xact, comp_len)); +} + +static const void * +hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid, + size_t reqlen, size_t *comp_len0, uint32_t comp_type) +{ + const struct rndis_comp_hdr *comp; + size_t comp_len, min_complen = *comp_len0; + + KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid)); + KASSERT(min_complen >= sizeof(*comp), + ("invalid minimum complete len %zu", min_complen)); + + /* + * Execute the xact setup by the caller. + */ + comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none, + &comp_len); + if (comp == NULL) + return (NULL); /* * Check this RNDIS complete message. @@ -1038,51 +931,34 @@ done: return (error); } -#define HALT_COMPLETION_WAIT_COUNT 25 - /* * RNDIS filter halt device */ static int -hv_rf_halt_device(rndis_device *device) +hv_rf_halt_device(struct hn_softc *sc) { - rndis_request *request; - int i, ret; - - /* Attempt to do a rndis device halt */ - request = hv_rndis_request(device, REMOTE_NDIS_HALT_MSG, - RNDIS_MESSAGE_SIZE(rndis_halt_request)); - if (request == NULL) { - return (-1); - } - - /* initialize "poor man's semaphore" */ - request->halt_complete_flag = 0; - - ret = hv_rf_send_request(device, request, REMOTE_NDIS_HALT_MSG); - if (ret != 0) { - return (-1); - } + struct vmbus_xact *xact; + struct rndis_halt_req *halt; + struct hn_send_ctx sndc; + size_t comp_len; - /* - * Wait for halt response from halt callback. We must wait for - * the transaction response before freeing the request and other - * resources. - */ - for (i=HALT_COMPLETION_WAIT_COUNT; i > 0; i--) { - if (request->halt_complete_flag != 0) { - break; - } - DELAY(400); - } - if (i == 0) { - return (-1); + xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for RNDIS halt\n"); + return (ENXIO); } + halt = vmbus_xact_req_data(xact); + halt->rm_type = REMOTE_NDIS_HALT_MSG; + halt->rm_len = sizeof(*halt); + halt->rm_rid = hn_rndis_rid(sc); + + /* No RNDIS completion; rely on NVS message send completion */ + hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len); - device->state = RNDIS_DEV_UNINITIALIZED; - - hv_put_rndis_request(device, request); - + vmbus_xact_put(xact); + if (bootverbose) + if_printf(sc->hn_ifp, "RNDIS halt done\n"); return (0); } @@ -1252,7 +1128,7 @@ hv_rf_on_device_remove(struct hn_softc * int ret; /* Halt and release the rndis device */ - ret = hv_rf_halt_device(rndis_dev); + ret = hv_rf_halt_device(sc); sc->rndis_dev = NULL; hv_put_rndis_device(rndis_dev); @@ -1292,33 +1168,6 @@ hv_rf_on_close(struct hn_softc *sc) return (hn_rndis_set_rxfilter(sc, 0)); } -static void -hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct hn_softc *sc, - struct vmbus_channel *chan __unused, const void *data __unused, - int dlen __unused) -{ - if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID) - hn_chim_free(sc, sndc->hn_chim_idx); -} - -static void -hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct hn_softc *sc, - struct vmbus_channel *chan __unused, const void *data __unused, - int dlen __unused) -{ - rndis_request *request = sndc->hn_cbarg; - - if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID) - hn_chim_free(sc, sndc->hn_chim_idx); - - /* - * Notify hv_rf_halt_device() about halt completion. - * The halt code must wait for completion before freeing - * the transaction resources. - */ - request->halt_complete_flag = 1; -} - void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 06:34:18 2016 (r307184) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 06:39:06 2016 (r307185) @@ -112,6 +112,8 @@ struct vmbus_xact; const void *hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, size_t *resp_len); +void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, + struct vmbus_channel *chan, const void *data, int dlen); uint32_t hn_chim_alloc(struct hn_softc *sc); void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:47:04 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 10FEEC0F704; Thu, 13 Oct 2016 06:47:04 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C5B5C1498; Thu, 13 Oct 2016 06:47:03 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6l2Vl000146; Thu, 13 Oct 2016 06:47:02 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6l2Jp000140; Thu, 13 Oct 2016 06:47:02 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130647.u9D6l2Jp000140@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:47:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307186 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:47:04 -0000 Author: sephe Date: Thu Oct 13 06:47:02 2016 New Revision: 307186 URL: https://svnweb.freebsd.org/changeset/base/307186 Log: MFC 305052-305054,305110 305052 hyperv/hn: Remove the useless rndis_device and related bits Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7687 305053 hyperv/hn: Log packet message alignment. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7689 305054 hyperv/hn: Remove unnecessary NULL check. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7690 305110 hyperv/hn: Consolidate NVS transaction execution. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7704 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 06:47:02 2016 (r307186) @@ -106,21 +106,45 @@ hn_chim_alloc(struct hn_softc *sc) const void * hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, - void *req, int reqlen, size_t *resp_len) + void *req, int reqlen, size_t *resplen0, uint32_t type) { struct hn_send_ctx sndc; + size_t resplen, min_resplen = *resplen0; + const struct hn_nvs_hdr *hdr; int error; + KASSERT(min_resplen >= sizeof(*hdr), + ("invalid minimum response len %zu", min_resplen)); + + /* + * Execute the xact setup by the caller. + */ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); - vmbus_xact_activate(xact); + vmbus_xact_activate(xact); error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, req, reqlen, &sndc); if (error) { vmbus_xact_deactivate(xact); - return NULL; + return (NULL); } - return (vmbus_xact_wait(xact, resp_len)); + hdr = vmbus_xact_wait(xact, &resplen); + + /* + * Check this NVS response message. + */ + if (resplen < min_resplen) { + if_printf(sc->hn_ifp, "invalid NVS resp len %zu\n", resplen); + return (NULL); + } + if (hdr->nvs_type != type) { + if_printf(sc->hn_ifp, "unexpected NVS resp 0x%08x, " + "expect 0x%08x\n", hdr->nvs_type, type); + return (NULL); + } + /* All pass! */ + *resplen0 = resplen; + return (hdr); } static __inline int @@ -180,24 +204,14 @@ hv_nv_init_rx_buffer_with_net_vsp(struct conn->nvs_gpadl = sc->hn_rxbuf_gpadl; conn->nvs_sig = HN_NVS_RXBUF_SIG; - resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len); + resp_len = sizeof(*resp); + resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len, + HN_NVS_TYPE_RXBUF_CONNRESP); if (resp == NULL) { if_printf(sc->hn_ifp, "exec rxbuf conn failed\n"); error = EIO; goto cleanup; } - if (resp_len < sizeof(*resp)) { - if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n", - resp_len); - error = EINVAL; - goto cleanup; - } - if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) { - if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n", - resp->nvs_type); - error = EINVAL; - goto cleanup; - } status = resp->nvs_status; vmbus_xact_put(xact); @@ -263,24 +277,14 @@ hv_nv_init_send_buffer_with_net_vsp(stru chim->nvs_gpadl = sc->hn_chim_gpadl; chim->nvs_sig = HN_NVS_CHIM_SIG; - resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len); + resp_len = sizeof(*resp); + resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len, + HN_NVS_TYPE_CHIM_CONNRESP); if (resp == NULL) { if_printf(sc->hn_ifp, "exec chim conn failed\n"); error = EIO; goto cleanup; } - if (resp_len < sizeof(*resp)) { - if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n", - resp_len); - error = EINVAL; - goto cleanup; - } - if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) { - if_printf(sc->hn_ifp, "not chim conn resp, type %u\n", - resp->nvs_type); - error = EINVAL; - goto cleanup; - } status = resp->nvs_status; sectsz = resp->nvs_sectsz; @@ -441,24 +445,14 @@ hv_nv_negotiate_nvsp_protocol(struct hn_ init->nvs_ver_min = nvs_ver; init->nvs_ver_max = nvs_ver; - resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len); + resp_len = sizeof(*resp); + resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len, + HN_NVS_TYPE_INIT_RESP); if (resp == NULL) { if_printf(sc->hn_ifp, "exec init failed\n"); vmbus_xact_put(xact); return (EIO); } - if (resp_len < sizeof(*resp)) { - if_printf(sc->hn_ifp, "invalid init resp length %zu\n", - resp_len); - vmbus_xact_put(xact); - return (EINVAL); - } - if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) { - if_printf(sc->hn_ifp, "not init resp, type %u\n", - resp->nvs_type); - vmbus_xact_put(xact); - return (EINVAL); - } status = resp->nvs_status; vmbus_xact_put(xact); @@ -640,7 +634,7 @@ cleanup: * Net VSC on device remove */ int -hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) +hv_nv_on_device_remove(struct hn_softc *sc) { hv_nv_disconnect_from_vsp(sc); Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 06:47:02 2016 (r307186) @@ -237,8 +237,8 @@ typedef void (*pfn_on_send_rx_completion #define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP) typedef struct { - uint8_t mac_addr[6]; /* Assumption unsigned long */ - uint8_t link_state; + uint8_t mac_addr[ETHER_ADDR_LEN]; + uint32_t link_state; } netvsc_device_info; #define HN_XACT_REQ_PGCNT 2 @@ -352,7 +352,6 @@ typedef struct hn_softc { int hn_initdone; /* See hv_netvsc_drv_freebsd.c for rules on how to use */ int temp_unusable; - struct rndis_device_ *rndis_dev; struct vmbus_channel *hn_prichan; int hn_rx_ring_cnt; @@ -401,8 +400,7 @@ struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); int hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr); -int hv_nv_on_device_remove(struct hn_softc *sc, - boolean_t destroy_channel); +int hv_nv_on_device_remove(struct hn_softc *sc); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); void hv_nv_subchan_attach(struct vmbus_channel *chan, Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 06:47:02 2016 (r307186) @@ -156,8 +156,8 @@ __FBSDID("$FreeBSD$"); #define HN_TX_DATA_BOUNDARY PAGE_SIZE #define HN_TX_DATA_MAXSIZE IP_MAXPACKET #define HN_TX_DATA_SEGSIZE PAGE_SIZE -#define HN_TX_DATA_SEGCNT_MAX \ - (NETVSC_PACKET_MAXPAGE - HV_RF_NUM_TX_RESERVED_PAGE_BUFS) +/* -1 for RNDIS packet message */ +#define HN_TX_DATA_SEGCNT_MAX (NETVSC_PACKET_MAXPAGE - 1) #define HN_DIRECT_TX_SIZE_DEF 128 @@ -663,7 +663,7 @@ netvsc_detach(device_t dev) * the netdevice. */ - hv_rf_on_device_remove(sc, HV_RF_NV_DESTROY_CHANNEL); + hv_rf_on_device_remove(sc); hn_stop_tx_tasks(sc); @@ -1047,7 +1047,8 @@ hn_encap(struct hn_tx_ring *txr, struct } *m_head0 = m_head; - txr->hn_gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS; + /* +1 RNDIS packet message */ + txr->hn_gpa_cnt = nsegs + 1; /* send packet with page buffer */ txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr); @@ -1055,12 +1056,11 @@ hn_encap(struct hn_tx_ring *txr, struct txr->hn_gpa[0].gpa_len = rndis_msg_size; /* - * Fill the page buffers with mbuf info starting at index - * HV_RF_NUM_TX_RESERVED_PAGE_BUFS. + * Fill the page buffers with mbuf info after the page + * buffer for RNDIS packet message. */ for (i = 0; i < nsegs; ++i) { - struct vmbus_gpa *gpa = &txr->hn_gpa[ - i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS]; + struct vmbus_gpa *gpa = &txr->hn_gpa[i + 1]; gpa->gpa_page = atop(segs[i].ds_addr); gpa->gpa_ofs = segs[i].ds_addr & PAGE_MASK; @@ -1594,7 +1594,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, * MTU to take effect. This includes tearing down, but not * deleting the channel, then bringing it back up. */ - error = hv_rf_on_device_remove(sc, HV_RF_NV_RETAIN_CHANNEL); + error = hv_rf_on_device_remove(sc); if (error) { NV_LOCK(sc); sc->temp_unusable = FALSE; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:47:02 2016 (r307186) @@ -72,15 +72,14 @@ __FBSDID("$FreeBSD$"); /* * Forward declarations */ -static void hv_rf_receive_response(rndis_device *device, - const rndis_msg *response); -static void hv_rf_receive_indicate_status(rndis_device *device, +static void hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response); static void hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen); -static inline int hv_rf_query_device_mac(rndis_device *device); -static inline int hv_rf_query_device_link_status(rndis_device *device); -static int hv_rf_init_device(rndis_device *device); +static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr); +static int hv_rf_query_device_link_status(struct hn_softc *sc, + uint32_t *link_status); +static int hv_rf_init_device(struct hn_softc *sc); static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0); @@ -158,94 +157,24 @@ hv_get_ppi_data(rndis_packet *rpkt, uint return (NULL); } - -/* - * Allow module_param to work and override to switch to promiscuous mode. - */ -static inline rndis_device * -hv_get_rndis_device(void) -{ - rndis_device *device; - - device = malloc(sizeof(rndis_device), M_NETVSC, M_WAITOK | M_ZERO); - - mtx_init(&device->req_lock, "HV-FRL", NULL, MTX_DEF); - - /* Same effect as STAILQ_HEAD_INITIALIZER() static initializer */ - STAILQ_INIT(&device->myrequest_list); - - device->state = RNDIS_DEV_UNINITIALIZED; - - return (device); -} - -/* - * - */ -static inline void -hv_put_rndis_device(rndis_device *device) -{ - mtx_destroy(&device->req_lock); - free(device, M_NETVSC); -} - -/* - * RNDIS filter receive response - */ -static void -hv_rf_receive_response(rndis_device *device, const rndis_msg *response) -{ - rndis_request *request = NULL; - rndis_request *next_request; - boolean_t found = FALSE; - - mtx_lock(&device->req_lock); - request = STAILQ_FIRST(&device->myrequest_list); - while (request != NULL) { - /* - * All request/response message contains request_id as the - * first field - */ - if (request->request_msg.msg.init_request.request_id == - response->msg.init_complete.request_id) { - found = TRUE; - break; - } - next_request = STAILQ_NEXT(request, mylist_entry); - request = next_request; - } - mtx_unlock(&device->req_lock); - - if (found) { - if (response->msg_len <= sizeof(rndis_msg)) { - memcpy(&request->response_msg, response, - response->msg_len); - } else { - request->response_msg.msg.init_complete.status = - RNDIS_STATUS_BUFFER_OVERFLOW; - } - sema_post(&request->wait_sema); - } -} - /* * RNDIS filter receive indicate status */ static void -hv_rf_receive_indicate_status(rndis_device *device, const rndis_msg *response) +hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response) { const rndis_indicate_status *indicate = &response->msg.indicate_status; switch(indicate->status) { case RNDIS_STATUS_MEDIA_CONNECT: - netvsc_linkstatus_callback(device->sc, 1); + netvsc_linkstatus_callback(sc, 1); break; case RNDIS_STATUS_MEDIA_DISCONNECT: - netvsc_linkstatus_callback(device->sc, 0); + netvsc_linkstatus_callback(sc, 0); break; default: /* TODO: */ - device_printf(device->sc->hn_dev, + if_printf(sc->hn_ifp, "unknown status %d received\n", indicate->status); break; } @@ -375,14 +304,9 @@ int hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen) { - rndis_device *rndis_dev; const rndis_msg *rndis_hdr; const struct rndis_comp_hdr *comp; - rndis_dev = sc->rndis_dev; - if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) - return (EINVAL); - rndis_hdr = data; switch (rndis_hdr->ndis_msg_type) { /* data message */ @@ -396,17 +320,14 @@ hv_rf_on_receive(struct hn_softc *sc, st case REMOTE_NDIS_SET_CMPLT: case REMOTE_NDIS_KEEPALIVE_CMPLT: comp = data; - if (comp->rm_rid <= HN_RNDIS_RID_COMPAT_MAX) { - /* Transition time compat code */ - hv_rf_receive_response(rndis_dev, rndis_hdr); - } else { - vmbus_xact_ctx_wakeup(sc->hn_xact, data, dlen); - } + KASSERT(comp->rm_rid > HN_RNDIS_RID_COMPAT_MAX, + ("invalid rid 0x%08x\n", comp->rm_rid)); + vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen); break; /* notification message */ case REMOTE_NDIS_INDICATE_STATUS_MSG: - hv_rf_receive_indicate_status(rndis_dev, rndis_hdr); + hv_rf_receive_indicate_status(sc, rndis_hdr); break; case REMOTE_NDIS_RESET_CMPLT: @@ -432,19 +353,18 @@ hv_rf_on_receive(struct hn_softc *sc, st * RNDIS filter query device MAC address */ static int -hv_rf_query_device_mac(rndis_device *device) +hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr) { - struct hn_softc *sc = device->sc; - size_t hwaddr_len; + size_t eaddr_len; int error; - hwaddr_len = ETHER_ADDR_LEN; + eaddr_len = ETHER_ADDR_LEN; error = hn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0, - device->hw_mac_addr, &hwaddr_len); + eaddr, &eaddr_len); if (error) return (error); - if (hwaddr_len != ETHER_ADDR_LEN) { - if_printf(sc->hn_ifp, "invalid hwaddr len %zu\n", hwaddr_len); + if (eaddr_len != ETHER_ADDR_LEN) { + if_printf(sc->hn_ifp, "invalid eaddr len %zu\n", eaddr_len); return (EINVAL); } return (0); @@ -453,16 +373,15 @@ hv_rf_query_device_mac(rndis_device *dev /* * RNDIS filter query device link status */ -static inline int -hv_rf_query_device_link_status(rndis_device *device) +static int +hv_rf_query_device_link_status(struct hn_softc *sc, uint32_t *link_status) { - struct hn_softc *sc = device->sc; size_t size; int error; - size = sizeof(uint32_t); + size = sizeof(*link_status); error = hn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS, NULL, 0, - &device->link_status, &size); + link_status, &size); if (error) return (error); if (size != sizeof(uint32_t)) { @@ -876,9 +795,8 @@ hn_rndis_set_rxfilter(struct hn_softc *s * RNDIS filter init device */ static int -hv_rf_init_device(rndis_device *device) +hv_rf_init_device(struct hn_softc *sc) { - struct hn_softc *sc = device->sc; struct rndis_init_req *req; const struct rndis_init_comp *comp; struct vmbus_xact *xact; @@ -886,9 +804,6 @@ hv_rf_init_device(rndis_device *device) uint32_t rid; int error; - /* XXX */ - device->state = RNDIS_DEV_INITIALIZED; - xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); if (xact == NULL) { if_printf(sc->hn_ifp, "no xact for RNDIS init\n"); @@ -919,15 +834,14 @@ hv_rf_init_device(rndis_device *device) goto done; } if (bootverbose) { - if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u\n", - comp->rm_ver_major, comp->rm_ver_minor, - comp->rm_pktmaxsz, comp->rm_pktmaxcnt); + if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u, " + "align %u\n", comp->rm_ver_major, comp->rm_ver_minor, + comp->rm_pktmaxsz, comp->rm_pktmaxcnt, + 1U << comp->rm_align); } error = 0; - done: - if (xact != NULL) - vmbus_xact_put(xact); + vmbus_xact_put(xact); return (error); } @@ -970,7 +884,6 @@ hv_rf_on_device_add(struct hn_softc *sc, int *nchan0, struct hn_rx_ring *rxr) { int ret; - rndis_device *rndis_dev; netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; device_t dev = sc->hn_dev; struct hn_nvs_subch_req *req; @@ -981,13 +894,6 @@ hv_rf_on_device_add(struct hn_softc *sc, int nchan = *nchan0; int rxr_cnt; - rndis_dev = hv_get_rndis_device(); - if (rndis_dev == NULL) { - return (ENOMEM); - } - sc->rndis_dev = rndis_dev; - rndis_dev->sc = sc; - /* * Let the inner driver handle this first to create the netvsc channel * NOTE! Once the channel is created, we may get a receive callback @@ -995,17 +901,15 @@ hv_rf_on_device_add(struct hn_softc *sc, * Note: Earlier code used a function pointer here. */ ret = hv_nv_on_device_add(sc, rxr); - if (ret != 0) { - hv_put_rndis_device(rndis_dev); + if (ret != 0) return (ret); - } /* * Initialize the rndis device */ /* Send the rndis initialization message */ - ret = hv_rf_init_device(rndis_dev); + ret = hv_rf_init_device(sc); if (ret != 0) { /* * TODO: If rndis init failed, we will need to shut down @@ -1014,19 +918,15 @@ hv_rf_on_device_add(struct hn_softc *sc, } /* Get the mac address */ - ret = hv_rf_query_device_mac(rndis_dev); + ret = hv_rf_query_device_mac(sc, dev_info->mac_addr); if (ret != 0) { /* TODO: shut down rndis device and the channel */ } /* Configure NDIS offload settings */ hn_rndis_conf_offload(sc); - - memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, ETHER_ADDR_LEN); - hv_rf_query_device_link_status(rndis_dev); - - dev_info->link_state = rndis_dev->link_status; + hv_rf_query_device_link_status(sc, &dev_info->link_state); if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) { /* @@ -1071,24 +971,14 @@ hv_rf_on_device_add(struct hn_softc *sc, req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; req->nvs_nsubch = nchan - 1; - resp = hn_nvs_xact_execute(sc, xact, req, sizeof(*req), &resp_len); + resp_len = sizeof(*resp); + resp = hn_nvs_xact_execute(sc, xact, req, sizeof(*req), &resp_len, + HN_NVS_TYPE_SUBCH_RESP); if (resp == NULL) { if_printf(sc->hn_ifp, "exec subch failed\n"); ret = EIO; goto out; } - if (resp_len < sizeof(*resp)) { - if_printf(sc->hn_ifp, "invalid subch resp length %zu\n", - resp_len); - ret = EINVAL; - goto out; - } - if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) { - if_printf(sc->hn_ifp, "not subch resp, type %u\n", - resp->nvs_type); - ret = EINVAL; - goto out; - } status = resp->nvs_status; nsubch = resp->nvs_nsubch; @@ -1122,19 +1012,15 @@ out: * RNDIS filter on device remove */ int -hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) +hv_rf_on_device_remove(struct hn_softc *sc) { - rndis_device *rndis_dev = sc->rndis_dev; int ret; /* Halt and release the rndis device */ ret = hv_rf_halt_device(sc); - sc->rndis_dev = NULL; - hv_put_rndis_device(rndis_dev); - /* Pass control to inner driver to remove the device */ - ret |= hv_nv_on_device_remove(sc, destroy_channel); + ret |= hv_nv_on_device_remove(sc); return (ret); } Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 06:47:02 2016 (r307186) @@ -36,80 +36,6 @@ #include /* - * Defines - */ - -/* Destroy or preserve channel on filter/netvsc teardown */ -#define HV_RF_NV_DESTROY_CHANNEL TRUE -#define HV_RF_NV_RETAIN_CHANNEL FALSE - -/* - * Number of page buffers to reserve for the RNDIS filter packet in the - * transmitted message. - */ -#define HV_RF_NUM_TX_RESERVED_PAGE_BUFS 1 - - -/* - * Data types - */ - -typedef enum { - RNDIS_DEV_UNINITIALIZED = 0, - RNDIS_DEV_INITIALIZING, - RNDIS_DEV_INITIALIZED, - RNDIS_DEV_DATAINITIALIZED, -} rndis_device_state; - -typedef struct rndis_request_ { - STAILQ_ENTRY(rndis_request_) mylist_entry; - struct sema wait_sema; - - /* - * The max response size is sizeof(rndis_msg) + PAGE_SIZE. - * - * XXX - * This is ugly and should be cleaned up once we busdma-fy - * RNDIS request bits. - */ - rndis_msg response_msg; - uint8_t buf_resp[PAGE_SIZE]; - - /* Simplify allocation by having a netvsc packet inline */ - struct hn_send_ctx send_ctx; - - /* - * The max request size is sizeof(rndis_msg) + PAGE_SIZE. - * - * NOTE: - * This is required for the large request like RSS settings. - * - * XXX - * This is ugly and should be cleaned up once we busdma-fy - * RNDIS request bits. - */ - rndis_msg request_msg; - uint8_t buf_req[PAGE_SIZE]; - - /* Fixme: Poor man's semaphore. */ - uint32_t halt_complete_flag; -} rndis_request; - -typedef struct rndis_device_ { - struct hn_softc *sc; - - rndis_device_state state; - uint32_t link_status; - uint32_t new_request_id; - - struct mtx req_lock; - - STAILQ_HEAD(RQ, rndis_request_) myrequest_list; - - uint8_t hw_mac_addr[ETHER_ADDR_LEN]; -} rndis_device; - -/* * Externs */ struct hn_rx_ring; @@ -119,7 +45,7 @@ int hv_rf_on_receive(struct hn_softc *sc void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan, struct hn_rx_ring *rxr); -int hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel); +int hv_rf_on_device_remove(struct hn_softc *sc); int hv_rf_on_open(struct hn_softc *sc); int hv_rf_on_close(struct hn_softc *sc); Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 06:39:06 2016 (r307185) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 06:47:02 2016 (r307186) @@ -111,7 +111,7 @@ struct vmbus_xact; const void *hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, - size_t *resp_len); + size_t *resp_len, uint32_t type); void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, const void *data, int dlen); uint32_t hn_chim_alloc(struct hn_softc *sc); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:49:01 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BD571C0F80D; Thu, 13 Oct 2016 06:49:01 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8067916CB; Thu, 13 Oct 2016 06:49:01 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6n0W3000267; Thu, 13 Oct 2016 06:49:00 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6n0n6000266; Thu, 13 Oct 2016 06:49:00 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130649.u9D6n0n6000266@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:49:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307187 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:49:01 -0000 Author: sephe Date: Thu Oct 13 06:49:00 2016 New Revision: 307187 URL: https://svnweb.freebsd.org/changeset/base/307187 Log: MFC 305111 hyperv/timesync: Rework time adjustment policy - By default, adjust time upon SYNC request. It can be disabled through hw.hvtimesync.ignore_sync_req. SYNC request will be sent by hypervisor the host is resumed, rebooted, etc. - By default, adjust time upon SAMPLE request, if there is 100ms difference between VM time and hypervisor time. This can be disabled through hw.hvtimesync.sample_drift. And nuke the unnecessary task, since channel callback is running in a Hyper-V taskqueue nowadays. Submitted by: YanZhe Chen Discussed with: Dexuan Cui , Hongjiang Zhang , sephe Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7707 Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 06:47:02 2016 (r307186) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 06:49:00 2016 (r307187) @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -52,11 +52,7 @@ #define HV_ICTIMESYNCFLAG_SYNC 1 #define HV_ICTIMESYNCFLAG_SAMPLE 2 #define HV_NANO_SEC_PER_SEC 1000000000 - -/* Time Sync data */ -typedef struct { - uint64_t data; -} time_sync_data; +#define HV_NANO_SEC_PER_MILLI_SEC 1000000 static const struct vmbus_ic_desc vmbus_timesync_descs[] = { { @@ -75,22 +71,43 @@ struct hv_ictimesync_data { uint8_t flags; } __packed; -typedef struct hv_timesync_sc { - hv_util_sc util_sc; - struct task task; - time_sync_data time_msg; -} hv_timesync_sc; +/* + * Globals + */ +SYSCTL_NODE(_hw, OID_AUTO, hvtimesync, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, + "Hyper-V timesync interface"); + +/* Ignore the sync request when set to 1. */ +static int ignore_sync_req = 0; +SYSCTL_INT(_hw_hvtimesync, OID_AUTO, ignore_sync_req, CTLFLAG_RWTUN, + &ignore_sync_req, 0, + "Ignore the sync request when set to 1."); + +/* + * Trigger sample sync when drift exceeds threshold (ms). + * Ignore the sample request when set to 0. + */ +static int sample_drift = 100; +SYSCTL_INT(_hw_hvtimesync, OID_AUTO, sample_drift, CTLFLAG_RWTUN, + &sample_drift, 0, + "Threshold that makes sample request trigger the sync."); /** - * Set host time based on time sync message from host + * @brief Synchronize time with host after reboot, restore, etc. + * + * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. + * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time + * message after the timesync channel is opened. Since the hv_utils module is + * loaded after hv_vmbus, the first message is usually missed. The other + * thing is, systime is automatically set to emulated hardware clock which may + * not be UTC time or in the same time zone. So, to override these effects, we + * use the first 50 time samples for initial system time setting. */ -static void -hv_set_host_time(void *context, int pending) +static inline +void hv_adj_guesttime(hv_util_sc *sc, uint64_t hosttime, uint8_t flags) { - hv_timesync_sc *softc = (hv_timesync_sc*)context; - uint64_t hosttime = softc->time_msg.data; struct timespec guest_ts, host_ts; - uint64_t host_tns; + uint64_t host_tns, guest_tns; int64_t diff; int error; @@ -99,37 +116,35 @@ hv_set_host_time(void *context, int pend host_ts.tv_nsec = (long)(host_tns%HV_NANO_SEC_PER_SEC); nanotime(&guest_ts); + guest_tns = guest_ts.tv_sec * HV_NANO_SEC_PER_SEC + guest_ts.tv_nsec; - diff = (int64_t)host_ts.tv_sec - (int64_t)guest_ts.tv_sec; + if ((flags & HV_ICTIMESYNCFLAG_SYNC) != 0 && ignore_sync_req == 0) { + if (bootverbose) { + device_printf(sc->ic_dev, "handle sync request " + "{host: %ju, guest: %ju}\n", + (uintmax_t)host_tns, (uintmax_t)guest_tns); + } - /* - * If host differs by 5 seconds then make the guest catch up - */ - if (diff > 5 || diff < -5) { error = kern_clock_settime(curthread, CLOCK_REALTIME, &host_ts); + return; } -} -/** - * @brief Synchronize time with host after reboot, restore, etc. - * - * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. - * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time - * message after the timesync channel is opened. Since the hv_utils module is - * loaded after hv_vmbus, the first message is usually missed. The other - * thing is, systime is automatically set to emulated hardware clock which may - * not be UTC time or in the same time zone. So, to override these effects, we - * use the first 50 time samples for initial system time setting. - */ -static inline -void hv_adj_guesttime(hv_timesync_sc *sc, uint64_t hosttime, uint8_t flags) -{ - sc->time_msg.data = hosttime; - - if (((flags & HV_ICTIMESYNCFLAG_SYNC) != 0) || - ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0)) { - taskqueue_enqueue(taskqueue_thread, &sc->task); + if ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0 && sample_drift != 0) { + if (bootverbose) { + device_printf(sc->ic_dev, "handle sample request " + "{host: %ju, guest: %ju}\n", + (uintmax_t)host_tns, (uintmax_t)guest_tns); + } + + diff = (int64_t)(host_tns - guest_tns) / HV_NANO_SEC_PER_MILLI_SEC; + if (diff > sample_drift || diff < -sample_drift) { + error = kern_clock_settime(curthread, CLOCK_REALTIME, + &host_ts); + if (bootverbose) + device_printf(sc->ic_dev, "trigger sample sync"); + } + return; } } @@ -145,12 +160,12 @@ hv_timesync_cb(struct vmbus_channel *cha int ret; uint8_t* time_buf; struct hv_ictimesync_data* timedatap; - hv_timesync_sc *softc; + hv_util_sc *softc; - softc = (hv_timesync_sc*)context; - time_buf = softc->util_sc.receive_buffer; + softc = (hv_util_sc*)context; + time_buf = softc->receive_buffer; - recvlen = softc->util_sc.ic_buflen; + recvlen = softc->ic_buflen; ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId); KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough")); /* XXX check recvlen to make sure that it contains enough data */ @@ -162,7 +177,7 @@ hv_timesync_cb(struct vmbus_channel *cha if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { int error; - error = vmbus_ic_negomsg(&softc->util_sc, time_buf, &recvlen); + error = vmbus_ic_negomsg(softc, time_buf, &recvlen); if (error) return; } else { @@ -190,18 +205,12 @@ hv_timesync_probe(device_t dev) static int hv_timesync_attach(device_t dev) { - hv_timesync_sc *softc = device_get_softc(dev); - - TASK_INIT(&softc->task, 1, hv_set_host_time, softc); return hv_util_attach(dev, hv_timesync_cb); } static int hv_timesync_detach(device_t dev) { - hv_timesync_sc *softc = device_get_softc(dev); - - taskqueue_drain(taskqueue_thread, &softc->task); return hv_util_detach(dev); } @@ -213,7 +222,7 @@ static device_method_t timesync_methods[ { 0, 0 } }; -static driver_t timesync_driver = { "hvtimesync", timesync_methods, sizeof(hv_timesync_sc)}; +static driver_t timesync_driver = { "hvtimesync", timesync_methods, sizeof(hv_util_sc)}; static devclass_t timesync_devclass; From owner-svn-src-stable-10@freebsd.org Thu Oct 13 06:55:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8A647C0FB08; Thu, 13 Oct 2016 06:55:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 400C41AD5; Thu, 13 Oct 2016 06:55:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D6tq0o003893; Thu, 13 Oct 2016 06:55:52 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D6tqCH003890; Thu, 13 Oct 2016 06:55:52 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130655.u9D6tqCH003890@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 06:55:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307188 - in stable/10/sys: dev/hyperv/netvsc net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 06:55:53 -0000 Author: sephe Date: Thu Oct 13 06:55:51 2016 New Revision: 307188 URL: https://svnweb.freebsd.org/changeset/base/307188 Log: MFC 305173,305174 305173 net/rndis: Add comment for rndis_set_parameter Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7705 305174 hyperv/hn: Remove unused function Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7706 Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:49:00 2016 (r307187) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Thu Oct 13 06:55:51 2016 (r307188) @@ -904,7 +904,5 @@ void* hv_set_rppi_data(rndis_msg *rndis_ uint32_t rppi_size, int pkt_type); -void* hv_get_ppi_data(rndis_packet *rpkt, uint32_t type); - #endif /* __HV_RNDIS_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:49:00 2016 (r307187) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 06:55:51 2016 (r307188) @@ -129,35 +129,6 @@ hv_set_rppi_data(rndis_msg *rndis_mesg, } /* - * Get the Per-Packet-Info with the specified type - * return NULL if not found. - */ -void * -hv_get_ppi_data(rndis_packet *rpkt, uint32_t type) -{ - rndis_per_packet_info *ppi; - int len; - - if (rpkt->per_pkt_info_offset == 0) - return (NULL); - - ppi = (rndis_per_packet_info *)((unsigned long)rpkt + - rpkt->per_pkt_info_offset); - len = rpkt->per_pkt_info_length; - - while (len > 0) { - if (ppi->type == type) - return (void *)((unsigned long)ppi + - ppi->per_packet_info_offset); - - len -= ppi->size; - ppi = (rndis_per_packet_info *)((unsigned long)ppi + ppi->size); - } - - return (NULL); -} - -/* * RNDIS filter receive indicate status */ static void Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 06:49:00 2016 (r307187) +++ stable/10/sys/net/rndis.h Thu Oct 13 06:55:51 2016 (r307188) @@ -217,6 +217,9 @@ struct rndis_set_comp { uint32_t rm_status; }; +/* + * Parameter used by OID_GEN_RNDIS_CONFIG_PARAMETER. + */ #define REMOTE_NDIS_SET_PARAM_NUMERIC 0x00000000 #define REMOTE_NDIS_SET_PARAM_STRING 0x00000002 From owner-svn-src-stable-10@freebsd.org Thu Oct 13 07:17:06 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 70AF2C0F2CE; Thu, 13 Oct 2016 07:17:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3C20CF02; Thu, 13 Oct 2016 07:17:06 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D7H5Or011550; Thu, 13 Oct 2016 07:17:05 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D7H4r9011543; Thu, 13 Oct 2016 07:17:04 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130717.u9D7H4r9011543@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 07:17:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307193 - in stable/10/sys: dev/hyperv/netvsc net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 07:17:06 -0000 Author: sephe Date: Thu Oct 13 07:17:04 2016 New Revision: 307193 URL: https://svnweb.freebsd.org/changeset/base/307193 Log: MFC 305175,305176,305179,305182,305268,305270,305276 305175 net/rndis: Define per-packet-info for RNDIS packet message Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7708 305176 hyperv/hn: Stringent per-packet-info verification. While I'm here, minor style changes. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7709 305179 hyperv/hn: Fix VLAN tag construction. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7716 305182 net/rndis: Define types for RNDIS pktinfo rm_type field. They are defined by NDIS spec, so the NDIS prefix. Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7717 305268 hyperv/hn: Rework RXCSUM related bits Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7735 305270 hyperv/hn: Simplify RX hash related bits. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7736 305276 hyperv/hn: Use the per-packet-info types defined by net/rndis.h Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7737 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnreg.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h stable/10/sys/dev/hyperv/netvsc/ndis.h stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:17:04 2016 (r307193) @@ -1307,6 +1307,7 @@ netvsc_recv(struct hn_rx_ring *rxr, cons struct ifnet *ifp = rxr->hn_ifp; struct mbuf *m_new; int size, do_lro = 0, do_csum = 1; + int hash_type = M_HASHTYPE_OPAQUE; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) return (0); @@ -1352,28 +1353,29 @@ netvsc_recv(struct hn_rx_ring *rxr, cons do_csum = 0; /* receive side checksum offload */ - if (info->csum_info != NULL) { + if (info->csum_info != HN_NDIS_RXCSUM_INFO_INVALID) { /* IP csum offload */ - if (info->csum_info->receive.ip_csum_succeeded && do_csum) { + if ((info->csum_info & NDIS_RXCSUM_INFO_IPCS_OK) && do_csum) { m_new->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); rxr->hn_csum_ip++; } /* TCP/UDP csum offload */ - if ((info->csum_info->receive.tcp_csum_succeeded || - info->csum_info->receive.udp_csum_succeeded) && do_csum) { + if ((info->csum_info & (NDIS_RXCSUM_INFO_UDPCS_OK | + NDIS_RXCSUM_INFO_TCPCS_OK)) && do_csum) { m_new->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); m_new->m_pkthdr.csum_data = 0xffff; - if (info->csum_info->receive.tcp_csum_succeeded) + if (info->csum_info & NDIS_RXCSUM_INFO_TCPCS_OK) rxr->hn_csum_tcp++; else rxr->hn_csum_udp++; } - if (info->csum_info->receive.ip_csum_succeeded && - info->csum_info->receive.tcp_csum_succeeded) + if ((info->csum_info & + (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) == + (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) do_lro = 1; } else { const struct ether_header *eh; @@ -1429,20 +1431,20 @@ netvsc_recv(struct hn_rx_ring *rxr, cons } } skip: - if (info->vlan_info != NULL) { - m_new->m_pkthdr.ether_vtag = info->vlan_info->u1.s1.vlan_id; + if (info->vlan_info != HN_NDIS_VLAN_INFO_INVALID) { + m_new->m_pkthdr.ether_vtag = EVL_MAKETAG( + NDIS_VLAN_INFO_ID(info->vlan_info), + NDIS_VLAN_INFO_PRI(info->vlan_info), + NDIS_VLAN_INFO_CFI(info->vlan_info)); m_new->m_flags |= M_VLANTAG; } - if (info->hash_info != NULL && info->hash_value != NULL) { - int hash_type = M_HASHTYPE_OPAQUE; - + if (info->hash_info != HN_NDIS_HASH_INFO_INVALID) { rxr->hn_rss_pkts++; - m_new->m_pkthdr.flowid = info->hash_value->hash_value; - if ((info->hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) == + m_new->m_pkthdr.flowid = info->hash_value; + if ((info->hash_info & NDIS_HASH_FUNCTION_MASK) == NDIS_HASH_FUNCTION_TOEPLITZ) { - uint32_t type = - (info->hash_info->hash_info & NDIS_HASH_TYPE_MASK); + uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK); switch (type) { case NDIS_HASH_IPV4: @@ -1470,14 +1472,10 @@ skip: break; } } - M_HASHTYPE_SET(m_new, hash_type); } else { - if (info->hash_value != NULL) - m_new->m_pkthdr.flowid = info->hash_value->hash_value; - else - m_new->m_pkthdr.flowid = rxr->hn_rx_idx; - M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE); + m_new->m_pkthdr.flowid = rxr->hn_rx_idx; } + M_HASHTYPE_SET(m_new, hash_type); /* * Note: Moved RX completion back to hv_nv_on_receive() so all Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:17:04 2016 (r307193) @@ -154,79 +154,92 @@ hv_rf_receive_indicate_status(struct hn_ static int hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info) { - const rndis_per_packet_info *ppi; - uint32_t mask, len; + const struct rndis_pktinfo *pi; + uint32_t mask = 0, len; - info->vlan_info = NULL; - info->csum_info = NULL; - info->hash_info = NULL; - info->hash_value = NULL; + info->vlan_info = HN_NDIS_VLAN_INFO_INVALID; + info->csum_info = HN_NDIS_RXCSUM_INFO_INVALID; + info->hash_info = HN_NDIS_HASH_INFO_INVALID; if (rpkt->per_pkt_info_offset == 0) - return 0; + return (0); + if (__predict_false(rpkt->per_pkt_info_offset & + (RNDIS_PKTINFO_ALIGN - 1))) + return (EINVAL); + if (__predict_false(rpkt->per_pkt_info_offset < + RNDIS_PACKET_MSG_OFFSET_MIN)) + return (EINVAL); - ppi = (const rndis_per_packet_info *) + pi = (const struct rndis_pktinfo *) ((const uint8_t *)rpkt + rpkt->per_pkt_info_offset); len = rpkt->per_pkt_info_length; - mask = 0; while (len != 0) { - const void *ppi_dptr; - uint32_t ppi_dlen; + const void *data; + uint32_t dlen; - if (__predict_false(ppi->size < ppi->per_packet_info_offset)) - return EINVAL; - ppi_dlen = ppi->size - ppi->per_packet_info_offset; - ppi_dptr = (const uint8_t *)ppi + ppi->per_packet_info_offset; - - switch (ppi->type) { - case ieee_8021q_info: - if (__predict_false(ppi_dlen < sizeof(ndis_8021q_info))) - return EINVAL; - info->vlan_info = ppi_dptr; + if (__predict_false(len < sizeof(*pi))) + return (EINVAL); + if (__predict_false(len < pi->rm_size)) + return (EINVAL); + len -= pi->rm_size; + + if (__predict_false(pi->rm_size & (RNDIS_PKTINFO_ALIGN - 1))) + return (EINVAL); + if (__predict_false(pi->rm_size < pi->rm_pktinfooffset)) + return (EINVAL); + dlen = pi->rm_size - pi->rm_pktinfooffset; + data = pi->rm_data; + + switch (pi->rm_type) { + case NDIS_PKTINFO_TYPE_VLAN: + if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE)) + return (EINVAL); + info->vlan_info = *((const uint32_t *)data); mask |= HV_RF_RECVINFO_VLAN; break; - case tcpip_chksum_info: - if (__predict_false(ppi_dlen < - sizeof(rndis_tcp_ip_csum_info))) - return EINVAL; - info->csum_info = ppi_dptr; + case NDIS_PKTINFO_TYPE_CSUM: + if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE)) + return (EINVAL); + info->csum_info = *((const uint32_t *)data); mask |= HV_RF_RECVINFO_CSUM; break; - case nbl_hash_value: - if (__predict_false(ppi_dlen < - sizeof(struct rndis_hash_value))) - return EINVAL; - info->hash_value = ppi_dptr; + case HN_NDIS_PKTINFO_TYPE_HASHVAL: + if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE)) + return (EINVAL); + info->hash_value = *((const uint32_t *)data); mask |= HV_RF_RECVINFO_HASHVAL; break; - case nbl_hash_info: - if (__predict_false(ppi_dlen < - sizeof(struct rndis_hash_info))) - return EINVAL; - info->hash_info = ppi_dptr; + case HN_NDIS_PKTINFO_TYPE_HASHINF: + if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE)) + return (EINVAL); + info->hash_info = *((const uint32_t *)data); mask |= HV_RF_RECVINFO_HASHINF; break; default: - goto skip; + goto next; } if (mask == HV_RF_RECVINFO_ALL) { /* All found; done */ break; } -skip: - if (__predict_false(len < ppi->size)) - return EINVAL; - len -= ppi->size; - ppi = (const rndis_per_packet_info *) - ((const uint8_t *)ppi + ppi->size); +next: + pi = (const struct rndis_pktinfo *) + ((const uint8_t *)pi + pi->rm_size); } - return 0; + + /* + * Final fixup. + * - If there is no hash value, invalidate the hash info. + */ + if ((mask & HV_RF_RECVINFO_HASHVAL) == 0) + info->hash_info = HN_NDIS_HASH_INFO_INVALID; + return (0); } /* Modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:17:04 2016 (r307193) @@ -208,4 +208,17 @@ struct hn_nvs_rndis_ack { } __packed; CTASSERT(sizeof(struct hn_nvs_rndis_ack) >= HN_NVS_REQSIZE_MIN); +/* + * RNDIS extension + */ + +/* Per-packet hash info */ +#define HN_NDIS_HASH_INFO_SIZE sizeof(uint32_t) +#define HN_NDIS_PKTINFO_TYPE_HASHINF NDIS_PKTINFO_TYPE_ORIG_NBLIST +/* NDIS_HASH_ */ + +/* Per-packet hash value */ +#define HN_NDIS_HASH_VALUE_SIZE sizeof(uint32_t) +#define HN_NDIS_PKTINFO_TYPE_HASHVAL NDIS_PKTINFO_TYPE_PKT_CANCELID + #endif /* !_IF_HNREG_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:17:04 2016 (r307193) @@ -55,11 +55,15 @@ struct rndix_hash_value; struct ndis_8021q_info_; struct rndis_tcp_ip_csum_info_; +#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff +#define HN_NDIS_RXCSUM_INFO_INVALID 0 +#define HN_NDIS_HASH_INFO_INVALID 0 + struct hn_recvinfo { - const struct ndis_8021q_info_ *vlan_info; - const struct rndis_tcp_ip_csum_info_ *csum_info; - const struct rndis_hash_info *hash_info; - const struct rndis_hash_value *hash_value; + uint32_t vlan_info; + uint32_t csum_info; + uint32_t hash_info; + uint32_t hash_value; }; #define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:17:04 2016 (r307193) @@ -203,4 +203,32 @@ struct ndis_rssprm_toeplitz { uint32_t rss_ind[NDIS_HASH_INDCNT]; }; +/* + * Per-packet-info + */ + +/* VLAN */ +#define NDIS_VLAN_INFO_SIZE sizeof(uint32_t) +#define NDIS_VLAN_INFO_PRI_MASK 0x0007 +#define NDIS_VLAN_INFO_CFI_MASK 0x0008 +#define NDIS_VLAN_INFO_ID_MASK 0xfff0 +#define NDIS_VLAN_INFO_MAKE(id, pri, cfi) \ + (((pri) & NVIS_VLAN_INFO_PRI_MASK) | \ + (((cfi) & 0x1) << 3) | (((id) & 0xfff) << 4)) +#define NDIS_VLAN_INFO_ID(inf) (((inf) & NDIS_VLAN_INFO_ID_MASK) >> 4) +#define NDIS_VLAN_INFO_CFI(inf) (((inf) & NDIS_VLAN_INFO_CFI_MASK) >> 3) +#define NDIS_VLAN_INFO_PRI(inf) ((inf) & NDIS_VLAN_INFO_PRI_MASK) + +/* Reception checksum */ +#define NDIS_RXCSUM_INFO_SIZE sizeof(uint32_t) +#define NDIS_RXCSUM_INFO_TCPCS_FAILED 0x0001 +#define NDIS_RXCSUM_INFO_UDPCS_FAILED 0x0002 +#define NDIS_RXCSUM_INFO_IPCS_FAILED 0x0004 +#define NDIS_RXCSUM_INFO_TCPCS_OK 0x0008 +#define NDIS_RXCSUM_INFO_UDPCS_OK 0x0010 +#define NDIS_RXCSUM_INFO_IPCS_OK 0x0020 +#define NDIS_RXCSUM_INFO_LOOPBACK 0x0040 +#define NDIS_RXCSUM_INFO_TCPCS_INVAL 0x0080 +#define NDIS_RXCSUM_INFO_IPCS_INVAL 0x0100 + #endif /* !_NET_NDIS_H_ */ Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 07:12:20 2016 (r307192) +++ stable/10/sys/net/rndis.h Thu Oct 13 07:17:04 2016 (r307193) @@ -112,6 +112,39 @@ struct rndis_packet_msg { }; /* + * Minimum value for rm_dataoffset, rm_oobdataoffset, and + * rm_pktinfooffset. + */ +#define RNDIS_PACKET_MSG_OFFSET_MIN \ + (sizeof(struct rndis_packet_msg) - \ + __offsetof(struct rndis_packet_msg, rm_dataoffset)) + +/* Per-packet-info for RNDIS data message */ +struct rndis_pktinfo { + uint32_t rm_size; + uint32_t rm_type; /* NDIS_PKTINFO_TYPE_ */ + uint32_t rm_pktinfooffset; + uint8_t rm_data[]; +}; + +#define RNDIS_PKTINFO_OFFSET \ + __offsetof(struct rndis_pktinfo, rm_data[0]) +#define RNDIS_PKTINFO_ALIGN 4 + +#define NDIS_PKTINFO_TYPE_CSUM 0 +#define NDIS_PKTINFO_TYPE_IPSEC 1 +#define NDIS_PKTINFO_TYPE_LSO 2 +#define NDIS_PKTINFO_TYPE_CLASSIFY 3 +/* reserved 4 */ +#define NDIS_PKTINFO_TYPE_SGLIST 5 +#define NDIS_PKTINFO_TYPE_VLAN 6 +#define NDIS_PKTINFO_TYPE_ORIG 7 +#define NDIS_PKTINFO_TYPE_PKT_CANCELID 8 +#define NDIS_PKTINFO_TYPE_ORIG_NBLIST 9 +#define NDIS_PKTINFO_TYPE_CACHE_NBLIST 10 +#define NDIS_PKTINFO_TYPE_PKT_PAD 11 + +/* * RNDIS control messages */ struct rndis_comp_hdr { From owner-svn-src-stable-10@freebsd.org Thu Oct 13 07:22:14 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D40D2C0F5E0; Thu, 13 Oct 2016 07:22:14 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A5A02774; Thu, 13 Oct 2016 07:22:14 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D7MDwo014506; Thu, 13 Oct 2016 07:22:13 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D7MDSw014505; Thu, 13 Oct 2016 07:22:13 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130722.u9D7MDSw014505@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 07:22:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307194 - stable/10/sys/net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 07:22:14 -0000 Author: sephe Date: Thu Oct 13 07:22:13 2016 New Revision: 307194 URL: https://svnweb.freebsd.org/changeset/base/307194 Log: MFC 305277,305278 305277 net/rndis: Add comment for rndis_comp_hdr Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7738 305278 net/rndis: Define common message header for RNDIS messages. And avoid RNDIS_HEADER_OFFSET hardcoding. Reviewed by: hps Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7739 Modified: stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 07:17:04 2016 (r307193) +++ stable/10/sys/net/rndis.h Thu Oct 13 07:22:13 2016 (r307194) @@ -93,6 +93,14 @@ #define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 /* + * Common RNDIS message header. + */ +struct rndis_msghdr { + uint32_t rm_type; + uint32_t rm_len; +}; + +/* * RNDIS data message */ #define REMOTE_NDIS_PACKET_MSG 0x00000001 @@ -147,6 +155,12 @@ struct rndis_pktinfo { /* * RNDIS control messages */ + +/* + * Common header for RNDIS completion messages. + * + * NOTE: It does not apply to REMOTE_NDIS_RESET_CMPLT. + */ struct rndis_comp_hdr { uint32_t rm_type; uint32_t rm_len; @@ -316,7 +330,7 @@ struct rndis_keepalive_comp { #define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000 /* RNDIS offsets */ -#define RNDIS_HEADER_OFFSET 8 /* bytes */ +#define RNDIS_HEADER_OFFSET ((uint32_t)sizeof(struct rndis_msghdr)) #define RNDIS_DATA_OFFSET \ ((uint32_t)(sizeof(struct rndis_packet_msg) - RNDIS_HEADER_OFFSET)) From owner-svn-src-stable-10@freebsd.org Thu Oct 13 07:35:21 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 73B54C0FD60; Thu, 13 Oct 2016 07:35:21 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3EEFF7D4; Thu, 13 Oct 2016 07:35:21 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D7ZKpe019049; Thu, 13 Oct 2016 07:35:20 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D7ZKtH019045; Thu, 13 Oct 2016 07:35:20 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130735.u9D7ZKtH019045@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 07:35:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307197 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 07:35:21 -0000 Author: sephe Date: Thu Oct 13 07:35:19 2016 New Revision: 307197 URL: https://svnweb.freebsd.org/changeset/base/307197 Log: MFC 305279-305281 305279 hyperv/ic: Minor style fix. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7743 305280 hyperv/ic: Cleanup shutdown channel callback. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7744 305281 hyperv/ic: Cleanup timesync channel callback. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7745 Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c stable/10/sys/dev/hyperv/utilities/hv_shutdown.c stable/10/sys/dev/hyperv/utilities/hv_timesync.c stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 07:32:25 2016 (r307196) +++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Thu Oct 13 07:35:19 2016 (r307197) @@ -69,7 +69,7 @@ vmbus_heartbeat_cb(struct vmbus_channel if (error) return; - if (dlen < sizeof(struct vmbus_icmsg_hdr)) { + if (dlen < sizeof(*hdr)) { device_printf(sc->ic_dev, "invalid data len %d\n", dlen); return; } Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 07:32:25 2016 (r307196) +++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Thu Oct 13 07:35:19 2016 (r307197) @@ -22,28 +22,23 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ -/* - * A common driver for all hyper-V util services. - */ +#include +__FBSDID("$FreeBSD$"); #include -#include #include -#include +#include #include #include -#include -#include #include #include #include -#include -#include "hv_util.h" +#include +#include + #include "vmbus_if.h" static const struct vmbus_ic_desc vmbus_shutdown_descs[] = { @@ -56,73 +51,78 @@ static const struct vmbus_ic_desc vmbus_ VMBUS_IC_DESC_END }; -/** - * Shutdown - */ static void -hv_shutdown_cb(struct vmbus_channel *channel, void *context) +vmbus_shutdown_cb(struct vmbus_channel *chan, void *xsc) { - uint8_t* buf; - uint8_t execute_shutdown = 0; - hv_vmbus_icmsg_hdr* icmsghdrp; - uint32_t recv_len; - uint64_t request_id; - int ret; - hv_vmbus_shutdown_msg_data* shutdown_msg; - hv_util_sc *softc; - - softc = (hv_util_sc*)context; - buf = softc->receive_buffer;; - - recv_len = softc->ic_buflen; - ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id); - KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough")); - /* XXX check recv_len to make sure that it contains enough data */ - - if ((ret == 0) && recv_len > 0) { - - icmsghdrp = (struct hv_vmbus_icmsg_hdr *) - &buf[sizeof(struct hv_vmbus_pipe_hdr)]; - - if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - int error; + struct hv_util_sc *sc = xsc; + struct vmbus_icmsg_hdr *hdr; + struct vmbus_icmsg_shutdown *msg; + int dlen, error, do_shutdown = 0; + uint64_t xactid; + void *data; + + /* + * Receive request. + */ + data = sc->receive_buffer; + dlen = sc->ic_buflen; + error = vmbus_chan_recv(chan, data, &dlen, &xactid); + KASSERT(error != ENOBUFS, ("icbuf is not large enough")); + if (error) + return; + + if (dlen < sizeof(*hdr)) { + device_printf(sc->ic_dev, "invalid data len %d\n", dlen); + return; + } + hdr = data; - error = vmbus_ic_negomsg(softc, buf, &recv_len); + /* + * Update request, which will be echoed back as response. + */ + switch (hdr->ic_type) { + case VMBUS_ICMSG_TYPE_NEGOTIATE: + error = vmbus_ic_negomsg(sc, data, &dlen); if (error) return; - } else { - shutdown_msg = - (struct hv_vmbus_shutdown_msg_data *) - &buf[sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; - - switch (shutdown_msg->flags) { - case 0: - case 1: - icmsghdrp->status = HV_S_OK; - execute_shutdown = 1; - if(bootverbose) - printf("Shutdown request received -" - " graceful shutdown initiated\n"); - break; - default: - icmsghdrp->status = HV_E_FAIL; - execute_shutdown = 0; - printf("Shutdown request received -" - " Invalid request\n"); - break; - } - } + break; - icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | - HV_ICMSGHDRFLAG_RESPONSE; + case VMBUS_ICMSG_TYPE_SHUTDOWN: + if (dlen < VMBUS_ICMSG_SHUTDOWN_SIZE_MIN) { + device_printf(sc->ic_dev, "invalid shutdown len %d\n", + dlen); + return; + } + msg = data; - vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, - buf, recv_len, request_id); + /* XXX ic_flags definition? */ + if (msg->ic_haltflags == 0 || msg->ic_haltflags == 1) { + device_printf(sc->ic_dev, "shutdown requested\n"); + hdr->ic_status = VMBUS_ICMSG_STATUS_OK; + do_shutdown = 1; + } else { + device_printf(sc->ic_dev, "unknown shutdown flags " + "0x%08x\n", msg->ic_haltflags); + hdr->ic_status = VMBUS_ICMSG_STATUS_FAIL; + } + break; + + default: + device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type); + break; } - if (execute_shutdown) - shutdown_nice(RB_POWEROFF); + /* + * Send response by echoing the updated request back. + */ + hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP; + error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0, + data, dlen, xactid); + if (error) + device_printf(sc->ic_dev, "resp send failed: %d\n", error); + + if (do_shutdown) + shutdown_nice(RB_POWEROFF); } static int @@ -135,7 +135,8 @@ hv_shutdown_probe(device_t dev) static int hv_shutdown_attach(device_t dev) { - return hv_util_attach(dev, hv_shutdown_cb); + + return (hv_util_attach(dev, vmbus_shutdown_cb)); } static device_method_t shutdown_methods[] = { Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 07:32:25 2016 (r307196) +++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Thu Oct 13 07:35:19 2016 (r307197) @@ -22,37 +22,25 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ -/* - * A common driver for all hyper-V util services. - */ +#include +__FBSDID("$FreeBSD$"); #include -#include #include -#include +#include #include -#include -#include #include -#include #include +#include #include #include -#include -#include "hv_util.h" -#include "vmbus_if.h" +#include +#include -#define HV_WLTIMEDELTA 116444736000000000L /* in 100ns unit */ -#define HV_ICTIMESYNCFLAG_PROBE 0 -#define HV_ICTIMESYNCFLAG_SYNC 1 -#define HV_ICTIMESYNCFLAG_SAMPLE 2 -#define HV_NANO_SEC_PER_SEC 1000000000 -#define HV_NANO_SEC_PER_MILLI_SEC 1000000 +#include "vmbus_if.h" static const struct vmbus_ic_desc vmbus_timesync_descs[] = { { @@ -64,135 +52,144 @@ static const struct vmbus_ic_desc vmbus_ VMBUS_IC_DESC_END }; -struct hv_ictimesync_data { - uint64_t parenttime; - uint64_t childtime; - uint64_t roundtriptime; - uint8_t flags; -} __packed; - -/* - * Globals - */ SYSCTL_NODE(_hw, OID_AUTO, hvtimesync, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, "Hyper-V timesync interface"); -/* Ignore the sync request when set to 1. */ -static int ignore_sync_req = 0; -SYSCTL_INT(_hw_hvtimesync, OID_AUTO, ignore_sync_req, CTLFLAG_RWTUN, - &ignore_sync_req, 0, - "Ignore the sync request when set to 1."); +static int vmbus_ts_ignore_sync = 0; +SYSCTL_INT(_hw_hvtimesync, OID_AUTO, ignore_sync, CTLFLAG_RWTUN, + &vmbus_ts_ignore_sync, 0, "Ignore the sync request."); /* * Trigger sample sync when drift exceeds threshold (ms). * Ignore the sample request when set to 0. */ -static int sample_drift = 100; -SYSCTL_INT(_hw_hvtimesync, OID_AUTO, sample_drift, CTLFLAG_RWTUN, - &sample_drift, 0, - "Threshold that makes sample request trigger the sync."); - -/** - * @brief Synchronize time with host after reboot, restore, etc. - * - * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. - * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time - * message after the timesync channel is opened. Since the hv_utils module is - * loaded after hv_vmbus, the first message is usually missed. The other - * thing is, systime is automatically set to emulated hardware clock which may - * not be UTC time or in the same time zone. So, to override these effects, we - * use the first 50 time samples for initial system time setting. - */ -static inline -void hv_adj_guesttime(hv_util_sc *sc, uint64_t hosttime, uint8_t flags) +static int vmbus_ts_sample_thresh = 100; +SYSCTL_INT(_hw_hvtimesync, OID_AUTO, sample_thresh, CTLFLAG_RWTUN, + &vmbus_ts_sample_thresh, 0, + "Threshold that makes sample request trigger the sync (unit: ms)."); + +static int vmbus_ts_sample_verbose = 0; +SYSCTL_INT(_hw_hvtimesync, OID_AUTO, sample_verbose, CTLFLAG_RWTUN, + &vmbus_ts_sample_verbose, 0, "Increase sample request verbosity."); + +static void +vmbus_timesync(struct hv_util_sc *sc, uint64_t hvtime, uint8_t tsflags) { - struct timespec guest_ts, host_ts; - uint64_t host_tns, guest_tns; - int64_t diff; - int error; - - host_tns = (hosttime - HV_WLTIMEDELTA) * 100; - host_ts.tv_sec = (time_t)(host_tns/HV_NANO_SEC_PER_SEC); - host_ts.tv_nsec = (long)(host_tns%HV_NANO_SEC_PER_SEC); + struct timespec vm_ts; + uint64_t hv_ns, vm_ns; - nanotime(&guest_ts); - guest_tns = guest_ts.tv_sec * HV_NANO_SEC_PER_SEC + guest_ts.tv_nsec; + hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE) * VMBUS_ICMSG_TS_FACTOR; + nanotime(&vm_ts); + vm_ns = (vm_ts.tv_sec * NANOSEC) + vm_ts.tv_nsec; + + if ((tsflags & VMBUS_ICMSG_TS_FLAG_SYNC) && !vmbus_ts_ignore_sync) { + struct timespec hv_ts; - if ((flags & HV_ICTIMESYNCFLAG_SYNC) != 0 && ignore_sync_req == 0) { if (bootverbose) { - device_printf(sc->ic_dev, "handle sync request " - "{host: %ju, guest: %ju}\n", - (uintmax_t)host_tns, (uintmax_t)guest_tns); + device_printf(sc->ic_dev, "apply sync request, " + "hv: %ju, vm: %ju\n", + (uintmax_t)hv_ns, (uintmax_t)vm_ns); } - - error = kern_clock_settime(curthread, CLOCK_REALTIME, - &host_ts); + hv_ts.tv_sec = hv_ns / NANOSEC; + hv_ts.tv_nsec = hv_ns % NANOSEC; + kern_clock_settime(curthread, CLOCK_REALTIME, &hv_ts); + /* Done! */ return; } - if ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0 && sample_drift != 0) { - if (bootverbose) { - device_printf(sc->ic_dev, "handle sample request " - "{host: %ju, guest: %ju}\n", - (uintmax_t)host_tns, (uintmax_t)guest_tns); + if ((tsflags & VMBUS_ICMSG_TS_FLAG_SAMPLE) && + vmbus_ts_sample_thresh > 0) { + int64_t diff; + + if (vmbus_ts_sample_verbose) { + device_printf(sc->ic_dev, "sample request, " + "hv: %ju, vm: %ju\n", + (uintmax_t)hv_ns, (uintmax_t)vm_ns); } - diff = (int64_t)(host_tns - guest_tns) / HV_NANO_SEC_PER_MILLI_SEC; - if (diff > sample_drift || diff < -sample_drift) { - error = kern_clock_settime(curthread, CLOCK_REALTIME, - &host_ts); - if (bootverbose) - device_printf(sc->ic_dev, "trigger sample sync"); + if (hv_ns > vm_ns) + diff = hv_ns - vm_ns; + else + diff = vm_ns - hv_ns; + /* nanosec -> millisec */ + diff /= 1000000; + + if (diff > vmbus_ts_sample_thresh) { + struct timespec hv_ts; + + if (bootverbose) { + device_printf(sc->ic_dev, + "apply sample request, hv: %ju, vm: %ju\n", + (uintmax_t)hv_ns, (uintmax_t)vm_ns); + } + hv_ts.tv_sec = hv_ns / NANOSEC; + hv_ts.tv_nsec = hv_ns % NANOSEC; + kern_clock_settime(curthread, CLOCK_REALTIME, &hv_ts); } + /* Done */ return; } } -/** - * Time Sync Channel message handler - */ static void -hv_timesync_cb(struct vmbus_channel *channel, void *context) +vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc) { - hv_vmbus_icmsg_hdr* icmsghdrp; - uint32_t recvlen; - uint64_t requestId; - int ret; - uint8_t* time_buf; - struct hv_ictimesync_data* timedatap; - hv_util_sc *softc; - - softc = (hv_util_sc*)context; - time_buf = softc->receive_buffer; - - recvlen = softc->ic_buflen; - ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId); - KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough")); - /* XXX check recvlen to make sure that it contains enough data */ - - if ((ret == 0) && recvlen > 0) { - icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[ - sizeof(struct hv_vmbus_pipe_hdr)]; + struct hv_util_sc *sc = xsc; + struct vmbus_icmsg_hdr *hdr; + const struct vmbus_icmsg_timesync *msg; + int dlen, error; + uint64_t xactid; + void *data; + + /* + * Receive request. + */ + data = sc->receive_buffer; + dlen = sc->ic_buflen; + error = vmbus_chan_recv(chan, data, &dlen, &xactid); + KASSERT(error != ENOBUFS, ("icbuf is not large enough")); + if (error) + return; - if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - int error; + if (dlen < sizeof(*hdr)) { + device_printf(sc->ic_dev, "invalid data len %d\n", dlen); + return; + } + hdr = data; - error = vmbus_ic_negomsg(softc, time_buf, &recvlen); + /* + * Update request, which will be echoed back as response. + */ + switch (hdr->ic_type) { + case VMBUS_ICMSG_TYPE_NEGOTIATE: + error = vmbus_ic_negomsg(sc, data, &dlen); if (error) return; - } else { - timedatap = (struct hv_ictimesync_data *) &time_buf[ - sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; - hv_adj_guesttime(softc, timedatap->parenttime, timedatap->flags); - } + break; - icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION - | HV_ICMSGHDRFLAG_RESPONSE; - - vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, - time_buf, recvlen, requestId); + case VMBUS_ICMSG_TYPE_TIMESYNC: + if (dlen < sizeof(*msg)) { + device_printf(sc->ic_dev, "invalid timesync len %d\n", + dlen); + return; + } + msg = data; + vmbus_timesync(sc, msg->ic_hvtime, msg->ic_tsflags); + break; + + default: + device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type); + break; } + + /* + * Send response by echoing the updated request back. + */ + hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP; + error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0, + data, dlen, xactid); + if (error) + device_printf(sc->ic_dev, "resp send failed: %d\n", error); } static int @@ -205,20 +202,15 @@ hv_timesync_probe(device_t dev) static int hv_timesync_attach(device_t dev) { - return hv_util_attach(dev, hv_timesync_cb); -} -static int -hv_timesync_detach(device_t dev) -{ - return hv_util_detach(dev); + return (hv_util_attach(dev, vmbus_timesync_cb)); } static device_method_t timesync_methods[] = { /* Device interface */ DEVMETHOD(device_probe, hv_timesync_probe), DEVMETHOD(device_attach, hv_timesync_attach), - DEVMETHOD(device_detach, hv_timesync_detach), + DEVMETHOD(device_detach, hv_util_detach), { 0, 0 } }; Modified: stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h ============================================================================== --- stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Oct 13 07:32:25 2016 (r307196) +++ stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Oct 13 07:35:19 2016 (r307197) @@ -91,4 +91,35 @@ struct vmbus_icmsg_heartbeat { #define VMBUS_ICMSG_HEARTBEAT_SIZE_MIN \ __offsetof(struct vmbus_icmsg_heartbeat, ic_rsvd[0]) +/* VMBUS_ICMSG_TYPE_SHUTDOWN */ +struct vmbus_icmsg_shutdown { + struct vmbus_icmsg_hdr ic_hdr; + uint32_t ic_code; + uint32_t ic_timeo; + uint32_t ic_haltflags; + uint8_t ic_msg[2048]; +} __packed; + +#define VMBUS_ICMSG_SHUTDOWN_SIZE_MIN \ + __offsetof(struct vmbus_icmsg_shutdown, ic_msg[0]) + +/* VMBUS_ICMSG_TYPE_TIMESYNC */ +struct vmbus_icmsg_timesync { + struct vmbus_icmsg_hdr ic_hdr; + uint64_t ic_hvtime; + uint64_t ic_vmtime; + uint64_t ic_rtt; + uint8_t ic_tsflags; /* VMBUS_ICMSG_TS_FLAG_ */ +} __packed; + +#define VMBUS_ICMSG_TS_FLAG_SYNC 0x01 +#define VMBUS_ICMSG_TS_FLAG_SAMPLE 0x02 + +/* XXX consolidate w/ hyperv */ +#define VMBUS_ICMSG_TS_BASE 116444736000000000ULL +#define VMBUS_ICMSG_TS_FACTOR 100ULL +#ifndef NANOSEC +#define NANOSEC 1000000000ULL +#endif + #endif /* !_VMBUS_ICREG_H_ */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 07:42:46 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 444DCC0F210; Thu, 13 Oct 2016 07:42:46 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 101FEFCE; Thu, 13 Oct 2016 07:42:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D7gjCs023008; Thu, 13 Oct 2016 07:42:45 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D7gi6f023002; Thu, 13 Oct 2016 07:42:44 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130742.u9D7gi6f023002@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 07:42:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307198 - in stable/10/sys: dev/hyperv/netvsc dev/hyperv/vmbus net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 07:42:46 -0000 Author: sephe Date: Thu Oct 13 07:42:44 2016 New Revision: 307198 URL: https://svnweb.freebsd.org/changeset/base/307198 Log: MFC 305405,305407,305408,305410,305411,305453 305405 hyperv/vmbus: Stringent header length and total length check. While I'm here, minor style changes. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7752 305407 hyperv/hn: Stringent NVS notification length check. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7753 305408 hyperv/hn: Stringent NVS RNDIS packets length checks. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7755 305410 net/rndis: Define RNDIS status message, which could be sent by device. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7757 305411 hyperv/hn: Stringent RNDIS control message length check. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7758 305453 hyperv/hn: Stringent RNDIS packet message length/offset check. While I'm here, use definition in net/rndis.h Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7782 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 07:42:44 2016 (r307198) @@ -741,32 +741,53 @@ hv_nv_on_receive(struct hn_softc *sc, st { const struct vmbus_chanpkt_rxbuf *pkt; const struct hn_nvs_hdr *nvs_hdr; - int count = 0; - int i = 0; + int count, i, hlen; - /* Make sure that this is a RNDIS message. */ + if (__predict_false(VMBUS_CHANPKT_DATALEN(pkthdr) < sizeof(*nvs_hdr))) { + if_printf(rxr->hn_ifp, "invalid nvs RNDIS\n"); + return; + } nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr); + + /* Make sure that this is a RNDIS message. */ if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) { if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n", nvs_hdr->nvs_type); return; } - + + hlen = VMBUS_CHANPKT_GETLEN(pkthdr->cph_hlen); + if (__predict_false(hlen < sizeof(*pkt))) { + if_printf(rxr->hn_ifp, "invalid rxbuf chanpkt\n"); + return; + } pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; - if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) { - if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n", + if (__predict_false(pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID)) { + if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n", pkt->cp_rxbuf_id); return; } count = pkt->cp_rxbuf_cnt; + if (__predict_false(hlen < + __offsetof(struct vmbus_chanpkt_rxbuf, cp_rxbuf[count]))) { + if_printf(rxr->hn_ifp, "invalid rxbuf_cnt %d\n", count); + return; + } /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ - for (i = 0; i < count; i++) { - hv_rf_on_receive(sc, rxr, - rxr->hn_rxbuf + pkt->cp_rxbuf[i].rb_ofs, - pkt->cp_rxbuf[i].rb_len); + for (i = 0; i < count; ++i) { + int ofs, len; + + ofs = pkt->cp_rxbuf[i].rb_ofs; + len = pkt->cp_rxbuf[i].rb_len; + if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) { + if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, " + "ofs %d, len %d\n", i, ofs, len); + continue; + } + hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len); } /* @@ -815,7 +836,12 @@ hn_proc_notify(struct hn_softc *sc, cons { const struct hn_nvs_hdr *hdr; + if (VMBUS_CHANPKT_DATALEN(pkt) < sizeof(*hdr)) { + if_printf(sc->hn_ifp, "invalid nvs notify\n"); + return; + } hdr = VMBUS_CHANPKT_CONST_DATA(pkt); + if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) { /* Useless; ignore */ return; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:42:44 2016 (r307198) @@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$"); * Forward declarations */ static void hv_rf_receive_indicate_status(struct hn_softc *sc, - const rndis_msg *response); + const void *data, int dlen); static void hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen); static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr); @@ -132,59 +132,50 @@ hv_set_rppi_data(rndis_msg *rndis_mesg, * RNDIS filter receive indicate status */ static void -hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response) +hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen) { - const rndis_indicate_status *indicate = &response->msg.indicate_status; - - switch(indicate->status) { + const struct rndis_status_msg *msg; + + if (dlen < sizeof(*msg)) { + if_printf(sc->hn_ifp, "invalid RNDIS status\n"); + return; + } + msg = data; + + switch (msg->rm_status) { case RNDIS_STATUS_MEDIA_CONNECT: netvsc_linkstatus_callback(sc, 1); break; + case RNDIS_STATUS_MEDIA_DISCONNECT: netvsc_linkstatus_callback(sc, 0); break; + default: /* TODO: */ - if_printf(sc->hn_ifp, - "unknown status %d received\n", indicate->status); + if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n", + msg->rm_status); break; } } static int -hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hn_recvinfo *info) +hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_recvinfo *info) { - const struct rndis_pktinfo *pi; - uint32_t mask = 0, len; - - info->vlan_info = HN_NDIS_VLAN_INFO_INVALID; - info->csum_info = HN_NDIS_RXCSUM_INFO_INVALID; - info->hash_info = HN_NDIS_HASH_INFO_INVALID; - - if (rpkt->per_pkt_info_offset == 0) - return (0); - if (__predict_false(rpkt->per_pkt_info_offset & - (RNDIS_PKTINFO_ALIGN - 1))) - return (EINVAL); - if (__predict_false(rpkt->per_pkt_info_offset < - RNDIS_PACKET_MSG_OFFSET_MIN)) - return (EINVAL); + const struct rndis_pktinfo *pi = info_data; + uint32_t mask = 0; - pi = (const struct rndis_pktinfo *) - ((const uint8_t *)rpkt + rpkt->per_pkt_info_offset); - len = rpkt->per_pkt_info_length; - - while (len != 0) { + while (info_dlen != 0) { const void *data; uint32_t dlen; - if (__predict_false(len < sizeof(*pi))) + if (__predict_false(info_dlen < sizeof(*pi))) return (EINVAL); - if (__predict_false(len < pi->rm_size)) + if (__predict_false(info_dlen < pi->rm_size)) return (EINVAL); - len -= pi->rm_size; + info_dlen -= pi->rm_size; - if (__predict_false(pi->rm_size & (RNDIS_PKTINFO_ALIGN - 1))) + if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK)) return (EINVAL); if (__predict_false(pi->rm_size < pi->rm_pktinfooffset)) return (EINVAL); @@ -242,76 +233,223 @@ next: return (0); } +static __inline bool +hn_rndis_check_overlap(int off, int len, int check_off, int check_len) +{ + + if (off < check_off) { + if (__predict_true(off + len <= check_off)) + return (false); + } else if (off > check_off) { + if (__predict_true(check_off + check_len <= off)) + return (false); + } + return (true); +} + /* * RNDIS filter receive data */ static void hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen) { - const rndis_msg *message = data; - const rndis_packet *rndis_pkt; - uint32_t data_offset; + const struct rndis_packet_msg *pkt; struct hn_recvinfo info; - - rndis_pkt = &message->msg.packet; + int data_off, pktinfo_off, data_len, pktinfo_len; /* - * Fixme: Handle multiple rndis pkt msgs that may be enclosed in this - * netvsc packet (ie tot_data_buf_len != message_length) + * Check length. */ + if (__predict_false(dlen < sizeof(*pkt))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n"); + return; + } + pkt = data; - /* Remove rndis header, then pass data packet up the stack */ - data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; + if (__predict_false(dlen < pkt->rm_len)) { + if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, " + "dlen %d, msglen %u\n", dlen, pkt->rm_len); + return; + } + if (__predict_false(pkt->rm_len < + pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, " + "msglen %u, data %u, oob %u, pktinfo %u\n", + pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen, + pkt->rm_pktinfolen); + return; + } + if (__predict_false(pkt->rm_datalen == 0)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n"); + return; + } - dlen -= data_offset; - if (dlen < rndis_pkt->data_length) { - if_printf(rxr->hn_ifp, - "total length %u is less than data length %u\n", - dlen, rndis_pkt->data_length); + /* + * Check offests. + */ +#define IS_OFFSET_INVALID(ofs) \ + ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \ + ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK)) + + /* XXX Hyper-V does not meet data offset alignment requirement */ + if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "data offset %u\n", pkt->rm_dataoffset); + return; + } + if (__predict_false(pkt->rm_oobdataoffset > 0 && + IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob offset %u\n", pkt->rm_oobdataoffset); + return; + } + if (__predict_true(pkt->rm_pktinfooffset > 0) && + __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo offset %u\n", pkt->rm_pktinfooffset); return; } - dlen = rndis_pkt->data_length; - data = (const uint8_t *)data + data_offset; +#undef IS_OFFSET_INVALID - if (hv_rf_find_recvinfo(rndis_pkt, &info)) { - if_printf(rxr->hn_ifp, "recvinfo parsing failed\n"); + data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset); + data_len = pkt->rm_datalen; + pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset); + pktinfo_len = pkt->rm_pktinfolen; + + /* + * Check OOB coverage. + */ + if (__predict_false(pkt->rm_oobdatalen != 0)) { + int oob_off, oob_len; + + if_printf(rxr->hn_ifp, "got oobdata\n"); + oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset); + oob_len = pkt->rm_oobdatalen; + + if (__predict_false(oob_off + oob_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overflow, msglen %u, oob abs %d len %d\n", + pkt->rm_len, oob_off, oob_len); + return; + } + + /* + * Check against data. + */ + if (hn_rndis_check_overlap(oob_off, oob_len, + data_off, data_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overlaps data, oob abs %d len %d, " + "data abs %d len %d\n", + oob_off, oob_len, data_off, data_len); + return; + } + + /* + * Check against pktinfo. + */ + if (pktinfo_len != 0 && + hn_rndis_check_overlap(oob_off, oob_len, + pktinfo_off, pktinfo_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overlaps pktinfo, oob abs %d len %d, " + "pktinfo abs %d len %d\n", + oob_off, oob_len, pktinfo_off, pktinfo_len); + return; + } + } + + /* + * Check per-packet-info coverage and find useful per-packet-info. + */ + info.vlan_info = HN_NDIS_VLAN_INFO_INVALID; + info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID; + info.hash_info = HN_NDIS_HASH_INFO_INVALID; + if (__predict_true(pktinfo_len != 0)) { + bool overlap; + int error; + + if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo overflow, msglen %u, " + "pktinfo abs %d len %d\n", + pkt->rm_len, pktinfo_off, pktinfo_len); + return; + } + + /* + * Check packet info coverage. + */ + overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len, + data_off, data_len); + if (__predict_false(overlap)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo overlap data, pktinfo abs %d len %d, " + "data abs %d len %d\n", + pktinfo_off, pktinfo_len, data_off, data_len); + return; + } + + /* + * Find useful per-packet-info. + */ + error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off, + pktinfo_len, &info); + if (__predict_false(error)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg " + "pktinfo\n"); + return; + } + } + + if (__predict_false(data_off + data_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "data overflow, msglen %u, data abs %d len %d\n", + pkt->rm_len, data_off, data_len); return; } - netvsc_recv(rxr, data, dlen, &info); + netvsc_recv(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); } /* * RNDIS filter on receive */ -int +void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen) { - const rndis_msg *rndis_hdr; const struct rndis_comp_hdr *comp; + const struct rndis_msghdr *hdr; + + if (__predict_false(dlen < sizeof(*hdr))) { + if_printf(rxr->hn_ifp, "invalid RNDIS msg\n"); + return; + } + hdr = data; - rndis_hdr = data; - switch (rndis_hdr->ndis_msg_type) { - /* data message */ + switch (hdr->rm_type) { case REMOTE_NDIS_PACKET_MSG: hv_rf_receive_data(rxr, data, dlen); break; - /* completion messages */ case REMOTE_NDIS_INITIALIZE_CMPLT: case REMOTE_NDIS_QUERY_CMPLT: case REMOTE_NDIS_SET_CMPLT: - case REMOTE_NDIS_KEEPALIVE_CMPLT: + case REMOTE_NDIS_KEEPALIVE_CMPLT: /* unused */ + if (dlen < sizeof(*comp)) { + if_printf(rxr->hn_ifp, "invalid RNDIS cmplt\n"); + return; + } comp = data; + KASSERT(comp->rm_rid > HN_RNDIS_RID_COMPAT_MAX, - ("invalid rid 0x%08x\n", comp->rm_rid)); + ("invalid RNDIS rid 0x%08x\n", comp->rm_rid)); vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen); break; - /* notification message */ case REMOTE_NDIS_INDICATE_STATUS_MSG: - hv_rf_receive_indicate_status(sc, rndis_hdr); + hv_rf_receive_indicate_status(sc, data, dlen); break; case REMOTE_NDIS_RESET_CMPLT: @@ -322,15 +460,14 @@ hv_rf_on_receive(struct hn_softc *sc, st * RESET is not issued by hn(4), so this message should * _not_ be observed. */ - if_printf(sc->hn_ifp, "RESET CMPLT received\n"); + if_printf(rxr->hn_ifp, "RESET cmplt received\n"); break; default: - if_printf(sc->hn_ifp, "unknown RNDIS message 0x%x\n", - rndis_hdr->ndis_msg_type); + if_printf(rxr->hn_ifp, "unknown RNDIS msg 0x%x\n", + hdr->rm_type); break; } - return (0); } /* @@ -552,7 +689,7 @@ hn_rndis_query(struct hn_softc *sc, uint * Check output data length and offset. */ /* ofs is the offset from the beginning of comp. */ - ofs = RNDIS_QUERY_COMP_INFOBUFABS(comp->rm_infobufoffset); + ofs = RNDIS_QUERY_COMP_INFOBUFOFFSET_ABS(comp->rm_infobufoffset); if (ofs < sizeof(*comp) || ofs + comp->rm_infobuflen > comp_len) { if_printf(sc->hn_ifp, "RNDIS query invalid comp ib off/len, " "%u/%u\n", comp->rm_infobufoffset, comp->rm_infobuflen); Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 07:42:44 2016 (r307198) @@ -40,7 +40,7 @@ */ struct hn_rx_ring; -int hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, +void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan, Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 07:42:44 2016 (r307198) @@ -721,7 +721,20 @@ vmbus_chan_recv(struct vmbus_channel *ch error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); if (error) - return error; + return (error); + + if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) { + device_printf(chan->ch_dev, "invalid hlen %u\n", + pkt.cph_hlen); + /* XXX this channel is dead actually. */ + return (EIO); + } + if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) { + device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n", + pkt.cph_hlen, pkt.cph_tlen); + /* XXX this channel is dead actually. */ + return (EIO); + } hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen); dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen; @@ -729,7 +742,7 @@ vmbus_chan_recv(struct vmbus_channel *ch if (*dlen0 < dlen) { /* Return the size of this packet's data. */ *dlen0 = dlen; - return ENOBUFS; + return (ENOBUFS); } *xactid = pkt.cph_xactid; @@ -739,7 +752,7 @@ vmbus_chan_recv(struct vmbus_channel *ch error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen); KASSERT(!error, ("vmbus_rxbr_read failed")); - return 0; + return (0); } int @@ -751,13 +764,26 @@ vmbus_chan_recv_pkt(struct vmbus_channel error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt)); if (error) - return error; + return (error); + + if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) { + device_printf(chan->ch_dev, "invalid hlen %u\n", + pkt.cph_hlen); + /* XXX this channel is dead actually. */ + return (EIO); + } + if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) { + device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n", + pkt.cph_hlen, pkt.cph_tlen); + /* XXX this channel is dead actually. */ + return (EIO); + } pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen); if (*pktlen0 < pktlen) { /* Return the size of this packet. */ *pktlen0 = pktlen; - return ENOBUFS; + return (ENOBUFS); } *pktlen0 = pktlen; @@ -765,7 +791,7 @@ vmbus_chan_recv_pkt(struct vmbus_channel error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0); KASSERT(!error, ("vmbus_rxbr_read failed")); - return 0; + return (0); } static void Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Thu Oct 13 07:42:44 2016 (r307198) @@ -153,6 +153,9 @@ do { \ #define VMBUS_CHANPKT_TOTLEN(tlen) \ roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN) +#define VMBUS_CHANPKT_HLEN_MIN \ + (sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT) + struct vmbus_chanpkt { struct vmbus_chanpkt_hdr cp_hdr; } __packed; Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Thu Oct 13 07:35:19 2016 (r307197) +++ stable/10/sys/net/rndis.h Thu Oct 13 07:42:44 2016 (r307198) @@ -127,6 +127,14 @@ struct rndis_packet_msg { (sizeof(struct rndis_packet_msg) - \ __offsetof(struct rndis_packet_msg, rm_dataoffset)) +/* Offset from the beginning of rndis_packet_msg. */ +#define RNDIS_PACKET_MSG_OFFSET_ABS(ofs) \ + ((ofs) + __offsetof(struct rndis_packet_msg, rm_dataoffset)) + +#define RNDIS_PACKET_MSG_OFFSET_ALIGN 4 +#define RNDIS_PACKET_MSG_OFFSET_ALIGNMASK \ + (RNDIS_PACKET_MSG_OFFSET_ALIGN - 1) + /* Per-packet-info for RNDIS data message */ struct rndis_pktinfo { uint32_t rm_size; @@ -137,7 +145,8 @@ struct rndis_pktinfo { #define RNDIS_PKTINFO_OFFSET \ __offsetof(struct rndis_pktinfo, rm_data[0]) -#define RNDIS_PKTINFO_ALIGN 4 +#define RNDIS_PKTINFO_SIZE_ALIGN 4 +#define RNDIS_PKTINFO_SIZE_ALIGNMASK (RNDIS_PKTINFO_SIZE_ALIGN - 1) #define NDIS_PKTINFO_TYPE_CSUM 0 #define NDIS_PKTINFO_TYPE_IPSEC 1 @@ -236,7 +245,8 @@ struct rndis_query_comp { uint32_t rm_infobufoffset; }; -#define RNDIS_QUERY_COMP_INFOBUFABS(ofs) \ +/* infobuf offset from the beginning of rndis_query_comp. */ +#define RNDIS_QUERY_COMP_INFOBUFOFFSET_ABS(ofs) \ ((ofs) + __offsetof(struct rndis_query_req, rm_rid)) /* Send a set object request. */ @@ -295,9 +305,28 @@ struct rndis_reset_comp { uint32_t rm_adrreset; }; -/* 802.3 link-state or undefined message error. */ +/* 802.3 link-state or undefined message error. Sent by device. */ #define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007 +struct rndis_status_msg { + uint32_t rm_type; + uint32_t rm_len; + uint32_t rm_status; + uint32_t rm_stbuflen; + uint32_t rm_stbufoffset; + /* rndis_diag_info */ +}; + +/* + * Immediately after rndis_status_msg.rm_stbufoffset, if a control + * message is malformatted, or a packet message contains inappropriate + * content. + */ +struct rndis_diag_info { + uint32_t rm_diagstatus; + uint32_t rm_erroffset; +}; + /* Keepalive messsage. May be sent by device. */ #define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008 #define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008 From owner-svn-src-stable-10@freebsd.org Thu Oct 13 07:52:40 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EEB9BC0FA61; Thu, 13 Oct 2016 07:52:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B8176DE0; Thu, 13 Oct 2016 07:52:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D7qdOK026947; Thu, 13 Oct 2016 07:52:39 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D7qdsg026940; Thu, 13 Oct 2016 07:52:39 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130752.u9D7qdsg026940@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 07:52:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307199 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 07:52:41 -0000 Author: sephe Date: Thu Oct 13 07:52:39 2016 New Revision: 307199 URL: https://svnweb.freebsd.org/changeset/base/307199 Log: MFC 305454,305455,305521,305524-305526 305454 hyperv/hn: Fix VLAN tag setup for outgoing VLAN packets. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7785 305455 hyperv/hn: Avoid bit fields for LSOv2 setup. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7786 305521 hyperv/hn: Avoid bit fields for TXCSUM setup. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7792 305524 hyperv/hn: Cleanup RNDIS packet message encapsulation. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7793 305525 hyperv/hn: Simplify per-packet-info construction. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7794 305526 hyperv/hn: Nuke unused bits Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7795 Deleted: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnreg.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h stable/10/sys/dev/hyperv/netvsc/ndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 07:52:39 2016 (r307199) @@ -47,9 +47,9 @@ #include #include #include -#include #include #include +#include MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); @@ -512,15 +512,15 @@ hv_nv_connect_to_vsp(struct hn_softc *sc for (i = protocol_number - 1; i >= 0; i--) { if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { sc->hn_nvs_ver = protocol_list[i]; - sc->hn_ndis_ver = NDIS_VERSION_6_30; + sc->hn_ndis_ver = HN_NDIS_VERSION_6_30; if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) - sc->hn_ndis_ver = NDIS_VERSION_6_1; + sc->hn_ndis_ver = HN_NDIS_VERSION_6_1; if (bootverbose) { if_printf(sc->hn_ifp, "NVS version 0x%x, " "NDIS version %u.%u\n", sc->hn_nvs_ver, - NDIS_VERSION_MAJOR(sc->hn_ndis_ver), - NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } break; } @@ -546,8 +546,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc memset(&ndis, 0, sizeof(ndis)); ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; - ndis.nvs_ndis_major = NDIS_VERSION_MAJOR(sc->hn_ndis_ver); - ndis.nvs_ndis_minor = NDIS_VERSION_MINOR(sc->hn_ndis_ver); + ndis.nvs_ndis_major = HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver); + ndis.nvs_ndis_minor = HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver); /* NOTE: No response. */ ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); @@ -763,7 +763,7 @@ hv_nv_on_receive(struct hn_softc *sc, st } pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; - if (__predict_false(pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID)) { + if (__predict_false(pkt->cp_rxbuf_id != HN_NVS_RXBUF_SIG)) { if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n", pkt->cp_rxbuf_id); return; Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 07:52:39 2016 (r307199) @@ -74,110 +74,6 @@ MALLOC_DECLARE(M_NETVSC); #define NVSP_PROTOCOL_VERSION_2 0x30002 #define NVSP_PROTOCOL_VERSION_4 0x40000 #define NVSP_PROTOCOL_VERSION_5 0x50000 -#define NVSP_MIN_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_1) -#define NVSP_MAX_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_2) - -#define NVSP_PROTOCOL_VERSION_CURRENT NVSP_PROTOCOL_VERSION_2 - -#define VERSION_4_OFFLOAD_SIZE 22 - -#define NVSP_OPERATIONAL_STATUS_OK (0x00000000) -#define NVSP_OPERATIONAL_STATUS_DEGRADED (0x00000001) -#define NVSP_OPERATIONAL_STATUS_NONRECOVERABLE (0x00000002) -#define NVSP_OPERATIONAL_STATUS_NO_CONTACT (0x00000003) -#define NVSP_OPERATIONAL_STATUS_LOST_COMMUNICATION (0x00000004) - -/* - * Maximun number of transfer pages (packets) the VSP will use on a receive - */ -#define NVSP_MAX_PACKETS_PER_RECEIVE 375 - -/* vRSS stuff */ -#define RNDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 -#define RNDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 - -#define RNDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2 -#define RNDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 - -struct rndis_obj_header { - uint8_t type; - uint8_t rev; - uint16_t size; -} __packed; - -/* rndis_recv_scale_cap/cap_flag */ -#define RNDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000 -#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000 -#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000 -#define RNDIS_RSS_CAPS_USING_MSI_X 0x08000000 -#define RNDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000 -#define RNDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200 -#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400 - -/* RNDIS_RECEIVE_SCALE_CAPABILITIES */ -struct rndis_recv_scale_cap { - struct rndis_obj_header hdr; - uint32_t cap_flag; - uint32_t num_int_msg; - uint32_t num_recv_que; - uint16_t num_indirect_tabent; -} __packed; - -/* rndis_recv_scale_param flags */ -#define RNDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001 -#define RNDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002 -#define RNDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004 -#define RNDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008 -#define RNDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010 - -/* Hash info bits */ -#define RNDIS_HASH_FUNC_TOEPLITZ 0x00000001 -#define RNDIS_HASH_IPV4 0x00000100 -#define RNDIS_HASH_TCP_IPV4 0x00000200 -#define RNDIS_HASH_IPV6 0x00000400 -#define RNDIS_HASH_IPV6_EX 0x00000800 -#define RNDIS_HASH_TCP_IPV6 0x00001000 -#define RNDIS_HASH_TCP_IPV6_EX 0x00002000 - -#define RNDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4) -#define RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 - -#define ITAB_NUM 128 -#define HASH_KEYLEN RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 - -/* RNDIS_RECEIVE_SCALE_PARAMETERS */ -typedef struct rndis_recv_scale_param_ { - struct rndis_obj_header hdr; - - /* Qualifies the rest of the information */ - uint16_t flag; - - /* The base CPU number to do receive processing. not used */ - uint16_t base_cpu_number; - - /* This describes the hash function and type being enabled */ - uint32_t hashinfo; - - /* The size of indirection table array */ - uint16_t indirect_tabsize; - - /* The offset of the indirection table from the beginning of this - * structure - */ - uint32_t indirect_taboffset; - - /* The size of the hash secret key */ - uint16_t hashkey_size; - - /* The offset of the secret key from the beginning of this structure */ - uint32_t hashkey_offset; - - uint32_t processor_masks_offset; - uint32_t num_processor_masks; - uint32_t processor_masks_entry_size; -} rndis_recv_scale_param; /* * The following arguably belongs in a separate header file @@ -188,18 +84,10 @@ typedef struct rndis_recv_scale_param_ { */ #define NETVSC_SEND_BUFFER_SIZE (1024*1024*15) /* 15M */ -#define NETVSC_SEND_BUFFER_ID 0xface #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */ #define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */ -#define NETVSC_RECEIVE_BUFFER_ID 0xcafe - -#define NETVSC_RECEIVE_SG_COUNT 1 - -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT 256 - /* * Maximum MTU we permit to be configured for a netvsc interface. * When the code was developed, a max MTU of 12232 was tested and @@ -208,7 +96,6 @@ typedef struct rndis_recv_scale_param_ { #define NETVSC_MAX_CONFIGURABLE_MTU (9 * 1024) #define NETVSC_PACKET_SIZE PAGE_SIZE -#define VRSS_SEND_TABLE_SIZE 16 /* * Data types @@ -216,26 +103,9 @@ typedef struct rndis_recv_scale_param_ { struct vmbus_channel; -typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *); - #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) #define NETVSC_PACKET_MAXPAGE 32 -#define NETVSC_VLAN_PRIO_MASK 0xe000 -#define NETVSC_VLAN_PRIO_SHIFT 13 -#define NETVSC_VLAN_VID_MASK 0x0fff - -#define TYPE_IPV4 2 -#define TYPE_IPV6 4 -#define TYPE_TCP 2 -#define TYPE_UDP 4 - -#define TRANSPORT_TYPE_NOT_IP 0 -#define TRANSPORT_TYPE_IPV4_TCP ((TYPE_IPV4 << 16) | TYPE_TCP) -#define TRANSPORT_TYPE_IPV4_UDP ((TYPE_IPV4 << 16) | TYPE_UDP) -#define TRANSPORT_TYPE_IPV6_TCP ((TYPE_IPV6 << 16) | TYPE_TCP) -#define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP) - typedef struct { uint8_t mac_addr[ETHER_ADDR_LEN]; uint32_t link_state; Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:52:39 2016 (r307199) @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include - +#include #include #include @@ -120,7 +120,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include @@ -144,14 +143,14 @@ __FBSDID("$FreeBSD$"); #define HN_RING_CNT_DEF_MAX 8 -#define HN_RNDIS_MSG_LEN \ - (sizeof(rndis_msg) + \ - RNDIS_HASHVAL_PPI_SIZE + \ - RNDIS_VLAN_PPI_SIZE + \ - RNDIS_TSO_PPI_SIZE + \ - RNDIS_CSUM_PPI_SIZE) -#define HN_RNDIS_MSG_BOUNDARY PAGE_SIZE -#define HN_RNDIS_MSG_ALIGN CACHE_LINE_SIZE +#define HN_RNDIS_PKT_LEN \ + (sizeof(struct rndis_packet_msg) + \ + HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_VLAN_INFO_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_LSO2_INFO_SIZE) + \ + HN_RNDIS_PKTINFO_SIZE(NDIS_TXCSUM_INFO_SIZE)) +#define HN_RNDIS_PKT_BOUNDARY PAGE_SIZE +#define HN_RNDIS_PKT_ALIGN CACHE_LINE_SIZE #define HN_TX_DATA_BOUNDARY PAGE_SIZE #define HN_TX_DATA_MAXSIZE IP_MAXPACKET @@ -175,9 +174,9 @@ struct hn_txdesc { bus_dmamap_t data_dmap; - bus_addr_t rndis_msg_paddr; - rndis_msg *rndis_msg; - bus_dmamap_t rndis_msg_dmap; + bus_addr_t rndis_pkt_paddr; + struct rndis_packet_msg *rndis_pkt; + bus_dmamap_t rndis_pkt_dmap; }; #define HN_TXD_FLAG_ONLIST 0x1 @@ -839,7 +838,7 @@ hn_tx_done(struct hn_send_ctx *sndc, str } void -netvsc_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) +hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { #if defined(INET) || defined(INET6) struct lro_ctrl *lro = &rxr->hn_lro; @@ -863,6 +862,15 @@ netvsc_channel_rollup(struct hn_rx_ring hn_txeof(txr); } +static __inline uint32_t +hn_rndis_pktmsg_offset(uint32_t ofs) +{ + + KASSERT(ofs >= sizeof(struct rndis_packet_msg), + ("invalid RNDIS packet msg offset %u", ofs)); + return (ofs - __offsetof(struct rndis_packet_msg, rm_dataoffset)); +} + /* * NOTE: * If this function fails, then both txd and m_head0 will be freed. @@ -873,14 +881,10 @@ hn_encap(struct hn_tx_ring *txr, struct bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX]; int error, nsegs, i; struct mbuf *m_head = *m_head0; - rndis_msg *rndis_mesg; - rndis_packet *rndis_pkt; - rndis_per_packet_info *rppi; - struct rndis_hash_value *hash_value; - uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx; - int send_buf_section_size; - - tot_data_buf_len = m_head->m_pkthdr.len; + struct rndis_packet_msg *pkt; + uint32_t send_buf_section_idx; + int send_buf_section_size, pktlen; + uint32_t *pi_data; /* * extension points to the area reserved for the @@ -888,45 +892,34 @@ hn_encap(struct hn_tx_ring *txr, struct * the netvsc_packet (and rppi struct, if present; * length is updated later). */ - rndis_mesg = txd->rndis_msg; - /* XXX not necessary */ - memset(rndis_mesg, 0, HN_RNDIS_MSG_LEN); - rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; - - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset = sizeof(rndis_packet); - rndis_pkt->data_length = tot_data_buf_len; - rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet); - - rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); + pkt = txd->rndis_pkt; + pkt->rm_type = REMOTE_NDIS_PACKET_MSG; + pkt->rm_len = sizeof(*pkt) + m_head->m_pkthdr.len; + pkt->rm_dataoffset = sizeof(*pkt); + pkt->rm_datalen = m_head->m_pkthdr.len; + pkt->rm_pktinfooffset = sizeof(*pkt); + pkt->rm_pktinfolen = 0; /* * Set the hash value for this packet, so that the host could * dispatch the TX done event for this packet back to this TX * ring's channel. */ - rndis_msg_size += RNDIS_HASHVAL_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASHVAL_PPI_SIZE, - nbl_hash_value); - hash_value = (struct rndis_hash_value *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - hash_value->hash_value = txr->hn_tx_idx; + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL); + *pi_data = txr->hn_tx_idx; if (m_head->m_flags & M_VLANTAG) { - ndis_8021q_info *rppi_vlan_info; - - rndis_msg_size += RNDIS_VLAN_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE, - ieee_8021q_info); - - rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - rppi_vlan_info->u1.s1.vlan_id = - m_head->m_pkthdr.ether_vtag & 0xfff; + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN); + *pi_data = NDIS_VLAN_INFO_MAKE( + EVL_VLANOFTAG(m_head->m_pkthdr.ether_vtag), + EVL_PRIOFTAG(m_head->m_pkthdr.ether_vtag), + EVL_CFIOFTAG(m_head->m_pkthdr.ether_vtag)); } if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - rndis_tcp_tso_info *tso_info; +#if defined(INET6) || defined(INET) struct ether_vlan_header *eh; int ether_len; @@ -939,15 +932,8 @@ hn_encap(struct hn_tx_ring *txr, struct else ether_len = ETHER_HDR_LEN; - rndis_msg_size += RNDIS_TSO_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE, - tcp_large_send_info); - - tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); - tso_info->lso_v2_xmit.type = - RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; - + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_LSO2_INFO_SIZE, NDIS_PKTINFO_TYPE_LSO); #ifdef INET if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) { struct ip *ip = @@ -956,13 +942,12 @@ hn_encap(struct hn_tx_ring *txr, struct struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + iph_len); - tso_info->lso_v2_xmit.ip_version = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4; ip->ip_len = 0; ip->ip_sum = 0; - th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(IPPROTO_TCP)); + *pi_data = NDIS_LSO2_INFO_MAKEIPV4(0, + m_head->m_pkthdr.tso_segsz); } #endif #if defined(INET6) && defined(INET) @@ -974,53 +959,47 @@ hn_encap(struct hn_tx_ring *txr, struct (m_head->m_data + ether_len); struct tcphdr *th = (struct tcphdr *)(ip6 + 1); - tso_info->lso_v2_xmit.ip_version = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; ip6->ip6_plen = 0; th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + *pi_data = NDIS_LSO2_INFO_MAKEIPV6(0, + m_head->m_pkthdr.tso_segsz); } #endif - tso_info->lso_v2_xmit.tcp_header_offset = 0; - tso_info->lso_v2_xmit.mss = m_head->m_pkthdr.tso_segsz; +#endif /* INET6 || INET */ } else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) { - rndis_tcp_ip_csum_info *csum_info; - - rndis_msg_size += RNDIS_CSUM_PPI_SIZE; - rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE, - tcpip_chksum_info); - csum_info = (rndis_tcp_ip_csum_info *)((uint8_t *)rppi + - rppi->per_packet_info_offset); + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM); + *pi_data = NDIS_TXCSUM_INFO_IPV4; - csum_info->xmit.is_ipv4 = 1; if (m_head->m_pkthdr.csum_flags & CSUM_IP) - csum_info->xmit.ip_header_csum = 1; + *pi_data |= NDIS_TXCSUM_INFO_IPCS; - if (m_head->m_pkthdr.csum_flags & CSUM_TCP) { - csum_info->xmit.tcp_csum = 1; - csum_info->xmit.tcp_header_offset = 0; - } else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) { - csum_info->xmit.udp_csum = 1; - } + if (m_head->m_pkthdr.csum_flags & CSUM_TCP) + *pi_data |= NDIS_TXCSUM_INFO_TCPCS; + else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) + *pi_data |= NDIS_TXCSUM_INFO_UDPCS; } - rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size; - tot_data_buf_len = rndis_mesg->msg_len; + pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; + /* Convert RNDIS packet message offsets */ + pkt->rm_dataoffset = hn_rndis_pktmsg_offset(pkt->rm_dataoffset); + pkt->rm_pktinfooffset = hn_rndis_pktmsg_offset(pkt->rm_pktinfooffset); /* * Chimney send, if the packet could fit into one chimney buffer. */ - if (tot_data_buf_len < txr->hn_chim_size) { + if (pkt->rm_len < txr->hn_chim_size) { txr->hn_tx_chimney_tried++; send_buf_section_idx = hn_chim_alloc(txr->hn_sc); if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) { uint8_t *dest = txr->hn_sc->hn_chim + (send_buf_section_idx * txr->hn_sc->hn_chim_szmax); - memcpy(dest, rndis_mesg, rndis_msg_size); - dest += rndis_msg_size; + memcpy(dest, pkt, pktlen); + dest += pktlen; m_copydata(m_head, 0, m_head->m_pkthdr.len, dest); - send_buf_section_size = tot_data_buf_len; + send_buf_section_size = pkt->rm_len; txr->hn_gpa_cnt = 0; txr->hn_tx_chimney++; goto done; @@ -1051,9 +1030,9 @@ hn_encap(struct hn_tx_ring *txr, struct txr->hn_gpa_cnt = nsegs + 1; /* send packet with page buffer */ - txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr); - txr->hn_gpa[0].gpa_ofs = txd->rndis_msg_paddr & PAGE_MASK; - txr->hn_gpa[0].gpa_len = rndis_msg_size; + txr->hn_gpa[0].gpa_page = atop(txd->rndis_pkt_paddr); + txr->hn_gpa[0].gpa_ofs = txd->rndis_pkt_paddr & PAGE_MASK; + txr->hn_gpa[0].gpa_len = pktlen; /* * Fill the page buffers with mbuf info after the page @@ -1301,7 +1280,7 @@ hn_lro_rx(struct lro_ctrl *lc, struct mb * Note: This is no longer used as a callback */ int -netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, +hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info) { struct ifnet *ifp = rxr->hn_ifp; @@ -2154,8 +2133,8 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_AR char verstr[16]; snprintf(verstr, sizeof(verstr), "%u.%u", - NDIS_VERSION_MAJOR(sc->hn_ndis_ver), - NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); } @@ -2515,16 +2494,16 @@ hn_create_tx_ring(struct hn_softc *sc, i parent_dtag = bus_get_dma_tag(dev); - /* DMA tag for RNDIS messages. */ + /* DMA tag for RNDIS packet messages. */ error = bus_dma_tag_create(parent_dtag, /* parent */ - HN_RNDIS_MSG_ALIGN, /* alignment */ - HN_RNDIS_MSG_BOUNDARY, /* boundary */ + HN_RNDIS_PKT_ALIGN, /* alignment */ + HN_RNDIS_PKT_BOUNDARY, /* boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - HN_RNDIS_MSG_LEN, /* maxsize */ + HN_RNDIS_PKT_LEN, /* maxsize */ 1, /* nsegments */ - HN_RNDIS_MSG_LEN, /* maxsegsize */ + HN_RNDIS_PKT_LEN, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockfuncarg */ @@ -2559,28 +2538,28 @@ hn_create_tx_ring(struct hn_softc *sc, i txd->txr = txr; /* - * Allocate and load RNDIS messages. + * Allocate and load RNDIS packet message. */ error = bus_dmamem_alloc(txr->hn_tx_rndis_dtag, - (void **)&txd->rndis_msg, - BUS_DMA_WAITOK | BUS_DMA_COHERENT, - &txd->rndis_msg_dmap); + (void **)&txd->rndis_pkt, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, + &txd->rndis_pkt_dmap); if (error) { device_printf(dev, - "failed to allocate rndis_msg, %d\n", i); + "failed to allocate rndis_packet_msg, %d\n", i); return error; } error = bus_dmamap_load(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap, - txd->rndis_msg, HN_RNDIS_MSG_LEN, - hyperv_dma_map_paddr, &txd->rndis_msg_paddr, + txd->rndis_pkt_dmap, + txd->rndis_pkt, HN_RNDIS_PKT_LEN, + hyperv_dma_map_paddr, &txd->rndis_pkt_paddr, BUS_DMA_NOWAIT); if (error) { device_printf(dev, - "failed to load rndis_msg, %d\n", i); + "failed to load rndis_packet_msg, %d\n", i); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2591,9 +2570,9 @@ hn_create_tx_ring(struct hn_softc *sc, i device_printf(dev, "failed to allocate tx data dmamap\n"); bus_dmamap_unload(txr->hn_tx_rndis_dtag, - txd->rndis_msg_dmap); + txd->rndis_pkt_dmap); bus_dmamem_free(txr->hn_tx_rndis_dtag, - txd->rndis_msg, txd->rndis_msg_dmap); + txd->rndis_pkt, txd->rndis_pkt_dmap); return error; } @@ -2651,9 +2630,9 @@ hn_txdesc_dmamap_destroy(struct hn_txdes KASSERT(txd->m == NULL, ("still has mbuf installed")); KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("still dma mapped")); - bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap); - bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_msg, - txd->rndis_msg_dmap); + bus_dmamap_unload(txr->hn_tx_rndis_dtag, txd->rndis_pkt_dmap); + bus_dmamem_free(txr->hn_tx_rndis_dtag, txd->rndis_pkt, + txd->rndis_pkt_dmap); bus_dmamap_destroy(txr->hn_tx_data_dtag, txd->data_dmap); } Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:52:39 2016 (r307199) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -49,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -103,29 +103,40 @@ again: return ((rid & 0xffff) << 16); } -/* - * Set the Per-Packet-Info with the specified type - */ void * -hv_set_rppi_data(rndis_msg *rndis_mesg, uint32_t rppi_size, - int pkt_type) +hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, + size_t pi_dlen, uint32_t pi_type) { - rndis_packet *rndis_pkt; - rndis_per_packet_info *rppi; + const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen); + struct rndis_pktinfo *pi; - rndis_pkt = &rndis_mesg->msg.packet; - rndis_pkt->data_offset += rppi_size; + KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0, + ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen)); - rppi = (rndis_per_packet_info *)((char *)rndis_pkt + - rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_length); + /* + * Per-packet-info does not move; it only grows. + * + * NOTE: + * rm_pktinfooffset in this phase counts from the beginning + * of rndis_packet_msg. + */ + KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize, + ("%u pktinfo overflows RNDIS packet msg", pi_type)); + pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset + + pkt->rm_pktinfolen); + pkt->rm_pktinfolen += pi_size; + + pi->rm_size = pi_size; + pi->rm_type = pi_type; + pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET; - rppi->size = rppi_size; - rppi->type = pkt_type; - rppi->per_packet_info_offset = sizeof(rndis_per_packet_info); + /* Data immediately follow per-packet-info. */ + pkt->rm_dataoffset += pi_size; - rndis_pkt->per_pkt_info_length += rppi_size; + /* Update RNDIS packet msg length */ + pkt->rm_len += pi_size; - return (rppi); + return (pi->rm_data); } /* @@ -409,7 +420,7 @@ hv_rf_receive_data(struct hn_rx_ring *rx pkt->rm_len, data_off, data_len); return; } - netvsc_recv(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); + hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); } /* @@ -721,7 +732,7 @@ hn_rndis_get_rsscaps(struct hn_softc *sc /* * Only NDIS 6.30+ is supported. */ - KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); *rxr_cnt = 0; @@ -817,7 +828,7 @@ hn_rndis_conf_offload(struct hn_softc *s memset(¶ms, 0, sizeof(params)); params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; - if (sc->hn_ndis_ver < NDIS_VERSION_6_30) { + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30) { params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; paramsz = NDIS_OFFLOAD_PARAMS_SIZE_6_1; } else { @@ -829,7 +840,7 @@ hn_rndis_conf_offload(struct hn_softc *s params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; - if (sc->hn_ndis_ver >= NDIS_VERSION_6_30) { + if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; } @@ -856,7 +867,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, i /* * Only NDIS 6.30+ is supported. */ - KASSERT(sc->hn_ndis_ver >= NDIS_VERSION_6_30, + KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); memset(rss, 0, sizeof(*rss)); @@ -1049,7 +1060,7 @@ hv_rf_on_device_add(struct hn_softc *sc, hv_rf_query_device_link_status(sc, &dev_info->link_state); - if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) { + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) { /* * Either RSS is not supported, or multiple RX/TX rings * are not requested. @@ -1179,5 +1190,5 @@ void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { - netvsc_channel_rollup(rxr, txr); + hn_chan_rollup(rxr, txr); } Modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:52:39 2016 (r307199) @@ -32,6 +32,14 @@ #include #include +/* + * NDIS protocol version numbers + */ +#define HN_NDIS_VERSION_6_1 0x00060001 +#define HN_NDIS_VERSION_6_30 0x0006001e +#define HN_NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) +#define HN_NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) + #define HN_NVS_RXBUF_SIG 0xcafe #define HN_NVS_CHIM_SIG 0xface @@ -221,4 +229,8 @@ CTASSERT(sizeof(struct hn_nvs_rndis_ack) #define HN_NDIS_HASH_VALUE_SIZE sizeof(uint32_t) #define HN_NDIS_PKTINFO_TYPE_HASHVAL NDIS_PKTINFO_TYPE_PKT_CANCELID +/* Per-packet-info size */ +#define HN_RNDIS_PKTINFO_SIZE(dlen) \ + __offsetof(struct rndis_pktinfo, rm_data[dlen]) + #endif /* !_IF_HNREG_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 07:52:39 2016 (r307199) @@ -112,6 +112,7 @@ hn_nvs_send_sglist(struct vmbus_channel } struct vmbus_xact; +struct rndis_packet_msg; const void *hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, @@ -121,6 +122,13 @@ void hn_nvs_sent_xact(struct hn_send_ct uint32_t hn_chim_alloc(struct hn_softc *sc); void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); +void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, + size_t pktsize, size_t pi_dlen, uint32_t pi_type); + +int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, + const struct hn_recvinfo *info); +void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); + extern struct hn_send_ctx hn_send_ctx_none; #endif /* !_IF_HNVAR_H_ */ Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:42:44 2016 (r307198) +++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 07:52:39 2016 (r307199) @@ -213,7 +213,7 @@ struct ndis_rssprm_toeplitz { #define NDIS_VLAN_INFO_CFI_MASK 0x0008 #define NDIS_VLAN_INFO_ID_MASK 0xfff0 #define NDIS_VLAN_INFO_MAKE(id, pri, cfi) \ - (((pri) & NVIS_VLAN_INFO_PRI_MASK) | \ + (((pri) & NDIS_VLAN_INFO_PRI_MASK) | \ (((cfi) & 0x1) << 3) | (((id) & 0xfff) << 4)) #define NDIS_VLAN_INFO_ID(inf) (((inf) & NDIS_VLAN_INFO_ID_MASK) >> 4) #define NDIS_VLAN_INFO_CFI(inf) (((inf) & NDIS_VLAN_INFO_CFI_MASK) >> 3) @@ -231,4 +231,31 @@ struct ndis_rssprm_toeplitz { #define NDIS_RXCSUM_INFO_TCPCS_INVAL 0x0080 #define NDIS_RXCSUM_INFO_IPCS_INVAL 0x0100 +/* LSOv2 */ +#define NDIS_LSO2_INFO_SIZE sizeof(uint32_t) +#define NDIS_LSO2_INFO_MSS_MASK 0x000fffff +#define NDIS_LSO2_INFO_THOFF_MASK 0x3ff00000 +#define NDIS_LSO2_INFO_ISLSO2 0x40000000 +#define NDIS_LSO2_INFO_ISIPV6 0x80000000 + +#define NDIS_LSO2_INFO_MAKE(thoff, mss) \ + ((((uint32_t)(mss)) & NDIS_LSO2_INFO_MSS_MASK) | \ + ((((uint32_t)(thoff)) & 0x3ff) << 20) | \ + NDIS_LSO2_INFO_ISLSO2) + +#define NDIS_LSO2_INFO_MAKEIPV4(thoff, mss) \ + NDIS_LSO2_INFO_MAKE((thoff), (mss)) + +#define NDIS_LSO2_INFO_MAKEIPV6(thoff, mss) \ + (NDIS_LSO2_INFO_MAKE((thoff), (mss)) | NDIS_LSO2_INFO_ISIPV6) + +/* Transmission checksum */ +#define NDIS_TXCSUM_INFO_SIZE sizeof(uint32_t) +#define NDIS_TXCSUM_INFO_IPV4 0x00000001 +#define NDIS_TXCSUM_INFO_IPV6 0x00000002 +#define NDIS_TXCSUM_INFO_TCPCS 0x00000004 +#define NDIS_TXCSUM_INFO_UDPCS 0x00000008 +#define NDIS_TXCSUM_INFO_IPCS 0x00000010 +#define NDIS_TXCSUM_INFO_THOFF 0x03ff0000 + #endif /* !_NET_NDIS_H_ */ From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:01:40 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 16BEAC0F1D3; Thu, 13 Oct 2016 08:01:40 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B17633B1; Thu, 13 Oct 2016 08:01:39 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D81cTX029403; Thu, 13 Oct 2016 08:01:38 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D81c1C029397; Thu, 13 Oct 2016 08:01:38 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130801.u9D81c1C029397@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:01:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307200 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:01:40 -0000 Author: sephe Date: Thu Oct 13 08:01:38 2016 New Revision: 307200 URL: https://svnweb.freebsd.org/changeset/base/307200 Log: MFC 305578-305581 305578 hyperv/hn: Pull vmbus channel open up. While I'm here, pull up the channel callback related code too. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7805 305579 hyperv/hn: Push RXBUF size adjustment down. It is not used in other places. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7806 305580 hyperv/hn: Factor out function to do NVS initialization. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7807 305581 hyperv/hn: Pass MTU around. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7808 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 08:01:38 2016 (r307200) @@ -56,20 +56,11 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper /* * Forward declarations */ -static void hv_nv_on_channel_callback(struct vmbus_channel *chan, - void *xrxr); static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); -static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *, int); +static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); static int hv_nv_destroy_send_buffer(struct hn_softc *sc); static int hv_nv_destroy_rx_buffer(struct hn_softc *sc); -static int hv_nv_connect_to_vsp(struct hn_softc *sc); -static void hv_nv_on_send_completion(struct hn_softc *sc, - struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); -static void hv_nv_on_receive_completion(struct vmbus_channel *chan, - uint64_t tid); -static void hv_nv_on_receive(struct hn_softc *sc, - struct hn_rx_ring *rxr, struct vmbus_channel *chan, - const struct vmbus_chanpkt_hdr *pkt); +static int hv_nv_connect_to_vsp(struct hn_softc *sc, int mtu); static void hn_nvs_sent_none(struct hn_send_ctx *sndc, struct hn_softc *, struct vmbus_channel *chan, const void *, int); @@ -77,6 +68,13 @@ static void hn_nvs_sent_none(struct hn_s struct hn_send_ctx hn_send_ctx_none = HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); +static const uint32_t hn_nvs_version[] = { + HN_NVS_VERSION_5, + HN_NVS_VERSION_4, + HN_NVS_VERSION_2, + HN_NVS_VERSION_1 +}; + uint32_t hn_chim_alloc(struct hn_softc *sc) { @@ -162,17 +160,22 @@ hn_nvs_req_send(struct hn_softc *sc, voi * Hyper-V extensible switch and the synthetic data path. */ static int -hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size) +hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) { struct vmbus_xact *xact = NULL; struct hn_nvs_rxbuf_conn *conn; const struct hn_nvs_rxbuf_connresp *resp; size_t resp_len; uint32_t status; - int error; + int error, rxbuf_size; - KASSERT(rxbuf_size <= NETVSC_RECEIVE_BUFFER_SIZE, - ("invalid rxbuf size %d", rxbuf_size)); + /* + * Limit RXBUF size for old NVS. + */ + if (sc->hn_nvs_ver <= HN_NVS_VERSION_2) + rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; + else + rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE; /* * Connect the RXBUF GPADL to the primary channel. @@ -427,7 +430,7 @@ hv_nv_destroy_send_buffer(struct hn_soft } static int -hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, uint32_t nvs_ver) +hn_nvs_doinit(struct hn_softc *sc, uint32_t nvs_ver) { struct vmbus_xact *xact; struct hn_nvs_init *init; @@ -488,57 +491,55 @@ hv_nv_send_ndis_config(struct hn_softc * return (error); } -/* - * Net VSC connect to VSP - */ static int -hv_nv_connect_to_vsp(struct hn_softc *sc) +hn_nvs_init(struct hn_softc *sc) { - uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, - NVSP_PROTOCOL_VERSION_2, - NVSP_PROTOCOL_VERSION_4, - NVSP_PROTOCOL_VERSION_5 }; int i; - int protocol_number = nitems(protocol_list); - int ret = 0; - device_t dev = sc->hn_dev; - struct ifnet *ifp = sc->arpcom.ac_ifp; - struct hn_nvs_ndis_init ndis; - int rxbuf_size; - /* - * Negotiate the NVSP version. Try the latest NVSP first. - */ - for (i = protocol_number - 1; i >= 0; i--) { - if (hv_nv_negotiate_nvsp_protocol(sc, protocol_list[i]) == 0) { - sc->hn_nvs_ver = protocol_list[i]; + for (i = 0; i < nitems(hn_nvs_version); ++i) { + int error; + + error = hn_nvs_doinit(sc, hn_nvs_version[i]); + if (!error) { + sc->hn_nvs_ver = hn_nvs_version[i]; + + /* Set NDIS version according to NVS version. */ sc->hn_ndis_ver = HN_NDIS_VERSION_6_30; - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) + if (sc->hn_nvs_ver <= HN_NVS_VERSION_4) sc->hn_ndis_ver = HN_NDIS_VERSION_6_1; + if (bootverbose) { if_printf(sc->hn_ifp, "NVS version 0x%x, " - "NDIS version %u.%u\n", - sc->hn_nvs_ver, + "NDIS version %u.%u\n", sc->hn_nvs_ver, HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } - break; + return (0); } } + if_printf(sc->hn_ifp, "no NVS available\n"); + return (ENXIO); +} - if (i < 0) { - if (bootverbose) - device_printf(dev, "failed to negotiate a valid " - "protocol.\n"); - return (EPROTO); - } +/* + * Net VSC connect to VSP + */ +static int +hv_nv_connect_to_vsp(struct hn_softc *sc, int mtu) +{ + int ret = 0; + struct hn_nvs_ndis_init ndis; + + ret = hn_nvs_init(sc); + if (ret != 0) + return (ret); /* * Set the MTU if supported by this NVSP protocol version * This needs to be right after the NVSP init message per Haiyang */ - if (sc->hn_nvs_ver >= NVSP_PROTOCOL_VERSION_2) - ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); + if (sc->hn_nvs_ver >= HN_NVS_VERSION_2) + ret = hv_nv_send_ndis_config(sc, mtu); /* * Initialize NDIS. @@ -556,13 +557,7 @@ hv_nv_connect_to_vsp(struct hn_softc *sc goto cleanup; } - /* Post the big receive buffer to NetVSP */ - if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_2) - rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; - else - rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE; - - ret = hv_nv_init_rx_buffer_with_net_vsp(sc, rxbuf_size); + ret = hv_nv_init_rx_buffer_with_net_vsp(sc); if (ret == 0) ret = hv_nv_init_send_buffer_with_net_vsp(sc); @@ -580,54 +575,19 @@ hv_nv_disconnect_from_vsp(struct hn_soft hv_nv_destroy_send_buffer(sc); } -void -hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr) -{ - KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), - ("chan%u subidx %u, rxr%d mismatch", - vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); - vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, - NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, - hv_nv_on_channel_callback, rxr); -} - /* * Net VSC on device add * * Callback when the device belonging to this driver is added */ int -hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr) +hv_nv_on_device_add(struct hn_softc *sc, int mtu) { - struct vmbus_channel *chan = sc->hn_prichan; - int ret = 0; - - /* - * Open the channel - */ - KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), - ("chan%u subidx %u, rxr%d mismatch", - vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); - ret = vmbus_chan_open(chan, - NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, - NULL, 0, hv_nv_on_channel_callback, rxr); - if (ret != 0) - goto cleanup; /* * Connect with the NetVsp */ - ret = hv_nv_connect_to_vsp(sc); - if (ret != 0) - goto close; - - return (0); - -close: - /* Now, we can close the channel safely */ - vmbus_chan_close(chan); -cleanup: - return (ret); + return (hv_nv_connect_to_vsp(sc, mtu)); } /* @@ -683,25 +643,6 @@ hn_chim_free(struct hn_softc *sc, uint32 } /* - * Net VSC on send completion - */ -static void -hv_nv_on_send_completion(struct hn_softc *sc, struct vmbus_channel *chan, - const struct vmbus_chanpkt_hdr *pkt) -{ - struct hn_send_ctx *sndc; - - sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; - sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt), - VMBUS_CHANPKT_DATALEN(pkt)); - /* - * NOTE: - * 'sndc' CAN NOT be accessed anymore, since it can be freed by - * its callback. - */ -} - -/* * Net VSC on send * Sends a packet on the specified Hyper-V device. * Returns 0 on success, non-zero on failure. @@ -728,190 +669,3 @@ hv_nv_on_send(struct vmbus_channel *chan return (ret); } - -/* - * Net VSC on receive - * - * In the FreeBSD Hyper-V virtual world, this function deals exclusively - * with virtual addresses. - */ -static void -hv_nv_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, - struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) -{ - const struct vmbus_chanpkt_rxbuf *pkt; - const struct hn_nvs_hdr *nvs_hdr; - int count, i, hlen; - - if (__predict_false(VMBUS_CHANPKT_DATALEN(pkthdr) < sizeof(*nvs_hdr))) { - if_printf(rxr->hn_ifp, "invalid nvs RNDIS\n"); - return; - } - nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr); - - /* Make sure that this is a RNDIS message. */ - if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) { - if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n", - nvs_hdr->nvs_type); - return; - } - - hlen = VMBUS_CHANPKT_GETLEN(pkthdr->cph_hlen); - if (__predict_false(hlen < sizeof(*pkt))) { - if_printf(rxr->hn_ifp, "invalid rxbuf chanpkt\n"); - return; - } - pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; - - if (__predict_false(pkt->cp_rxbuf_id != HN_NVS_RXBUF_SIG)) { - if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n", - pkt->cp_rxbuf_id); - return; - } - - count = pkt->cp_rxbuf_cnt; - if (__predict_false(hlen < - __offsetof(struct vmbus_chanpkt_rxbuf, cp_rxbuf[count]))) { - if_printf(rxr->hn_ifp, "invalid rxbuf_cnt %d\n", count); - return; - } - - /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ - for (i = 0; i < count; ++i) { - int ofs, len; - - ofs = pkt->cp_rxbuf[i].rb_ofs; - len = pkt->cp_rxbuf[i].rb_len; - if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) { - if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, " - "ofs %d, len %d\n", i, ofs, len); - continue; - } - hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len); - } - - /* - * Moved completion call back here so that all received - * messages (not just data messages) will trigger a response - * message back to the host. - */ - hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid); -} - -/* - * Net VSC on receive completion - * - * Send a receive completion packet to RNDIS device (ie NetVsp) - */ -static void -hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid) -{ - struct hn_nvs_rndis_ack ack; - int retries = 0; - int ret = 0; - - ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK; - ack.nvs_status = HN_NVS_STATUS_OK; - -retry_send_cmplt: - /* Send the completion */ - ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, - VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid); - if (ret == 0) { - /* success */ - /* no-op */ - } else if (ret == EAGAIN) { - /* no more room... wait a bit and attempt to retry 3 times */ - retries++; - - if (retries < 4) { - DELAY(100); - goto retry_send_cmplt; - } - } -} - -static void -hn_proc_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) -{ - const struct hn_nvs_hdr *hdr; - - if (VMBUS_CHANPKT_DATALEN(pkt) < sizeof(*hdr)) { - if_printf(sc->hn_ifp, "invalid nvs notify\n"); - return; - } - hdr = VMBUS_CHANPKT_CONST_DATA(pkt); - - if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) { - /* Useless; ignore */ - return; - } - if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type); -} - -/* - * Net VSC on channel callback - */ -static void -hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr) -{ - struct hn_rx_ring *rxr = xrxr; - struct hn_softc *sc = rxr->hn_ifp->if_softc; - void *buffer; - int bufferlen = NETVSC_PACKET_SIZE; - - buffer = rxr->hn_rdbuf; - do { - struct vmbus_chanpkt_hdr *pkt = buffer; - uint32_t bytes_rxed; - int ret; - - bytes_rxed = bufferlen; - ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); - if (ret == 0) { - if (bytes_rxed > 0) { - switch (pkt->cph_type) { - case VMBUS_CHANPKT_TYPE_COMP: - hv_nv_on_send_completion(sc, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_RXBUF: - hv_nv_on_receive(sc, rxr, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_INBAND: - hn_proc_notify(sc, pkt); - break; - default: - if_printf(rxr->hn_ifp, - "unknown chan pkt %u\n", - pkt->cph_type); - break; - } - } - } else if (ret == ENOBUFS) { - /* Handle large packet */ - if (bufferlen > NETVSC_PACKET_SIZE) { - free(buffer, M_NETVSC); - buffer = NULL; - } - - /* alloc new buffer */ - buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); - if (buffer == NULL) { - if_printf(rxr->hn_ifp, - "hv_cb malloc buffer failed, len=%u\n", - bytes_rxed); - bufferlen = 0; - break; - } - bufferlen = bytes_rxed; - } else { - /* No more packets */ - break; - } - } while (1); - - if (bufferlen > NETVSC_PACKET_SIZE) - free(buffer, M_NETVSC); - - hv_rf_channel_rollup(rxr, rxr->hn_txr); -} Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:01:38 2016 (r307200) @@ -68,13 +68,6 @@ MALLOC_DECLARE(M_NETVSC); -#define NVSP_INVALID_PROTOCOL_VERSION (0xFFFFFFFF) - -#define NVSP_PROTOCOL_VERSION_1 2 -#define NVSP_PROTOCOL_VERSION_2 0x30002 -#define NVSP_PROTOCOL_VERSION_4 0x40000 -#define NVSP_PROTOCOL_VERSION_5 0x50000 - /* * The following arguably belongs in a separate header file */ @@ -269,12 +262,10 @@ extern int hv_promisc_mode; struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); -int hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr); +int hv_nv_on_device_add(struct hn_softc *sc, int mtu); int hv_nv_on_device_remove(struct hn_softc *sc); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); -void hv_nv_subchan_attach(struct vmbus_channel *chan, - struct hn_rx_ring *rxr); #endif /* __HV_NET_VSC_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:01:38 2016 (r307200) @@ -348,9 +348,18 @@ static int hn_encap(struct hn_tx_ring *, static int hn_create_rx_data(struct hn_softc *sc, int); static void hn_destroy_rx_data(struct hn_softc *sc); static void hn_set_chim_size(struct hn_softc *, int); -static void hn_channel_attach(struct hn_softc *, struct vmbus_channel *); -static void hn_subchan_attach(struct hn_softc *, struct vmbus_channel *); -static void hn_subchan_setup(struct hn_softc *); +static int hn_chan_attach(struct hn_softc *, struct vmbus_channel *); +static int hn_attach_subchans(struct hn_softc *); +static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr); + +static void hn_nvs_handle_notify(struct hn_softc *sc, + const struct vmbus_chanpkt_hdr *pkt); +static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, + const struct vmbus_chanpkt_hdr *pkt); +static void hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, + struct vmbus_channel *chan, + const struct vmbus_chanpkt_hdr *pkthdr); +static void hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid); static int hn_transmit(struct ifnet *, struct mbuf *); static void hn_xmit_qflush(struct ifnet *); @@ -528,12 +537,13 @@ netvsc_attach(device_t dev) /* * Associate the first TX/RX ring w/ the primary channel. */ - hn_channel_attach(sc, sc->hn_prichan); + error = hn_chan_attach(sc, sc->hn_prichan); + if (error) + goto failed; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; ifp->if_init = hn_ifinit; - /* needed by hv_rf_on_device_add() code */ ifp->if_mtu = ETHERMTU; if (hn_use_if_start) { int qdepth = hn_get_txswq_depth(&sc->hn_tx_ring[0]); @@ -570,8 +580,7 @@ netvsc_attach(device_t dev) if (sc->hn_xact == NULL) goto failed; - error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, - &sc->hn_rx_ring[0]); + error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, ETHERMTU); if (error) goto failed; KASSERT(ring_cnt > 0 && ring_cnt <= sc->hn_rx_ring_inuse, @@ -588,8 +597,11 @@ netvsc_attach(device_t dev) device_printf(dev, "%d TX ring, %d RX ring\n", sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); - if (sc->hn_rx_ring_inuse > 1) - hn_subchan_setup(sc); + if (sc->hn_rx_ring_inuse > 1) { + error = hn_attach_subchans(sc); + if (error) + goto failed; + } #if __FreeBSD_version >= 1100099 if (sc->hn_rx_ring_inuse > 1) { @@ -1582,9 +1594,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, /* Wait for subchannels to be destroyed */ vmbus_subchan_drain(sc->hn_prichan); + sc->hn_rx_ring[0].hn_rx_flags &= ~HN_RX_FLAG_ATTACHED; + sc->hn_tx_ring[0].hn_tx_flags &= ~HN_TX_FLAG_ATTACHED; + hn_chan_attach(sc, sc->hn_prichan); /* XXX check error */ + ring_cnt = sc->hn_rx_ring_inuse; error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, - &sc->hn_rx_ring[0]); + ifr->ifr_mtu); if (error) { NV_LOCK(sc); sc->temp_unusable = FALSE; @@ -1610,7 +1626,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, sc->hn_tx_ring[r].hn_tx_flags &= ~HN_TX_FLAG_ATTACHED; } - hn_subchan_setup(sc); + hn_attach_subchans(sc); /* XXX check error */ } if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) @@ -3003,14 +3019,18 @@ hn_xmit_txeof_taskfunc(void *xtxr, int p mtx_unlock(&txr->hn_tx_lock); } -static void -hn_channel_attach(struct hn_softc *sc, struct vmbus_channel *chan) +static int +hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan) { struct hn_rx_ring *rxr; - int idx; + struct hn_tx_ring *txr = NULL; + int idx, error; idx = vmbus_chan_subidx(chan); + /* + * Link this channel to RX/TX ring. + */ KASSERT(idx >= 0 && idx < sc->hn_rx_ring_inuse, ("invalid channel index %d, should > 0 && < %d", idx, sc->hn_rx_ring_inuse)); @@ -3020,60 +3040,260 @@ hn_channel_attach(struct hn_softc *sc, s rxr->hn_rx_flags |= HN_RX_FLAG_ATTACHED; if (bootverbose) { - if_printf(sc->hn_ifp, "link RX ring %d to channel%u\n", + if_printf(sc->hn_ifp, "link RX ring %d to chan%u\n", idx, vmbus_chan_id(chan)); } if (idx < sc->hn_tx_ring_inuse) { - struct hn_tx_ring *txr = &sc->hn_tx_ring[idx]; - + txr = &sc->hn_tx_ring[idx]; KASSERT((txr->hn_tx_flags & HN_TX_FLAG_ATTACHED) == 0, ("TX ring %d already attached", idx)); txr->hn_tx_flags |= HN_TX_FLAG_ATTACHED; txr->hn_chan = chan; if (bootverbose) { - if_printf(sc->hn_ifp, "link TX ring %d to channel%u\n", + if_printf(sc->hn_ifp, "link TX ring %d to chan%u\n", idx, vmbus_chan_id(chan)); } } - /* Bind channel to a proper CPU */ + /* Bind this channel to a proper CPU. */ vmbus_chan_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus); -} - -static void -hn_subchan_attach(struct hn_softc *sc, struct vmbus_channel *chan) -{ - KASSERT(!vmbus_chan_is_primary(chan), - ("subchannel callback on primary channel")); - hn_channel_attach(sc, chan); + /* Open this channel */ + error = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, + NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hn_chan_callback, rxr); + if (error) { + if_printf(sc->hn_ifp, "open chan%u failed: %d\n", + vmbus_chan_id(chan), error); + rxr->hn_rx_flags &= ~HN_RX_FLAG_ATTACHED; + if (txr != NULL) + txr->hn_tx_flags &= ~HN_TX_FLAG_ATTACHED; + } + return (error); } -static void -hn_subchan_setup(struct hn_softc *sc) +static int +hn_attach_subchans(struct hn_softc *sc) { struct vmbus_channel **subchans; int subchan_cnt = sc->hn_rx_ring_inuse - 1; - int i; + int i, error = 0; /* Wait for sub-channels setup to complete. */ subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); /* Attach the sub-channels. */ for (i = 0; i < subchan_cnt; ++i) { - struct vmbus_channel *subchan = subchans[i]; - - /* NOTE: Calling order is critical. */ - hn_subchan_attach(sc, subchan); - hv_nv_subchan_attach(subchan, - &sc->hn_rx_ring[vmbus_chan_subidx(subchan)]); + error = hn_chan_attach(sc, subchans[i]); + if (error) + break; } /* Release the sub-channels */ vmbus_subchan_rel(subchans, subchan_cnt); - if_printf(sc->hn_ifp, "%d sub-channels setup done\n", subchan_cnt); + + if (error) { + if_printf(sc->hn_ifp, "sub-channels attach failed: %d\n", error); + } else { + if (bootverbose) { + if_printf(sc->hn_ifp, "%d sub-channels attached\n", + subchan_cnt); + } + } + return (error); +} + +static void +hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) +{ + const struct hn_nvs_hdr *hdr; + + if (VMBUS_CHANPKT_DATALEN(pkt) < sizeof(*hdr)) { + if_printf(sc->hn_ifp, "invalid nvs notify\n"); + return; + } + hdr = VMBUS_CHANPKT_CONST_DATA(pkt); + + if (hdr->nvs_type == HN_NVS_TYPE_TXTBL_NOTE) { + /* Useless; ignore */ + return; + } + if_printf(sc->hn_ifp, "got notify, nvs type %u\n", hdr->nvs_type); +} + +static void +hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, + const struct vmbus_chanpkt_hdr *pkt) +{ + struct hn_send_ctx *sndc; + + sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; + sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt), + VMBUS_CHANPKT_DATALEN(pkt)); + /* + * NOTE: + * 'sndc' CAN NOT be accessed anymore, since it can be freed by + * its callback. + */ +} + +static void +hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, + struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) +{ + const struct vmbus_chanpkt_rxbuf *pkt; + const struct hn_nvs_hdr *nvs_hdr; + int count, i, hlen; + + if (__predict_false(VMBUS_CHANPKT_DATALEN(pkthdr) < sizeof(*nvs_hdr))) { + if_printf(rxr->hn_ifp, "invalid nvs RNDIS\n"); + return; + } + nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr); + + /* Make sure that this is a RNDIS message. */ + if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) { + if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n", + nvs_hdr->nvs_type); + return; + } + + hlen = VMBUS_CHANPKT_GETLEN(pkthdr->cph_hlen); + if (__predict_false(hlen < sizeof(*pkt))) { + if_printf(rxr->hn_ifp, "invalid rxbuf chanpkt\n"); + return; + } + pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; + + if (__predict_false(pkt->cp_rxbuf_id != HN_NVS_RXBUF_SIG)) { + if_printf(rxr->hn_ifp, "invalid rxbuf_id 0x%08x\n", + pkt->cp_rxbuf_id); + return; + } + + count = pkt->cp_rxbuf_cnt; + if (__predict_false(hlen < + __offsetof(struct vmbus_chanpkt_rxbuf, cp_rxbuf[count]))) { + if_printf(rxr->hn_ifp, "invalid rxbuf_cnt %d\n", count); + return; + } + + /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ + for (i = 0; i < count; ++i) { + int ofs, len; + + ofs = pkt->cp_rxbuf[i].rb_ofs; + len = pkt->cp_rxbuf[i].rb_len; + if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) { + if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, " + "ofs %d, len %d\n", i, ofs, len); + continue; + } + hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len); + } + + /* + * Moved completion call back here so that all received + * messages (not just data messages) will trigger a response + * message back to the host. + */ + hn_nvs_ack_rxbuf(chan, pkt->cp_hdr.cph_xactid); +} + +/* + * Net VSC on receive completion + * + * Send a receive completion packet to RNDIS device (ie NetVsp) + */ +static void +hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid) +{ + struct hn_nvs_rndis_ack ack; + int retries = 0; + int ret = 0; + + ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK; + ack.nvs_status = HN_NVS_STATUS_OK; + +retry_send_cmplt: + /* Send the completion */ + ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, + VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid); + if (ret == 0) { + /* success */ + /* no-op */ + } else if (ret == EAGAIN) { + /* no more room... wait a bit and attempt to retry 3 times */ + retries++; + + if (retries < 4) { + DELAY(100); + goto retry_send_cmplt; + } + } +} + +static void +hn_chan_callback(struct vmbus_channel *chan, void *xrxr) +{ + struct hn_rx_ring *rxr = xrxr; + struct hn_softc *sc = rxr->hn_ifp->if_softc; + void *buffer; + int bufferlen = NETVSC_PACKET_SIZE; + + buffer = rxr->hn_rdbuf; + do { + struct vmbus_chanpkt_hdr *pkt = buffer; + uint32_t bytes_rxed; + int ret; + + bytes_rxed = bufferlen; + ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); + if (ret == 0) { + switch (pkt->cph_type) { + case VMBUS_CHANPKT_TYPE_COMP: + hn_nvs_handle_comp(sc, chan, pkt); + break; + case VMBUS_CHANPKT_TYPE_RXBUF: + hn_nvs_handle_rxbuf(sc, rxr, chan, pkt); + break; + case VMBUS_CHANPKT_TYPE_INBAND: + hn_nvs_handle_notify(sc, pkt); + break; + default: + if_printf(rxr->hn_ifp, + "unknown chan pkt %u\n", + pkt->cph_type); + break; + } + } else if (ret == ENOBUFS) { + /* Handle large packet */ + if (bufferlen > NETVSC_PACKET_SIZE) { + free(buffer, M_NETVSC); + buffer = NULL; + } + + /* alloc new buffer */ + buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); + if (buffer == NULL) { + if_printf(rxr->hn_ifp, + "hv_cb malloc buffer failed, len=%u\n", + bytes_rxed); + bufferlen = 0; + break; + } + bufferlen = bytes_rxed; + } else { + /* No more packets */ + break; + } + } while (1); + + if (bufferlen > NETVSC_PACKET_SIZE) + free(buffer, M_NETVSC); + + hv_rf_channel_rollup(rxr, rxr->hn_txr); } static void Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 08:01:38 2016 (r307200) @@ -1013,7 +1013,7 @@ hv_rf_halt_device(struct hn_softc *sc) */ int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, - int *nchan0, struct hn_rx_ring *rxr) + int *nchan0, int mtu) { int ret; netvsc_device_info *dev_info = (netvsc_device_info *)additl_info; @@ -1032,7 +1032,7 @@ hv_rf_on_device_add(struct hn_softc *sc, * (hv_rf_on_receive()) before this call is completed. * Note: Earlier code used a function pointer here. */ - ret = hv_nv_on_device_add(sc, rxr); + ret = hv_nv_on_device_add(sc, mtu); if (ret != 0) return (ret); Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Thu Oct 13 08:01:38 2016 (r307200) @@ -44,7 +44,7 @@ void hv_rf_on_receive(struct hn_softc *s const void *data, int dlen); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan, - struct hn_rx_ring *rxr); + int mtu); int hv_rf_on_device_remove(struct hn_softc *sc); int hv_rf_on_open(struct hn_softc *sc); int hv_rf_on_close(struct hn_softc *sc); Modified: stable/10/sys/dev/hyperv/netvsc/if_hnreg.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 07:52:39 2016 (r307199) +++ stable/10/sys/dev/hyperv/netvsc/if_hnreg.h Thu Oct 13 08:01:38 2016 (r307200) @@ -40,6 +40,14 @@ #define HN_NDIS_VERSION_MAJOR(ver) (((ver) & 0xffff0000) >> 16) #define HN_NDIS_VERSION_MINOR(ver) ((ver) & 0xffff) +/* + * NVS versions. + */ +#define HN_NVS_VERSION_1 0x00002 +#define HN_NVS_VERSION_2 0x30002 +#define HN_NVS_VERSION_4 0x40000 +#define HN_NVS_VERSION_5 0x50000 + #define HN_NVS_RXBUF_SIG 0xcafe #define HN_NVS_CHIM_SIG 0xface From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:03:49 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 84045C0F27E; Thu, 13 Oct 2016 08:03:49 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 379F984F; Thu, 13 Oct 2016 08:03:49 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D83mLp030787; Thu, 13 Oct 2016 08:03:48 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D83mTI030786; Thu, 13 Oct 2016 08:03:48 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130803.u9D83mTI030786@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:03:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307201 - stable/10/sys/dev/hyperv/utilities X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:03:49 -0000 Author: sephe Date: Thu Oct 13 08:03:48 2016 New Revision: 307201 URL: https://svnweb.freebsd.org/changeset/base/307201 Log: MFC 305585 hyperv/kvp: Fix IPv4/IPv6 address injection support. The GUID string provided by hypervisor has leading and trailing braces, while our GUID string does not have braces at all. Both braces should be ignored, when the GUID strings are compared. Submitted by: Hongjiang Zhang Modified by: sephe Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7809 Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c ============================================================================== --- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 08:01:38 2016 (r307200) +++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Thu Oct 13 08:03:48 2016 (r307201) @@ -332,20 +332,23 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(stru if (devclass_get_devices(devclass_find("hn"), &devs, &devcnt) == 0) { for (devcnt = devcnt - 1; devcnt >= 0; devcnt--) { - /* XXX access other driver's softc? are you kidding? */ device_t dev = devs[devcnt]; struct vmbus_channel *chan; char buf[HYPERV_GUID_STRLEN]; + int n; - /* - * Trying to find GUID of Network Device - */ chan = vmbus_get_channel(dev); - hyperv_guid2str(vmbus_chan_guid_inst(chan), - buf, sizeof(buf)); + n = hyperv_guid2str(vmbus_chan_guid_inst(chan), buf, + sizeof(buf)); - if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id, - HYPERV_GUID_STRLEN - 1) == 0) { + /* + * The string in the 'kvp_ip_val.adapter_id' has + * braces around the GUID; skip the leading brace + * in 'kvp_ip_val.adapter_id'. + */ + if (strncmp(buf, + ((char *)&umsg->body.kvp_ip_val.adapter_id) + 1, + n) == 0) { strlcpy((char *)umsg->body.kvp_ip_val.adapter_id, device_get_nameunit(dev), MAX_ADAPTER_ID_SIZE); break; From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:06:50 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 90F6BC0F393; Thu, 13 Oct 2016 08:06:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6B8449E6; Thu, 13 Oct 2016 08:06:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D86nQ8031074; Thu, 13 Oct 2016 08:06:49 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D86njZ031073; Thu, 13 Oct 2016 08:06:49 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130806.u9D86njZ031073@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:06:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307202 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:06:50 -0000 Author: sephe Date: Thu Oct 13 08:06:49 2016 New Revision: 307202 URL: https://svnweb.freebsd.org/changeset/base/307202 Log: MFC 305586,305587 305586 hyperv/hn: Function renaming. While I'm here, remove obvious comment. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7810 305587 hyperv/hn: Factor out NVS NDIS initialization Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7811 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 08:03:48 2016 (r307201) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 08:06:49 2016 (r307202) @@ -469,12 +469,10 @@ hn_nvs_doinit(struct hn_softc *sc, uint3 } /* - * Send NDIS version 2 config packet containing MTU. - * - * Not valid for NDIS version 1. + * Configure MTU and enable VLAN. */ static int -hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu) +hn_nvs_conf_ndis(struct hn_softc *sc, int mtu) { struct hn_nvs_ndis_conf conf; int error; @@ -492,6 +490,24 @@ hv_nv_send_ndis_config(struct hn_softc * } static int +hn_nvs_init_ndis(struct hn_softc *sc) +{ + struct hn_nvs_ndis_init ndis; + int error; + + memset(&ndis, 0, sizeof(ndis)); + ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; + ndis.nvs_ndis_major = HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver); + ndis.nvs_ndis_minor = HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver); + + /* NOTE: No response. */ + error = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); + if (error) + if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", error); + return (error); +} + +static int hn_nvs_init(struct hn_softc *sc) { int i; @@ -521,47 +537,37 @@ hn_nvs_init(struct hn_softc *sc) return (ENXIO); } -/* - * Net VSC connect to VSP - */ static int hv_nv_connect_to_vsp(struct hn_softc *sc, int mtu) { - int ret = 0; - struct hn_nvs_ndis_init ndis; + int ret; + /* + * Initialize NVS. + */ ret = hn_nvs_init(sc); if (ret != 0) return (ret); - /* - * Set the MTU if supported by this NVSP protocol version - * This needs to be right after the NVSP init message per Haiyang - */ - if (sc->hn_nvs_ver >= HN_NVS_VERSION_2) - ret = hv_nv_send_ndis_config(sc, mtu); + if (sc->hn_nvs_ver >= HN_NVS_VERSION_2) { + /* + * Configure NDIS before initializing it. + */ + ret = hn_nvs_conf_ndis(sc, mtu); + if (ret != 0) + return (ret); + } /* * Initialize NDIS. */ - - memset(&ndis, 0, sizeof(ndis)); - ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; - ndis.nvs_ndis_major = HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver); - ndis.nvs_ndis_minor = HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver); - - /* NOTE: No response. */ - ret = hn_nvs_req_send(sc, &ndis, sizeof(ndis)); - if (ret != 0) { - if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret); - goto cleanup; - } + ret = hn_nvs_init_ndis(sc); + if (ret != 0) + return (ret); ret = hv_nv_init_rx_buffer_with_net_vsp(sc); if (ret == 0) ret = hv_nv_init_send_buffer_with_net_vsp(sc); - -cleanup: return (ret); } From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:09:42 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 04C5FC0F51B; Thu, 13 Oct 2016 08:09:42 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D5EECD9C; Thu, 13 Oct 2016 08:09:41 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D89f4g031338; Thu, 13 Oct 2016 08:09:41 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D89eO8031336; Thu, 13 Oct 2016 08:09:40 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130809.u9D89eO8031336@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:09:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307203 - in stable/10: lib/libstand sys/boot/i386/pxeldr X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:09:42 -0000 Author: sephe Date: Thu Oct 13 08:09:40 2016 New Revision: 307203 URL: https://svnweb.freebsd.org/changeset/base/307203 Log: MFC 305588 pxeboot: Add nfs.read_size tunable. Increase this tunable improves kernel loading speed. Submitted by: Jun Su Reviewed by: rpokala, wblock (previous version) Obtained from: DragonFlyBSD Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7756 Modified: stable/10/lib/libstand/nfs.c stable/10/sys/boot/i386/pxeldr/pxeboot.8 Directory Properties: stable/10/ (props changed) Modified: stable/10/lib/libstand/nfs.c ============================================================================== --- stable/10/lib/libstand/nfs.c Thu Oct 13 08:06:49 2016 (r307202) +++ stable/10/lib/libstand/nfs.c Thu Oct 13 08:09:40 2016 (r307203) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -50,7 +51,8 @@ __FBSDID("$FreeBSD$"); #define NFS_DEBUGxx -#define NFSREAD_SIZE 1024 +#define NFSREAD_MIN_SIZE 1024 +#define NFSREAD_MAX_SIZE 4096 /* Define our own NFS attributes without NQNFS stuff. */ #ifdef OLD_NFSV2 @@ -83,7 +85,7 @@ struct nfs_read_repl { n_long errno; struct nfsv2_fattrs fa; n_long count; - u_char data[NFSREAD_SIZE]; + u_char data[NFSREAD_MAX_SIZE]; }; #ifndef NFS_NOSYMLINK @@ -210,6 +212,8 @@ struct fs_ops nfs_fsops = { nfs_readdir }; +static int nfs_read_size = NFSREAD_MIN_SIZE; + #ifdef OLD_NFSV2 /* * Fetch the root file handle (call mount daemon) @@ -264,6 +268,17 @@ nfs_getrootfh(struct iodesc *d, char *pa if (repl->errno) return (ntohl(repl->errno)); bcopy(repl->fh, fhp, sizeof(repl->fh)); + + /* + * Improve boot performance over NFS + */ + if (getenv("nfs.read_size") != NULL) + nfs_read_size = strtol(getenv("nfs.read_size"), NULL, 0); + if (nfs_read_size < NFSREAD_MIN_SIZE) + nfs_read_size = NFSREAD_MIN_SIZE; + if (nfs_read_size > NFSREAD_MAX_SIZE) + nfs_read_size = NFSREAD_MAX_SIZE; + return (0); } @@ -401,11 +416,11 @@ nfs_readdata(struct nfs_iodesc *d, off_t bcopy(d->fh, args->fh, NFS_FHSIZE); args->off = htonl((n_long)off); - if (len > NFSREAD_SIZE) - len = NFSREAD_SIZE; + if (len > nfs_read_size) + len = nfs_read_size; args->len = htonl((n_long)len); args->xxx = htonl((n_long)0); - hlen = sizeof(*repl) - NFSREAD_SIZE; + hlen = offsetof(struct nfs_read_rpl, data[0]); cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ, args, sizeof(*args), @@ -1022,7 +1037,7 @@ nfs_readdata(struct nfs_iodesc *d, off_t uint32_t count; uint32_t eof; uint32_t len; - u_char data[NFSREAD_SIZE]; + u_char data[NFSREAD_MAX_SIZE]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; @@ -1045,10 +1060,10 @@ nfs_readdata(struct nfs_iodesc *d, off_t pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t); args->fhoffcnt[pos++] = 0; args->fhoffcnt[pos++] = htonl((uint32_t)off); - if (len > NFSREAD_SIZE) - len = NFSREAD_SIZE; + if (len > nfs_read_size) + len = nfs_read_size; args->fhoffcnt[pos] = htonl((uint32_t)len); - hlen = sizeof(*repl) - NFSREAD_SIZE; + hlen = offsetof(struct repl, data[0]); cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ, args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)), Modified: stable/10/sys/boot/i386/pxeldr/pxeboot.8 ============================================================================== --- stable/10/sys/boot/i386/pxeldr/pxeboot.8 Thu Oct 13 08:06:49 2016 (r307202) +++ stable/10/sys/boot/i386/pxeldr/pxeboot.8 Thu Oct 13 08:09:40 2016 (r307203) @@ -85,6 +85,14 @@ expects to fetch .Pa /boot/loader.rc from the specified server before loading any other files. .Pp +.Nm +defaults to a conservative 1024 byte NFS data packet size. +This may be changed by setting the +.Va nfs.read_size +variable in +.Pa /boot/loader.conf . +Valid values range from 1024 to 4096 bytes. +.Pp In all other respects, .Nm acts just like From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:47:52 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D4F85C10165; Thu, 13 Oct 2016 08:47:52 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9D2FC83F; Thu, 13 Oct 2016 08:47:52 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D8lpTa046535; Thu, 13 Oct 2016 08:47:51 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D8lprY046530; Thu, 13 Oct 2016 08:47:51 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130847.u9D8lprY046530@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:47:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307206 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:47:52 -0000 Author: sephe Date: Thu Oct 13 08:47:51 2016 New Revision: 307206 URL: https://svnweb.freebsd.org/changeset/base/307206 Log: MFC 305724,305725,305727-305730,305760,305761,305763,305788 305724 hyperv/hn: Rename RXBUF connect/disconnect functions. Minor cleanup and wording in error messages. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7823 305725 hyperv/hn: Rename chimney sending buffer connect/disconnect functions. Minor cleanup and wording in error messages. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7825 305727 hyperv/hn: Function rename. - Minor style changes. - Nuke unnecessary indirection. - Nuke unapplied comment. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7827 305728 hyperv/hn: Reorganize sub-channel allocation. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7829 305729 hyperv/hn: Reorganize RNDIS attach Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7830 305730 hyperv/hn: Pull ether address and link status extraction up. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7831 305760 hyperv/hn: Reorganize channel attach/detach code. This paves the way for further attach/detach code reorganization. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7858 305761 hyperv/hn: Regroup synthetic parts attach code. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7859 305763 hyperv/hn: Reorganize synthetic parts attach code. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7860 305788 hyperv/hn: Pull RSS key and indirect table setup up. This paves the way for the dynamic RSS key and indirect table setting. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7864 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 08:35:08 2016 (r307205) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Thu Oct 13 08:47:51 2016 (r307206) @@ -56,11 +56,10 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper /* * Forward declarations */ -static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); -static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); -static int hv_nv_destroy_send_buffer(struct hn_softc *sc); -static int hv_nv_destroy_rx_buffer(struct hn_softc *sc); -static int hv_nv_connect_to_vsp(struct hn_softc *sc, int mtu); +static int hn_nvs_conn_chim(struct hn_softc *sc); +static int hn_nvs_conn_rxbuf(struct hn_softc *); +static int hn_nvs_disconn_chim(struct hn_softc *sc); +static int hn_nvs_disconn_rxbuf(struct hn_softc *sc); static void hn_nvs_sent_none(struct hn_send_ctx *sndc, struct hn_softc *, struct vmbus_channel *chan, const void *, int); @@ -102,7 +101,7 @@ hn_chim_alloc(struct hn_softc *sc) return (ret); } -const void * +static const void * hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, size_t *resplen0, uint32_t type) { @@ -153,14 +152,8 @@ hn_nvs_req_send(struct hn_softc *sc, voi req, reqlen, &hn_send_ctx_none)); } -/* - * Net VSC initialize receive buffer with net VSP - * - * Net VSP: Network virtual services client, also known as the - * Hyper-V extensible switch and the synthetic data path. - */ static int -hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) +hn_nvs_conn_rxbuf(struct hn_softc *sc) { struct vmbus_xact *xact = NULL; struct hn_nvs_rxbuf_conn *conn; @@ -187,7 +180,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct error = vmbus_chan_gpadl_connect(sc->hn_prichan, sc->hn_rxbuf_dma.hv_paddr, rxbuf_size, &sc->hn_rxbuf_gpadl); if (error) { - if_printf(sc->hn_ifp, "rxbuf gpadl connect failed: %d\n", + if_printf(sc->hn_ifp, "rxbuf gpadl conn failed: %d\n", error); goto cleanup; } @@ -211,7 +204,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len, HN_NVS_TYPE_RXBUF_CONNRESP); if (resp == NULL) { - if_printf(sc->hn_ifp, "exec rxbuf conn failed\n"); + if_printf(sc->hn_ifp, "exec nvs rxbuf conn failed\n"); error = EIO; goto cleanup; } @@ -221,7 +214,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct xact = NULL; if (status != HN_NVS_STATUS_OK) { - if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status); + if_printf(sc->hn_ifp, "nvs rxbuf conn failed: %x\n", status); error = EIO; goto cleanup; } @@ -232,15 +225,12 @@ hv_nv_init_rx_buffer_with_net_vsp(struct cleanup: if (xact != NULL) vmbus_xact_put(xact); - hv_nv_destroy_rx_buffer(sc); + hn_nvs_disconn_rxbuf(sc); return (error); } -/* - * Net VSC initialize send buffer with net VSP - */ static int -hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) +hn_nvs_conn_chim(struct hn_softc *sc) { struct vmbus_xact *xact = NULL; struct hn_nvs_chim_conn *chim; @@ -260,8 +250,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru sc->hn_chim_dma.hv_paddr, NETVSC_SEND_BUFFER_SIZE, &sc->hn_chim_gpadl); if (error) { - if_printf(sc->hn_ifp, "chimney sending buffer gpadl " - "connect failed: %d\n", error); + if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error); goto cleanup; } @@ -284,7 +273,7 @@ hv_nv_init_send_buffer_with_net_vsp(stru resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len, HN_NVS_TYPE_CHIM_CONNRESP); if (resp == NULL) { - if_printf(sc->hn_ifp, "exec chim conn failed\n"); + if_printf(sc->hn_ifp, "exec nvs chim conn failed\n"); error = EIO; goto cleanup; } @@ -295,14 +284,14 @@ hv_nv_init_send_buffer_with_net_vsp(stru xact = NULL; if (status != HN_NVS_STATUS_OK) { - if_printf(sc->hn_ifp, "chim conn failed: %x\n", status); + if_printf(sc->hn_ifp, "nvs chim conn failed: %x\n", status); error = EIO; goto cleanup; } if (sectsz == 0) { if_printf(sc->hn_ifp, "zero chimney sending buffer " "section size\n"); - return 0; + return (0); } sc->hn_chim_szmax = sectsz; @@ -326,22 +315,19 @@ hv_nv_init_send_buffer_with_net_vsp(stru if_printf(sc->hn_ifp, "chimney sending buffer %d/%d\n", sc->hn_chim_szmax, sc->hn_chim_cnt); } - return 0; + return (0); cleanup: if (xact != NULL) vmbus_xact_put(xact); - hv_nv_destroy_send_buffer(sc); + hn_nvs_disconn_chim(sc); return (error); } -/* - * Net VSC destroy receive buffer - */ static int -hv_nv_destroy_rx_buffer(struct hn_softc *sc) +hn_nvs_disconn_rxbuf(struct hn_softc *sc) { - int ret = 0; + int error; if (sc->hn_flags & HN_FLAG_RXBUF_CONNECTED) { struct hn_nvs_rxbuf_disconn disconn; @@ -354,38 +340,35 @@ hv_nv_destroy_rx_buffer(struct hn_softc disconn.nvs_sig = HN_NVS_RXBUF_SIG; /* NOTE: No response. */ - ret = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); - if (ret != 0) { + error = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); + if (error) { if_printf(sc->hn_ifp, - "send rxbuf disconn failed: %d\n", ret); - return (ret); + "send nvs rxbuf disconn failed: %d\n", error); + return (error); } sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED; } - + if (sc->hn_rxbuf_gpadl != 0) { /* * Disconnect RXBUF from primary channel. */ - ret = vmbus_chan_gpadl_disconnect(sc->hn_prichan, + error = vmbus_chan_gpadl_disconnect(sc->hn_prichan, sc->hn_rxbuf_gpadl); - if (ret != 0) { + if (error) { if_printf(sc->hn_ifp, - "rxbuf disconn failed: %d\n", ret); - return (ret); + "rxbuf gpadl disconn failed: %d\n", error); + return (error); } sc->hn_rxbuf_gpadl = 0; } - return (ret); + return (0); } -/* - * Net VSC destroy send buffer - */ static int -hv_nv_destroy_send_buffer(struct hn_softc *sc) +hn_nvs_disconn_chim(struct hn_softc *sc) { - int ret = 0; + int error; if (sc->hn_flags & HN_FLAG_CHIM_CONNECTED) { struct hn_nvs_chim_disconn disconn; @@ -398,25 +381,25 @@ hv_nv_destroy_send_buffer(struct hn_soft disconn.nvs_sig = HN_NVS_CHIM_SIG; /* NOTE: No response. */ - ret = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); - if (ret != 0) { + error = hn_nvs_req_send(sc, &disconn, sizeof(disconn)); + if (error) { if_printf(sc->hn_ifp, - "send chim disconn failed: %d\n", ret); - return (ret); + "send nvs chim disconn failed: %d\n", error); + return (error); } sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED; } - + if (sc->hn_chim_gpadl != 0) { /* * Disconnect chimney sending buffer from primary channel. */ - ret = vmbus_chan_gpadl_disconnect(sc->hn_prichan, + error = vmbus_chan_gpadl_disconnect(sc->hn_prichan, sc->hn_chim_gpadl); - if (ret != 0) { + if (error) { if_printf(sc->hn_ifp, - "chim disconn failed: %d\n", ret); - return (ret); + "chim gpadl disconn failed: %d\n", error); + return (error); } sc->hn_chim_gpadl = 0; } @@ -425,8 +408,7 @@ hv_nv_destroy_send_buffer(struct hn_soft free(sc->hn_chim_bmap, M_NETVSC); sc->hn_chim_bmap = NULL; } - - return (ret); + return (0); } static int @@ -537,38 +519,48 @@ hn_nvs_init(struct hn_softc *sc) return (ENXIO); } -static int -hv_nv_connect_to_vsp(struct hn_softc *sc, int mtu) +int +hn_nvs_attach(struct hn_softc *sc, int mtu) { - int ret; + int error; /* * Initialize NVS. */ - ret = hn_nvs_init(sc); - if (ret != 0) - return (ret); + error = hn_nvs_init(sc); + if (error) + return (error); if (sc->hn_nvs_ver >= HN_NVS_VERSION_2) { /* * Configure NDIS before initializing it. */ - ret = hn_nvs_conf_ndis(sc, mtu); - if (ret != 0) - return (ret); + error = hn_nvs_conf_ndis(sc, mtu); + if (error) + return (error); } /* * Initialize NDIS. */ - ret = hn_nvs_init_ndis(sc); - if (ret != 0) - return (ret); - - ret = hv_nv_init_rx_buffer_with_net_vsp(sc); - if (ret == 0) - ret = hv_nv_init_send_buffer_with_net_vsp(sc); - return (ret); + error = hn_nvs_init_ndis(sc); + if (error) + return (error); + + /* + * Connect RXBUF. + */ + error = hn_nvs_conn_rxbuf(sc); + if (error) + return (error); + + /* + * Connect chimney sending buffer. + */ + error = hn_nvs_conn_chim(sc); + if (error) + return (error); + return (0); } /* @@ -577,23 +569,8 @@ hv_nv_connect_to_vsp(struct hn_softc *sc static void hv_nv_disconnect_from_vsp(struct hn_softc *sc) { - hv_nv_destroy_rx_buffer(sc); - hv_nv_destroy_send_buffer(sc); -} - -/* - * Net VSC on device add - * - * Callback when the device belonging to this driver is added - */ -int -hv_nv_on_device_add(struct hn_softc *sc, int mtu) -{ - - /* - * Connect with the NetVsp - */ - return (hv_nv_connect_to_vsp(sc, mtu)); + hn_nvs_disconn_rxbuf(sc); + hn_nvs_disconn_chim(sc); } /* @@ -604,11 +581,6 @@ hv_nv_on_device_remove(struct hn_softc * { hv_nv_disconnect_from_vsp(sc); - - /* Now, we can close the channel safely */ - - vmbus_chan_close(sc->hn_prichan); - return (0); } @@ -675,3 +647,54 @@ hv_nv_on_send(struct vmbus_channel *chan return (ret); } + +int +hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0) +{ + struct vmbus_xact *xact; + struct hn_nvs_subch_req *req; + const struct hn_nvs_subch_resp *resp; + int error, nsubch_req; + uint32_t nsubch; + size_t resp_len; + + nsubch_req = *nsubch0; + KASSERT(nsubch_req > 0, ("invalid # of sub-channels %d", nsubch_req)); + + xact = vmbus_xact_get(sc->hn_xact, sizeof(*req)); + if (xact == NULL) { + if_printf(sc->hn_ifp, "no xact for nvs subch alloc\n"); + return (ENXIO); + } + req = vmbus_xact_req_data(xact); + req->nvs_type = HN_NVS_TYPE_SUBCH_REQ; + req->nvs_op = HN_NVS_SUBCH_OP_ALLOC; + req->nvs_nsubch = nsubch_req; + + resp_len = sizeof(*resp); + resp = hn_nvs_xact_execute(sc, xact, req, sizeof(*req), &resp_len, + HN_NVS_TYPE_SUBCH_RESP); + if (resp == NULL) { + if_printf(sc->hn_ifp, "exec nvs subch alloc failed\n"); + error = EIO; + goto done; + } + if (resp->nvs_status != HN_NVS_STATUS_OK) { + if_printf(sc->hn_ifp, "nvs subch alloc failed: %x\n", + resp->nvs_status); + error = EIO; + goto done; + } + + nsubch = resp->nvs_nsubch; + if (nsubch > nsubch_req) { + if_printf(sc->hn_ifp, "%u subchans are allocated, " + "requested %d\n", nsubch, nsubch_req); + nsubch = nsubch_req; + } + *nsubch0 = nsubch; + error = 0; +done: + vmbus_xact_put(xact); + return (error); +} Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:35:08 2016 (r307205) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:47:51 2016 (r307206) @@ -99,11 +99,6 @@ struct vmbus_channel; #define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) #define NETVSC_PACKET_MAXPAGE 32 -typedef struct { - uint8_t mac_addr[ETHER_ADDR_LEN]; - uint32_t link_state; -} netvsc_device_info; - #define HN_XACT_REQ_PGCNT 2 #define HN_XACT_RESP_PGCNT 2 #define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE) @@ -262,7 +257,7 @@ extern int hv_promisc_mode; struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); -int hv_nv_on_device_add(struct hn_softc *sc, int mtu); +int hn_nvs_attach(struct hn_softc *sc, int mtu); int hv_nv_on_device_remove(struct hn_softc *sc); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:35:08 2016 (r307205) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:47:51 2016 (r307206) @@ -349,8 +349,12 @@ static int hn_create_rx_data(struct hn_s static void hn_destroy_rx_data(struct hn_softc *sc); static void hn_set_chim_size(struct hn_softc *, int); static int hn_chan_attach(struct hn_softc *, struct vmbus_channel *); +static void hn_chan_detach(struct hn_softc *, struct vmbus_channel *); static int hn_attach_subchans(struct hn_softc *); +static void hn_detach_allchans(struct hn_softc *); static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr); +static void hn_set_ring_inuse(struct hn_softc *, int); +static int hn_synth_attach(struct hn_softc *, int); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); @@ -368,6 +372,14 @@ static void hn_xmit_txeof(struct hn_tx_r static void hn_xmit_taskfunc(void *, int); static void hn_xmit_txeof_taskfunc(void *, int); +static const uint8_t hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa +}; + #if __FreeBSD_version >= 1100099 static void hn_set_lro_lenlim(struct hn_softc *sc, int lenlim) @@ -457,7 +469,8 @@ netvsc_attach(device_t dev) { struct sysctl_oid_list *child; struct sysctl_ctx_list *ctx; - netvsc_device_info device_info; + uint8_t eaddr[ETHER_ADDR_LEN]; + uint32_t link_status; hn_softc_t *sc; int unit = device_get_unit(dev); struct ifnet *ifp = NULL; @@ -535,9 +548,17 @@ netvsc_attach(device_t dev) goto failed; /* - * Associate the first TX/RX ring w/ the primary channel. + * Create transaction context for NVS and RNDIS transactions. */ - error = hn_chan_attach(sc, sc->hn_prichan); + sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev), + HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0); + if (sc->hn_xact == NULL) + goto failed; + + /* + * Attach the synthetic parts, i.e. NVS and RNDIS. + */ + error = hn_synth_attach(sc, ETHERMTU); if (error) goto failed; @@ -575,34 +596,6 @@ netvsc_attach(device_t dev) IFCAP_LRO; ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; - sc->hn_xact = vmbus_xact_ctx_create(bus_get_dma_tag(dev), - HN_XACT_REQ_SIZE, HN_XACT_RESP_SIZE, 0); - if (sc->hn_xact == NULL) - goto failed; - - error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, ETHERMTU); - if (error) - goto failed; - KASSERT(ring_cnt > 0 && ring_cnt <= sc->hn_rx_ring_inuse, - ("invalid channel count %d, should be less than %d", - ring_cnt, sc->hn_rx_ring_inuse)); - - /* - * Set the # of TX/RX rings that could be used according to - * the # of channels that host offered. - */ - if (sc->hn_tx_ring_inuse > ring_cnt) - sc->hn_tx_ring_inuse = ring_cnt; - sc->hn_rx_ring_inuse = ring_cnt; - device_printf(dev, "%d TX ring, %d RX ring\n", - sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); - - if (sc->hn_rx_ring_inuse > 1) { - error = hn_attach_subchans(sc); - if (error) - goto failed; - } - #if __FreeBSD_version >= 1100099 if (sc->hn_rx_ring_inuse > 1) { /* @@ -613,9 +606,11 @@ netvsc_attach(device_t dev) } #endif - if (device_info.link_state == NDIS_MEDIA_STATE_CONNECTED) { + error = hn_rndis_get_linkstatus(sc, &link_status); + if (error) + goto failed; + if (link_status == NDIS_MEDIA_STATE_CONNECTED) sc->hn_carrier = 1; - } tso_maxlen = hn_tso_maxlen; if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET) @@ -626,7 +621,10 @@ netvsc_attach(device_t dev) ifp->if_hw_tsomax = tso_maxlen - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); - ether_ifattach(ifp, device_info.mac_addr); + error = hn_rndis_get_eaddr(sc, eaddr); + if (error) + goto failed; + ether_ifattach(ifp, eaddr); if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax, ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize); @@ -675,6 +673,7 @@ netvsc_detach(device_t dev) */ hv_rf_on_device_remove(sc); + hn_detach_allchans(sc); hn_stop_tx_tasks(sc); @@ -1519,8 +1518,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, #ifdef INET struct ifaddr *ifa = (struct ifaddr *)data; #endif - netvsc_device_info device_info; - int mask, error = 0, ring_cnt; + int mask, error = 0; int retry_cnt = 500; switch(cmd) { @@ -1591,43 +1589,16 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, break; } - /* Wait for subchannels to be destroyed */ - vmbus_subchan_drain(sc->hn_prichan); - - sc->hn_rx_ring[0].hn_rx_flags &= ~HN_RX_FLAG_ATTACHED; - sc->hn_tx_ring[0].hn_tx_flags &= ~HN_TX_FLAG_ATTACHED; - hn_chan_attach(sc, sc->hn_prichan); /* XXX check error */ - - ring_cnt = sc->hn_rx_ring_inuse; - error = hv_rf_on_device_add(sc, &device_info, &ring_cnt, - ifr->ifr_mtu); - if (error) { - NV_LOCK(sc); - sc->temp_unusable = FALSE; - NV_UNLOCK(sc); - break; - } - /* # of channels can _not_ be changed */ - KASSERT(sc->hn_rx_ring_inuse == ring_cnt, - ("RX ring count %d and channel count %u mismatch", - sc->hn_rx_ring_cnt, ring_cnt)); - if (sc->hn_rx_ring_inuse > 1) { - int r; + /* + * Detach all of the channels. + */ + hn_detach_allchans(sc); - /* - * Skip the rings on primary channel; they are - * handled by the hv_rf_on_device_add() above. - */ - for (r = 1; r < sc->hn_rx_ring_cnt; ++r) { - sc->hn_rx_ring[r].hn_rx_flags &= - ~HN_RX_FLAG_ATTACHED; - } - for (r = 1; r < sc->hn_tx_ring_cnt; ++r) { - sc->hn_tx_ring[r].hn_tx_flags &= - ~HN_TX_FLAG_ATTACHED; - } - hn_attach_subchans(sc); /* XXX check error */ - } + /* + * Attach the synthetic parts, i.e. NVS and RNDIS. + * XXX check error. + */ + hn_synth_attach(sc, ifr->ifr_mtu); if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) hn_set_chim_size(sc, sc->hn_chim_szmax); @@ -3073,6 +3044,42 @@ hn_chan_attach(struct hn_softc *sc, stru return (error); } +static void +hn_chan_detach(struct hn_softc *sc, struct vmbus_channel *chan) +{ + struct hn_rx_ring *rxr; + int idx; + + idx = vmbus_chan_subidx(chan); + + /* + * Link this channel to RX/TX ring. + */ + KASSERT(idx >= 0 && idx < sc->hn_rx_ring_inuse, + ("invalid channel index %d, should > 0 && < %d", + idx, sc->hn_rx_ring_inuse)); + rxr = &sc->hn_rx_ring[idx]; + KASSERT((rxr->hn_rx_flags & HN_RX_FLAG_ATTACHED), + ("RX ring %d is not attached", idx)); + rxr->hn_rx_flags &= ~HN_RX_FLAG_ATTACHED; + + if (idx < sc->hn_tx_ring_inuse) { + struct hn_tx_ring *txr = &sc->hn_tx_ring[idx]; + + KASSERT((txr->hn_tx_flags & HN_TX_FLAG_ATTACHED), + ("TX ring %d is not attached attached", idx)); + txr->hn_tx_flags &= ~HN_TX_FLAG_ATTACHED; + } + + /* + * Close this channel. + * + * NOTE: + * Channel closing does _not_ destroy the target channel. + */ + vmbus_chan_close(chan); +} + static int hn_attach_subchans(struct hn_softc *sc) { @@ -3080,17 +3087,16 @@ hn_attach_subchans(struct hn_softc *sc) int subchan_cnt = sc->hn_rx_ring_inuse - 1; int i, error = 0; - /* Wait for sub-channels setup to complete. */ - subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); + if (subchan_cnt == 0) + return (0); /* Attach the sub-channels. */ + subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); for (i = 0; i < subchan_cnt; ++i) { error = hn_chan_attach(sc, subchans[i]); if (error) break; } - - /* Release the sub-channels */ vmbus_subchan_rel(subchans, subchan_cnt); if (error) { @@ -3105,6 +3111,202 @@ hn_attach_subchans(struct hn_softc *sc) } static void +hn_detach_allchans(struct hn_softc *sc) +{ + struct vmbus_channel **subchans; + int subchan_cnt = sc->hn_rx_ring_inuse - 1; + int i; + + if (subchan_cnt == 0) + goto back; + + /* Detach the sub-channels. */ + subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt); + for (i = 0; i < subchan_cnt; ++i) + hn_chan_detach(sc, subchans[i]); + vmbus_subchan_rel(subchans, subchan_cnt); + +back: + /* + * Detach the primary channel, _after_ all sub-channels + * are detached. + */ + hn_chan_detach(sc, sc->hn_prichan); + + /* Wait for sub-channels to be destroyed, if any. */ + vmbus_subchan_drain(sc->hn_prichan); + +#ifdef INVARIANTS + for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { + KASSERT((sc->hn_rx_ring[i].hn_rx_flags & + HN_RX_FLAG_ATTACHED) == 0, + ("%dth RX ring is still attached", i)); + } + for (i = 0; i < sc->hn_tx_ring_cnt; ++i) { + KASSERT((sc->hn_tx_ring[i].hn_tx_flags & + HN_TX_FLAG_ATTACHED) == 0, + ("%dth TX ring is still attached", i)); + } +#endif +} + +static int +hn_synth_alloc_subchans(struct hn_softc *sc, int *nsubch) +{ + struct vmbus_channel **subchans; + int nchan, rxr_cnt, error; + + nchan = *nsubch + 1; + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) { + /* + * Either RSS is not supported, or multiple RX/TX rings + * are not requested. + */ + *nsubch = 0; + return (0); + } + + /* + * Get RSS capabilities, e.g. # of RX rings, and # of indirect + * table entries. + */ + error = hn_rndis_get_rsscaps(sc, &rxr_cnt); + if (error) { + /* No RSS; this is benign. */ + *nsubch = 0; + return (0); + } + if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n", + rxr_cnt, nchan); + + if (nchan > rxr_cnt) + nchan = rxr_cnt; + if (nchan == 1) { + if_printf(sc->hn_ifp, "only 1 channel is supported, no vRSS\n"); + *nsubch = 0; + return (0); + } + + /* + * Allocate sub-channels from NVS. + */ + *nsubch = nchan - 1; + error = hn_nvs_alloc_subchans(sc, nsubch); + if (error || *nsubch == 0) { + /* Failed to allocate sub-channels. */ + *nsubch = 0; + return (0); + } + + /* + * Wait for all sub-channels to become ready before moving on. + */ + subchans = vmbus_subchan_get(sc->hn_prichan, *nsubch); + vmbus_subchan_rel(subchans, *nsubch); + return (0); +} + +static int +hn_synth_attach(struct hn_softc *sc, int mtu) +{ + struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; + int error, nsubch, nchan, i; + + /* + * Attach the primary channel _before_ attaching NVS and RNDIS. + */ + error = hn_chan_attach(sc, sc->hn_prichan); + if (error) + return (error); + + /* + * Attach NVS. + */ + error = hn_nvs_attach(sc, mtu); + if (error) + return (error); + + /* + * Attach RNDIS _after_ NVS is attached. + */ + error = hn_rndis_attach(sc); + if (error) + return (error); + + /* + * Allocate sub-channels for multi-TX/RX rings. + * + * NOTE: + * The # of RX rings that can be used is equivalent to the # of + * channels to be requested. + */ + nsubch = sc->hn_rx_ring_cnt - 1; + error = hn_synth_alloc_subchans(sc, &nsubch); + if (error) + return (error); + + nchan = nsubch + 1; + if (nchan == 1) { + /* Only the primary channel can be used; done */ + goto back; + } + + /* + * Configure RSS key and indirect table _after_ all sub-channels + * are allocated. + */ + + /* Setup default RSS key. */ + memcpy(rss->rss_key, hn_rss_key_default, sizeof(rss->rss_key)); + + /* Setup default RSS indirect table. */ + /* TODO: Take ndis_rss_caps.ndis_nind into account. */ + for (i = 0; i < NDIS_HASH_INDCNT; ++i) + rss->rss_ind[i] = i % nchan; + + error = hn_rndis_conf_rss(sc); + if (error) { + /* + * Failed to configure RSS key or indirect table; only + * the primary channel can be used. + */ + nchan = 1; + } +back: + /* + * Set the # of TX/RX rings that could be used according to + * the # of channels that NVS offered. + */ + hn_set_ring_inuse(sc, nchan); + + /* + * Attach the sub-channels, if any. + */ + error = hn_attach_subchans(sc); + if (error) + return (error); + return (0); +} + +static void +hn_set_ring_inuse(struct hn_softc *sc, int ring_cnt) +{ + KASSERT(ring_cnt > 0 && ring_cnt <= sc->hn_rx_ring_cnt, + ("invalid ring count %d", ring_cnt)); + + if (sc->hn_tx_ring_cnt > ring_cnt) + sc->hn_tx_ring_inuse = ring_cnt; + else + sc->hn_tx_ring_inuse = sc->hn_tx_ring_cnt; + sc->hn_rx_ring_inuse = ring_cnt; + + if (bootverbose) { + if_printf(sc->hn_ifp, "%d TX ring, %d RX ring\n", + sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse); + } +} + +static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { const struct hn_nvs_hdr *hdr; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 08:35:08 2016 (r307205) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 08:47:51 2016 (r307206) @@ -76,18 +76,12 @@ static void hv_rf_receive_indicate_statu const void *data, int dlen); static void hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen); -static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr); -static int hv_rf_query_device_link_status(struct hn_softc *sc, - uint32_t *link_status); -static int hv_rf_init_device(struct hn_softc *sc); static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0); static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen); static int hn_rndis_conf_offload(struct hn_softc *sc); -static int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt); -static int hn_rndis_conf_rss(struct hn_softc *sc, int nchan); static __inline uint32_t hn_rndis_rid(struct hn_softc *sc) @@ -481,11 +475,8 @@ hv_rf_on_receive(struct hn_softc *sc, st } } -/* - * RNDIS filter query device MAC address - */ -static int -hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr) +int +hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr) { size_t eaddr_len; int error; @@ -502,11 +493,8 @@ hv_rf_query_device_mac(struct hn_softc * return (0); } -/* - * RNDIS filter query device link status - */ -static int -hv_rf_query_device_link_status(struct hn_softc *sc, uint32_t *link_status) +int +hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status) { size_t size; int error; @@ -523,14 +511,6 @@ hv_rf_query_device_link_status(struct hn return (0); } -static uint8_t netvsc_hash_key[NDIS_HASH_KEYSIZE_TOEPLITZ] = { - 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, - 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, - 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, - 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa -}; - static const void * hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, struct hn_send_ctx *sndc, size_t *comp_len) @@ -722,7 +702,7 @@ done: return (error); } -static int +int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) { struct ndis_rss_caps in, caps; @@ -857,12 +837,12 @@ hn_rndis_conf_offload(struct hn_softc *s return (error); } -static int -hn_rndis_conf_rss(struct hn_softc *sc, int nchan) +int +hn_rndis_conf_rss(struct hn_softc *sc) { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; struct ndis_rss_params *prm = &rss->rss_params; - int i, error; + int error; /* * Only NDIS 6.30+ is supported. @@ -870,7 +850,12 @@ hn_rndis_conf_rss(struct hn_softc *sc, i KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); - memset(rss, 0, sizeof(*rss)); + /* + * NOTE: + * DO NOT whack rss_key and rss_ind, which are setup by the caller. + */ + memset(prm, 0, sizeof(*prm)); + prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; prm->ndis_hdr.ndis_size = sizeof(*rss); @@ -885,14 +870,6 @@ hn_rndis_conf_rss(struct hn_softc *sc, i prm->ndis_keyoffset = __offsetof(struct ndis_rssprm_toeplitz, rss_key[0]); - /* Setup RSS key */ - memcpy(rss->rss_key, netvsc_hash_key, sizeof(rss->rss_key)); - - /* Setup RSS indirect table */ - /* TODO: Take ndis_rss_caps.ndis_nind into account */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:50:20 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 865A0C10342; Thu, 13 Oct 2016 08:50:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 50E72B34; Thu, 13 Oct 2016 08:50:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D8oI20046688; Thu, 13 Oct 2016 08:50:18 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D8oIgZ046687; Thu, 13 Oct 2016 08:50:18 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130850.u9D8oIgZ046687@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:50:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307207 - stable/10/sys/dev/hyperv/vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:50:20 -0000 Author: sephe Date: Thu Oct 13 08:50:18 2016 New Revision: 307207 URL: https://svnweb.freebsd.org/changeset/base/307207 Log: MFC 305789 hyperv/vmbus: Make sure that the sub-channel count is valid. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7865 Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 08:47:51 2016 (r307206) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Oct 13 08:50:18 2016 (r307207) @@ -1346,6 +1346,8 @@ vmbus_subchan_get(struct vmbus_channel * struct vmbus_channel **ret, *chan; int i; + KASSERT(subchan_cnt > 0, ("invalid sub-channel count %d", subchan_cnt)); + ret = malloc(subchan_cnt * sizeof(struct vmbus_channel *), M_TEMP, M_WAITOK); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 08:56:54 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3A921C105C9; Thu, 13 Oct 2016 08:56:54 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1409AEC; Thu, 13 Oct 2016 08:56:54 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D8urOQ050363; Thu, 13 Oct 2016 08:56:53 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D8urVR050361; Thu, 13 Oct 2016 08:56:53 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130856.u9D8urVR050361@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 08:56:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307208 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 08:56:54 -0000 Author: sephe Date: Thu Oct 13 08:56:52 2016 New Revision: 307208 URL: https://svnweb.freebsd.org/changeset/base/307208 Log: MFC 305790-305793 305790 hyperv/hn: Remove unused softc field Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7866 305791 hyperv/hn: Deprecate hn_softc_t Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7867 305792 hyperv/hn: Function renaming: hn_ifinit -> hn_init No functional changes. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7868 305793 hyperv/hn: Cleanup hn_ioctl. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7869 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:50:18 2016 (r307207) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:56:52 2016 (r307208) @@ -198,12 +198,11 @@ struct hn_tx_ring { /* * Device-specific softc structure */ -typedef struct hn_softc { +struct hn_softc { struct ifnet *hn_ifp; struct arpcom arpcom; struct ifmedia hn_media; device_t hn_dev; - uint8_t hn_unit; int hn_carrier; int hn_if_flags; struct mtx hn_lock; @@ -245,7 +244,7 @@ typedef struct hn_softc { uint32_t hn_ndis_ver; struct ndis_rssprm_toeplitz hn_rss; -} hn_softc_t; +}; #define HN_FLAG_RXBUF_CONNECTED 0x0001 #define HN_FLAG_CHIM_CONNECTED 0x0002 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:50:18 2016 (r307207) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:56:52 2016 (r307208) @@ -312,9 +312,9 @@ static u_int hn_cpu_index; /* * Forward declarations */ -static void hn_stop(hn_softc_t *sc); -static void hn_ifinit_locked(hn_softc_t *sc); -static void hn_ifinit(void *xsc); +static void hn_stop(struct hn_softc *sc); +static void hn_init_locked(struct hn_softc *sc); +static void hn_init(void *xsc); static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); static int hn_start_locked(struct hn_tx_ring *txr, int len); static void hn_start(struct ifnet *ifp); @@ -467,19 +467,15 @@ hn_cpuset_setthread_task(void *xmask, in static int netvsc_attach(device_t dev) { + struct hn_softc *sc = device_get_softc(dev); struct sysctl_oid_list *child; struct sysctl_ctx_list *ctx; uint8_t eaddr[ETHER_ADDR_LEN]; uint32_t link_status; - hn_softc_t *sc; - int unit = device_get_unit(dev); struct ifnet *ifp = NULL; int error, ring_cnt, tx_ring_cnt; int tso_maxlen; - sc = device_get_softc(dev); - - sc->hn_unit = unit; sc->hn_dev = dev; sc->hn_prichan = vmbus_get_channel(dev); @@ -564,7 +560,7 @@ netvsc_attach(device_t dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; - ifp->if_init = hn_ifinit; + ifp->if_init = hn_init; ifp->if_mtu = ETHERMTU; if (hn_use_if_start) { int qdepth = hn_get_txswq_depth(&sc->hn_tx_ring[0]); @@ -1513,29 +1509,13 @@ skip: static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - hn_softc_t *sc = ifp->if_softc; + struct hn_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; -#ifdef INET - struct ifaddr *ifa = (struct ifaddr *)data; -#endif int mask, error = 0; int retry_cnt = 500; - switch(cmd) { - - case SIOCSIFADDR: -#ifdef INET - if (ifa->ifa_addr->sa_family == AF_INET) { - ifp->if_flags |= IFF_UP; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - hn_ifinit(sc); - arp_ifinit(ifp, ifa); - } else -#endif - error = ether_ioctl(ifp, cmd, data); - break; + switch (cmd) { case SIOCSIFMTU: - /* Check MTU value change */ if (ifp->if_mtu == ifr->ifr_mtu) break; @@ -1603,12 +1583,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) hn_set_chim_size(sc, sc->hn_chim_szmax); - hn_ifinit_locked(sc); + hn_init_locked(sc); NV_LOCK(sc); sc->temp_unusable = FALSE; NV_UNLOCK(sc); break; + case SIOCSIFFLAGS: do { NV_LOCK(sc); @@ -1649,7 +1630,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, /* do something here for Hyper-V */ } else #endif - hn_ifinit_locked(sc); + hn_init_locked(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { hn_stop(sc); @@ -1659,8 +1640,8 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, sc->temp_unusable = FALSE; NV_UNLOCK(sc); sc->hn_if_flags = ifp->if_flags; - error = 0; break; + case SIOCSIFCAP: NV_LOCK(sc); @@ -1699,38 +1680,32 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, } NV_UNLOCK(sc); - error = 0; break; + case SIOCADDMULTI: case SIOCDELMULTI: -#ifdef notyet - /* Fixme: Multicast mode? */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - NV_LOCK(sc); - netvsc_setmulti(sc); - NV_UNLOCK(sc); - error = 0; - } -#endif - error = EINVAL; + /* Always all-multi */ + /* + * TODO: + * Enable/disable all-multi according to the emptiness of + * the mcast address list. + */ break; + case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->hn_media, cmd); break; + default: error = ether_ioctl(ifp, cmd, data); break; } - return (error); } -/* - * - */ static void -hn_stop(hn_softc_t *sc) +hn_stop(struct hn_softc *sc) { struct ifnet *ifp; int ret, i; @@ -1809,11 +1784,8 @@ do_sched: } } -/* - * - */ static void -hn_ifinit_locked(hn_softc_t *sc) +hn_init_locked(struct hn_softc *sc) { struct ifnet *ifp; int ret, i; @@ -1845,9 +1817,9 @@ hn_ifinit_locked(hn_softc_t *sc) * */ static void -hn_ifinit(void *xsc) +hn_init(void *xsc) { - hn_softc_t *sc = xsc; + struct hn_softc *sc = xsc; NV_LOCK(sc); if (sc->temp_unusable) { @@ -1857,7 +1829,7 @@ hn_ifinit(void *xsc) sc->temp_unusable = TRUE; NV_UNLOCK(sc); - hn_ifinit_locked(sc); + hn_init_locked(sc); NV_LOCK(sc); sc->temp_unusable = FALSE; @@ -1871,11 +1843,9 @@ hn_ifinit(void *xsc) static void hn_watchdog(struct ifnet *ifp) { - hn_softc_t *sc; - sc = ifp->if_softc; - printf("hn%d: watchdog timeout -- resetting\n", sc->hn_unit); - hn_ifinit(sc); /*???*/ + if_printf(ifp, "watchdog timeout -- resetting\n"); + hn_init(ifp->if_softc); /* XXX */ ifp->if_oerrors++; } #endif @@ -3545,7 +3515,7 @@ static device_method_t netvsc_methods[] static driver_t netvsc_driver = { NETVSC_DEVNAME, netvsc_methods, - sizeof(hn_softc_t) + sizeof(struct hn_softc) }; static devclass_t netvsc_devclass; From owner-svn-src-stable-10@freebsd.org Thu Oct 13 09:00:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A1276C10806; Thu, 13 Oct 2016 09:00:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7C5972F1; Thu, 13 Oct 2016 09:00:45 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D90iCj050592; Thu, 13 Oct 2016 09:00:44 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D90i3Y050590; Thu, 13 Oct 2016 09:00:44 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130900.u9D90i3Y050590@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 09:00:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307209 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 09:00:45 -0000 Author: sephe Date: Thu Oct 13 09:00:44 2016 New Revision: 307209 URL: https://svnweb.freebsd.org/changeset/base/307209 Log: MFC 305794 hyperv/hn: Use sx for the main lock. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7870 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 08:56:52 2016 (r307208) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Thu Oct 13 09:00:44 2016 (r307209) @@ -205,10 +205,7 @@ struct hn_softc { device_t hn_dev; int hn_carrier; int hn_if_flags; - struct mtx hn_lock; - int hn_initdone; - /* See hv_netvsc_drv_freebsd.c for rules on how to use */ - int temp_unusable; + struct sx hn_lock; struct vmbus_channel *hn_prichan; int hn_rx_ring_cnt; Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 08:56:52 2016 (r307208) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 09:00:44 2016 (r307209) @@ -197,21 +197,12 @@ struct hn_txdesc { #define HN_LRO_ACKCNT_DEF 1 -/* - * Be aware that this sleepable mutex will exhibit WITNESS errors when - * certain TCP and ARP code paths are taken. This appears to be a - * well-known condition, as all other drivers checked use a sleeping - * mutex to protect their transmit paths. - * Also Be aware that mutexes do not play well with semaphores, and there - * is a conflicting semaphore in a certain channel code path. - */ -#define NV_LOCK_INIT(_sc, _name) \ - mtx_init(&(_sc)->hn_lock, _name, MTX_NETWORK_LOCK, MTX_DEF) -#define NV_LOCK(_sc) mtx_lock(&(_sc)->hn_lock) -#define NV_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->hn_lock, MA_OWNED) -#define NV_UNLOCK(_sc) mtx_unlock(&(_sc)->hn_lock) -#define NV_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->hn_lock) - +#define HN_LOCK_INIT(sc) \ + sx_init(&(sc)->hn_lock, device_get_nameunit((sc)->hn_dev)) +#define HN_LOCK_ASSERT(sc) sx_assert(&(sc)->hn_lock, SA_XLOCKED) +#define HN_LOCK_DESTROY(sc) sx_destroy(&(sc)->hn_lock) +#define HN_LOCK(sc) sx_xlock(&(sc)->hn_lock) +#define HN_UNLOCK(sc) sx_xunlock(&(sc)->hn_lock) /* * Globals @@ -478,6 +469,7 @@ netvsc_attach(device_t dev) sc->hn_dev = dev; sc->hn_prichan = vmbus_get_channel(dev); + HN_LOCK_INIT(sc); if (hn_tx_taskq == NULL) { sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK, @@ -500,7 +492,6 @@ netvsc_attach(device_t dev) } else { sc->hn_tx_taskq = hn_tx_taskq; } - NV_LOCK_INIT(sc, "NetVSCLock"); ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER); ifp->if_softc = sc; @@ -681,6 +672,7 @@ netvsc_detach(device_t dev) taskqueue_free(sc->hn_tx_taskq); vmbus_xact_ctx_destroy(sc->hn_xact); + HN_LOCK_DESTROY(sc); return (0); } @@ -1491,39 +1483,27 @@ skip: return (0); } -/* - * Rules for using sc->temp_unusable: - * 1. sc->temp_unusable can only be read or written while holding NV_LOCK() - * 2. code reading sc->temp_unusable under NV_LOCK(), and finding - * sc->temp_unusable set, must release NV_LOCK() and exit - * 3. to retain exclusive control of the interface, - * sc->temp_unusable must be set by code before releasing NV_LOCK() - * 4. only code setting sc->temp_unusable can clear sc->temp_unusable - * 5. code setting sc->temp_unusable must eventually clear sc->temp_unusable - */ - -/* - * Standard ioctl entry point. Called when the user wants to configure - * the interface. - */ static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct hn_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; int mask, error = 0; - int retry_cnt = 500; - + switch (cmd) { case SIOCSIFMTU: - if (ifp->if_mtu == ifr->ifr_mtu) - break; - if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) { error = EINVAL; break; } + HN_LOCK(sc); + + if (ifp->if_mtu == ifr->ifr_mtu) { + HN_UNLOCK(sc); + break; + } + /* Obtain and record requested MTU */ ifp->if_mtu = ifr->ifr_mtu; @@ -1532,40 +1512,18 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, * Make sure that LRO aggregation length limit is still * valid, after the MTU change. */ - NV_LOCK(sc); if (sc->hn_rx_ring[0].hn_lro.lro_length_lim < HN_LRO_LENLIM_MIN(ifp)) hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp)); - NV_UNLOCK(sc); #endif - do { - NV_LOCK(sc); - if (!sc->temp_unusable) { - sc->temp_unusable = TRUE; - retry_cnt = -1; - } - NV_UNLOCK(sc); - if (retry_cnt > 0) { - retry_cnt--; - DELAY(5 * 1000); - } - } while (retry_cnt > 0); - - if (retry_cnt == 0) { - error = EINVAL; - break; - } - /* We must remove and add back the device to cause the new * MTU to take effect. This includes tearing down, but not * deleting the channel, then bringing it back up. */ error = hv_rf_on_device_remove(sc); if (error) { - NV_LOCK(sc); - sc->temp_unusable = FALSE; - NV_UNLOCK(sc); + HN_UNLOCK(sc); break; } @@ -1585,29 +1543,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, hn_init_locked(sc); - NV_LOCK(sc); - sc->temp_unusable = FALSE; - NV_UNLOCK(sc); + HN_UNLOCK(sc); break; case SIOCSIFFLAGS: - do { - NV_LOCK(sc); - if (!sc->temp_unusable) { - sc->temp_unusable = TRUE; - retry_cnt = -1; - } - NV_UNLOCK(sc); - if (retry_cnt > 0) { - retry_cnt--; - DELAY(5 * 1000); - } - } while (retry_cnt > 0); - - if (retry_cnt == 0) { - error = EINVAL; - break; - } + HN_LOCK(sc); if (ifp->if_flags & IFF_UP) { /* @@ -1636,14 +1576,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, hn_stop(sc); } } - NV_LOCK(sc); - sc->temp_unusable = FALSE; - NV_UNLOCK(sc); sc->hn_if_flags = ifp->if_flags; + + HN_UNLOCK(sc); break; case SIOCSIFCAP: - NV_LOCK(sc); + HN_LOCK(sc); mask = ifr->ifr_reqcap ^ ifp->if_capenable; if (mask & IFCAP_TXCSUM) { @@ -1679,7 +1618,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, ifp->if_hwassist &= ~CSUM_IP6_TSO; } - NV_UNLOCK(sc); + HN_UNLOCK(sc); break; case SIOCADDMULTI: @@ -1710,6 +1649,8 @@ hn_stop(struct hn_softc *sc) struct ifnet *ifp; int ret, i; + HN_LOCK_ASSERT(sc); + ifp = sc->hn_ifp; if (bootverbose) @@ -1721,7 +1662,6 @@ hn_stop(struct hn_softc *sc) sc->hn_tx_ring[i].hn_oactive = 0; if_link_state_change(ifp, LINK_STATE_DOWN); - sc->hn_initdone = 0; ret = hv_rf_on_close(sc); } @@ -1790,6 +1730,8 @@ hn_init_locked(struct hn_softc *sc) struct ifnet *ifp; int ret, i; + HN_LOCK_ASSERT(sc); + ifp = sc->hn_ifp; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { @@ -1799,11 +1741,8 @@ hn_init_locked(struct hn_softc *sc) hv_promisc_mode = 1; ret = hv_rf_on_open(sc); - if (ret != 0) { + if (ret != 0) return; - } else { - sc->hn_initdone = 1; - } atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) @@ -1813,27 +1752,14 @@ hn_init_locked(struct hn_softc *sc) if_link_state_change(ifp, LINK_STATE_UP); } -/* - * - */ static void hn_init(void *xsc) { struct hn_softc *sc = xsc; - NV_LOCK(sc); - if (sc->temp_unusable) { - NV_UNLOCK(sc); - return; - } - sc->temp_unusable = TRUE; - NV_UNLOCK(sc); - + HN_LOCK(sc); hn_init_locked(sc); - - NV_LOCK(sc); - sc->temp_unusable = FALSE; - NV_UNLOCK(sc); + HN_UNLOCK(sc); } #ifdef LATER @@ -1864,13 +1790,15 @@ hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS if (error || req->newptr == NULL) return error; + HN_LOCK(sc); if (lenlim < HN_LRO_LENLIM_MIN(sc->hn_ifp) || - lenlim > TCP_LRO_LENGTH_MAX) + lenlim > TCP_LRO_LENGTH_MAX) { + HN_UNLOCK(sc); return EINVAL; - - NV_LOCK(sc); + } hn_set_lro_lenlim(sc, lenlim); - NV_UNLOCK(sc); + HN_UNLOCK(sc); + return 0; } @@ -1897,10 +1825,10 @@ hn_lro_ackcnt_sysctl(SYSCTL_HANDLER_ARGS * count limit. */ --ackcnt; - NV_LOCK(sc); + HN_LOCK(sc); for (i = 0; i < sc->hn_rx_ring_inuse; ++i) sc->hn_rx_ring[i].hn_lro.lro_ackcnt_lim = ackcnt; - NV_UNLOCK(sc); + HN_UNLOCK(sc); return 0; } @@ -1921,7 +1849,7 @@ hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARG if (error || req->newptr == NULL) return error; - NV_LOCK(sc); + HN_LOCK(sc); for (i = 0; i < sc->hn_rx_ring_inuse; ++i) { struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; @@ -1930,7 +1858,7 @@ hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARG else rxr->hn_trust_hcsum &= ~hcsum; } - NV_UNLOCK(sc); + HN_UNLOCK(sc); return 0; } @@ -1948,7 +1876,9 @@ hn_chim_size_sysctl(SYSCTL_HANDLER_ARGS) if (chim_size > sc->hn_chim_szmax || chim_size <= 0) return EINVAL; + HN_LOCK(sc); hn_set_chim_size(sc, chim_size); + HN_UNLOCK(sc); return 0; } @@ -2073,12 +2003,12 @@ hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARG if (error || req->newptr == NULL) return error; - NV_LOCK(sc); + HN_LOCK(sc); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { txr = &sc->hn_tx_ring[i]; *((int *)((uint8_t *)txr + ofs)) = conf; } - NV_UNLOCK(sc); + HN_UNLOCK(sc); return 0; } @@ -2732,10 +2662,8 @@ hn_set_chim_size(struct hn_softc *sc, in { int i; - NV_LOCK(sc); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) sc->hn_tx_ring[i].hn_chim_size = chim_size; - NV_UNLOCK(sc); } static void From owner-svn-src-stable-10@freebsd.org Thu Oct 13 09:18:57 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5B8A8C10D1F; Thu, 13 Oct 2016 09:18:57 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 331BA235; Thu, 13 Oct 2016 09:18:57 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D9IuvI058321; Thu, 13 Oct 2016 09:18:56 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D9Iuui058320; Thu, 13 Oct 2016 09:18:56 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130918.u9D9Iuui058320@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 09:18:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307211 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 09:18:57 -0000 Author: sephe Date: Thu Oct 13 09:18:56 2016 New Revision: 307211 URL: https://svnweb.freebsd.org/changeset/base/307211 Log: MFC 305801,305923,305924 305801 hyperv/hn: Fix some ifnet settings - ifnet.if_mtu does not require explicit setting. - ifnet.if_hdrlen must be set after ether_ifattach(). Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7873 305923 hyperv/hn: Regroup ifnet setup code. While I'm here, add comment along the attach DEVMETHOD. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7874 305924 hyperv/hn: Put debug message under bootverbose Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7875 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 09:06:29 2016 (r307210) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 09:18:56 2016 (r307211) @@ -471,6 +471,9 @@ netvsc_attach(device_t dev) sc->hn_prichan = vmbus_get_channel(dev); HN_LOCK_INIT(sc); + /* + * Setup taskqueue for transmission. + */ if (hn_tx_taskq == NULL) { sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK, taskqueue_thread_enqueue, &sc->hn_tx_taskq); @@ -493,11 +496,22 @@ netvsc_attach(device_t dev) sc->hn_tx_taskq = hn_tx_taskq; } + /* + * Allocate ifnet and setup its name earlier, so that if_printf + * can be used by functions, which will be called after + * ether_ifattach(). + */ ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER); ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); /* + * Initialize ifmedia earlier so that it can be unconditionally + * destroyed, if error happened later on. + */ + ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts); + + /* * Figure out the # of RX rings (ring_cnt) and the # of TX rings * to use (tx_ring_cnt). * @@ -527,6 +541,10 @@ netvsc_attach(device_t dev) */ sc->hn_cpu = atomic_fetchadd_int(&hn_cpu_index, ring_cnt) % mp_ncpus; + /* + * Create enough TX/RX rings, even if only limited number of + * channels can be allocated. + */ error = hn_create_tx_data(sc, tx_ring_cnt); if (error) goto failed; @@ -549,10 +567,54 @@ netvsc_attach(device_t dev) if (error) goto failed; + error = hn_rndis_get_linkstatus(sc, &link_status); + if (error) + goto failed; + if (link_status == NDIS_MEDIA_STATE_CONNECTED) + sc->hn_carrier = 1; + + error = hn_rndis_get_eaddr(sc, eaddr); + if (error) + goto failed; + +#if __FreeBSD_version >= 1100099 + if (sc->hn_rx_ring_inuse > 1) { + /* + * Reduce TCP segment aggregation limit for multiple + * RX rings to increase ACK timeliness. + */ + hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF); + } +#endif + + hn_set_chim_size(sc, sc->hn_chim_szmax); + if (hn_tx_chimney_size > 0 && + hn_tx_chimney_size < sc->hn_chim_szmax) + hn_set_chim_size(sc, hn_tx_chimney_size); + + ctx = device_get_sysctl_ctx(dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD, + &sc->hn_nvs_ver, 0, "NVS version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_ndis_version_sysctl, "A", "NDIS version"); + + /* + * Setup the ifmedia, which has been initialized earlier. + */ + ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO); + /* XXX ifmedia_set really should do this for us */ + sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media; + + /* + * Setup the ifnet for this interface. + */ + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; ifp->if_init = hn_init; - ifp->if_mtu = ETHERMTU; if (hn_use_if_start) { int qdepth = hn_get_txswq_depth(&sc->hn_tx_ring[0]); @@ -565,16 +627,6 @@ netvsc_attach(device_t dev) ifp->if_qflush = hn_xmit_qflush; } - ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts); - ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL); - ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO); - /* XXX ifmedia_set really should do this for us */ - sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media; - - /* - * Tell upper layers that we support full VLAN capability. - */ - ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO | IFCAP_LRO; @@ -583,54 +635,27 @@ netvsc_attach(device_t dev) IFCAP_LRO; ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; -#if __FreeBSD_version >= 1100099 - if (sc->hn_rx_ring_inuse > 1) { - /* - * Reduce TCP segment aggregation limit for multiple - * RX rings to increase ACK timeliness. - */ - hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF); - } -#endif - - error = hn_rndis_get_linkstatus(sc, &link_status); - if (error) - goto failed; - if (link_status == NDIS_MEDIA_STATE_CONNECTED) - sc->hn_carrier = 1; - tso_maxlen = hn_tso_maxlen; if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET) tso_maxlen = IP_MAXPACKET; - ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX; ifp->if_hw_tsomaxsegsize = PAGE_SIZE; ifp->if_hw_tsomax = tso_maxlen - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); - error = hn_rndis_get_eaddr(sc, eaddr); - if (error) - goto failed; ether_ifattach(ifp, eaddr); - if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax, - ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize); - - hn_set_chim_size(sc, sc->hn_chim_szmax); - if (hn_tx_chimney_size > 0 && - hn_tx_chimney_size < sc->hn_chim_szmax) - hn_set_chim_size(sc, hn_tx_chimney_size); + if (bootverbose) { + if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax, + ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize); + } - ctx = device_get_sysctl_ctx(dev); - child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); - SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD, - &sc->hn_nvs_ver, 0, "NVS version"); - SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", - CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, - hn_ndis_version_sysctl, "A", "NDIS version"); + /* Inform the upper layer about the long frame support. */ + ifp->if_hdrlen = sizeof(struct ether_vlan_header); return (0); failed: + /* TODO: reuse netvsc_detach() */ hn_destroy_tx_data(sc); if (ifp != NULL) if_free(ifp); From owner-svn-src-stable-10@freebsd.org Thu Oct 13 09:27:10 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 29509C10FAA; Thu, 13 Oct 2016 09:27:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DB6EDA84; Thu, 13 Oct 2016 09:27:09 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D9R8Rn062269; Thu, 13 Oct 2016 09:27:08 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D9R8hW062265; Thu, 13 Oct 2016 09:27:08 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610130927.u9D9R8hW062265@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 09:27:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307212 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 09:27:10 -0000 Author: sephe Date: Thu Oct 13 09:27:08 2016 New Revision: 307212 URL: https://svnweb.freebsd.org/changeset/base/307212 Log: MFC 305925,305926,305960 305925 hyperv/hn: Don't mess up RSS key and indirect table after attachment. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7889 305926 hyperv/hn: Add sysctls to dynamic adjust RSS key and indirect table Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7890 305960 hyperv/hn: Apply RSS indirect table fixup before configure RNDIS RSS. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7916 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/if_hnvar.h stable/10/sys/dev/hyperv/netvsc/ndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 09:18:56 2016 (r307211) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Thu Oct 13 09:27:08 2016 (r307212) @@ -327,6 +327,8 @@ static int hn_rx_stat_ulong_sysctl(SYSCT static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS); static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); static int hn_create_tx_ring(struct hn_softc *, int); static void hn_destroy_tx_ring(struct hn_tx_ring *); @@ -393,6 +395,62 @@ hn_get_txswq_depth(const struct hn_tx_ri } static int +hn_rss_reconfig(struct hn_softc *sc) +{ + int error; + + HN_LOCK_ASSERT(sc); + + /* + * Disable RSS first. + * + * NOTE: + * Direct reconfiguration by setting the UNCHG flags does + * _not_ work properly. + */ + if (bootverbose) + if_printf(sc->hn_ifp, "disable RSS\n"); + error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_DISABLE); + if (error) { + if_printf(sc->hn_ifp, "RSS disable failed\n"); + return (error); + } + + /* + * Reenable the RSS w/ the updated RSS key or indirect + * table. + */ + if (bootverbose) + if_printf(sc->hn_ifp, "reconfig RSS\n"); + error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE); + if (error) { + if_printf(sc->hn_ifp, "RSS reconfig failed\n"); + return (error); + } + return (0); +} + +static void +hn_rss_ind_fixup(struct hn_softc *sc, int nchan) +{ + struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; + int i; + + /* + * Check indirect table to make sure that all channels in it + * can be used. + */ + for (i = 0; i < NDIS_HASH_INDCNT; ++i) { + if (rss->rss_ind[i] >= nchan) { + if_printf(sc->hn_ifp, + "RSS indirect table %d fixup: %u -> %d\n", + i, rss->rss_ind[i], nchan - 1); + rss->rss_ind[i] = nchan - 1; + } + } +} + +static int hn_ifmedia_upd(struct ifnet *ifp __unused) { @@ -599,6 +657,12 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_ndis_version_sysctl, "A", "NDIS version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", + CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, + hn_rss_key_sysctl, "IU", "RSS key"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_ind", + CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, + hn_rss_ind_sysctl, "IU", "RSS indirect table"); /* * Setup the ifmedia, which has been initialized earlier. @@ -2051,6 +2115,51 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_AR } static int +hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + int error; + + HN_LOCK(sc); + + error = SYSCTL_OUT(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key)); + if (error || req->newptr == NULL) + goto back; + + error = SYSCTL_IN(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key)); + if (error) + goto back; + + error = hn_rss_reconfig(sc); +back: + HN_UNLOCK(sc); + return (error); +} + +static int +hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + int error; + + HN_LOCK(sc); + + error = SYSCTL_OUT(req, sc->hn_rss.rss_ind, sizeof(sc->hn_rss.rss_ind)); + if (error || req->newptr == NULL) + goto back; + + error = SYSCTL_IN(req, sc->hn_rss.rss_ind, sizeof(sc->hn_rss.rss_ind)); + if (error) + goto back; + + hn_rss_ind_fixup(sc, sc->hn_rx_ring_inuse); + error = hn_rss_reconfig(sc); +back: + HN_UNLOCK(sc); + return (error); +} + +static int hn_check_iplen(const struct mbuf *m, int hoff) { const struct ip *ip; @@ -3179,15 +3288,34 @@ hn_synth_attach(struct hn_softc *sc, int * are allocated. */ - /* Setup default RSS key. */ - memcpy(rss->rss_key, hn_rss_key_default, sizeof(rss->rss_key)); + if (!device_is_attached(sc->hn_dev)) { + /* + * Setup default RSS key and indirect table for the + * attach DEVMETHOD. They can be altered later on, + * so don't mess them up once this interface is attached. + */ + if (bootverbose) { + if_printf(sc->hn_ifp, "setup default RSS key and " + "indirect table\n"); + } + + /* Setup default RSS key. */ + memcpy(rss->rss_key, hn_rss_key_default, sizeof(rss->rss_key)); - /* Setup default RSS indirect table. */ - /* TODO: Take ndis_rss_caps.ndis_nind into account. */ - for (i = 0; i < NDIS_HASH_INDCNT; ++i) - rss->rss_ind[i] = i % nchan; + /* Setup default RSS indirect table. */ + /* TODO: Take ndis_rss_caps.ndis_nind into account. */ + for (i = 0; i < NDIS_HASH_INDCNT; ++i) + rss->rss_ind[i] = i % nchan; + } else { + /* + * # of usable channels may be changed, so we have to + * make sure that all entries in RSS indirect table + * are valid. + */ + hn_rss_ind_fixup(sc, nchan); + } - error = hn_rndis_conf_rss(sc); + error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE); if (error) { /* * Failed to configure RSS key or indirect table; only Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 09:18:56 2016 (r307211) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Thu Oct 13 09:27:08 2016 (r307212) @@ -838,7 +838,7 @@ hn_rndis_conf_offload(struct hn_softc *s } int -hn_rndis_conf_rss(struct hn_softc *sc) +hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; struct ndis_rss_params *prm = &rss->rss_params; @@ -859,6 +859,7 @@ hn_rndis_conf_rss(struct hn_softc *sc) prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; prm->ndis_hdr.ndis_size = sizeof(*rss); + prm->ndis_flags = flags; prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ | NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6; Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 09:18:56 2016 (r307211) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Thu Oct 13 09:27:08 2016 (r307212) @@ -118,7 +118,7 @@ uint32_t hn_chim_alloc(struct hn_softc * void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); int hn_rndis_attach(struct hn_softc *sc); -int hn_rndis_conf_rss(struct hn_softc *sc); +int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, size_t pktsize, size_t pi_dlen, uint32_t pi_type); int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt); Modified: stable/10/sys/dev/hyperv/netvsc/ndis.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 09:18:56 2016 (r307211) +++ stable/10/sys/dev/hyperv/netvsc/ndis.h Thu Oct 13 09:27:08 2016 (r307212) @@ -188,6 +188,7 @@ struct ndis_rss_params { #define NDIS_RSS_PARAMS_REV_1 1 /* NDIS 6.0 */ #define NDIS_RSS_PARAMS_REV_2 2 /* NDIS 6.20 */ +#define NDIS_RSS_FLAG_NONE 0x0000 #define NDIS_RSS_FLAG_BCPU_UNCHG 0x0001 #define NDIS_RSS_FLAG_HASH_UNCHG 0x0002 #define NDIS_RSS_FLAG_IND_UNCHG 0x0004 From owner-svn-src-stable-10@freebsd.org Thu Oct 13 09:37:22 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 46E58C0E55E; Thu, 13 Oct 2016 09:37:22 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1823E21B; Thu, 13 Oct 2016 09:37:22 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9D9bLdX065947; Thu, 13 Oct 2016 09:37:21 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9D9bL0v065946; Thu, 13 Oct 2016 09:37:21 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201610130937.u9D9bL0v065946@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= Date: Thu, 13 Oct 2016 09:37:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307213 - stable/10/sys/x86/x86 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 09:37:22 -0000 Author: royger Date: Thu Oct 13 09:37:21 2016 New Revision: 307213 URL: https://svnweb.freebsd.org/changeset/base/307213 Log: MFC r303491: Revert r291022: x86/intr: allow mutex recursion in intr_remove_handler Sponsored by: Citrix Systems R&D Modified: stable/10/sys/x86/x86/intr_machdep.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/x86/x86/intr_machdep.c ============================================================================== --- stable/10/sys/x86/x86/intr_machdep.c Thu Oct 13 09:27:08 2016 (r307212) +++ stable/10/sys/x86/x86/intr_machdep.c Thu Oct 13 09:37:21 2016 (r307213) @@ -197,28 +197,19 @@ int intr_remove_handler(void *cookie) { struct intsrc *isrc; - int error, mtx_owned; + int error; isrc = intr_handler_source(cookie); error = intr_event_remove_handler(cookie); if (error == 0) { - /* - * Recursion is needed here so PICs can remove interrupts - * while resuming. It was previously not possible due to - * intr_resume holding the intr_table_lock and - * intr_remove_handler recursing on it. - */ - mtx_owned = mtx_owned(&intr_table_lock); - if (mtx_owned == 0) - mtx_lock(&intr_table_lock); + mtx_lock(&intr_table_lock); isrc->is_handlers--; if (isrc->is_handlers == 0) { isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); isrc->is_pic->pic_disable_intr(isrc); } intrcnt_updatename(isrc); - if (mtx_owned == 0) - mtx_unlock(&intr_table_lock); + mtx_unlock(&intr_table_lock); } return (error); } From owner-svn-src-stable-10@freebsd.org Thu Oct 13 09:43:05 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 44317C0E720; Thu, 13 Oct 2016 09:43:05 +0000 (UTC) (envelope-from sepherosa@gmail.com) Received: from mail-vk0-x235.google.com (mail-vk0-x235.google.com [IPv6:2607:f8b0:400c:c05::235]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id F249FF5; Thu, 13 Oct 2016 09:43:04 +0000 (UTC) (envelope-from sepherosa@gmail.com) Received: by mail-vk0-x235.google.com with SMTP id 83so48215797vkd.0; Thu, 13 Oct 2016 02:43:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=ClnhcjVSrMJlUpQit60S3251UubEniZAoDvPetQ7nQY=; b=TuF5msw4WntcMyY60VL4FLE05SHKHRSYTUNt/l16e6z+Qg8L7DW0BF4ifC31C2JnKn CJX+CSU6MCrV7k20XlKwfpI/ng6W7sUA3D7y7iBnmxy6QB5zuX4VjaySlNcDiXR0L6kZ Hp24N+phh7iDbzxNhSFzrswek3U3i3dxzqIOV+aH5CLOqdnq137CoDp3kchYkF78h1Zx i/ff4TZq1j6MP55NeeQ76OJrZAhttV8ZaupnxLaeY8V5qcOezzO9LLUQYUSOT5P/8PAu yN6UT8ySUSStmo4sq0t33lwNTni1UDiGKE3uhzoe5/pGHhz/VGVrWj7r2xvfhfqRHt0t Irkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=ClnhcjVSrMJlUpQit60S3251UubEniZAoDvPetQ7nQY=; b=In/GP/E50/DsxJBjs/7FM/BIT430RlumsbYDL3c5FswzB27gJmjAG5JSdkmuVyczIm BCffyvHwFY00dGPA9x63YGZEJBicjbEta041ITfKKM2xdQfoq4gC7vM8fA5fLYioEVtk 4TgMaMNRndq+k3ok7k5VF5l4dDm4xVyi2pDhCmZAD+NBzYzaV0tR2mRpUHwrPQEULMrS N0GltwjL302E3YQlOxR9inL77DF+/wZN0mXE8TJfIIrFg+bCskLtmO5vbLQCkKR6Gmb3 b8cU5iSh4iDg9heSrGIOf/YF2msPiAUZYHhRUc465/KgAXOedcgHEx1rcC+CGlRAMriM NXvA== X-Gm-Message-State: AA6/9RnazG5aCf5tuhzRlsRsCB1ELr2HF3YdsrXJQkSo4NO0rxZOlQFSq1slDi4S/8hH6p7qAOKrZrO8HhNiAQ== X-Received: by 10.31.120.14 with SMTP id t14mr3716006vkc.55.1476351783737; Thu, 13 Oct 2016 02:43:03 -0700 (PDT) MIME-Version: 1.0 Received: by 10.176.81.121 with HTTP; Thu, 13 Oct 2016 02:43:03 -0700 (PDT) In-Reply-To: <201610130937.u9D9bL0v065946@repo.freebsd.org> References: <201610130937.u9D9bL0v065946@repo.freebsd.org> From: Sepherosa Ziehau Date: Thu, 13 Oct 2016 17:43:03 +0800 Message-ID: Subject: Re: svn commit: r307213 - stable/10/sys/x86/x86 To: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Oct 2016 09:43:05 -0000 On Thu, Oct 13, 2016 at 5:37 PM, Roger Pau Monn=C3=A9 = wrote: > Author: royger > Date: Thu Oct 13 09:37:21 2016 > New Revision: 307213 > URL: https://svnweb.freebsd.org/changeset/base/307213 > > Log: > MFC r303491: > > Revert r291022: x86/intr: allow mutex recursion in intr_remove_handler > > Sponsored by: Citrix Systems R&D Thank you very much! From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:03:55 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2A1C1C10EA8; Fri, 14 Oct 2016 02:03:55 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DB6F21BC; Fri, 14 Oct 2016 02:03:54 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E23rud041271; Fri, 14 Oct 2016 02:03:53 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E23rUU041270; Fri, 14 Oct 2016 02:03:53 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140203.u9E23rUU041270@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:03:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307244 - stable/10/sys/x86/x86 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:03:55 -0000 Author: sephe Date: Fri Oct 14 02:03:53 2016 New Revision: 307244 URL: https://svnweb.freebsd.org/changeset/base/307244 Log: MFC 305722 x86: Use sx lock for interrupt sources. - Certain pic_assign_cpu, e.g. msi_assign_cpu can have quite a long call chain. For msi_assign_cpu, mutex makes complex PCI bridge drivers more tricky, e.g. sleep can note be called, etc, it will be pretty tricky for upcoming Hyper-V PCI bridge driver for PCI pass-through. - It is not used on any hot code path nor non-sleepable context, so sx should have the same effect as mutex. PIC list is still protected by mutex to keep suspend/resume work. Discussed with: jhb Reviewed by: jhb Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7784 Modified: stable/10/sys/x86/x86/intr_machdep.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/x86/x86/intr_machdep.c ============================================================================== --- stable/10/sys/x86/x86/intr_machdep.c Fri Oct 14 01:53:15 2016 (r307243) +++ stable/10/sys/x86/x86/intr_machdep.c Fri Oct 14 02:03:53 2016 (r307244) @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,8 @@ typedef void (*mask_fn)(void *); static int intrcnt_index; static struct intsrc *interrupt_sources[NUM_IO_INTS]; -static struct mtx intr_table_lock; +static struct sx intrsrc_lock; +static struct mtx intrpic_lock; static struct mtx intrcnt_lock; static TAILQ_HEAD(pics_head, pic) pics; @@ -117,14 +119,14 @@ intr_register_pic(struct pic *pic) { int error; - mtx_lock(&intr_table_lock); + mtx_lock(&intrpic_lock); if (intr_pic_registered(pic)) error = EBUSY; else { TAILQ_INSERT_TAIL(&pics, pic, pics); error = 0; } - mtx_unlock(&intr_table_lock); + mtx_unlock(&intrpic_lock); return (error); } @@ -148,16 +150,16 @@ intr_register_source(struct intsrc *isrc vector); if (error) return (error); - mtx_lock(&intr_table_lock); + sx_xlock(&intrsrc_lock); if (interrupt_sources[vector] != NULL) { - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); intr_event_destroy(isrc->is_event); return (EEXIST); } intrcnt_register(isrc); interrupt_sources[vector] = isrc; isrc->is_handlers = 0; - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); return (0); } @@ -181,14 +183,14 @@ intr_add_handler(const char *name, int v error = intr_event_add_handler(isrc->is_event, name, filter, handler, arg, intr_priority(flags), flags, cookiep); if (error == 0) { - mtx_lock(&intr_table_lock); + sx_xlock(&intrsrc_lock); intrcnt_updatename(isrc); isrc->is_handlers++; if (isrc->is_handlers == 1) { isrc->is_pic->pic_enable_intr(isrc); isrc->is_pic->pic_enable_source(isrc); } - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); } return (error); } @@ -202,14 +204,14 @@ intr_remove_handler(void *cookie) isrc = intr_handler_source(cookie); error = intr_event_remove_handler(cookie); if (error == 0) { - mtx_lock(&intr_table_lock); + sx_xlock(&intrsrc_lock); isrc->is_handlers--; if (isrc->is_handlers == 0) { isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); isrc->is_pic->pic_disable_intr(isrc); } intrcnt_updatename(isrc); - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); } return (error); } @@ -283,12 +285,12 @@ intr_resume(bool suspend_cancelled) #ifndef DEV_ATPIC atpic_reset(); #endif - mtx_lock(&intr_table_lock); + mtx_lock(&intrpic_lock); TAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_resume != NULL) pic->pic_resume(pic, suspend_cancelled); } - mtx_unlock(&intr_table_lock); + mtx_unlock(&intrpic_lock); } void @@ -296,12 +298,12 @@ intr_suspend(void) { struct pic *pic; - mtx_lock(&intr_table_lock); + mtx_lock(&intrpic_lock); TAILQ_FOREACH_REVERSE(pic, &pics, pics_head, pics) { if (pic->pic_suspend != NULL) pic->pic_suspend(pic); } - mtx_unlock(&intr_table_lock); + mtx_unlock(&intrpic_lock); } static int @@ -317,9 +319,9 @@ intr_assign_cpu(void *arg, u_char cpu) */ if (assign_cpu && cpu != NOCPU) { isrc = arg; - mtx_lock(&intr_table_lock); + sx_xlock(&intrsrc_lock); error = isrc->is_pic->pic_assign_cpu(isrc, cpu_apic_ids[cpu]); - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); } else error = 0; return (error); @@ -379,7 +381,8 @@ intr_init(void *dummy __unused) intrcnt_setname("???", 0); intrcnt_index = 1; TAILQ_INIT(&pics); - mtx_init(&intr_table_lock, "intr sources", NULL, MTX_DEF); + mtx_init(&intrpic_lock, "intrpic", NULL, MTX_DEF); + sx_init(&intrsrc_lock, "intrsrc"); mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); @@ -527,7 +530,7 @@ intr_shuffle_irqs(void *arg __unused) return; /* Round-robin assign a CPU to each enabled source. */ - mtx_lock(&intr_table_lock); + sx_xlock(&intrsrc_lock); assign_cpu = 1; for (i = 0; i < NUM_IO_INTS; i++) { isrc = interrupt_sources[i]; @@ -548,7 +551,7 @@ intr_shuffle_irqs(void *arg __unused) } } - mtx_unlock(&intr_table_lock); + sx_xunlock(&intrsrc_lock); } SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:19:48 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A0DB9C1117F; Fri, 14 Oct 2016 02:19:48 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 62879B67; Fri, 14 Oct 2016 02:19:48 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2JlJs045484; Fri, 14 Oct 2016 02:19:47 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2Jlxh045480; Fri, 14 Oct 2016 02:19:47 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140219.u9E2Jlxh045480@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:19:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307245 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:19:48 -0000 Author: sephe Date: Fri Oct 14 02:19:47 2016 New Revision: 307245 URL: https://svnweb.freebsd.org/changeset/base/307245 Log: MFC 305962,305964-305967 305962 hyperv/hn: Don't allow NVS and NDIS version change upon reinitailization NVS and NDIS version change would break too much assumption and static configuration. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7919 305964 hyperv/hn: Save capabilities for later use. And don't allow capability changes during reinitialization, which breaks too much static configuration. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7922 305965 hyperv/hn: Don't allow MTU change, if it is not supported by the NVS. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7923 305966 hyperv/hn: Stringent RSS sysctl checks - Don't change RNDIS RSS configuration for RSS key sysctl, if the interface is not capable of RSS yet. - Don't change RSS indirect table (both cached one and RNDIS RSS configuration), if the interface is not capable of RSS yet. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7924 305967 hyperv/hn: Allow RSS capability flipping upon attach/reinit. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7927 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:03:53 2016 (r307244) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:19:47 2016 (r307245) @@ -466,9 +466,15 @@ hn_nvs_conf_ndis(struct hn_softc *sc, in /* NOTE: No response. */ error = hn_nvs_req_send(sc, &conf, sizeof(conf)); - if (error) + if (error) { if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); - return (error); + return (error); + } + + if (bootverbose) + if_printf(sc->hn_ifp, "nvs ndis conf done\n"); + sc->hn_caps |= HN_CAP_MTU | HN_CAP_VLAN; + return (0); } static int @@ -494,6 +500,22 @@ hn_nvs_init(struct hn_softc *sc) { int i; + if (device_is_attached(sc->hn_dev)) { + /* + * NVS version and NDIS version MUST NOT be changed. + */ + if (bootverbose) { + if_printf(sc->hn_ifp, "reinit NVS version 0x%x, " + "NDIS version %u.%u\n", sc->hn_nvs_ver, + HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), + HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); + } + return (hn_nvs_doinit(sc, sc->hn_nvs_ver)); + } + + /* + * Find the supported NVS version and set NDIS version accordingly. + */ for (i = 0; i < nitems(hn_nvs_version); ++i) { int error; Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:03:53 2016 (r307244) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:19:47 2016 (r307245) @@ -229,7 +229,8 @@ struct hn_softc { struct vmbus_xact_ctx *hn_xact; uint32_t hn_nvs_ver; - uint32_t hn_flags; + uint32_t hn_caps; /* HN_CAP_ */ + uint32_t hn_flags; /* HN_FLAG_ */ void *hn_rxbuf; uint32_t hn_rxbuf_gpadl; struct hyperv_dma hn_rxbuf_dma; @@ -245,6 +246,18 @@ struct hn_softc { #define HN_FLAG_RXBUF_CONNECTED 0x0001 #define HN_FLAG_CHIM_CONNECTED 0x0002 +#define HN_FLAG_HAS_RSSKEY 0x0004 +#define HN_FLAG_HAS_RSSIND 0x0008 + +#define HN_CAP_VLAN 0x0001 +#define HN_CAP_MTU 0x0002 +#define HN_CAP_IPCS 0x0004 +#define HN_CAP_TCP4CS 0x0008 +#define HN_CAP_TCP6CS 0x0010 +#define HN_CAP_UDP4CS 0x0020 +#define HN_CAP_UDP6CS 0x0040 +#define HN_CAP_TSO4 0x0080 +#define HN_CAP_TSO6 0x0100 /* * Externs Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:03:53 2016 (r307244) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:19:47 2016 (r307245) @@ -327,6 +327,7 @@ static int hn_rx_stat_ulong_sysctl(SYSCT static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS); static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); @@ -436,6 +437,8 @@ hn_rss_ind_fixup(struct hn_softc *sc, in struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; int i; + KASSERT(nchan > 1, ("invalid # of channels %d", nchan)); + /* * Check indirect table to make sure that all channels in it * can be used. @@ -657,6 +660,9 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_ndis_version_sysctl, "A", "NDIS version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "caps", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_caps_sysctl, "A", "capabilities"); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_rss_key_sysctl, "IU", "RSS key"); @@ -1588,6 +1594,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, HN_LOCK(sc); + if ((sc->hn_caps & HN_CAP_MTU) == 0) { + /* Can't change MTU */ + HN_UNLOCK(sc); + error = EOPNOTSUPP; + break; + } + if (ifp->if_mtu == ifr->ifr_mtu) { HN_UNLOCK(sc); break; @@ -2115,6 +2128,30 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_AR } static int +hn_caps_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char caps_str[128]; + uint32_t caps; + + HN_LOCK(sc); + caps = sc->hn_caps; + HN_UNLOCK(sc); + snprintf(caps_str, sizeof(caps_str), "%b", caps, + "\020" + "\001VLAN" + "\002MTU" + "\003IPCS" + "\004TCP4CS" + "\005TCP6CS" + "\006UDP4CS" + "\007UDP6CS" + "\010TSO4" + "\011TSO6"); + return sysctl_handle_string(oidp, caps_str, sizeof(caps_str), req); +} + +static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) { struct hn_softc *sc = arg1; @@ -2129,8 +2166,14 @@ hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) error = SYSCTL_IN(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key)); if (error) goto back; + sc->hn_flags |= HN_FLAG_HAS_RSSKEY; - error = hn_rss_reconfig(sc); + if (sc->hn_rx_ring_inuse > 1) { + error = hn_rss_reconfig(sc); + } else { + /* Not RSS capable, at least for now; just save the RSS key. */ + error = 0; + } back: HN_UNLOCK(sc); return (error); @@ -2148,9 +2191,19 @@ hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS) if (error || req->newptr == NULL) goto back; + /* + * Don't allow RSS indirect table change, if this interface is not + * RSS capable currently. + */ + if (sc->hn_rx_ring_inuse == 1) { + error = EOPNOTSUPP; + goto back; + } + error = SYSCTL_IN(req, sc->hn_rss.rss_ind, sizeof(sc->hn_rss.rss_ind)); if (error) goto back; + sc->hn_flags |= HN_FLAG_HAS_RSSIND; hn_rss_ind_fixup(sc, sc->hn_rx_ring_inuse); error = hn_rss_reconfig(sc); @@ -3243,6 +3296,11 @@ hn_synth_attach(struct hn_softc *sc, int { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; int error, nsubch, nchan, i; + uint32_t old_caps; + + /* Save capabilities for later verification. */ + old_caps = sc->hn_caps; + sc->hn_caps = 0; /* * Attach the primary channel _before_ attaching NVS and RNDIS. @@ -3266,6 +3324,17 @@ hn_synth_attach(struct hn_softc *sc, int return (error); /* + * Make sure capabilities are not changed. + */ + if (device_is_attached(sc->hn_dev) && old_caps != sc->hn_caps) { + if_printf(sc->hn_ifp, "caps mismatch old 0x%08x, new 0x%08x\n", + old_caps, sc->hn_caps); + /* Restore old capabilities and abort. */ + sc->hn_caps = old_caps; + return ENXIO; + } + + /* * Allocate sub-channels for multi-TX/RX rings. * * NOTE: @@ -3288,24 +3357,29 @@ hn_synth_attach(struct hn_softc *sc, int * are allocated. */ - if (!device_is_attached(sc->hn_dev)) { + if ((sc->hn_flags & HN_FLAG_HAS_RSSKEY) == 0) { /* - * Setup default RSS key and indirect table for the - * attach DEVMETHOD. They can be altered later on, - * so don't mess them up once this interface is attached. + * RSS key is not set yet; set it to the default RSS key. */ - if (bootverbose) { - if_printf(sc->hn_ifp, "setup default RSS key and " - "indirect table\n"); - } - - /* Setup default RSS key. */ + if (bootverbose) + if_printf(sc->hn_ifp, "setup default RSS key\n"); memcpy(rss->rss_key, hn_rss_key_default, sizeof(rss->rss_key)); + sc->hn_flags |= HN_FLAG_HAS_RSSKEY; + } - /* Setup default RSS indirect table. */ + if ((sc->hn_flags & HN_FLAG_HAS_RSSIND) == 0) { + /* + * RSS indirect table is not set yet; set it up in round- + * robin fashion. + */ + if (bootverbose) { + if_printf(sc->hn_ifp, "setup default RSS indirect " + "table\n"); + } /* TODO: Take ndis_rss_caps.ndis_nind into account. */ for (i = 0; i < NDIS_HASH_INDCNT; ++i) rss->rss_ind[i] = i % nchan; + sc->hn_flags |= HN_FLAG_HAS_RSSIND; } else { /* * # of usable channels may be changed, so we have to Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:03:53 2016 (r307244) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:19:47 2016 (r307245) @@ -801,6 +801,7 @@ static int hn_rndis_conf_offload(struct hn_softc *sc) { struct ndis_offload_params params; + uint32_t caps; size_t paramsz; int error; @@ -817,24 +818,29 @@ hn_rndis_conf_offload(struct hn_softc *s } params.ndis_hdr.ndis_size = paramsz; + caps = HN_CAP_IPCS | HN_CAP_TCP4CS | HN_CAP_TCP6CS; params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { + caps |= HN_CAP_UDP4CS | HN_CAP_UDP6CS; params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; } + caps |= HN_CAP_TSO4; params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; /* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); if (error) { if_printf(sc->hn_ifp, "offload config failed: %d\n", error); - } else { - if (bootverbose) - if_printf(sc->hn_ifp, "offload config done\n"); + return (error); } - return (error); + + if (bootverbose) + if_printf(sc->hn_ifp, "offload config done\n"); + sc->hn_caps |= caps; + return (0); } int From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:27:20 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A7A76C11399; Fri, 14 Oct 2016 02:27:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6A997F5D; Fri, 14 Oct 2016 02:27:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2RJBX049290; Fri, 14 Oct 2016 02:27:19 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2RJ10049288; Fri, 14 Oct 2016 02:27:19 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140227.u9E2RJ10049288@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:27:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307246 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:27:20 -0000 Author: sephe Date: Fri Oct 14 02:27:19 2016 New Revision: 307246 URL: https://svnweb.freebsd.org/changeset/base/307246 Log: MFC 306013,306014 306013 hyperv/hn: Fix ifnet hwassist setup. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7948 306014 hyperv/hn: Let the caller of hn_nvs_doinit() do the error logging. So that NVS version probing failure does not look too scary. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7950 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:19:47 2016 (r307245) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:27:19 2016 (r307246) @@ -443,8 +443,15 @@ hn_nvs_doinit(struct hn_softc *sc, uint3 vmbus_xact_put(xact); if (status != HN_NVS_STATUS_OK) { - if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n", - nvs_ver); + if (bootverbose) { + /* + * Caller may try another NVS version, and will log + * error if there are no more NVS versions to try, + * so don't bark out loud here. + */ + if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n", + nvs_ver); + } return (EINVAL); } return (0); @@ -498,7 +505,7 @@ hn_nvs_init_ndis(struct hn_softc *sc) static int hn_nvs_init(struct hn_softc *sc) { - int i; + int i, error; if (device_is_attached(sc->hn_dev)) { /* @@ -510,15 +517,19 @@ hn_nvs_init(struct hn_softc *sc) HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver), HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver)); } - return (hn_nvs_doinit(sc, sc->hn_nvs_ver)); + + error = hn_nvs_doinit(sc, sc->hn_nvs_ver); + if (error) { + if_printf(sc->hn_ifp, "reinit NVS version 0x%x " + "failed: %d\n", sc->hn_nvs_ver, error); + } + return (error); } /* * Find the supported NVS version and set NDIS version accordingly. */ for (i = 0; i < nitems(hn_nvs_version); ++i) { - int error; - error = hn_nvs_doinit(sc, hn_nvs_version[i]); if (!error) { sc->hn_nvs_ver = hn_nvs_version[i]; Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:19:47 2016 (r307245) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:27:19 2016 (r307246) @@ -182,14 +182,6 @@ struct hn_txdesc { #define HN_TXD_FLAG_ONLIST 0x1 #define HN_TXD_FLAG_DMAMAP 0x2 -/* - * Only enable UDP checksum offloading when it is on 2012R2 or - * later. UDP checksum offloading doesn't work on earlier - * Windows releases. - */ -#define HN_CSUM_ASSIST_WIN8 (CSUM_IP | CSUM_TCP) -#define HN_CSUM_ASSIST (CSUM_IP | CSUM_UDP | CSUM_TCP) - #define HN_LRO_LENLIM_MULTIRX_DEF (12 * ETHERMTU) #define HN_LRO_LENLIM_DEF (25 * ETHERMTU) /* YYY 2*MTU is a bit rough, but should be good enough. */ @@ -204,6 +196,13 @@ struct hn_txdesc { #define HN_LOCK(sc) sx_xlock(&(sc)->hn_lock) #define HN_UNLOCK(sc) sx_xunlock(&(sc)->hn_lock) +#define HN_CSUM_IP_MASK (CSUM_IP | CSUM_IP_TCP | CSUM_IP_UDP) +#define HN_CSUM_IP6_MASK (CSUM_IP6_TCP | CSUM_IP6_UDP) +#define HN_CSUM_IP_HWASSIST(sc) \ + ((sc)->hn_tx_ring[0].hn_csum_assist & HN_CSUM_IP_MASK) +#define HN_CSUM_IP6_HWASSIST(sc) \ + ((sc)->hn_tx_ring[0].hn_csum_assist & HN_CSUM_IP6_MASK) + /* * Globals */ @@ -328,12 +327,14 @@ static int hn_tx_stat_ulong_sysctl(SYSCT static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); static int hn_create_tx_ring(struct hn_softc *, int); static void hn_destroy_tx_ring(struct hn_tx_ring *); static int hn_create_tx_data(struct hn_softc *, int); +static void hn_fixup_tx_data(struct hn_softc *); static void hn_destroy_tx_data(struct hn_softc *); static void hn_start_taskfunc(void *, int); static void hn_start_txeof_taskfunc(void *, int); @@ -648,10 +649,10 @@ netvsc_attach(device_t dev) } #endif - hn_set_chim_size(sc, sc->hn_chim_szmax); - if (hn_tx_chimney_size > 0 && - hn_tx_chimney_size < sc->hn_chim_szmax) - hn_set_chim_size(sc, hn_tx_chimney_size); + /* + * Fixup TX stuffs after synthetic parts are attached. + */ + hn_fixup_tx_data(sc); ctx = device_get_sysctl_ctx(dev); child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); @@ -663,6 +664,9 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "caps", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_caps_sysctl, "A", "capabilities"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "hwassist", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_hwassist_sysctl, "A", "hwassist"); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_rss_key_sysctl, "IU", "RSS key"); @@ -697,13 +701,32 @@ netvsc_attach(device_t dev) ifp->if_qflush = hn_xmit_qflush; } - ifp->if_capabilities |= - IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO | - IFCAP_LRO; - ifp->if_capenable |= - IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO | - IFCAP_LRO; - ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO; + ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_LRO; +#ifdef foo + /* We can't diff IPv6 packets from IPv4 packets on RX path. */ + ifp->if_capabilities |= IFCAP_RXCSUM_IPV6; +#endif + if (sc->hn_caps & HN_CAP_VLAN) { + /* XXX not sure about VLAN_MTU. */ + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; + } + + ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist; + if (ifp->if_hwassist & HN_CSUM_IP_MASK) + ifp->if_capabilities |= IFCAP_TXCSUM; + if (ifp->if_hwassist & HN_CSUM_IP6_MASK) + ifp->if_capabilities |= IFCAP_TXCSUM_IPV6; + if (sc->hn_caps & HN_CAP_TSO4) { + ifp->if_capabilities |= IFCAP_TSO4; + ifp->if_hwassist |= CSUM_IP_TSO; + } + if (sc->hn_caps & HN_CAP_TSO6) { + ifp->if_capabilities |= IFCAP_TSO6; + ifp->if_hwassist |= CSUM_IP6_TSO; + } + + /* Enable all available capabilities by default. */ + ifp->if_capenable = ifp->if_capabilities; tso_maxlen = hn_tso_maxlen; if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET) @@ -1063,14 +1086,19 @@ hn_encap(struct hn_tx_ring *txr, struct } else if (m_head->m_pkthdr.csum_flags & txr->hn_csum_assist) { pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM); - *pi_data = NDIS_TXCSUM_INFO_IPV4; - - if (m_head->m_pkthdr.csum_flags & CSUM_IP) - *pi_data |= NDIS_TXCSUM_INFO_IPCS; + if (m_head->m_pkthdr.csum_flags & + (CSUM_IP6_TCP | CSUM_IP6_UDP)) { + *pi_data = NDIS_TXCSUM_INFO_IPV6; + } else { + *pi_data = NDIS_TXCSUM_INFO_IPV4; + if (m_head->m_pkthdr.csum_flags & CSUM_IP) + *pi_data |= NDIS_TXCSUM_INFO_IPCS; + } - if (m_head->m_pkthdr.csum_flags & CSUM_TCP) + if (m_head->m_pkthdr.csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP)) *pi_data |= NDIS_TXCSUM_INFO_TCPCS; - else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) + else if (m_head->m_pkthdr.csum_flags & + (CSUM_IP_UDP | CSUM_IP6_UDP)) *pi_data |= NDIS_TXCSUM_INFO_UDPCS; } @@ -1685,21 +1713,31 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, case SIOCSIFCAP: HN_LOCK(sc); - mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if (mask & IFCAP_TXCSUM) { ifp->if_capenable ^= IFCAP_TXCSUM; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= - sc->hn_tx_ring[0].hn_csum_assist; - } else { - ifp->if_hwassist &= - ~sc->hn_tx_ring[0].hn_csum_assist; - } + if (ifp->if_capenable & IFCAP_TXCSUM) + ifp->if_hwassist |= HN_CSUM_IP_HWASSIST(sc); + else + ifp->if_hwassist &= ~HN_CSUM_IP_HWASSIST(sc); + } + if (mask & IFCAP_TXCSUM_IPV6) { + ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; + if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) + ifp->if_hwassist |= HN_CSUM_IP6_HWASSIST(sc); + else + ifp->if_hwassist &= ~HN_CSUM_IP6_HWASSIST(sc); } + /* TODO: flip RNDIS offload parameters for RXCSUM. */ if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; +#ifdef foo + /* We can't diff IPv6 packets from IPv4 packets on RX path. */ + if (mask & IFCAP_RXCSUM_IPV6) + ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; +#endif if (mask & IFCAP_LRO) ifp->if_capenable ^= IFCAP_LRO; @@ -1711,7 +1749,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, else ifp->if_hwassist &= ~CSUM_IP_TSO; } - if (mask & IFCAP_TSO6) { ifp->if_capenable ^= IFCAP_TSO6; if (ifp->if_capenable & IFCAP_TSO6) @@ -2152,6 +2189,20 @@ hn_caps_sysctl(SYSCTL_HANDLER_ARGS) } static int +hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char assist_str[128]; + uint32_t hwassist; + + HN_LOCK(sc); + hwassist = sc->hn_ifp->if_hwassist; + HN_UNLOCK(sc); + snprintf(assist_str, sizeof(assist_str), "%b", hwassist, CSUM_BITS); + return sysctl_handle_string(oidp, assist_str, sizeof(assist_str), req); +} + +static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) { struct hn_softc *sc = arg1; @@ -2508,7 +2559,6 @@ hn_create_tx_ring(struct hn_softc *sc, i device_t dev = sc->hn_dev; bus_dma_tag_t parent_dtag; int error, i; - uint32_t version; txr->hn_sc = sc; txr->hn_tx_idx = id; @@ -2547,18 +2597,6 @@ hn_create_tx_ring(struct hn_softc *sc, i } txr->hn_direct_tx_size = hn_direct_tx_size; - version = VMBUS_GET_VERSION(device_get_parent(dev), dev); - if (version >= VMBUS_VERSION_WIN8_1) { - txr->hn_csum_assist = HN_CSUM_ASSIST; - } else { - txr->hn_csum_assist = HN_CSUM_ASSIST_WIN8; - if (id == 0) { - device_printf(dev, "bus version %u.%u, " - "no UDP checksum offloading\n", - VMBUS_VERSION_MAJOR(version), - VMBUS_VERSION_MINOR(version)); - } - } /* * Always schedule transmission instead of trying to do direct @@ -2854,6 +2892,35 @@ hn_set_chim_size(struct hn_softc *sc, in } static void +hn_fixup_tx_data(struct hn_softc *sc) +{ + uint64_t csum_assist; + int i; + + hn_set_chim_size(sc, sc->hn_chim_szmax); + if (hn_tx_chimney_size > 0 && + hn_tx_chimney_size < sc->hn_chim_szmax) + hn_set_chim_size(sc, hn_tx_chimney_size); + + csum_assist = 0; + if (sc->hn_caps & HN_CAP_IPCS) + csum_assist |= CSUM_IP; + if (sc->hn_caps & HN_CAP_TCP4CS) + csum_assist |= CSUM_IP_TCP; + if (sc->hn_caps & HN_CAP_UDP4CS) + csum_assist |= CSUM_IP_UDP; +#ifdef notyet + if (sc->hn_caps & HN_CAP_TCP6CS) + csum_assist |= CSUM_IP6_TCP; + if (sc->hn_caps & HN_CAP_UDP6CS) + csum_assist |= CSUM_IP6_UDP; +#endif + + for (i = 0; i < sc->hn_tx_ring_cnt; ++i) + sc->hn_tx_ring[i].hn_csum_assist = csum_assist; +} + +static void hn_destroy_tx_data(struct hn_softc *sc) { int i; From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:34:05 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7B24AC11541; Fri, 14 Oct 2016 02:34:05 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5639C6A7; Fri, 14 Oct 2016 02:34:05 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2Y4mG052951; Fri, 14 Oct 2016 02:34:04 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2Y4Na052947; Fri, 14 Oct 2016 02:34:04 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140234.u9E2Y4Na052947@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:34:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307247 - in stable/10/sys/dev/hyperv: include netvsc vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:34:05 -0000 Author: sephe Date: Fri Oct 14 02:34:03 2016 New Revision: 307247 URL: https://svnweb.freebsd.org/changeset/base/307247 Log: MFC 306072-306074,306076 306072 hyperv/vmbus: Allow bufrings preallocation. The assumption that the channel is only opened upon synthetic device attach time no longer holds, e.g. Hyper-V network device MTU changes. We have to allow device drivers to preallocate bufrings, e.g. in attach DEVMETHOD, to prevent bufring allocation failure once the system memory is fragmented after running for a while. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7960 306073 hyperv/hn: Allocate bufrings in attach DEVMETHOD. So that reinitialization, e.g. MTU change, will not fail when the system memory is excessively fragmented. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7961 306074 hyperv/vmbus: Assert that the bufring address is page aligned. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7962 306076 hyperv/hn: Put debug messages under bootverbose While I'm here, strip blank line. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7963 Modified: stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Fri Oct 14 02:27:19 2016 (r307246) +++ stable/10/sys/dev/hyperv/include/vmbus.h Fri Oct 14 02:34:03 2016 (r307247) @@ -109,6 +109,13 @@ struct vmbus_chanpkt_rxbuf { struct vmbus_rxbuf_desc cp_rxbuf[]; } __packed; +struct vmbus_chan_br { + void *cbr; + bus_addr_t cbr_paddr; + int cbr_txsz; + int cbr_rxsz; +}; + struct vmbus_channel; struct hyperv_guid; @@ -123,6 +130,9 @@ vmbus_get_channel(device_t dev) int vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size, const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg); +int vmbus_chan_open_br(struct vmbus_channel *chan, + const struct vmbus_chan_br *cbr, const void *udata, + int udlen, vmbus_chan_callback_t cb, void *cbarg); void vmbus_chan_close(struct vmbus_channel *chan); int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:27:19 2016 (r307246) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:34:03 2016 (r307247) @@ -136,6 +136,9 @@ struct hn_rx_ring { /* Rarely used stuffs */ struct sysctl_oid *hn_rx_sysctl_tree; int hn_rx_flags; + + void *hn_br; /* TX/RX bufring */ + struct hyperv_dma hn_br_dma; } __aligned(CACHE_LINE_SIZE); #define HN_TRUST_HCSUM_IP 0x0001 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:27:19 2016 (r307246) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:34:03 2016 (r307247) @@ -2378,7 +2378,8 @@ hn_create_rx_data(struct hn_softc *sc, i lroent_cnt = hn_lro_entry_count; if (lroent_cnt < TCP_LRO_ENTRIES) lroent_cnt = TCP_LRO_ENTRIES; - device_printf(dev, "LRO: entry count %d\n", lroent_cnt); + if (bootverbose) + device_printf(dev, "LRO: entry count %d\n", lroent_cnt); #endif #endif /* INET || INET6 */ @@ -2392,6 +2393,16 @@ hn_create_rx_data(struct hn_softc *sc, i for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; + rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev), + PAGE_SIZE, 0, + NETVSC_DEVICE_RING_BUFFER_SIZE + + NETVSC_DEVICE_RING_BUFFER_SIZE, + &rxr->hn_br_dma, BUS_DMA_WAITOK); + if (rxr->hn_br == NULL) { + device_printf(dev, "allocate bufring failed\n"); + return (ENOMEM); + } + if (hn_trust_hosttcp) rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_TCP; if (hn_trust_hostudp) @@ -2540,6 +2551,11 @@ hn_destroy_rx_data(struct hn_softc *sc) for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; + if (rxr->hn_br == NULL) + continue; + hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br); + rxr->hn_br = NULL; + #if defined(INET) || defined(INET6) tcp_lro_free(&rxr->hn_lro); #endif @@ -3145,6 +3161,7 @@ hn_xmit_txeof_taskfunc(void *xtxr, int p static int hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan) { + struct vmbus_chan_br cbr; struct hn_rx_ring *rxr; struct hn_tx_ring *txr = NULL; int idx, error; @@ -3183,9 +3200,14 @@ hn_chan_attach(struct hn_softc *sc, stru /* Bind this channel to a proper CPU. */ vmbus_chan_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus); - /* Open this channel */ - error = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, - NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hn_chan_callback, rxr); + /* + * Open this channel + */ + cbr.cbr = rxr->hn_br; + cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr; + cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE; + cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE; + error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr); if (error) { if_printf(sc->hn_ifp, "open chan%u failed: %d\n", vmbus_chan_id(chan), error); @@ -3328,8 +3350,10 @@ hn_synth_alloc_subchans(struct hn_softc *nsubch = 0; return (0); } - if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n", - rxr_cnt, nchan); + if (bootverbose) { + if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n", + rxr_cnt, nchan); + } if (nchan > rxr_cnt) nchan = rxr_cnt; @@ -3338,7 +3362,7 @@ hn_synth_alloc_subchans(struct hn_softc *nsubch = 0; return (0); } - + /* * Allocate sub-channels from NVS. */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Fri Oct 14 02:27:19 2016 (r307246) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Fri Oct 14 02:34:03 2016 (r307247) @@ -196,13 +196,45 @@ int vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size, const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg) { + struct vmbus_chan_br cbr; + int error; + + /* + * Allocate the TX+RX bufrings. + */ + KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated")); + chan->ch_bufring = hyperv_dmamem_alloc(bus_get_dma_tag(chan->ch_dev), + PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, + BUS_DMA_WAITOK); + if (chan->ch_bufring == NULL) { + device_printf(chan->ch_dev, "bufring allocation failed\n"); + return (ENOMEM); + } + + cbr.cbr = chan->ch_bufring; + cbr.cbr_paddr = chan->ch_bufring_dma.hv_paddr; + cbr.cbr_txsz = txbr_size; + cbr.cbr_rxsz = rxbr_size; + + error = vmbus_chan_open_br(chan, &cbr, udata, udlen, cb, cbarg); + if (error) { + hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); + chan->ch_bufring = NULL; + } + return (error); +} + +int +vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, + const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg) +{ struct vmbus_softc *sc = chan->ch_vmbus; const struct vmbus_chanmsg_chopen_resp *resp; const struct vmbus_message *msg; struct vmbus_chanmsg_chopen *req; struct vmbus_msghc *mh; uint32_t status; - int error; + int error, txbr_size, rxbr_size; uint8_t *br; if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { @@ -210,10 +242,21 @@ vmbus_chan_open(struct vmbus_channel *ch "invalid udata len %d for chan%u\n", udlen, chan->ch_id); return EINVAL; } + + br = cbr->cbr; + txbr_size = cbr->cbr_txsz; + rxbr_size = cbr->cbr_rxsz; KASSERT((txbr_size & PAGE_MASK) == 0, ("send bufring size is not multiple page")); KASSERT((rxbr_size & PAGE_MASK) == 0, ("recv bufring size is not multiple page")); + KASSERT((cbr->cbr_paddr & PAGE_MASK) == 0, + ("bufring is not page aligned")); + + /* + * Zero out the TX/RX bufrings, in case that they were used before. + */ + memset(br, 0, txbr_size + rxbr_size); if (atomic_testandset_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED_SHIFT)) @@ -230,20 +273,6 @@ vmbus_chan_open(struct vmbus_channel *ch else TASK_INIT(&chan->ch_task, 0, vmbus_chan_task_nobatch, chan); - /* - * Allocate the TX+RX bufrings. - * XXX should use ch_dev dtag - */ - br = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), - PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, - BUS_DMA_WAITOK | BUS_DMA_ZERO); - if (br == NULL) { - device_printf(sc->vmbus_dev, "bufring allocation failed\n"); - error = ENOMEM; - goto failed; - } - chan->ch_bufring = br; - /* TX bufring comes first */ vmbus_txbr_setup(&chan->ch_txbr, br, txbr_size); /* RX bufring immediately follows TX bufring */ @@ -255,7 +284,7 @@ vmbus_chan_open(struct vmbus_channel *ch /* * Connect the bufrings, both RX and TX, to this channel. */ - error = vmbus_chan_gpadl_connect(chan, chan->ch_bufring_dma.hv_paddr, + error = vmbus_chan_gpadl_connect(chan, cbr->cbr_paddr, txbr_size + rxbr_size, &chan->ch_bufring_gpadl); if (error) { device_printf(sc->vmbus_dev, @@ -316,10 +345,6 @@ failed: vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); chan->ch_bufring_gpadl = 0; } - if (chan->ch_bufring != NULL) { - hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); - chan->ch_bufring = NULL; - } atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); return error; } From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:36:52 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E4842C115BA; Fri, 14 Oct 2016 02:36:52 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B5F158A0; Fri, 14 Oct 2016 02:36:52 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2ap1l053121; Fri, 14 Oct 2016 02:36:51 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2apq2053120; Fri, 14 Oct 2016 02:36:51 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140236.u9E2apq2053120@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:36:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307248 - stable/10/sys/dev/pci X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:36:53 -0000 Author: sephe Date: Fri Oct 14 02:36:51 2016 New Revision: 307248 URL: https://svnweb.freebsd.org/changeset/base/307248 Log: MFC 306359 pci: Clear the MEM/PORT_EN bit when updating PCI BAR It's unsafe to update the BAR when the related EN bit is set. Submitted by: Dexuan Cui Reviewed by: jhb Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7914 Modified: stable/10/sys/dev/pci/pci.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/pci/pci.c ============================================================================== --- stable/10/sys/dev/pci/pci.c Fri Oct 14 02:34:03 2016 (r307247) +++ stable/10/sys/dev/pci/pci.c Fri Oct 14 02:36:51 2016 (r307248) @@ -4576,6 +4576,7 @@ pci_reserve_map(device_t dev, device_t c struct resource_list *rl = &dinfo->resources; struct resource *res; struct pci_map *pm; + uint16_t cmd; pci_addr_t map, testval; int mapsize; @@ -4660,8 +4661,17 @@ pci_reserve_map(device_t dev, device_t c device_printf(child, "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n", count, *rid, type, rman_get_start(res)); + + /* Disable decoding via the CMD register before updating the BAR */ + cmd = pci_read_config(child, PCIR_COMMAND, 2); + pci_write_config(child, PCIR_COMMAND, + cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2); + map = rman_get_start(res); pci_write_bar(child, pm, map); + + /* Restore the original value of the CMD register */ + pci_write_config(child, PCIR_COMMAND, cmd, 2); out: return (res); } From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:42:10 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 99C1BC11766; Fri, 14 Oct 2016 02:42:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3C92CB85; Fri, 14 Oct 2016 02:42:10 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2g97K055495; Fri, 14 Oct 2016 02:42:09 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2g8Ag054689; Fri, 14 Oct 2016 02:42:08 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140242.u9E2g8Ag054689@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:42:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307249 - in stable/10/sys/dev/hyperv: include vmbus X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:42:10 -0000 Author: sephe Date: Fri Oct 14 02:42:08 2016 New Revision: 307249 URL: https://svnweb.freebsd.org/changeset/base/307249 Log: MFC 306360,306387,306389 306360 hyperv/vmbus: Add dynamic device add and remove support Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8008 306387 hyperv/vmbus: Add functions to test RX/TX bufring emptiness Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8044 306389 hyperv/vmbus: Add function to drain channel interrupt task. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8045 Modified: stable/10/sys/dev/hyperv/include/vmbus.h stable/10/sys/dev/hyperv/vmbus/vmbus.c stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/include/vmbus.h ============================================================================== --- stable/10/sys/dev/hyperv/include/vmbus.h Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/include/vmbus.h Fri Oct 14 02:42:08 2016 (r307249) @@ -134,6 +134,7 @@ int vmbus_chan_open_br(struct vmbus_cha const struct vmbus_chan_br *cbr, const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg); void vmbus_chan_close(struct vmbus_channel *chan); +void vmbus_chan_intr_drain(struct vmbus_channel *chan); int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, int size, uint32_t *gpadl); @@ -174,5 +175,7 @@ const struct hyperv_guid * vmbus_chan_guid_inst(const struct vmbus_channel *chan); int vmbus_chan_prplist_nelem(int br_size, int prpcnt_max, int dlen_max); +bool vmbus_chan_rx_empty(const struct vmbus_channel *chan); +bool vmbus_chan_tx_empty(const struct vmbus_channel *chan); #endif /* !_VMBUS_H_ */ Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus.c Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/vmbus/vmbus.c Fri Oct 14 02:42:08 2016 (r307249) @@ -85,9 +85,7 @@ static int vmbus_connect(struct vmbus_ static int vmbus_req_channels(struct vmbus_softc *sc); static void vmbus_disconnect(struct vmbus_softc *); static int vmbus_scan(struct vmbus_softc *); -static void vmbus_scan_wait(struct vmbus_softc *); -static void vmbus_scan_newchan(struct vmbus_softc *); -static void vmbus_scan_newdev(struct vmbus_softc *); +static void vmbus_scan_teardown(struct vmbus_softc *); static void vmbus_scan_done(struct vmbus_softc *, const struct vmbus_message *); static void vmbus_chanmsg_handle(struct vmbus_softc *, @@ -395,50 +393,22 @@ vmbus_req_channels(struct vmbus_softc *s } static void -vmbus_scan_newchan(struct vmbus_softc *sc) +vmbus_scan_done_task(void *xsc, int pending __unused) { - mtx_lock(&sc->vmbus_scan_lock); - if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) - sc->vmbus_scan_chcnt++; - mtx_unlock(&sc->vmbus_scan_lock); + struct vmbus_softc *sc = xsc; + + mtx_lock(&Giant); + sc->vmbus_scandone = true; + mtx_unlock(&Giant); + wakeup(&sc->vmbus_scandone); } static void vmbus_scan_done(struct vmbus_softc *sc, const struct vmbus_message *msg __unused) { - mtx_lock(&sc->vmbus_scan_lock); - sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE; - mtx_unlock(&sc->vmbus_scan_lock); - wakeup(&sc->vmbus_scan_chcnt); -} - -static void -vmbus_scan_newdev(struct vmbus_softc *sc) -{ - mtx_lock(&sc->vmbus_scan_lock); - sc->vmbus_scan_devcnt++; - mtx_unlock(&sc->vmbus_scan_lock); - wakeup(&sc->vmbus_scan_devcnt); -} - -static void -vmbus_scan_wait(struct vmbus_softc *sc) -{ - uint32_t chancnt; - - mtx_lock(&sc->vmbus_scan_lock); - while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) { - mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0, - "waitch", 0); - } - chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE; - while (sc->vmbus_scan_devcnt != chancnt) { - mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0, - "waitdev", 0); - } - mtx_unlock(&sc->vmbus_scan_lock); + taskqueue_enqueue(sc->vmbus_devtq, &sc->vmbus_scandone_task); } static int @@ -447,31 +417,71 @@ vmbus_scan(struct vmbus_softc *sc) int error; /* + * Identify, probe and attach for non-channel devices. + */ + bus_generic_probe(sc->vmbus_dev); + bus_generic_attach(sc->vmbus_dev); + + /* + * This taskqueue serializes vmbus devices' attach and detach + * for channel offer and rescind messages. + */ + sc->vmbus_devtq = taskqueue_create("vmbus dev", M_WAITOK, + taskqueue_thread_enqueue, &sc->vmbus_devtq); + taskqueue_start_threads(&sc->vmbus_devtq, 1, PI_NET, "vmbusdev"); + TASK_INIT(&sc->vmbus_scandone_task, 0, vmbus_scan_done_task, sc); + + /* + * This taskqueue handles sub-channel detach, so that vmbus + * device's detach running in vmbus_devtq can drain its sub- + * channels. + */ + sc->vmbus_subchtq = taskqueue_create("vmbus subch", M_WAITOK, + taskqueue_thread_enqueue, &sc->vmbus_subchtq); + taskqueue_start_threads(&sc->vmbus_subchtq, 1, PI_NET, "vmbussch"); + + /* * Start vmbus scanning. */ error = vmbus_req_channels(sc); if (error) { device_printf(sc->vmbus_dev, "channel request failed: %d\n", error); - return error; + return (error); } /* - * Wait for all devices are added to vmbus. + * Wait for all vmbus devices from the initial channel offers to be + * attached. */ - vmbus_scan_wait(sc); - - /* - * Identify, probe and attach. - */ - bus_generic_probe(sc->vmbus_dev); - bus_generic_attach(sc->vmbus_dev); + GIANT_REQUIRED; + while (!sc->vmbus_scandone) + mtx_sleep(&sc->vmbus_scandone, &Giant, 0, "vmbusdev", 0); if (bootverbose) { device_printf(sc->vmbus_dev, "device scan, probe and attach " "done\n"); } - return 0; + return (0); +} + +static void +vmbus_scan_teardown(struct vmbus_softc *sc) +{ + + GIANT_REQUIRED; + if (sc->vmbus_devtq != NULL) { + mtx_unlock(&Giant); + taskqueue_free(sc->vmbus_devtq); + mtx_lock(&Giant); + sc->vmbus_devtq = NULL; + } + if (sc->vmbus_subchtq != NULL) { + mtx_unlock(&Giant); + taskqueue_free(sc->vmbus_subchtq); + mtx_lock(&Giant); + sc->vmbus_subchtq = NULL; + } } static void @@ -1000,45 +1010,35 @@ vmbus_add_child(struct vmbus_channel *ch { struct vmbus_softc *sc = chan->ch_vmbus; device_t parent = sc->vmbus_dev; - int error = 0; - /* New channel has been offered */ - vmbus_scan_newchan(sc); + mtx_lock(&Giant); chan->ch_dev = device_add_child(parent, NULL, -1); if (chan->ch_dev == NULL) { + mtx_unlock(&Giant); device_printf(parent, "device_add_child for chan%u failed\n", chan->ch_id); - error = ENXIO; - goto done; + return (ENXIO); } device_set_ivars(chan->ch_dev, chan); + device_probe_and_attach(chan->ch_dev); -done: - /* New device has been/should be added to vmbus. */ - vmbus_scan_newdev(sc); - return error; + mtx_unlock(&Giant); + return (0); } int vmbus_delete_child(struct vmbus_channel *chan) { - int error; - - if (chan->ch_dev == NULL) { - /* Failed to add a device. */ - return 0; - } + int error = 0; - /* - * XXXKYS: Ensure that this is the opposite of - * device_add_child() - */ mtx_lock(&Giant); - error = device_delete_child(chan->ch_vmbus->vmbus_dev, chan->ch_dev); + if (chan->ch_dev != NULL) { + error = device_delete_child(chan->ch_vmbus->vmbus_dev, + chan->ch_dev); + } mtx_unlock(&Giant); - - return error; + return (error); } static int @@ -1110,10 +1110,11 @@ vmbus_doattach(struct vmbus_softc *sc) return (0); sc->vmbus_flags |= VMBUS_FLAG_ATTACHED; - mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF); sc->vmbus_gpadl = VMBUS_GPADL_START; mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF); TAILQ_INIT(&sc->vmbus_prichans); + mtx_init(&sc->vmbus_chan_lock, "vmbus channel", NULL, MTX_DEF); + TAILQ_INIT(&sc->vmbus_chans); sc->vmbus_chmap = malloc( sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); @@ -1177,6 +1178,7 @@ vmbus_doattach(struct vmbus_softc *sc) return (ret); cleanup: + vmbus_scan_teardown(sc); vmbus_intr_teardown(sc); vmbus_dma_free(sc); if (sc->vmbus_xc != NULL) { @@ -1184,8 +1186,8 @@ cleanup: sc->vmbus_xc = NULL; } free(sc->vmbus_chmap, M_DEVBUF); - mtx_destroy(&sc->vmbus_scan_lock); mtx_destroy(&sc->vmbus_prichan_lock); + mtx_destroy(&sc->vmbus_chan_lock); return (ret); } @@ -1225,8 +1227,11 @@ vmbus_detach(device_t dev) { struct vmbus_softc *sc = device_get_softc(dev); + bus_generic_detach(dev); vmbus_chan_destroy_all(sc); + vmbus_scan_teardown(sc); + vmbus_disconnect(sc); if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) { @@ -1243,8 +1248,8 @@ vmbus_detach(device_t dev) } free(sc->vmbus_chmap, M_DEVBUF); - mtx_destroy(&sc->vmbus_scan_lock); mtx_destroy(&sc->vmbus_prichan_lock); + mtx_destroy(&sc->vmbus_chan_lock); return (0); } Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h Fri Oct 14 02:42:08 2016 (r307249) @@ -83,6 +83,20 @@ vmbus_txbr_maxpktsz(const struct vmbus_t return (tbr->txbr_dsize - sizeof(uint64_t) - 1); } +static __inline bool +vmbus_txbr_empty(const struct vmbus_txbr *tbr) +{ + + return (tbr->txbr_windex == tbr->txbr_rindex ? true : false); +} + +static __inline bool +vmbus_rxbr_empty(const struct vmbus_rxbr *rbr) +{ + + return (rbr->rxbr_windex == rbr->rxbr_rindex ? true : false); +} + static __inline int vmbus_br_nelem(int br_size, int elem_size) { Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c Fri Oct 14 02:42:08 2016 (r307249) @@ -59,10 +59,30 @@ static struct vmbus_channel *vmbus_chan_ static void vmbus_chan_free(struct vmbus_channel *); static int vmbus_chan_add(struct vmbus_channel *); static void vmbus_chan_cpu_default(struct vmbus_channel *); +static int vmbus_chan_release(struct vmbus_channel *); +static void vmbus_chan_set_chmap(struct vmbus_channel *); +static void vmbus_chan_clear_chmap(struct vmbus_channel *); + +static void vmbus_chan_ins_prilist(struct vmbus_softc *, + struct vmbus_channel *); +static void vmbus_chan_rem_prilist(struct vmbus_softc *, + struct vmbus_channel *); +static void vmbus_chan_ins_list(struct vmbus_softc *, + struct vmbus_channel *); +static void vmbus_chan_rem_list(struct vmbus_softc *, + struct vmbus_channel *); +static void vmbus_chan_ins_sublist(struct vmbus_channel *, + struct vmbus_channel *); +static void vmbus_chan_rem_sublist(struct vmbus_channel *, + struct vmbus_channel *); static void vmbus_chan_task(void *, int); static void vmbus_chan_task_nobatch(void *, int); -static void vmbus_chan_detach_task(void *, int); +static void vmbus_chan_clrchmap_task(void *, int); +static void vmbus_prichan_attach_task(void *, int); +static void vmbus_subchan_attach_task(void *, int); +static void vmbus_prichan_detach_task(void *, int); +static void vmbus_subchan_detach_task(void *, int); static void vmbus_chan_msgproc_choffer(struct vmbus_softc *, const struct vmbus_message *); @@ -96,6 +116,83 @@ vmbus_chan_signal_tx(const struct vmbus_ hypercall_signal_event(chan->ch_monprm_dma.hv_paddr); } +static void +vmbus_chan_ins_prilist(struct vmbus_softc *sc, struct vmbus_channel *chan) +{ + + mtx_assert(&sc->vmbus_prichan_lock, MA_OWNED); + if (atomic_testandset_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONPRIL_SHIFT)) + panic("channel is already on the prilist"); + TAILQ_INSERT_TAIL(&sc->vmbus_prichans, chan, ch_prilink); +} + +static void +vmbus_chan_rem_prilist(struct vmbus_softc *sc, struct vmbus_channel *chan) +{ + + mtx_assert(&sc->vmbus_prichan_lock, MA_OWNED); + if (atomic_testandclear_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONPRIL_SHIFT) == 0) + panic("channel is not on the prilist"); + TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink); +} + +static void +vmbus_chan_ins_sublist(struct vmbus_channel *prichan, + struct vmbus_channel *chan) +{ + + mtx_assert(&prichan->ch_subchan_lock, MA_OWNED); + + if (atomic_testandset_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONSUBL_SHIFT)) + panic("channel is already on the sublist"); + TAILQ_INSERT_TAIL(&prichan->ch_subchans, chan, ch_sublink); + + /* Bump sub-channel count. */ + prichan->ch_subchan_cnt++; +} + +static void +vmbus_chan_rem_sublist(struct vmbus_channel *prichan, + struct vmbus_channel *chan) +{ + + mtx_assert(&prichan->ch_subchan_lock, MA_OWNED); + + KASSERT(prichan->ch_subchan_cnt > 0, + ("invalid subchan_cnt %d", prichan->ch_subchan_cnt)); + prichan->ch_subchan_cnt--; + + if (atomic_testandclear_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONSUBL_SHIFT) == 0) + panic("channel is not on the sublist"); + TAILQ_REMOVE(&prichan->ch_subchans, chan, ch_sublink); +} + +static void +vmbus_chan_ins_list(struct vmbus_softc *sc, struct vmbus_channel *chan) +{ + + mtx_assert(&sc->vmbus_chan_lock, MA_OWNED); + if (atomic_testandset_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONLIST_SHIFT)) + panic("channel is already on the list"); + TAILQ_INSERT_TAIL(&sc->vmbus_chans, chan, ch_link); +} + +static void +vmbus_chan_rem_list(struct vmbus_softc *sc, struct vmbus_channel *chan) +{ + + mtx_assert(&sc->vmbus_chan_lock, MA_OWNED); + if (atomic_testandclear_int(&chan->ch_stflags, + VMBUS_CHAN_ST_ONLIST_SHIFT) == 0) + panic("channel is not on the list"); + TAILQ_REMOVE(&sc->vmbus_chans, chan, ch_link); +} + static int vmbus_chan_sysctl_mnf(SYSCTL_HANDLER_ARGS) { @@ -235,6 +332,7 @@ vmbus_chan_open_br(struct vmbus_channel struct vmbus_msghc *mh; uint32_t status; int error, txbr_size, rxbr_size; + task_fn_t *task_fn; uint8_t *br; if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { @@ -269,9 +367,10 @@ vmbus_chan_open_br(struct vmbus_channel chan->ch_tq = VMBUS_PCPU_GET(chan->ch_vmbus, event_tq, chan->ch_cpuid); if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) - TASK_INIT(&chan->ch_task, 0, vmbus_chan_task, chan); + task_fn = vmbus_chan_task; else - TASK_INIT(&chan->ch_task, 0, vmbus_chan_task_nobatch, chan); + task_fn = vmbus_chan_task_nobatch; + TASK_INIT(&chan->ch_task, 0, task_fn, chan); /* TX bufring comes first */ vmbus_txbr_setup(&chan->ch_txbr, br, txbr_size); @@ -293,6 +392,12 @@ vmbus_chan_open_br(struct vmbus_channel } /* + * Install this channel, before it is opened, but after everything + * else has been setup. + */ + vmbus_chan_set_chmap(chan); + + /* * Open channel w/ the bufring GPADL on the target CPU. */ mh = vmbus_msghc_get(sc, sizeof(*req)); @@ -341,6 +446,7 @@ vmbus_chan_open_br(struct vmbus_channel error = ENXIO; failed: + vmbus_chan_clear_chmap(chan); if (chan->ch_bufring_gpadl) { vmbus_chan_gpadl_disconnect(chan, chan->ch_bufring_gpadl); chan->ch_bufring_gpadl = 0; @@ -517,12 +623,38 @@ vmbus_chan_gpadl_disconnect(struct vmbus } static void +vmbus_chan_clrchmap_task(void *xchan, int pending __unused) +{ + struct vmbus_channel *chan = xchan; + + critical_enter(); + chan->ch_vmbus->vmbus_chmap[chan->ch_id] = NULL; + critical_exit(); +} + +static void +vmbus_chan_clear_chmap(struct vmbus_channel *chan) +{ + struct task chmap_task; + + TASK_INIT(&chmap_task, 0, vmbus_chan_clrchmap_task, chan); + taskqueue_enqueue(chan->ch_tq, &chmap_task); + taskqueue_drain(chan->ch_tq, &chmap_task); +} + +static void +vmbus_chan_set_chmap(struct vmbus_channel *chan) +{ + __compiler_membar(); + chan->ch_vmbus->vmbus_chmap[chan->ch_id] = chan; +} + +static void vmbus_chan_close_internal(struct vmbus_channel *chan) { struct vmbus_softc *sc = chan->ch_vmbus; struct vmbus_msghc *mh; struct vmbus_chanmsg_chclose *req; - struct taskqueue *tq = chan->ch_tq; int error; /* TODO: stringent check */ @@ -535,12 +667,14 @@ vmbus_chan_close_internal(struct vmbus_c sysctl_ctx_free(&chan->ch_sysctl_ctx); /* - * Set ch_tq to NULL to avoid more requests be scheduled. - * XXX pretty broken; need rework. + * NOTE: + * Order is critical. This channel _must_ be uninstalled first, + * else the channel task may be enqueued by the IDT after it has + * been drained. */ + vmbus_chan_clear_chmap(chan); + taskqueue_drain(chan->ch_tq, &chan->ch_task); chan->ch_tq = NULL; - taskqueue_drain(tq, &chan->ch_task); - chan->ch_cb = NULL; /* * Close this channel. @@ -622,6 +756,13 @@ vmbus_chan_close(struct vmbus_channel *c vmbus_chan_close_internal(chan); } +void +vmbus_chan_intr_drain(struct vmbus_channel *chan) +{ + + taskqueue_drain(chan->ch_tq, &chan->ch_task); +} + int vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, uint16_t flags, void *data, int dlen, uint64_t xactid) @@ -884,10 +1025,11 @@ vmbus_event_flags_proc(struct vmbus_soft flags &= ~(1UL << chid_ofs); chan = sc->vmbus_chmap[chid_base + chid_ofs]; - - /* if channel is closed or closing */ - if (chan == NULL || chan->ch_tq == NULL) + if (__predict_false(chan == NULL)) { + /* Channel is closed. */ continue; + } + __compiler_membar(); if (chan->ch_flags & VMBUS_CHAN_FLAG_BATCHREAD) vmbus_rxbr_intr_mask(&chan->ch_rxbr); @@ -968,7 +1110,6 @@ vmbus_chan_alloc(struct vmbus_softc *sc) chan->ch_vmbus = sc; mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); TAILQ_INIT(&chan->ch_subchans); - TASK_INIT(&chan->ch_detach_task, 0, vmbus_chan_detach_task, chan); vmbus_rxbr_init(&chan->ch_rxbr); vmbus_txbr_init(&chan->ch_txbr); @@ -978,9 +1119,14 @@ vmbus_chan_alloc(struct vmbus_softc *sc) static void vmbus_chan_free(struct vmbus_channel *chan) { - /* TODO: assert sub-channel list is empty */ - /* TODO: asset no longer on the primary channel's sub-channel list */ - /* TODO: asset no longer on the vmbus channel list */ + + KASSERT(TAILQ_EMPTY(&chan->ch_subchans) && chan->ch_subchan_cnt == 0, + ("still owns sub-channels")); + KASSERT((chan->ch_stflags & + (VMBUS_CHAN_ST_OPENED | + VMBUS_CHAN_ST_ONPRIL | + VMBUS_CHAN_ST_ONSUBL | + VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel")); hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); mtx_destroy(&chan->ch_subchan_lock); vmbus_rxbr_deinit(&chan->ch_rxbr); @@ -1007,7 +1153,6 @@ vmbus_chan_add(struct vmbus_channel *new newchan->ch_id); return EINVAL; } - sc->vmbus_chmap[newchan->ch_id] = newchan; if (bootverbose) { device_printf(sc->vmbus_dev, "chan%u subidx%u offer\n", @@ -1029,10 +1174,9 @@ vmbus_chan_add(struct vmbus_channel *new if (VMBUS_CHAN_ISPRIMARY(newchan)) { if (prichan == NULL) { /* Install the new primary channel */ - TAILQ_INSERT_TAIL(&sc->vmbus_prichans, newchan, - ch_prilink); + vmbus_chan_ins_prilist(sc, newchan); mtx_unlock(&sc->vmbus_prichan_lock); - return 0; + goto done; } else { mtx_unlock(&sc->vmbus_prichan_lock); device_printf(sc->vmbus_dev, "duplicated primary " @@ -1066,16 +1210,20 @@ vmbus_chan_add(struct vmbus_channel *new newchan->ch_dev = prichan->ch_dev; mtx_lock(&prichan->ch_subchan_lock); - TAILQ_INSERT_TAIL(&prichan->ch_subchans, newchan, ch_sublink); + vmbus_chan_ins_sublist(prichan, newchan); + mtx_unlock(&prichan->ch_subchan_lock); /* - * Bump up sub-channel count and notify anyone that is - * interested in this sub-channel, after this sub-channel - * is setup. + * Notify anyone that is interested in this sub-channel, + * after this sub-channel is setup. */ - prichan->ch_subchan_cnt++; - mtx_unlock(&prichan->ch_subchan_lock); wakeup(prichan); - +done: + /* + * Hook this channel up for later rescind. + */ + mtx_lock(&sc->vmbus_chan_lock); + vmbus_chan_ins_list(sc, newchan); + mtx_unlock(&sc->vmbus_chan_lock); return 0; } @@ -1126,6 +1274,7 @@ vmbus_chan_msgproc_choffer(struct vmbus_ { const struct vmbus_chanmsg_choffer *offer; struct vmbus_channel *chan; + task_fn_t *detach_fn, *attach_fn; int error; offer = (const struct vmbus_chanmsg_choffer *)msg->msg_data; @@ -1174,6 +1323,21 @@ vmbus_chan_msgproc_choffer(struct vmbus_ &sc->vmbus_tx_evtflags[chan->ch_id >> VMBUS_EVTFLAG_SHIFT]; chan->ch_evtflag_mask = 1UL << (chan->ch_id & VMBUS_EVTFLAG_MASK); + /* + * Setup attach and detach tasks. + */ + if (VMBUS_CHAN_ISPRIMARY(chan)) { + chan->ch_mgmt_tq = sc->vmbus_devtq; + attach_fn = vmbus_prichan_attach_task; + detach_fn = vmbus_prichan_detach_task; + } else { + chan->ch_mgmt_tq = sc->vmbus_subchtq; + attach_fn = vmbus_subchan_attach_task; + detach_fn = vmbus_subchan_detach_task; + } + TASK_INIT(&chan->ch_attach_task, 0, attach_fn, chan); + TASK_INIT(&chan->ch_detach_task, 0, detach_fn, chan); + /* Select default cpu for this channel. */ vmbus_chan_cpu_default(chan); @@ -1184,22 +1348,9 @@ vmbus_chan_msgproc_choffer(struct vmbus_ vmbus_chan_free(chan); return; } - - if (VMBUS_CHAN_ISPRIMARY(chan)) { - /* - * Add device for this primary channel. - * - * NOTE: - * Error is ignored here; don't have much to do if error - * really happens. - */ - vmbus_add_child(chan); - } + taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_attach_task); } -/* - * XXX pretty broken; need rework. - */ static void vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc, const struct vmbus_message *msg) @@ -1219,91 +1370,162 @@ vmbus_chan_msgproc_chrescind(struct vmbu note->chm_chanid); } - chan = sc->vmbus_chmap[note->chm_chanid]; - if (chan == NULL) + /* + * Find and remove the target channel from the channel list. + */ + mtx_lock(&sc->vmbus_chan_lock); + TAILQ_FOREACH(chan, &sc->vmbus_chans, ch_link) { + if (chan->ch_id == note->chm_chanid) + break; + } + if (chan == NULL) { + mtx_unlock(&sc->vmbus_chan_lock); + device_printf(sc->vmbus_dev, "chan%u is not offered\n", + note->chm_chanid); return; - sc->vmbus_chmap[note->chm_chanid] = NULL; + } + vmbus_chan_rem_list(sc, chan); + mtx_unlock(&sc->vmbus_chan_lock); + + if (VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * The target channel is a primary channel; remove the + * target channel from the primary channel list now, + * instead of later, so that it will not be found by + * other sub-channel offers, which are processed in + * this thread. + */ + mtx_lock(&sc->vmbus_prichan_lock); + vmbus_chan_rem_prilist(sc, chan); + mtx_unlock(&sc->vmbus_prichan_lock); + } - taskqueue_enqueue(taskqueue_thread, &chan->ch_detach_task); + /* Detach the target channel. */ + taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task); } -static void -vmbus_chan_detach_task(void *xchan, int pending __unused) +static int +vmbus_chan_release(struct vmbus_channel *chan) { - struct vmbus_channel *chan = xchan; + struct vmbus_softc *sc = chan->ch_vmbus; + struct vmbus_chanmsg_chfree *req; + struct vmbus_msghc *mh; + int error; - if (VMBUS_CHAN_ISPRIMARY(chan)) { - /* Only primary channel owns the device */ - vmbus_delete_child(chan); - /* NOTE: DO NOT free primary channel for now */ + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, "can not get msg hypercall for " + "chfree(chan%u)\n", chan->ch_id); + return (ENXIO); + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE; + req->chm_chanid = chan->ch_id; + + error = vmbus_msghc_exec_noresult(mh); + vmbus_msghc_put(sc, mh); + + if (error) { + device_printf(sc->vmbus_dev, "chfree(chan%u) failed: %d", + chan->ch_id, error); } else { - struct vmbus_softc *sc = chan->ch_vmbus; - struct vmbus_channel *pri_chan = chan->ch_prichan; - struct vmbus_chanmsg_chfree *req; - struct vmbus_msghc *mh; - int error; - - mh = vmbus_msghc_get(sc, sizeof(*req)); - if (mh == NULL) { - device_printf(sc->vmbus_dev, - "can not get msg hypercall for chfree(chan%u)\n", + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u freed\n", chan->ch_id); - goto remove; } + } + return (error); +} - req = vmbus_msghc_dataptr(mh); - req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHFREE; - req->chm_chanid = chan->ch_id; +static void +vmbus_prichan_detach_task(void *xchan, int pending __unused) +{ + struct vmbus_channel *chan = xchan; - error = vmbus_msghc_exec_noresult(mh); - vmbus_msghc_put(sc, mh); + KASSERT(VMBUS_CHAN_ISPRIMARY(chan), + ("chan%u is not primary channel", chan->ch_id)); - if (error) { - device_printf(sc->vmbus_dev, - "chfree(chan%u) failed: %d", - chan->ch_id, error); - /* NOTE: Move on! */ - } else { - if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u freed\n", - chan->ch_id); - } - } -remove: - mtx_lock(&pri_chan->ch_subchan_lock); - TAILQ_REMOVE(&pri_chan->ch_subchans, chan, ch_sublink); - KASSERT(pri_chan->ch_subchan_cnt > 0, - ("invalid subchan_cnt %d", pri_chan->ch_subchan_cnt)); - pri_chan->ch_subchan_cnt--; - mtx_unlock(&pri_chan->ch_subchan_lock); - wakeup(pri_chan); + /* Delete and detach the device associated with this channel. */ + vmbus_delete_child(chan); - vmbus_chan_free(chan); - } + /* Release this channel (back to vmbus). */ + vmbus_chan_release(chan); + + /* Free this channel's resource. */ + vmbus_chan_free(chan); +} + +static void +vmbus_subchan_detach_task(void *xchan, int pending __unused) +{ + struct vmbus_channel *chan = xchan; + struct vmbus_channel *pri_chan = chan->ch_prichan; + + KASSERT(!VMBUS_CHAN_ISPRIMARY(chan), + ("chan%u is primary channel", chan->ch_id)); + + /* Release this channel (back to vmbus). */ + vmbus_chan_release(chan); + + /* Unlink from its primary channel's sub-channel list. */ + mtx_lock(&pri_chan->ch_subchan_lock); + vmbus_chan_rem_sublist(pri_chan, chan); + mtx_unlock(&pri_chan->ch_subchan_lock); + /* Notify anyone that is waiting for this sub-channel to vanish. */ + wakeup(pri_chan); + + /* Free this channel's resource. */ + vmbus_chan_free(chan); +} + +static void +vmbus_prichan_attach_task(void *xchan, int pending __unused) +{ + + /* + * Add device for this primary channel. + */ + vmbus_add_child(xchan); +} + +static void +vmbus_subchan_attach_task(void *xchan __unused, int pending __unused) +{ + + /* Nothing */ } -/* - * Detach all devices and destroy the corresponding primary channels. - */ void vmbus_chan_destroy_all(struct vmbus_softc *sc) { - struct vmbus_channel *chan; - mtx_lock(&sc->vmbus_prichan_lock); - while ((chan = TAILQ_FIRST(&sc->vmbus_prichans)) != NULL) { - KASSERT(VMBUS_CHAN_ISPRIMARY(chan), ("not primary channel")); - TAILQ_REMOVE(&sc->vmbus_prichans, chan, ch_prilink); - mtx_unlock(&sc->vmbus_prichan_lock); + /* + * Detach all devices and destroy the corresponding primary + * channels. + */ + for (;;) { + struct vmbus_channel *chan; - vmbus_delete_child(chan); - vmbus_chan_free(chan); + mtx_lock(&sc->vmbus_chan_lock); + TAILQ_FOREACH(chan, &sc->vmbus_chans, ch_link) { + if (VMBUS_CHAN_ISPRIMARY(chan)) + break; + } + if (chan == NULL) { + /* No more primary channels; done. */ + mtx_unlock(&sc->vmbus_chan_lock); + break; + } + vmbus_chan_rem_list(sc, chan); + mtx_unlock(&sc->vmbus_chan_lock); mtx_lock(&sc->vmbus_prichan_lock); + vmbus_chan_rem_prilist(sc, chan); + mtx_unlock(&sc->vmbus_prichan_lock); + + taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task); } - bzero(sc->vmbus_chmap, - sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX); - mtx_unlock(&sc->vmbus_prichan_lock); } /* @@ -1477,3 +1699,17 @@ vmbus_chan_prplist_nelem(int br_size, in return (vmbus_br_nelem(br_size, elem_size)); } + +bool +vmbus_chan_tx_empty(const struct vmbus_channel *chan) +{ + + return (vmbus_txbr_empty(&chan->ch_txbr)); +} + +bool +vmbus_chan_rx_empty(const struct vmbus_channel *chan) +{ + + return (vmbus_rxbr_empty(&chan->ch_rxbr)); +} Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_chanvar.h Fri Oct 14 02:42:08 2016 (r307249) @@ -124,8 +124,14 @@ struct vmbus_channel { struct hyperv_dma ch_bufring_dma; uint32_t ch_bufring_gpadl; - struct task ch_detach_task; + struct task ch_attach_task; /* run in ch_mgmt_tq */ + struct task ch_detach_task; /* run in ch_mgmt_tq */ + struct taskqueue *ch_mgmt_tq; + + /* If this is a primary channel */ TAILQ_ENTRY(vmbus_channel) ch_prilink; /* primary chan link */ + + TAILQ_ENTRY(vmbus_channel) ch_link; /* channel link */ uint32_t ch_subidx; /* subchan index */ volatile uint32_t ch_stflags; /* atomic-op */ /* VMBUS_CHAN_ST_ */ @@ -150,7 +156,13 @@ struct vmbus_channel { #define VMBUS_CHAN_TXF_HASMNF 0x0001 #define VMBUS_CHAN_ST_OPENED_SHIFT 0 +#define VMBUS_CHAN_ST_ONPRIL_SHIFT 1 +#define VMBUS_CHAN_ST_ONSUBL_SHIFT 2 +#define VMBUS_CHAN_ST_ONLIST_SHIFT 3 #define VMBUS_CHAN_ST_OPENED (1 << VMBUS_CHAN_ST_OPENED_SHIFT) +#define VMBUS_CHAN_ST_ONPRIL (1 << VMBUS_CHAN_ST_ONPRIL_SHIFT) +#define VMBUS_CHAN_ST_ONSUBL (1 << VMBUS_CHAN_ST_ONSUBL_SHIFT) +#define VMBUS_CHAN_ST_ONLIST (1 << VMBUS_CHAN_ST_ONLIST_SHIFT) struct vmbus_softc; struct vmbus_message; Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h ============================================================================== --- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Fri Oct 14 02:36:51 2016 (r307248) +++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Fri Oct 14 02:42:08 2016 (r307249) @@ -107,14 +107,19 @@ struct vmbus_softc { struct hyperv_dma vmbus_mnf1_dma; struct hyperv_dma vmbus_mnf2_dma; - struct mtx vmbus_scan_lock; - uint32_t vmbus_scan_chcnt; -#define VMBUS_SCAN_CHCNT_DONE 0x80000000 - uint32_t vmbus_scan_devcnt; + bool vmbus_scandone; + struct task vmbus_scandone_task; + + struct taskqueue *vmbus_devtq; /* for dev attach/detach */ + struct taskqueue *vmbus_subchtq; /* for sub-chan attach/detach */ /* Primary channels */ struct mtx vmbus_prichan_lock; TAILQ_HEAD(, vmbus_channel) vmbus_prichans; + + /* Complete channel list */ + struct mtx vmbus_chan_lock; + TAILQ_HEAD(, vmbus_channel) vmbus_chans; }; #define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */ From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:52:50 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5DEBBC119AD; Fri, 14 Oct 2016 02:52:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2EADF143; Fri, 14 Oct 2016 02:52:50 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2qnj8060694; Fri, 14 Oct 2016 02:52:49 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2qmaQ060688; Fri, 14 Oct 2016 02:52:48 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140252.u9E2qmaQ060688@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:52:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307250 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:52:50 -0000 Author: sephe Date: Fri Oct 14 02:52:48 2016 New Revision: 307250 URL: https://svnweb.freebsd.org/changeset/base/307250 Log: MFC 306390-306392 306390 hyperv/hn: Suspend and resume the backend properly upon MTU change. Suspend: - Prevent the backend from being touched on TX path. - Clear the RNDIS RX filter, and wait for RX to drain. - Make sure that NVS see the chimney sending buffer and RXBUF disconnection, before unlink these buffers from the channel. Resume: - Reconfigure the RNDIS filter. - Allow TX path to work on the backend. - Kick start the TX eof task, in case the OACTIVE is set. This fixes various panics, when the interface has traffic and MTU is being changed. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8046 306391 hyperv/hn: Reorganize the synthetic parts detach. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8047 306392 hyperv/hn: Reorder the comment a little bit. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8048 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Fri Oct 14 02:52:48 2016 (r307250) @@ -347,6 +347,16 @@ hn_nvs_disconn_rxbuf(struct hn_softc *sc return (error); } sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED; + + /* + * Wait for the hypervisor to receive this NVS request. + */ + while (!vmbus_chan_tx_empty(sc->hn_prichan)) + pause("waittx", 1); + /* + * Linger long enough for NVS to disconnect RXBUF. + */ + pause("lingtx", (200 * hz) / 1000); } if (sc->hn_rxbuf_gpadl != 0) { @@ -388,6 +398,17 @@ hn_nvs_disconn_chim(struct hn_softc *sc) return (error); } sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED; + + /* + * Wait for the hypervisor to receive this NVS request. + */ + while (!vmbus_chan_tx_empty(sc->hn_prichan)) + pause("waittx", 1); + /* + * Linger long enough for NVS to disconnect chimney + * sending buffer. + */ + pause("lingtx", (200 * hz) / 1000); } if (sc->hn_chim_gpadl != 0) { @@ -596,27 +617,15 @@ hn_nvs_attach(struct hn_softc *sc, int m return (0); } -/* - * Net VSC disconnect from VSP - */ -static void -hv_nv_disconnect_from_vsp(struct hn_softc *sc) +void +hn_nvs_detach(struct hn_softc *sc) { + + /* NOTE: there are no requests to stop the NVS. */ hn_nvs_disconn_rxbuf(sc); hn_nvs_disconn_chim(sc); } -/* - * Net VSC on device remove - */ -int -hv_nv_on_device_remove(struct hn_softc *sc) -{ - - hv_nv_disconnect_from_vsp(sc); - return (0); -} - void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:52:48 2016 (r307250) @@ -178,6 +178,7 @@ struct hn_tx_ring { bus_dma_tag_t hn_tx_data_dtag; uint64_t hn_csum_assist; + int hn_suspended; int hn_gpa_cnt; struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE]; @@ -269,8 +270,6 @@ extern int hv_promisc_mode; struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); -int hn_nvs_attach(struct hn_softc *sc, int mtu); -int hv_nv_on_device_remove(struct hn_softc *sc); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:52:48 2016 (r307250) @@ -350,6 +350,11 @@ static void hn_detach_allchans(struct hn static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr); static void hn_set_ring_inuse(struct hn_softc *, int); static int hn_synth_attach(struct hn_softc *, int); +static void hn_synth_detach(struct hn_softc *); +static bool hn_tx_ring_pending(struct hn_tx_ring *); +static void hn_suspend(struct hn_softc *); +static void hn_resume(struct hn_softc *); +static void hn_tx_ring_qflush(struct hn_tx_ring *); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); @@ -756,29 +761,19 @@ failed: } /* - * Standard detach entry point + * TODO: Use this for error handling on attach path. */ static int netvsc_detach(device_t dev) { struct hn_softc *sc = device_get_softc(dev); - if (bootverbose) - printf("netvsc_detach\n"); - - /* - * XXXKYS: Need to clean up all our - * driver state; this is the driver - * unloading. - */ + /* TODO: ether_ifdetach */ - /* - * XXXKYS: Need to stop outgoing traffic and unregister - * the netdevice. - */ - - hv_rf_on_device_remove(sc); - hn_detach_allchans(sc); + HN_LOCK(sc); + /* TODO: hn_stop */ + hn_synth_detach(sc); + HN_UNLOCK(sc); hn_stop_tx_tasks(sc); @@ -791,6 +786,8 @@ netvsc_detach(device_t dev) vmbus_xact_ctx_destroy(sc->hn_xact); HN_LOCK_DESTROY(sc); + + /* TODO: if_free */ return (0); } @@ -921,6 +918,23 @@ hn_txdesc_hold(struct hn_txdesc *txd) atomic_add_int(&txd->refs, 1); } +static bool +hn_tx_ring_pending(struct hn_tx_ring *txr) +{ + bool pending = false; + +#ifndef HN_USE_TXDESC_BUFRING + mtx_lock_spin(&txr->hn_txlist_spin); + if (txr->hn_txdesc_avail != txr->hn_txdesc_cnt) + pending = true; + mtx_unlock_spin(&txr->hn_txlist_spin); +#else + if (!buf_ring_full(txr->hn_txdesc_br)) + pending = true; +#endif + return (pending); +} + static __inline void hn_txeof(struct hn_tx_ring *txr) { @@ -1263,6 +1277,9 @@ hn_start_locked(struct hn_tx_ring *txr, KASSERT(txr == &sc->hn_tx_ring[0], ("not the first TX ring")); mtx_assert(&txr->hn_tx_lock, MA_OWNED); + if (__predict_false(txr->hn_suspended)) + return 0; + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) return 0; @@ -1647,23 +1664,17 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp)); #endif - /* We must remove and add back the device to cause the new - * MTU to take effect. This includes tearing down, but not - * deleting the channel, then bringing it back up. - */ - error = hv_rf_on_device_remove(sc); - if (error) { - HN_UNLOCK(sc); - break; - } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_suspend(sc); /* - * Detach all of the channels. + * Detach the synthetics parts, i.e. NVS and RNDIS. */ - hn_detach_allchans(sc); + hn_synth_detach(sc); /* - * Attach the synthetic parts, i.e. NVS and RNDIS. + * Reattach the synthetic parts, i.e. NVS and RNDIS, + * with the new MTU setting. * XXX check error. */ hn_synth_attach(sc, ifr->ifr_mtu); @@ -1671,7 +1682,9 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) hn_set_chim_size(sc, sc->hn_chim_szmax); - hn_init_locked(sc); + /* All done! Resume now. */ + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_resume(sc); HN_UNLOCK(sc); break; @@ -3004,6 +3017,9 @@ hn_xmit(struct hn_tx_ring *txr, int len) KASSERT(hn_use_if_start == 0, ("hn_xmit is called, when if_start is enabled")); + if (__predict_false(txr->hn_suspended)) + return 0; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || txr->hn_oactive) return 0; @@ -3090,20 +3106,24 @@ do_sched: } static void +hn_tx_ring_qflush(struct hn_tx_ring *txr) +{ + struct mbuf *m; + + mtx_lock(&txr->hn_tx_lock); + while ((m = buf_ring_dequeue_sc(txr->hn_mbuf_br)) != NULL) + m_freem(m); + mtx_unlock(&txr->hn_tx_lock); +} + +static void hn_xmit_qflush(struct ifnet *ifp) { struct hn_softc *sc = ifp->if_softc; int i; - for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { - struct hn_tx_ring *txr = &sc->hn_tx_ring[i]; - struct mbuf *m; - - mtx_lock(&txr->hn_tx_lock); - while ((m = buf_ring_dequeue_sc(txr->hn_mbuf_br)) != NULL) - m_freem(m); - mtx_unlock(&txr->hn_tx_lock); - } + for (i = 0; i < sc->hn_tx_ring_inuse; ++i) + hn_tx_ring_qflush(&sc->hn_tx_ring[i]); if_qflush(ifp); } @@ -3504,6 +3524,26 @@ back: return (0); } +/* + * NOTE: + * The interface must have been suspended though hn_suspend(), before + * this function get called. + */ +static void +hn_synth_detach(struct hn_softc *sc) +{ + HN_LOCK_ASSERT(sc); + + /* Detach the RNDIS first. */ + hn_rndis_detach(sc); + + /* Detach NVS. */ + hn_nvs_detach(sc); + + /* Detach all of the channels. */ + hn_detach_allchans(sc); +} + static void hn_set_ring_inuse(struct hn_softc *sc, int ring_cnt) { @@ -3523,6 +3563,113 @@ hn_set_ring_inuse(struct hn_softc *sc, i } static void +hn_rx_drain(struct vmbus_channel *chan) +{ + + while (!vmbus_chan_rx_empty(chan) || !vmbus_chan_tx_empty(chan)) + pause("waitch", 1); + vmbus_chan_intr_drain(chan); +} + +static void +hn_suspend(struct hn_softc *sc) +{ + struct vmbus_channel **subch = NULL; + int i, nsubch; + + HN_LOCK_ASSERT(sc); + + /* + * Suspend TX. + */ + for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { + struct hn_tx_ring *txr = &sc->hn_tx_ring[i]; + + mtx_lock(&txr->hn_tx_lock); + txr->hn_suspended = 1; + mtx_unlock(&txr->hn_tx_lock); + /* No one is able send more packets now. */ + + /* Wait for all pending sends to finish. */ + while (hn_tx_ring_pending(txr)) + pause("hnwtx", 1 /* 1 tick */); + } + + /* + * Disable RX. + */ + hv_rf_on_close(sc); + + /* + * Give RNDIS enough time to flush all pending data packets. + */ + pause("waitrx", (200 * hz) / 1000); + + /* + * Drain RX/TX bufrings and interrupts. + */ + nsubch = sc->hn_rx_ring_inuse - 1; + if (nsubch > 0) + subch = vmbus_subchan_get(sc->hn_prichan, nsubch); + + if (subch != NULL) { + for (i = 0; i < nsubch; ++i) + hn_rx_drain(subch[i]); + } + hn_rx_drain(sc->hn_prichan); + + if (subch != NULL) + vmbus_subchan_rel(subch, nsubch); +} + +static void +hn_resume(struct hn_softc *sc) +{ + struct hn_tx_ring *txr; + int i; + + HN_LOCK_ASSERT(sc); + + /* + * Re-enable RX. + */ + hv_rf_on_open(sc); + + /* + * Make sure to clear suspend status on "all" TX rings, + * since hn_tx_ring_inuse can be changed after hn_suspend(). + */ + for (i = 0; i < sc->hn_tx_ring_cnt; ++i) { + txr = &sc->hn_tx_ring[i]; + + mtx_lock(&txr->hn_tx_lock); + txr->hn_suspended = 0; + mtx_unlock(&txr->hn_tx_lock); + } + + if (!hn_use_if_start) { + /* + * Flush unused drbrs, since hn_tx_ring_inuse may be + * reduced. + */ + for (i = sc->hn_tx_ring_inuse; i < sc->hn_tx_ring_cnt; ++i) + hn_tx_ring_qflush(&sc->hn_tx_ring[i]); + } + + /* + * Kick start TX. + */ + for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { + txr = &sc->hn_tx_ring[i]; + /* + * Use txeof task, so that any pending oactive can be + * cleared properly. + */ + taskqueue_enqueue(txr->hn_tx_taskq, &txr->hn_txeof_task); + } +} + +static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { const struct hn_nvs_hdr *hdr; Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:52:48 2016 (r307250) @@ -958,11 +958,8 @@ done: return (error); } -/* - * RNDIS filter halt device - */ static int -hv_rf_halt_device(struct hn_softc *sc) +hn_rndis_halt(struct hn_softc *sc) { struct vmbus_xact *xact; struct rndis_halt_req *halt; @@ -1009,21 +1006,12 @@ hn_rndis_attach(struct hn_softc *sc) return (0); } -/* - * RNDIS filter on device remove - */ -int -hv_rf_on_device_remove(struct hn_softc *sc) +void +hn_rndis_detach(struct hn_softc *sc) { - int ret; - - /* Halt and release the rndis device */ - ret = hv_rf_halt_device(sc); - - /* Pass control to inner driver to remove the device */ - ret |= hv_nv_on_device_remove(sc); - return (ret); + /* Halt the RNDIS. */ + hn_rndis_halt(sc); } /* Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Fri Oct 14 02:52:48 2016 (r307250) @@ -43,7 +43,6 @@ struct hn_rx_ring; void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); -int hv_rf_on_device_remove(struct hn_softc *sc); int hv_rf_on_open(struct hn_softc *sc); int hv_rf_on_close(struct hn_softc *sc); Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Oct 14 02:42:08 2016 (r307249) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Oct 14 02:52:48 2016 (r307250) @@ -118,6 +118,7 @@ uint32_t hn_chim_alloc(struct hn_softc * void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); int hn_rndis_attach(struct hn_softc *sc); +void hn_rndis_detach(struct hn_softc *sc); int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, size_t pktsize, size_t pi_dlen, uint32_t pi_type); @@ -127,6 +128,7 @@ int hn_rndis_get_linkstatus(struct hn_s uint32_t *link_status); int hn_nvs_attach(struct hn_softc *sc, int mtu); +void hn_nvs_detach(struct hn_softc *sc); int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch); void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, const void *data, int dlen); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 02:58:32 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E43FDC11A7F; Fri, 14 Oct 2016 02:58:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A4B5F33E; Fri, 14 Oct 2016 02:58:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E2wVtZ061002; Fri, 14 Oct 2016 02:58:31 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E2wViK060997; Fri, 14 Oct 2016 02:58:31 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140258.u9E2wViK060997@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 02:58:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307251 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 02:58:33 -0000 Author: sephe Date: Fri Oct 14 02:58:31 2016 New Revision: 307251 URL: https://svnweb.freebsd.org/changeset/base/307251 Log: MFC 306393 hyperv/hn: Flatten RX filter configuration. This paves way for more fixes. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8049 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:52:48 2016 (r307250) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 02:58:31 2016 (r307251) @@ -266,7 +266,6 @@ struct hn_softc { /* * Externs */ -extern int hv_promisc_mode; struct hn_send_ctx; void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:52:48 2016 (r307250) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 02:58:31 2016 (r307251) @@ -207,8 +207,6 @@ struct hn_txdesc { * Globals */ -int hv_promisc_mode = 0; /* normal mode by default */ - SYSCTL_NODE(_hw, OID_AUTO, hn, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Hyper-V network interface"); @@ -1799,7 +1797,7 @@ static void hn_stop(struct hn_softc *sc) { struct ifnet *ifp; - int ret, i; + int i; HN_LOCK_ASSERT(sc); @@ -1815,7 +1813,8 @@ hn_stop(struct hn_softc *sc) if_link_state_change(ifp, LINK_STATE_DOWN); - ret = hv_rf_on_close(sc); + /* Disable RX by clearing RX filter. */ + hn_rndis_set_rxfilter(sc, 0); } /* @@ -1890,9 +1889,8 @@ hn_init_locked(struct hn_softc *sc) return; } - hv_promisc_mode = 1; - - ret = hv_rf_on_open(sc); + /* TODO: add hn_rx_filter */ + ret = hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); if (ret != 0) return; @@ -3596,9 +3594,9 @@ hn_suspend(struct hn_softc *sc) } /* - * Disable RX. + * Disable RX by clearing RX filter. */ - hv_rf_on_close(sc); + hn_rndis_set_rxfilter(sc, 0); /* * Give RNDIS enough time to flush all pending data packets. @@ -3632,8 +3630,9 @@ hn_resume(struct hn_softc *sc) /* * Re-enable RX. + * TODO: add hn_rx_filter. */ - hv_rf_on_open(sc); + hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); /* * Make sure to clear suspend status on "all" TX rings, Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:52:48 2016 (r307250) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 02:58:31 2016 (r307251) @@ -888,7 +888,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, u return (error); } -static int +int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter) { int error; @@ -1014,35 +1014,6 @@ hn_rndis_detach(struct hn_softc *sc) hn_rndis_halt(sc); } -/* - * RNDIS filter on open - */ -int -hv_rf_on_open(struct hn_softc *sc) -{ - uint32_t filter; - - /* XXX */ - if (hv_promisc_mode != 1) { - filter = NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_ALL_MULTICAST | - NDIS_PACKET_TYPE_DIRECTED; - } else { - filter = NDIS_PACKET_TYPE_PROMISCUOUS; - } - return (hn_rndis_set_rxfilter(sc, filter)); -} - -/* - * RNDIS filter on close - */ -int -hv_rf_on_close(struct hn_softc *sc) -{ - - return (hn_rndis_set_rxfilter(sc, 0)); -} - void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Fri Oct 14 02:52:48 2016 (r307250) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.h Fri Oct 14 02:58:31 2016 (r307251) @@ -43,8 +43,6 @@ struct hn_rx_ring; void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen); void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); -int hv_rf_on_open(struct hn_softc *sc); -int hv_rf_on_close(struct hn_softc *sc); #endif /* __HV_RNDIS_FILTER_H__ */ Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Oct 14 02:52:48 2016 (r307250) +++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h Fri Oct 14 02:58:31 2016 (r307251) @@ -126,6 +126,8 @@ int hn_rndis_get_rsscaps(struct hn_soft int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); int hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status); +/* filter: NDIS_PACKET_TYPE_ or 0. */ +int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); int hn_nvs_attach(struct hn_softc *sc, int mtu); void hn_nvs_detach(struct hn_softc *sc); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 03:11:32 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A8570C11E99; Fri, 14 Oct 2016 03:11:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5FEF7FB2; Fri, 14 Oct 2016 03:11:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E3BVtG067125; Fri, 14 Oct 2016 03:11:31 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E3BVeN067123; Fri, 14 Oct 2016 03:11:31 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140311.u9E3BVeN067123@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 03:11:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307253 - in stable/10/sys: cam/ata sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 03:11:32 -0000 Author: sephe Date: Fri Oct 14 03:11:31 2016 New Revision: 307253 URL: https://svnweb.freebsd.org/changeset/base/307253 Log: MFC 306396 cam/ata: Allow drivers to veto ATA disk attachment. This eventhandler is mainly used by VMs, e.g. Hyper-V, whose disk controllers share the disks with the simulated ATA controllers. Submitted by: Hongjiang Zhang Discussed with: mav Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7693 Modified: stable/10/sys/cam/ata/ata_xpt.c stable/10/sys/sys/eventhandler.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ata/ata_xpt.c ============================================================================== --- stable/10/sys/cam/ata/ata_xpt.c Fri Oct 14 03:00:53 2016 (r307252) +++ stable/10/sys/cam/ata/ata_xpt.c Fri Oct 14 03:11:31 2016 (r307253) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -827,12 +828,24 @@ noerror: { struct ccb_pathinq cpi; int16_t *ptr; + int veto = 0; ident_buf = &softc->ident_data; for (ptr = (int16_t *)ident_buf; ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) { *ptr = le16toh(*ptr); } + + /* + * Allow others to veto this ATA disk attachment. This + * is mainly used by VMs, whose disk controllers may + * share the disks with the simulated ATA controllers. + */ + EVENTHANDLER_INVOKE(ada_probe_veto, path, ident_buf, &veto); + if (veto) { + goto device_fail; + } + if (strncmp(ident_buf->model, "FX", 2) && strncmp(ident_buf->model, "NEC", 3) && strncmp(ident_buf->model, "Pioneer", 7) && Modified: stable/10/sys/sys/eventhandler.h ============================================================================== --- stable/10/sys/sys/eventhandler.h Fri Oct 14 03:00:53 2016 (r307252) +++ stable/10/sys/sys/eventhandler.h Fri Oct 14 03:11:31 2016 (r307253) @@ -283,4 +283,11 @@ typedef void (*unregister_framebuffer_fn EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); +/* Veto ada attachment */ +struct cam_path; +struct ata_params; +typedef void (*ada_probe_veto_fn)(void *, struct cam_path *, + struct ata_params *, int *); +EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); + #endif /* SYS_EVENTHANDLER_H */ From owner-svn-src-stable-10@freebsd.org Fri Oct 14 03:22:20 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E34F2C10063; Fri, 14 Oct 2016 03:22:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A5202856; Fri, 14 Oct 2016 03:22:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E3MJAH072900; Fri, 14 Oct 2016 03:22:19 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E3MJrk072896; Fri, 14 Oct 2016 03:22:19 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140322.u9E3MJrk072896@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 03:22:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307254 - in stable/10/sys: conf dev/hyperv/stordisengage dev/hyperv/storvsc modules/hyperv modules/hyperv/stordisengage X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 03:22:21 -0000 Author: sephe Date: Fri Oct 14 03:22:19 2016 New Revision: 307254 URL: https://svnweb.freebsd.org/changeset/base/307254 Log: MFC 306426 hyperv/storvsc: Fix the blkvsc disk attachment issues. - The original 'disengage' ATA controller model does not work properly for all possible disk configurations. Use the newly added ATA disk veto eventhandler to fit into all possible disk configuration. - If the 'invalid LUN' happens on blkvsc controllers, return CAM_DEV_NOT_THERE so that CAM will not destroy attached disks under the blkvsc controllers. Submitted by: Hongjiang Zhang Discussed with: mav Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7693 Deleted: stable/10/sys/dev/hyperv/stordisengage/ stable/10/sys/modules/hyperv/stordisengage/ Modified: stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/modules/hyperv/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Fri Oct 14 03:11:31 2016 (r307253) +++ stable/10/sys/conf/files.amd64 Fri Oct 14 03:22:19 2016 (r307254) @@ -264,7 +264,6 @@ dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/netvsc/hv_net_vsc.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv -dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_heartbeat.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Fri Oct 14 03:11:31 2016 (r307253) +++ stable/10/sys/conf/files.i386 Fri Oct 14 03:22:19 2016 (r307254) @@ -241,7 +241,6 @@ dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/netvsc/hv_net_vsc.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv -dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_heartbeat.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Oct 14 03:11:31 2016 (r307253) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Oct 14 03:22:19 2016 (r307254) @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -202,6 +203,7 @@ struct storvsc_softc { struct vmbus_channel *hs_sel_chan[MAXCPU]; }; +static eventhandler_tag storvsc_handler_tag; /* * The size of the vmscsi_request has changed in win8. The * additional size is for the newly added elements in the @@ -898,21 +900,15 @@ hv_storvsc_on_channel_callback(struct vm static int storvsc_probe(device_t dev) { - int ata_disk_enable = 0; int ret = ENXIO; switch (storvsc_get_storage_type(dev)) { case DRIVER_BLKVSC: if(bootverbose) - device_printf(dev, "DRIVER_BLKVSC-Emulated ATA/IDE probe\n"); - if (!getenv_int("hw.ata.disk_enable", &ata_disk_enable)) { - if(bootverbose) - device_printf(dev, - "Enlightened ATA/IDE detected\n"); - device_set_desc(dev, g_drv_props_table[DRIVER_BLKVSC].drv_desc); - ret = BUS_PROBE_DEFAULT; - } else if(bootverbose) - device_printf(dev, "Emulated ATA/IDE set (hw.ata.disk_enable set)\n"); + device_printf(dev, + "Enlightened ATA/IDE detected\n"); + device_set_desc(dev, g_drv_props_table[DRIVER_BLKVSC].drv_desc); + ret = BUS_PROBE_DEFAULT; break; case DRIVER_STORVSC: if(bootverbose) @@ -2155,27 +2151,45 @@ storvsc_io_done(struct hv_storvsc_reques ccb->ccb_h.status &= ~CAM_STATUS_MASK; if (vm_srb->scsi_status == SCSI_STATUS_OK) { const struct scsi_generic *cmd; - + cmd = (const struct scsi_generic *) + ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? + csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes); if (vm_srb->srb_status != SRB_STATUS_SUCCESS) { - if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) { - xpt_print(ccb->ccb_h.path, "invalid LUN %d\n", - vm_srb->lun); - } else { - xpt_print(ccb->ccb_h.path, "Unknown SRB flag: %d\n", - vm_srb->srb_status); - } /* * If there are errors, for example, invalid LUN, * host will inform VM through SRB status. */ - ccb->ccb_h.status |= CAM_SEL_TIMEOUT; + if (bootverbose) { + if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) { + xpt_print(ccb->ccb_h.path, + "invalid LUN %d for op: %s\n", + vm_srb->lun, + scsi_op_desc(cmd->opcode, NULL)); + } else { + xpt_print(ccb->ccb_h.path, + "Unknown SRB flag: %d for op: %s\n", + vm_srb->srb_status, + scsi_op_desc(cmd->opcode, NULL)); + } + } + + /* + * XXX For a selection timeout, all of the LUNs + * on the target will be gone. It works for SCSI + * disks, but does not work for IDE disks. + * + * For CAM_DEV_NOT_THERE, CAM will only get + * rid of the device(s) specified by the path. + */ + if (storvsc_get_storage_type(sc->hs_dev) == + DRIVER_STORVSC) + ccb->ccb_h.status |= CAM_SEL_TIMEOUT; + else + ccb->ccb_h.status |= CAM_DEV_NOT_THERE; } else { ccb->ccb_h.status |= CAM_REQ_CMP; } - cmd = (const struct scsi_generic *) - ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? - csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes); if (cmd->opcode == INQUIRY) { struct scsi_inquiry_data *inq_data = (struct scsi_inquiry_data *)csio->data_ptr; @@ -2287,3 +2301,58 @@ storvsc_get_storage_type(device_t dev) return DRIVER_STORVSC; return DRIVER_UNKNOWN; } + +#define PCI_VENDOR_INTEL 0x8086 +#define PCI_PRODUCT_PIIX4 0x7111 + +static void +storvsc_ada_probe_veto(void *arg __unused, struct cam_path *path, + struct ata_params *ident_buf __unused, int *veto) +{ + + /* + * The ATA disks are shared with the controllers managed + * by this driver, so veto the ATA disks' attachment; the + * ATA disks will be attached as SCSI disks once this driver + * attached. + */ + if (path->device->protocol == PROTO_ATA) { + struct ccb_pathinq cpi; + + bzero(&cpi, sizeof(cpi)); + xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + if (cpi.ccb_h.status == CAM_REQ_CMP && + cpi.hba_vendor == PCI_VENDOR_INTEL && + cpi.hba_device == PCI_PRODUCT_PIIX4) { + (*veto)++; + if (bootverbose) { + xpt_print(path, + "Disable ATA disks on " + "simulated ATA controller (0x%04x%04x)\n", + cpi.hba_device, cpi.hba_vendor); + } + } + } +} + +static void +storvsc_sysinit(void *arg __unused) +{ + if (vm_guest == VM_GUEST_HV) { + storvsc_handler_tag = EVENTHANDLER_REGISTER(ada_probe_veto, + storvsc_ada_probe_veto, NULL, EVENTHANDLER_PRI_ANY); + } +} +SYSINIT(storvsc_sys_init, SI_SUB_DRIVERS, SI_ORDER_SECOND, storvsc_sysinit, + NULL); + +static void +storvsc_sysuninit(void *arg __unused) +{ + if (storvsc_handler_tag != NULL) + EVENTHANDLER_DEREGISTER(ada_probe_veto, storvsc_handler_tag); +} +SYSUNINIT(storvsc_sys_uninit, SI_SUB_DRIVERS, SI_ORDER_SECOND, + storvsc_sysuninit, NULL); Modified: stable/10/sys/modules/hyperv/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/Makefile Fri Oct 14 03:11:31 2016 (r307253) +++ stable/10/sys/modules/hyperv/Makefile Fri Oct 14 03:22:19 2016 (r307254) @@ -1,5 +1,5 @@ # $FreeBSD$ -SUBDIR = vmbus netvsc stordisengage storvsc utilities +SUBDIR = vmbus netvsc storvsc utilities .include From owner-svn-src-stable-10@freebsd.org Fri Oct 14 03:26:26 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 54BAFC101E4; Fri, 14 Oct 2016 03:26:26 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 12757BD6; Fri, 14 Oct 2016 03:26:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E3QPSX073133; Fri, 14 Oct 2016 03:26:25 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E3QP1G073132; Fri, 14 Oct 2016 03:26:25 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140326.u9E3QP1G073132@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 03:26:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307255 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 03:26:26 -0000 Author: sephe Date: Fri Oct 14 03:26:24 2016 New Revision: 307255 URL: https://svnweb.freebsd.org/changeset/base/307255 Log: MFC 306431,306432 306431 hyperv/hn: Move TX tasks' draining into hn_suspend(). This prepares to consolidate hn_stop() and netvsc_detach(). Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8055 306432 hyperv/hn: Consolidate hn_init() and hn_stop() Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8056 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 03:22:19 2016 (r307254) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 03:26:24 2016 (r307255) @@ -336,7 +336,6 @@ static void hn_fixup_tx_data(struct hn_s static void hn_destroy_tx_data(struct hn_softc *); static void hn_start_taskfunc(void *, int); static void hn_start_txeof_taskfunc(void *, int); -static void hn_stop_tx_tasks(struct hn_softc *); static int hn_encap(struct hn_tx_ring *, struct hn_txdesc *, struct mbuf **); static int hn_create_rx_data(struct hn_softc *sc, int); static void hn_destroy_rx_data(struct hn_softc *sc); @@ -352,6 +351,8 @@ static void hn_synth_detach(struct hn_so static bool hn_tx_ring_pending(struct hn_tx_ring *); static void hn_suspend(struct hn_softc *); static void hn_resume(struct hn_softc *); +static void hn_rx_drain(struct vmbus_channel *); +static void hn_tx_resume(struct hn_softc *, int); static void hn_tx_ring_qflush(struct hn_tx_ring *); static void hn_nvs_handle_notify(struct hn_softc *sc, @@ -773,8 +774,6 @@ netvsc_detach(device_t dev) hn_synth_detach(sc); HN_UNLOCK(sc); - hn_stop_tx_tasks(sc); - ifmedia_removeall(&sc->hn_media); hn_destroy_rx_data(sc); hn_destroy_tx_data(sc); @@ -1796,25 +1795,19 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, static void hn_stop(struct hn_softc *sc) { - struct ifnet *ifp; + struct ifnet *ifp = sc->hn_ifp; int i; HN_LOCK_ASSERT(sc); - ifp = sc->hn_ifp; - - if (bootverbose) - printf(" Closing Device ...\n"); + /* Clear RUNNING bit _before_ hn_suspend() */ + atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); + hn_suspend(sc); - atomic_clear_int(&ifp->if_drv_flags, - (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)); + /* Clear OACTIVE bit. */ + atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) sc->hn_tx_ring[i].hn_oactive = 0; - - if_link_state_change(ifp, LINK_STATE_DOWN); - - /* Disable RX by clearing RX filter. */ - hn_rndis_set_rxfilter(sc, 0); } /* @@ -1878,27 +1871,29 @@ do_sched: static void hn_init_locked(struct hn_softc *sc) { - struct ifnet *ifp; - int ret, i; + struct ifnet *ifp = sc->hn_ifp; + int i; HN_LOCK_ASSERT(sc); - ifp = sc->hn_ifp; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) return; - } /* TODO: add hn_rx_filter */ - ret = hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); - if (ret != 0) - return; + hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); + /* Clear OACTIVE bit. */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) sc->hn_tx_ring[i].hn_oactive = 0; + /* Clear TX 'suspended' bit. */ + hn_tx_resume(sc, sc->hn_tx_ring_inuse); + + /* Everything is ready; unleash! */ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); + + /* TODO: check RNDIS link status. */ if_link_state_change(ifp, LINK_STATE_UP); } @@ -2991,19 +2986,6 @@ hn_start_txeof_taskfunc(void *xtxr, int mtx_unlock(&txr->hn_tx_lock); } -static void -hn_stop_tx_tasks(struct hn_softc *sc) -{ - int i; - - for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { - struct hn_tx_ring *txr = &sc->hn_tx_ring[i]; - - taskqueue_drain(txr->hn_tx_taskq, &txr->hn_tx_task); - taskqueue_drain(txr->hn_tx_taskq, &txr->hn_txeof_task); - } -} - static int hn_xmit(struct hn_tx_ring *txr, int len) { @@ -3591,6 +3573,9 @@ hn_suspend(struct hn_softc *sc) /* Wait for all pending sends to finish. */ while (hn_tx_ring_pending(txr)) pause("hnwtx", 1 /* 1 tick */); + + taskqueue_drain(txr->hn_tx_taskq, &txr->hn_tx_task); + taskqueue_drain(txr->hn_tx_taskq, &txr->hn_txeof_task); } /* @@ -3621,9 +3606,25 @@ hn_suspend(struct hn_softc *sc) } static void +hn_tx_resume(struct hn_softc *sc, int tx_ring_cnt) +{ + int i; + + KASSERT(tx_ring_cnt <= sc->hn_tx_ring_cnt, + ("invalid TX ring count %d", tx_ring_cnt)); + + for (i = 0; i < tx_ring_cnt; ++i) { + struct hn_tx_ring *txr = &sc->hn_tx_ring[i]; + + mtx_lock(&txr->hn_tx_lock); + txr->hn_suspended = 0; + mtx_unlock(&txr->hn_tx_lock); + } +} + +static void hn_resume(struct hn_softc *sc) { - struct hn_tx_ring *txr; int i; HN_LOCK_ASSERT(sc); @@ -3638,13 +3639,7 @@ hn_resume(struct hn_softc *sc) * Make sure to clear suspend status on "all" TX rings, * since hn_tx_ring_inuse can be changed after hn_suspend(). */ - for (i = 0; i < sc->hn_tx_ring_cnt; ++i) { - txr = &sc->hn_tx_ring[i]; - - mtx_lock(&txr->hn_tx_lock); - txr->hn_suspended = 0; - mtx_unlock(&txr->hn_tx_lock); - } + hn_tx_resume(sc, sc->hn_tx_ring_cnt); if (!hn_use_if_start) { /* @@ -3659,7 +3654,8 @@ hn_resume(struct hn_softc *sc) * Kick start TX. */ for (i = 0; i < sc->hn_tx_ring_inuse; ++i) { - txr = &sc->hn_tx_ring[i]; + struct hn_tx_ring *txr = &sc->hn_tx_ring[i]; + /* * Use txeof task, so that any pending oactive can be * cleared properly. From owner-svn-src-stable-10@freebsd.org Fri Oct 14 03:32:21 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7C6CDC1054F; Fri, 14 Oct 2016 03:32:21 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3F406B2; Fri, 14 Oct 2016 03:32:21 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E3WKrP076791; Fri, 14 Oct 2016 03:32:20 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E3WKIT076789; Fri, 14 Oct 2016 03:32:20 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140332.u9E3WKIT076789@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 03:32:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307256 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 03:32:21 -0000 Author: sephe Date: Fri Oct 14 03:32:20 2016 New Revision: 307256 URL: https://svnweb.freebsd.org/changeset/base/307256 Log: MFC 306433 hyperv/hn: Don't set HASHVAL pktinfo for NDIS < 6.30 This unbreaks packet sending on WS2008R2. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8057 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 03:26:24 2016 (r307255) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 03:32:20 2016 (r307256) @@ -168,6 +168,7 @@ struct hn_tx_ring { struct buf_ring *hn_mbuf_br; int hn_oactive; int hn_tx_idx; + int hn_tx_flags; struct mtx hn_tx_lock; struct hn_softc *hn_sc; @@ -194,10 +195,10 @@ struct hn_tx_ring { struct hn_txdesc *hn_txdesc; bus_dma_tag_t hn_tx_rndis_dtag; struct sysctl_oid *hn_tx_sysctl_tree; - int hn_tx_flags; } __aligned(CACHE_LINE_SIZE); #define HN_TX_FLAG_ATTACHED 0x1 +#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */ /* * Device-specific softc structure Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 03:26:24 2016 (r307255) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 03:32:20 2016 (r307256) @@ -1028,14 +1028,16 @@ hn_encap(struct hn_tx_ring *txr, struct pkt->rm_pktinfooffset = sizeof(*pkt); pkt->rm_pktinfolen = 0; - /* - * Set the hash value for this packet, so that the host could - * dispatch the TX done event for this packet back to this TX - * ring's channel. - */ - pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, - HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL); - *pi_data = txr->hn_tx_idx; + if (txr->hn_tx_flags & HN_TX_FLAG_HASHVAL) { + /* + * Set the hash value for this packet, so that the host could + * dispatch the TX done event for this packet back to this TX + * ring's channel. + */ + pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, + HN_NDIS_HASH_VALUE_SIZE, HN_NDIS_PKTINFO_TYPE_HASHVAL); + *pi_data = txr->hn_tx_idx; + } if (m_head->m_flags & M_VLANTAG) { pi_data = hn_rndis_pktinfo_append(pkt, HN_RNDIS_PKT_LEN, @@ -2940,6 +2942,12 @@ hn_fixup_tx_data(struct hn_softc *sc) for (i = 0; i < sc->hn_tx_ring_cnt; ++i) sc->hn_tx_ring[i].hn_csum_assist = csum_assist; + + if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { + /* Support HASHVAL pktinfo on TX path. */ + for (i = 0; i < sc->hn_tx_ring_cnt; ++i) + sc->hn_tx_ring[i].hn_tx_flags |= HN_TX_FLAG_HASHVAL; + } } static void From owner-svn-src-stable-10@freebsd.org Fri Oct 14 04:14:00 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AC274C10ED2; Fri, 14 Oct 2016 04:14:00 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7D3F382C; Fri, 14 Oct 2016 04:14:00 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E4DxrN092124; Fri, 14 Oct 2016 04:13:59 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E4DxYw092123; Fri, 14 Oct 2016 04:13:59 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140413.u9E4DxYw092123@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 04:13:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307258 - stable/10/sys/x86/x86 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 04:14:00 -0000 Author: sephe Date: Fri Oct 14 04:13:59 2016 New Revision: 307258 URL: https://svnweb.freebsd.org/changeset/base/307258 Log: MFC 306481 x86/ioapic: Fix destination cpu for Hyper-V On Hyper-V: - Stick to the first cpu for all I/O APIC pins. - And don't allow destination cpu changes. Reviewed by: jhb Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7949 Modified: stable/10/sys/x86/x86/io_apic.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/x86/x86/io_apic.c ============================================================================== --- stable/10/sys/x86/x86/io_apic.c Fri Oct 14 03:37:35 2016 (r307257) +++ stable/10/sys/x86/x86/io_apic.c Fri Oct 14 04:13:59 2016 (r307258) @@ -325,6 +325,18 @@ ioapic_assign_cpu(struct intsrc *isrc, u u_int old_id; /* + * On Hyper-V: + * - Stick to the first cpu for all I/O APIC pins. + * - And don't allow destination cpu changes. + */ + if (vm_guest == VM_GUEST_HV) { + if (intpin->io_vector) + return (EINVAL); + else + apic_id = 0; + } + + /* * keep 1st core as the destination for NMI */ if (intpin->io_irq == IRQ_NMI) From owner-svn-src-stable-10@freebsd.org Fri Oct 14 04:53:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 90176C0F61B; Fri, 14 Oct 2016 04:53:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4904F6D9; Fri, 14 Oct 2016 04:53:53 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E4rqg7007255; Fri, 14 Oct 2016 04:53:52 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E4rq2e007253; Fri, 14 Oct 2016 04:53:52 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140453.u9E4rq2e007253@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 04:53:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307259 - stable/10/sys/dev/hyperv/netvsc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 04:53:53 -0000 Author: sephe Date: Fri Oct 14 04:53:52 2016 New Revision: 307259 URL: https://svnweb.freebsd.org/changeset/base/307259 Log: MFC 306482,306483 306482 hyperv/hn: If synthetic parts are detached, don't touch them. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8065 306483 hyperv/hn: Fix detach and attach error handling. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8066 Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 04:13:59 2016 (r307258) +++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h Fri Oct 14 04:53:52 2016 (r307259) @@ -253,6 +253,7 @@ struct hn_softc { #define HN_FLAG_CHIM_CONNECTED 0x0002 #define HN_FLAG_HAS_RSSKEY 0x0004 #define HN_FLAG_HAS_RSSIND 0x0008 +#define HN_FLAG_SYNTH_ATTACHED 0x0010 #define HN_CAP_VLAN 0x0001 #define HN_CAP_MTU 0x0002 Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 04:13:59 2016 (r307258) +++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Fri Oct 14 04:53:52 2016 (r307259) @@ -354,6 +354,7 @@ static void hn_resume(struct hn_softc *) static void hn_rx_drain(struct vmbus_channel *); static void hn_tx_resume(struct hn_softc *, int); static void hn_tx_ring_qflush(struct hn_tx_ring *); +static int netvsc_detach(device_t dev); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); @@ -407,6 +408,9 @@ hn_rss_reconfig(struct hn_softc *sc) HN_LOCK_ASSERT(sc); + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) + return (ENXIO); + /* * Disable RSS first. * @@ -752,27 +756,28 @@ netvsc_attach(device_t dev) return (0); failed: - /* TODO: reuse netvsc_detach() */ - hn_destroy_tx_data(sc); - if (ifp != NULL) - if_free(ifp); + if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) + hn_synth_detach(sc); + netvsc_detach(dev); return (error); } -/* - * TODO: Use this for error handling on attach path. - */ static int netvsc_detach(device_t dev) { struct hn_softc *sc = device_get_softc(dev); + struct ifnet *ifp = sc->hn_ifp; - /* TODO: ether_ifdetach */ - - HN_LOCK(sc); - /* TODO: hn_stop */ - hn_synth_detach(sc); - HN_UNLOCK(sc); + if (device_is_attached(dev)) { + HN_LOCK(sc); + if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_stop(sc); + hn_synth_detach(sc); + } + HN_UNLOCK(sc); + ether_ifdetach(ifp); + } ifmedia_removeall(&sc->hn_media); hn_destroy_rx_data(sc); @@ -781,10 +786,12 @@ netvsc_detach(device_t dev) if (sc->hn_tx_taskq != hn_tx_taskq) taskqueue_free(sc->hn_tx_taskq); - vmbus_xact_ctx_destroy(sc->hn_xact); - HN_LOCK_DESTROY(sc); + if (sc->hn_xact != NULL) + vmbus_xact_ctx_destroy(sc->hn_xact); + + if_free(ifp); - /* TODO: if_free */ + HN_LOCK_DESTROY(sc); return (0); } @@ -1638,6 +1645,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, HN_LOCK(sc); + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) { + HN_UNLOCK(sc); + break; + } + if ((sc->hn_caps & HN_CAP_MTU) == 0) { /* Can't change MTU */ HN_UNLOCK(sc); @@ -1691,6 +1703,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, case SIOCSIFFLAGS: HN_LOCK(sc); + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) { + HN_UNLOCK(sc); + break; + } + if (ifp->if_flags & IFF_UP) { /* * If only the state of the PROMISC flag changed, @@ -1802,6 +1819,9 @@ hn_stop(struct hn_softc *sc) HN_LOCK_ASSERT(sc); + KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, + ("synthetic parts were not attached")); + /* Clear RUNNING bit _before_ hn_suspend() */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); hn_suspend(sc); @@ -1878,6 +1898,9 @@ hn_init_locked(struct hn_softc *sc) HN_LOCK_ASSERT(sc); + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) + return; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) return; @@ -3397,6 +3420,9 @@ hn_synth_attach(struct hn_softc *sc, int int error, nsubch, nchan, i; uint32_t old_caps; + KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0, + ("synthetic parts were attached")); + /* Save capabilities for later verification. */ old_caps = sc->hn_caps; sc->hn_caps = 0; @@ -3509,6 +3535,8 @@ back: error = hn_attach_subchans(sc); if (error) return (error); + + sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED; return (0); } @@ -3522,6 +3550,9 @@ hn_synth_detach(struct hn_softc *sc) { HN_LOCK_ASSERT(sc); + KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, + ("synthetic parts were not attached")); + /* Detach the RNDIS first. */ hn_rndis_detach(sc); @@ -3530,6 +3561,8 @@ hn_synth_detach(struct hn_softc *sc) /* Detach all of the channels. */ hn_detach_allchans(sc); + + sc->hn_flags &= ~HN_FLAG_SYNTH_ATTACHED; } static void From owner-svn-src-stable-10@freebsd.org Fri Oct 14 05:05:25 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9B9E6C0F92A; Fri, 14 Oct 2016 05:05:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4B2A3C4A; Fri, 14 Oct 2016 05:05:25 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E55Oco011079; Fri, 14 Oct 2016 05:05:24 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E55O2V011076; Fri, 14 Oct 2016 05:05:24 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610140505.u9E55O2V011076@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 14 Oct 2016 05:05:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307260 - in stable/10/sys: dev/hyperv/netvsc modules/hyperv/vmbus net X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 05:05:25 -0000 Author: sephe Date: Fri Oct 14 05:05:23 2016 New Revision: 307260 URL: https://svnweb.freebsd.org/changeset/base/307260 Log: MFC 306484,306485 306484 hyperv/vmbus: Add missing vmbus_if.c to module build. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8067 306485 hyperv/hn: Add stubs for OFFLOAD_CURRENT_CONFIG and NETWORK_CHANGE status Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8068 Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c stable/10/sys/modules/hyperv/vmbus/Makefile stable/10/sys/net/rndis.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c ============================================================================== --- stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 04:53:52 2016 (r307259) +++ stable/10/sys/dev/hyperv/netvsc/hv_rndis_filter.c Fri Oct 14 05:05:23 2016 (r307260) @@ -156,6 +156,15 @@ hv_rf_receive_indicate_status(struct hn_ netvsc_linkstatus_callback(sc, 0); break; + case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG: + /* Not really useful; ignore. */ + break; + + case RNDIS_STATUS_NETWORK_CHANGE: + /* TODO */ + if_printf(sc->hn_ifp, "network changed\n"); + break; + default: /* TODO: */ if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n", Modified: stable/10/sys/modules/hyperv/vmbus/Makefile ============================================================================== --- stable/10/sys/modules/hyperv/vmbus/Makefile Fri Oct 14 04:53:52 2016 (r307259) +++ stable/10/sys/modules/hyperv/vmbus/Makefile Fri Oct 14 05:05:23 2016 (r307260) @@ -11,6 +11,7 @@ SRCS= hyperv.c \ vmbus_br.c \ vmbus_chan.c \ vmbus_et.c \ + vmbus_if.c \ vmbus_xact.c SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h vmbus_if.h Modified: stable/10/sys/net/rndis.h ============================================================================== --- stable/10/sys/net/rndis.h Fri Oct 14 04:53:52 2016 (r307259) +++ stable/10/sys/net/rndis.h Fri Oct 14 05:05:23 2016 (r307260) @@ -31,6 +31,8 @@ #define RNDIS_STATUS_PENDING 0x00000103L #define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BL #define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CL +#define RNDIS_STATUS_NETWORK_CHANGE 0x40010018L +#define RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG 0x40020006L #define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005L #define RNDIS_STATUS_FAILURE 0xC0000001L #define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBL From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:14:37 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 79AEAC11160; Fri, 14 Oct 2016 07:14:37 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3242EAE7; Fri, 14 Oct 2016 07:14:37 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7EalE060434; Fri, 14 Oct 2016 07:14:36 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7EaS9060430; Fri, 14 Oct 2016 07:14:36 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140714.u9E7EaS9060430@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:14:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307266 - in stable/10: cddl/contrib/opensolaris/cmd/zdb cddl/contrib/opensolaris/cmd/ztest sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/cddl/contrib/opensolaris/uts/common/fs/zfs... X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:14:37 -0000 Author: mav Date: Fri Oct 14 07:14:35 2016 New Revision: 307266 URL: https://svnweb.freebsd.org/changeset/base/307266 Log: MFC r305323: MFV r302991: 6950 ARC should cache compressed data illumos/illumos-gate@dcbf3bd6a1f1360fc1afcee9e22c6dcff7844bf2 https://github.com/illumos/illumos-gate/commit/dcbf3bd6a1f1360fc1afcee9e22c6dcff 7844bf2 https://www.illumos.org/issues/6950 When reading compressed data from disk, the ARC should keep the compressed block cached and only decompress it when consumers access the block. The uncompressed data should be short-lived allowing the ARC to cache a much large r amount of data. The DMU would also maintain a smaller cache of uncompressed blocks to minimize the impact of decompressing frequently accessed blocks. Reviewed by: Prakash Surya Reviewed by: Dan Kimmel Reviewed by: Matt Ahrens Reviewed by: Paul Dagnelie Reviewed by: Don Brady Reviewed by: Richard Elling Approved by: Richard Lowe Author: George Wilson Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_checksum.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct 14 07:13:43 2016 (r307265) +++ stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct 14 07:14:35 2016 (r307266) @@ -1289,7 +1289,7 @@ visit_indirect(spa_t *spa, const dnode_p } if (!err) ASSERT3U(fill, ==, BP_GET_FILL(bp)); - (void) arc_buf_remove_ref(buf, &buf); + arc_buf_destroy(buf, &buf); } return (err); Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:13:43 2016 (r307265) +++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:14:35 2016 (r307266) @@ -189,6 +189,7 @@ extern uint64_t metaslab_gang_bang; extern uint64_t metaslab_df_alloc_threshold; extern uint64_t zfs_deadman_synctime_ms; extern int metaslab_preload_limit; +extern boolean_t zfs_compressed_arc_enabled; static ztest_shared_opts_t *ztest_shared_opts; static ztest_shared_opts_t ztest_opts; @@ -5355,6 +5356,12 @@ ztest_resume_thread(void *arg) if (spa_suspended(spa)) ztest_resume(spa); (void) poll(NULL, 0, 100); + + /* + * Periodically change the zfs_compressed_arc_enabled setting. + */ + if (ztest_random(10) == 0) + zfs_compressed_arc_enabled = ztest_random(2); } return (NULL); } Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Oct 14 07:13:43 2016 (r307265) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Oct 14 07:14:35 2016 (r307266) @@ -120,9 +120,134 @@ * - ARC header release, as it removes from L2ARC buflists */ +/* + * ARC operation: + * + * Every block that is in the ARC is tracked by an arc_buf_hdr_t structure. + * This structure can point either to a block that is still in the cache or to + * one that is only accessible in an L2 ARC device, or it can provide + * information about a block that was recently evicted. If a block is + * only accessible in the L2ARC, then the arc_buf_hdr_t only has enough + * information to retrieve it from the L2ARC device. This information is + * stored in the l2arc_buf_hdr_t sub-structure of the arc_buf_hdr_t. A block + * that is in this state cannot access the data directly. + * + * Blocks that are actively being referenced or have not been evicted + * are cached in the L1ARC. The L1ARC (l1arc_buf_hdr_t) is a structure within + * the arc_buf_hdr_t that will point to the data block in memory. A block can + * only be read by a consumer if it has an l1arc_buf_hdr_t. The L1ARC + * caches data in two ways -- in a list of arc buffers (arc_buf_t) and + * also in the arc_buf_hdr_t's private physical data block pointer (b_pdata). + * Each arc buffer (arc_buf_t) is being actively accessed by a specific ARC + * consumer, and always contains uncompressed data. The ARC will provide + * references to this data and will keep it cached until it is no longer in + * use. Typically, the arc will try to cache only the L1ARC's physical data + * block and will aggressively evict any arc_buf_t that is no longer referenced. + * The amount of memory consumed by the arc_buf_t's can be seen via the + * "overhead_size" kstat. + * + * + * arc_buf_hdr_t + * +-----------+ + * | | + * | | + * | | + * +-----------+ + * l2arc_buf_hdr_t| | + * | | + * +-----------+ + * l1arc_buf_hdr_t| | + * | | arc_buf_t + * | b_buf +------------>+---------+ arc_buf_t + * | | |b_next +---->+---------+ + * | b_pdata +-+ |---------| |b_next +-->NULL + * +-----------+ | | | +---------+ + * | |b_data +-+ | | + * | +---------+ | |b_data +-+ + * +->+------+ | +---------+ | + * (potentially) | | | | + * compressed | | | | + * data +------+ | v + * +->+------+ +------+ + * uncompressed | | | | + * data | | | | + * +------+ +------+ + * + * The L1ARC's data pointer, however, may or may not be uncompressed. The + * ARC has the ability to store the physical data (b_pdata) associated with + * the DVA of the arc_buf_hdr_t. Since the b_pdata is a copy of the on-disk + * physical block, it will match its on-disk compression characteristics. + * If the block on-disk is compressed, then the physical data block + * in the cache will also be compressed and vice-versa. This behavior + * can be disabled by setting 'zfs_compressed_arc_enabled' to B_FALSE. When the + * compressed ARC functionality is disabled, the b_pdata will point to an + * uncompressed version of the on-disk data. + * + * When a consumer reads a block, the ARC must first look to see if the + * arc_buf_hdr_t is cached. If the hdr is cached and already has an arc_buf_t, + * then an additional arc_buf_t is allocated and the uncompressed data is + * bcopied from the existing arc_buf_t. If the hdr is cached but does not + * have an arc_buf_t, then the ARC allocates a new arc_buf_t and decompresses + * the b_pdata contents into the arc_buf_t's b_data. If the arc_buf_hdr_t's + * b_pdata is not compressed, then the block is shared with the newly + * allocated arc_buf_t. This block sharing only occurs with one arc_buf_t + * in the arc buffer chain. Sharing the block reduces the memory overhead + * required when the hdr is caching uncompressed blocks or the compressed + * arc functionality has been disabled via 'zfs_compressed_arc_enabled'. + * + * The diagram below shows an example of an uncompressed ARC hdr that is + * sharing its data with an arc_buf_t: + * + * arc_buf_hdr_t + * +-----------+ + * | | + * | | + * | | + * +-----------+ + * l2arc_buf_hdr_t| | + * | | + * +-----------+ + * l1arc_buf_hdr_t| | + * | | arc_buf_t (shared) + * | b_buf +------------>+---------+ arc_buf_t + * | | |b_next +---->+---------+ + * | b_pdata +-+ |---------| |b_next +-->NULL + * +-----------+ | | | +---------+ + * | |b_data +-+ | | + * | +---------+ | |b_data +-+ + * +->+------+ | +---------+ | + * | | | | + * uncompressed | | | | + * data +------+ | | + * ^ +->+------+ | + * | uncompressed | | | + * | data | | | + * | +------+ | + * +---------------------------------+ + * + * Writing to the arc requires that the ARC first discard the b_pdata + * since the physical block is about to be rewritten. The new data contents + * will be contained in the arc_buf_t (uncompressed). As the I/O pipeline + * performs the write, it may compress the data before writing it to disk. + * The ARC will be called with the transformed data and will bcopy the + * transformed on-disk block into a newly allocated b_pdata. + * + * When the L2ARC is in use, it will also take advantage of the b_pdata. The + * L2ARC will always write the contents of b_pdata to the L2ARC. This means + * that when compressed arc is enabled that the L2ARC blocks are identical + * to the on-disk block in the main data pool. This provides a significant + * advantage since the ARC can leverage the bp's checksum when reading from the + * L2ARC to determine if the contents are valid. However, if the compressed + * arc is disabled, then the L2ARC's block must be transformed to look + * like the physical block in the main data pool before comparing the + * checksum and determining its validity. + */ + #include #include +#include #include +#include #include #include #include @@ -154,10 +279,6 @@ static kcondvar_t arc_reclaim_thread_cv; static boolean_t arc_reclaim_thread_exit; static kcondvar_t arc_reclaim_waiters_cv; -static kmutex_t arc_user_evicts_lock; -static kcondvar_t arc_user_evicts_cv; -static boolean_t arc_user_evicts_thread_exit; - uint_t arc_reduce_dnlc_percent = 3; /* @@ -229,13 +350,14 @@ uint64_t zfs_arc_meta_min = 0; int zfs_arc_grow_retry = 0; int zfs_arc_shrink_shift = 0; int zfs_arc_p_min_shift = 0; -int zfs_disable_dup_eviction = 0; uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */ u_int zfs_arc_free_target = 0; /* Absolute min for arc min / max is 16MB. */ static uint64_t arc_abs_min = 16 << 20; +boolean_t zfs_compressed_arc_enabled = B_TRUE; + static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS); static int sysctl_vfs_zfs_arc_meta_limit(SYSCTL_HANDLER_ARGS); static int sysctl_vfs_zfs_arc_max(SYSCTL_HANDLER_ARGS); @@ -268,6 +390,8 @@ SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_ave SYSCTL_INT(_vfs_zfs, OID_AUTO, arc_shrink_shift, CTLFLAG_RW, &arc_shrink_shift, 0, "log2(fraction of arc to reclaim)"); +SYSCTL_INT(_vfs_zfs, OID_AUTO, compressed_arc_enabled, CTLFLAG_RDTUN, + &zfs_compressed_arc_enabled, 0, "Enable compressed ARC"); /* * We don't have a tunable for arc_free_target due to the dependency on @@ -349,7 +473,7 @@ typedef struct arc_state { /* * total amount of evictable data in this state */ - uint64_t arcs_lsize[ARC_BUFC_NUMTYPES]; + refcount_t arcs_esize[ARC_BUFC_NUMTYPES]; /* * total amount of data in this state; this includes: evictable, * non-evictable, ARC_BUFC_DATA, and ARC_BUFC_METADATA. @@ -415,6 +539,26 @@ typedef struct arc_stats { kstat_named_t arcstat_c_max; kstat_named_t arcstat_size; /* + * Number of compressed bytes stored in the arc_buf_hdr_t's b_pdata. + * Note that the compressed bytes may match the uncompressed bytes + * if the block is either not compressed or compressed arc is disabled. + */ + kstat_named_t arcstat_compressed_size; + /* + * Uncompressed size of the data stored in b_pdata. If compressed + * arc is disabled then this value will be identical to the stat + * above. + */ + kstat_named_t arcstat_uncompressed_size; + /* + * Number of bytes stored in all the arc_buf_t's. This is classified + * as "overhead" since this data is typically short-lived and will + * be evicted from the arc when it becomes unreferenced unless the + * zfs_keep_uncompressed_metadata or zfs_keep_uncompressed_level + * values have been set (see comment in dbuf.c for more information). + */ + kstat_named_t arcstat_overhead_size; + /* * Number of bytes consumed by internal ARC structures necessary * for tracking purposes; these structures are not actually * backed by ARC buffers. This includes arc_buf_hdr_t structures @@ -559,16 +703,12 @@ typedef struct arc_stats { kstat_named_t arcstat_l2_evict_reading; kstat_named_t arcstat_l2_evict_l1cached; kstat_named_t arcstat_l2_free_on_write; - kstat_named_t arcstat_l2_cdata_free_on_write; kstat_named_t arcstat_l2_abort_lowmem; kstat_named_t arcstat_l2_cksum_bad; kstat_named_t arcstat_l2_io_error; kstat_named_t arcstat_l2_size; kstat_named_t arcstat_l2_asize; kstat_named_t arcstat_l2_hdr_size; - kstat_named_t arcstat_l2_compress_successes; - kstat_named_t arcstat_l2_compress_zeros; - kstat_named_t arcstat_l2_compress_failures; kstat_named_t arcstat_l2_padding_needed; kstat_named_t arcstat_l2_write_trylock_fail; kstat_named_t arcstat_l2_write_passed_headroom; @@ -583,9 +723,6 @@ typedef struct arc_stats { kstat_named_t arcstat_l2_write_buffer_list_iter; kstat_named_t arcstat_l2_write_buffer_list_null_iter; kstat_named_t arcstat_memory_throttle_count; - kstat_named_t arcstat_duplicate_buffers; - kstat_named_t arcstat_duplicate_buffers_size; - kstat_named_t arcstat_duplicate_reads; kstat_named_t arcstat_meta_used; kstat_named_t arcstat_meta_limit; kstat_named_t arcstat_meta_max; @@ -628,6 +765,9 @@ static arc_stats_t arc_stats = { { "c_min", KSTAT_DATA_UINT64 }, { "c_max", KSTAT_DATA_UINT64 }, { "size", KSTAT_DATA_UINT64 }, + { "compressed_size", KSTAT_DATA_UINT64 }, + { "uncompressed_size", KSTAT_DATA_UINT64 }, + { "overhead_size", KSTAT_DATA_UINT64 }, { "hdr_size", KSTAT_DATA_UINT64 }, { "data_size", KSTAT_DATA_UINT64 }, { "metadata_size", KSTAT_DATA_UINT64 }, @@ -661,16 +801,12 @@ static arc_stats_t arc_stats = { { "l2_evict_reading", KSTAT_DATA_UINT64 }, { "l2_evict_l1cached", KSTAT_DATA_UINT64 }, { "l2_free_on_write", KSTAT_DATA_UINT64 }, - { "l2_cdata_free_on_write", KSTAT_DATA_UINT64 }, { "l2_abort_lowmem", KSTAT_DATA_UINT64 }, { "l2_cksum_bad", KSTAT_DATA_UINT64 }, { "l2_io_error", KSTAT_DATA_UINT64 }, { "l2_size", KSTAT_DATA_UINT64 }, { "l2_asize", KSTAT_DATA_UINT64 }, { "l2_hdr_size", KSTAT_DATA_UINT64 }, - { "l2_compress_successes", KSTAT_DATA_UINT64 }, - { "l2_compress_zeros", KSTAT_DATA_UINT64 }, - { "l2_compress_failures", KSTAT_DATA_UINT64 }, { "l2_padding_needed", KSTAT_DATA_UINT64 }, { "l2_write_trylock_fail", KSTAT_DATA_UINT64 }, { "l2_write_passed_headroom", KSTAT_DATA_UINT64 }, @@ -685,9 +821,6 @@ static arc_stats_t arc_stats = { { "l2_write_buffer_list_iter", KSTAT_DATA_UINT64 }, { "l2_write_buffer_list_null_iter", KSTAT_DATA_UINT64 }, { "memory_throttle_count", KSTAT_DATA_UINT64 }, - { "duplicate_buffers", KSTAT_DATA_UINT64 }, - { "duplicate_buffers_size", KSTAT_DATA_UINT64 }, - { "duplicate_reads", KSTAT_DATA_UINT64 }, { "arc_meta_used", KSTAT_DATA_UINT64 }, { "arc_meta_limit", KSTAT_DATA_UINT64 }, { "arc_meta_max", KSTAT_DATA_UINT64 }, @@ -760,8 +893,12 @@ static arc_state_t *arc_l2c_only; #define arc_meta_used ARCSTAT(arcstat_meta_used) /* size of metadata */ #define arc_meta_max ARCSTAT(arcstat_meta_max) /* max size of metadata */ -#define L2ARC_IS_VALID_COMPRESS(_c_) \ - ((_c_) == ZIO_COMPRESS_LZ4 || (_c_) == ZIO_COMPRESS_EMPTY) +/* compressed size of entire arc */ +#define arc_compressed_size ARCSTAT(arcstat_compressed_size) +/* uncompressed size of entire arc */ +#define arc_uncompressed_size ARCSTAT(arcstat_uncompressed_size) +/* number of bytes in the arc from arc_buf_t's */ +#define arc_overhead_size ARCSTAT(arcstat_overhead_size) static int arc_no_grow; /* Don't try to grow cache size */ static uint64_t arc_tempreserve; @@ -821,6 +958,7 @@ struct arc_write_callback { */ typedef struct l1arc_buf_hdr { kmutex_t b_freeze_lock; + zio_cksum_t *b_freeze_cksum; #ifdef ZFS_DEBUG /* * used for debugging wtih kmem_flags - by allocating and freeing @@ -831,9 +969,10 @@ typedef struct l1arc_buf_hdr { #endif arc_buf_t *b_buf; - uint32_t b_datacnt; + uint32_t b_bufcnt; /* for waiting on writes to complete */ kcondvar_t b_cv; + uint8_t b_byteswap; /* protected by arc state mutex */ arc_state_t *b_state; @@ -846,8 +985,7 @@ typedef struct l1arc_buf_hdr { refcount_t b_refcnt; arc_callback_t *b_acb; - /* temporary buffer holder for in-flight compressed or padded data */ - void *b_tmp_cdata; + void *b_pdata; } l1arc_buf_hdr_t; typedef struct l2arc_dev l2arc_dev_t; @@ -856,9 +994,6 @@ typedef struct l2arc_buf_hdr { /* protected by arc_buf_hdr mutex */ l2arc_dev_t *b_dev; /* L2ARC device */ uint64_t b_daddr; /* disk address, offset byte */ - /* real alloc'd buffer size depending on b_compress applied */ - int32_t b_asize; - uint8_t b_compress; list_node_t b_l2node; } l2arc_buf_hdr_t; @@ -867,20 +1002,37 @@ struct arc_buf_hdr { /* protected by hash lock */ dva_t b_dva; uint64_t b_birth; - /* - * Even though this checksum is only set/verified when a buffer is in - * the L1 cache, it needs to be in the set of common fields because it - * must be preserved from the time before a buffer is written out to - * L2ARC until after it is read back in. - */ - zio_cksum_t *b_freeze_cksum; + arc_buf_contents_t b_type; arc_buf_hdr_t *b_hash_next; arc_flags_t b_flags; - /* immutable */ - int32_t b_size; - uint64_t b_spa; + /* + * This field stores the size of the data buffer after + * compression, and is set in the arc's zio completion handlers. + * It is in units of SPA_MINBLOCKSIZE (e.g. 1 == 512 bytes). + * + * While the block pointers can store up to 32MB in their psize + * field, we can only store up to 32MB minus 512B. This is due + * to the bp using a bias of 1, whereas we use a bias of 0 (i.e. + * a field of zeros represents 512B in the bp). We can't use a + * bias of 1 since we need to reserve a psize of zero, here, to + * represent holes and embedded blocks. + * + * This isn't a problem in practice, since the maximum size of a + * buffer is limited to 16MB, so we never need to store 32MB in + * this field. Even in the upstream illumos code base, the + * maximum size of a buffer is limited to 16MB. + */ + uint16_t b_psize; + + /* + * This field stores the size of the data buffer before + * compression, and cannot change once set. It is in units + * of SPA_MINBLOCKSIZE (e.g. 2 == 1024 bytes) + */ + uint16_t b_lsize; /* immutable */ + uint64_t b_spa; /* immutable */ /* L2ARC fields. Undefined when not in L2ARC. */ l2arc_buf_hdr_t b_l2hdr; @@ -984,9 +1136,6 @@ sysctl_vfs_zfs_arc_min(SYSCTL_HANDLER_AR } #endif -static arc_buf_t *arc_eviction_list; -static arc_buf_hdr_t arc_eviction_hdr; - #define GHOST_STATE(state) \ ((state) == arc_mru_ghost || (state) == arc_mfu_ghost || \ (state) == arc_l2c_only) @@ -995,25 +1144,35 @@ static arc_buf_hdr_t arc_eviction_hdr; #define HDR_IO_IN_PROGRESS(hdr) ((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS) #define HDR_IO_ERROR(hdr) ((hdr)->b_flags & ARC_FLAG_IO_ERROR) #define HDR_PREFETCH(hdr) ((hdr)->b_flags & ARC_FLAG_PREFETCH) -#define HDR_FREED_IN_READ(hdr) ((hdr)->b_flags & ARC_FLAG_FREED_IN_READ) -#define HDR_BUF_AVAILABLE(hdr) ((hdr)->b_flags & ARC_FLAG_BUF_AVAILABLE) +#define HDR_COMPRESSION_ENABLED(hdr) \ + ((hdr)->b_flags & ARC_FLAG_COMPRESSED_ARC) #define HDR_L2CACHE(hdr) ((hdr)->b_flags & ARC_FLAG_L2CACHE) -#define HDR_L2COMPRESS(hdr) ((hdr)->b_flags & ARC_FLAG_L2COMPRESS) #define HDR_L2_READING(hdr) \ - (((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS) && \ - ((hdr)->b_flags & ARC_FLAG_HAS_L2HDR)) + (((hdr)->b_flags & ARC_FLAG_IO_IN_PROGRESS) && \ + ((hdr)->b_flags & ARC_FLAG_HAS_L2HDR)) #define HDR_L2_WRITING(hdr) ((hdr)->b_flags & ARC_FLAG_L2_WRITING) #define HDR_L2_EVICTED(hdr) ((hdr)->b_flags & ARC_FLAG_L2_EVICTED) #define HDR_L2_WRITE_HEAD(hdr) ((hdr)->b_flags & ARC_FLAG_L2_WRITE_HEAD) +#define HDR_SHARED_DATA(hdr) ((hdr)->b_flags & ARC_FLAG_SHARED_DATA) #define HDR_ISTYPE_METADATA(hdr) \ - ((hdr)->b_flags & ARC_FLAG_BUFC_METADATA) + ((hdr)->b_flags & ARC_FLAG_BUFC_METADATA) #define HDR_ISTYPE_DATA(hdr) (!HDR_ISTYPE_METADATA(hdr)) #define HDR_HAS_L1HDR(hdr) ((hdr)->b_flags & ARC_FLAG_HAS_L1HDR) #define HDR_HAS_L2HDR(hdr) ((hdr)->b_flags & ARC_FLAG_HAS_L2HDR) +/* For storing compression mode in b_flags */ +#define HDR_COMPRESS_OFFSET (highbit64(ARC_FLAG_COMPRESS_0) - 1) + +#define HDR_GET_COMPRESS(hdr) ((enum zio_compress)BF32_GET((hdr)->b_flags, \ + HDR_COMPRESS_OFFSET, SPA_COMPRESSBITS)) +#define HDR_SET_COMPRESS(hdr, cmp) BF32_SET((hdr)->b_flags, \ + HDR_COMPRESS_OFFSET, SPA_COMPRESSBITS, (cmp)); + +#define ARC_BUF_LAST(buf) ((buf)->b_next == NULL) + /* * Other sizes */ @@ -1066,16 +1225,6 @@ uint64_t zfs_crc64_table[256]; #define L2ARC_FEED_SECS 1 /* caching interval secs */ #define L2ARC_FEED_MIN_MS 200 /* min caching interval ms */ -/* - * Used to distinguish headers that are being process by - * l2arc_write_buffers(), but have yet to be assigned to a l2arc disk - * address. This can happen when the header is added to the l2arc's list - * of buffers to write in the first stage of l2arc_write_buffers(), but - * has not yet been written out which happens in the second stage of - * l2arc_write_buffers(). - */ -#define L2ARC_ADDR_UNSET ((uint64_t)(-1)) - #define l2arc_writes_sent ARCSTAT(arcstat_l2_writes_sent) #define l2arc_writes_done ARCSTAT(arcstat_l2_writes_done) @@ -1110,41 +1259,47 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, l2arc_nor SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, anon_size, CTLFLAG_RD, &ARC_anon.arcs_size.rc_count, 0, "size of anonymous state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, anon_metadata_lsize, CTLFLAG_RD, - &ARC_anon.arcs_lsize[ARC_BUFC_METADATA], 0, "size of anonymous state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, anon_data_lsize, CTLFLAG_RD, - &ARC_anon.arcs_lsize[ARC_BUFC_DATA], 0, "size of anonymous state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, anon_metadata_esize, CTLFLAG_RD, + &ARC_anon.arcs_esize[ARC_BUFC_METADATA].rc_count, 0, + "size of anonymous state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, anon_data_esize, CTLFLAG_RD, + &ARC_anon.arcs_esize[ARC_BUFC_DATA].rc_count, 0, + "size of anonymous state"); SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_size, CTLFLAG_RD, &ARC_mru.arcs_size.rc_count, 0, "size of mru state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_metadata_lsize, CTLFLAG_RD, - &ARC_mru.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mru state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_data_lsize, CTLFLAG_RD, - &ARC_mru.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mru state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_metadata_esize, CTLFLAG_RD, + &ARC_mru.arcs_esize[ARC_BUFC_METADATA].rc_count, 0, + "size of metadata in mru state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_data_esize, CTLFLAG_RD, + &ARC_mru.arcs_esize[ARC_BUFC_DATA].rc_count, 0, + "size of data in mru state"); SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_ghost_size, CTLFLAG_RD, &ARC_mru_ghost.arcs_size.rc_count, 0, "size of mru ghost state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_ghost_metadata_lsize, CTLFLAG_RD, - &ARC_mru_ghost.arcs_lsize[ARC_BUFC_METADATA], 0, +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_ghost_metadata_esize, CTLFLAG_RD, + &ARC_mru_ghost.arcs_esize[ARC_BUFC_METADATA].rc_count, 0, "size of metadata in mru ghost state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_ghost_data_lsize, CTLFLAG_RD, - &ARC_mru_ghost.arcs_lsize[ARC_BUFC_DATA], 0, +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mru_ghost_data_esize, CTLFLAG_RD, + &ARC_mru_ghost.arcs_esize[ARC_BUFC_DATA].rc_count, 0, "size of data in mru ghost state"); SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_size, CTLFLAG_RD, &ARC_mfu.arcs_size.rc_count, 0, "size of mfu state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_metadata_lsize, CTLFLAG_RD, - &ARC_mfu.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mfu state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_data_lsize, CTLFLAG_RD, - &ARC_mfu.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mfu state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_metadata_esize, CTLFLAG_RD, + &ARC_mfu.arcs_esize[ARC_BUFC_METADATA].rc_count, 0, + "size of metadata in mfu state"); +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_data_esize, CTLFLAG_RD, + &ARC_mfu.arcs_esize[ARC_BUFC_DATA].rc_count, 0, + "size of data in mfu state"); SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_ghost_size, CTLFLAG_RD, &ARC_mfu_ghost.arcs_size.rc_count, 0, "size of mfu ghost state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_ghost_metadata_lsize, CTLFLAG_RD, - &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_METADATA], 0, +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_ghost_metadata_esize, CTLFLAG_RD, + &ARC_mfu_ghost.arcs_esize[ARC_BUFC_METADATA].rc_count, 0, "size of metadata in mfu ghost state"); -SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_ghost_data_lsize, CTLFLAG_RD, - &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_DATA], 0, +SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, mfu_ghost_data_esize, CTLFLAG_RD, + &ARC_mfu_ghost.arcs_esize[ARC_BUFC_DATA].rc_count, 0, "size of data in mfu ghost state"); SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, l2c_only_size, CTLFLAG_RD, @@ -1177,12 +1332,10 @@ static kmutex_t l2arc_free_on_write_mtx; static uint64_t l2arc_ndev; /* number of devices */ typedef struct l2arc_read_callback { - arc_buf_t *l2rcb_buf; /* read buffer */ - spa_t *l2rcb_spa; /* spa */ + arc_buf_hdr_t *l2rcb_hdr; /* read buffer */ blkptr_t l2rcb_bp; /* original blkptr */ zbookmark_phys_t l2rcb_zb; /* original bookmark */ int l2rcb_flags; /* original flags */ - enum zio_compress l2rcb_compress; /* applied compress */ void *l2rcb_data; /* temporary buffer */ } l2arc_read_callback_t; @@ -1195,7 +1348,7 @@ typedef struct l2arc_data_free { /* protected by l2arc_free_on_write_mtx */ void *l2df_data; size_t l2df_size; - void (*l2df_func)(void *, size_t); + arc_buf_contents_t l2df_type; list_node_t l2df_list_node; } l2arc_data_free_t; @@ -1203,21 +1356,22 @@ static kmutex_t l2arc_feed_thr_lock; static kcondvar_t l2arc_feed_thr_cv; static uint8_t l2arc_thread_exit; -static void arc_get_data_buf(arc_buf_t *); +static void *arc_get_data_buf(arc_buf_hdr_t *, uint64_t, void *); +static void arc_free_data_buf(arc_buf_hdr_t *, void *, uint64_t, void *); +static void arc_hdr_free_pdata(arc_buf_hdr_t *hdr); +static void arc_hdr_alloc_pdata(arc_buf_hdr_t *); static void arc_access(arc_buf_hdr_t *, kmutex_t *); static boolean_t arc_is_overflowing(); static void arc_buf_watch(arc_buf_t *); static arc_buf_contents_t arc_buf_type(arc_buf_hdr_t *); static uint32_t arc_bufc_to_flags(arc_buf_contents_t); +static inline void arc_hdr_set_flags(arc_buf_hdr_t *hdr, arc_flags_t flags); +static inline void arc_hdr_clear_flags(arc_buf_hdr_t *hdr, arc_flags_t flags); static boolean_t l2arc_write_eligible(uint64_t, arc_buf_hdr_t *); static void l2arc_read_done(zio_t *); -static boolean_t l2arc_transform_buf(arc_buf_hdr_t *, boolean_t); -static void l2arc_decompress_zio(zio_t *, arc_buf_hdr_t *, enum zio_compress); -static void l2arc_release_cdata_buf(arc_buf_hdr_t *); - static void l2arc_trim(const arc_buf_hdr_t *hdr) { @@ -1226,13 +1380,9 @@ l2arc_trim(const arc_buf_hdr_t *hdr) ASSERT(HDR_HAS_L2HDR(hdr)); ASSERT(MUTEX_HELD(&dev->l2ad_mtx)); - if (hdr->b_l2hdr.b_daddr == L2ARC_ADDR_UNSET) - return; - if (hdr->b_l2hdr.b_asize != 0) { + if (HDR_GET_PSIZE(hdr) != 0) { trim_map_free(dev->l2ad_vdev, hdr->b_l2hdr.b_daddr, - hdr->b_l2hdr.b_asize, 0); - } else { - ASSERT3U(hdr->b_l2hdr.b_compress, ==, ZIO_COMPRESS_EMPTY); + HDR_GET_PSIZE(hdr), 0); } } @@ -1253,14 +1403,14 @@ buf_hash(uint64_t spa, const dva_t *dva, return (crc); } -#define BUF_EMPTY(buf) \ - ((buf)->b_dva.dva_word[0] == 0 && \ - (buf)->b_dva.dva_word[1] == 0) - -#define BUF_EQUAL(spa, dva, birth, buf) \ - ((buf)->b_dva.dva_word[0] == (dva)->dva_word[0]) && \ - ((buf)->b_dva.dva_word[1] == (dva)->dva_word[1]) && \ - ((buf)->b_birth == birth) && ((buf)->b_spa == spa) +#define HDR_EMPTY(hdr) \ + ((hdr)->b_dva.dva_word[0] == 0 && \ + (hdr)->b_dva.dva_word[1] == 0) + +#define HDR_EQUAL(spa, dva, birth, hdr) \ + ((hdr)->b_dva.dva_word[0] == (dva)->dva_word[0]) && \ + ((hdr)->b_dva.dva_word[1] == (dva)->dva_word[1]) && \ + ((hdr)->b_birth == birth) && ((hdr)->b_spa == spa) static void buf_discard_identity(arc_buf_hdr_t *hdr) @@ -1282,7 +1432,7 @@ buf_hash_find(uint64_t spa, const blkptr mutex_enter(hash_lock); for (hdr = buf_hash_table.ht_table[idx]; hdr != NULL; hdr = hdr->b_hash_next) { - if (BUF_EQUAL(spa, dva, birth, hdr)) { + if (HDR_EQUAL(spa, dva, birth, hdr)) { *lockp = hash_lock; return (hdr); } @@ -1320,13 +1470,13 @@ buf_hash_insert(arc_buf_hdr_t *hdr, kmut for (fhdr = buf_hash_table.ht_table[idx], i = 0; fhdr != NULL; fhdr = fhdr->b_hash_next, i++) { - if (BUF_EQUAL(hdr->b_spa, &hdr->b_dva, hdr->b_birth, fhdr)) + if (HDR_EQUAL(hdr->b_spa, &hdr->b_dva, hdr->b_birth, fhdr)) return (fhdr); } hdr->b_hash_next = buf_hash_table.ht_table[idx]; buf_hash_table.ht_table[idx] = hdr; - hdr->b_flags |= ARC_FLAG_IN_HASH_TABLE; + arc_hdr_set_flags(hdr, ARC_FLAG_IN_HASH_TABLE); /* collect some hash table performance data */ if (i > 0) { @@ -1354,12 +1504,12 @@ buf_hash_remove(arc_buf_hdr_t *hdr) hdrp = &buf_hash_table.ht_table[idx]; while ((fhdr = *hdrp) != hdr) { - ASSERT(fhdr != NULL); + ASSERT3P(fhdr, !=, NULL); hdrp = &fhdr->b_hash_next; } *hdrp = hdr->b_hash_next; hdr->b_hash_next = NULL; - hdr->b_flags &= ~ARC_FLAG_IN_HASH_TABLE; + arc_hdr_clear_flags(hdr, ARC_FLAG_IN_HASH_TABLE); /* collect some hash table performance data */ ARCSTAT_BUMPDOWN(arcstat_hash_elements); @@ -1445,7 +1595,7 @@ hdr_full_dest(void *vbuf, void *unused) { arc_buf_hdr_t *hdr = vbuf; - ASSERT(BUF_EMPTY(hdr)); + ASSERT(HDR_EMPTY(hdr)); cv_destroy(&hdr->b_l1hdr.b_cv); refcount_destroy(&hdr->b_l1hdr.b_refcnt); mutex_destroy(&hdr->b_l1hdr.b_freeze_lock); @@ -1459,7 +1609,7 @@ hdr_l2only_dest(void *vbuf, void *unused { arc_buf_hdr_t *hdr = vbuf; - ASSERT(BUF_EMPTY(hdr)); + ASSERT(HDR_EMPTY(hdr)); arc_space_return(HDR_L2ONLY_SIZE, ARC_SPACE_L2HDRS); } @@ -1532,166 +1682,138 @@ retry: } } -/* - * Transition between the two allocation states for the arc_buf_hdr struct. - * The arc_buf_hdr struct can be allocated with (hdr_full_cache) or without - * (hdr_l2only_cache) the fields necessary for the L1 cache - the smaller - * version is used when a cache buffer is only in the L2ARC in order to reduce - * memory usage. - */ -static arc_buf_hdr_t * -arc_hdr_realloc(arc_buf_hdr_t *hdr, kmem_cache_t *old, kmem_cache_t *new) -{ - ASSERT(HDR_HAS_L2HDR(hdr)); - - arc_buf_hdr_t *nhdr; - l2arc_dev_t *dev = hdr->b_l2hdr.b_dev; - - ASSERT((old == hdr_full_cache && new == hdr_l2only_cache) || - (old == hdr_l2only_cache && new == hdr_full_cache)); - - nhdr = kmem_cache_alloc(new, KM_PUSHPAGE); - - ASSERT(MUTEX_HELD(HDR_LOCK(hdr))); - buf_hash_remove(hdr); - - bcopy(hdr, nhdr, HDR_L2ONLY_SIZE); - - if (new == hdr_full_cache) { - nhdr->b_flags |= ARC_FLAG_HAS_L1HDR; - /* - * arc_access and arc_change_state need to be aware that a - * header has just come out of L2ARC, so we set its state to - * l2c_only even though it's about to change. - */ - nhdr->b_l1hdr.b_state = arc_l2c_only; - - /* Verify previous threads set to NULL before freeing */ - ASSERT3P(nhdr->b_l1hdr.b_tmp_cdata, ==, NULL); - } else { - ASSERT(hdr->b_l1hdr.b_buf == NULL); - ASSERT0(hdr->b_l1hdr.b_datacnt); - - /* - * If we've reached here, We must have been called from - * arc_evict_hdr(), as such we should have already been - * removed from any ghost list we were previously on - * (which protects us from racing with arc_evict_state), - * thus no locking is needed during this check. - */ - ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node)); - - /* - * A buffer must not be moved into the arc_l2c_only - * state if it's not finished being written out to the - * l2arc device. Otherwise, the b_l1hdr.b_tmp_cdata field - * might try to be accessed, even though it was removed. - */ - VERIFY(!HDR_L2_WRITING(hdr)); - VERIFY3P(hdr->b_l1hdr.b_tmp_cdata, ==, NULL); +#define ARC_MINTIME (hz>>4) /* 62 ms */ -#ifdef ZFS_DEBUG - if (hdr->b_l1hdr.b_thawed != NULL) { - kmem_free(hdr->b_l1hdr.b_thawed, 1); - hdr->b_l1hdr.b_thawed = NULL; - } -#endif +static inline boolean_t +arc_buf_is_shared(arc_buf_t *buf) +{ + boolean_t shared = (buf->b_data != NULL && + buf->b_data == buf->b_hdr->b_l1hdr.b_pdata); + IMPLY(shared, HDR_SHARED_DATA(buf->b_hdr)); + return (shared); +} - nhdr->b_flags &= ~ARC_FLAG_HAS_L1HDR; +static inline void +arc_cksum_free(arc_buf_hdr_t *hdr) +{ + ASSERT(HDR_HAS_L1HDR(hdr)); + mutex_enter(&hdr->b_l1hdr.b_freeze_lock); + if (hdr->b_l1hdr.b_freeze_cksum != NULL) { + kmem_free(hdr->b_l1hdr.b_freeze_cksum, sizeof (zio_cksum_t)); + hdr->b_l1hdr.b_freeze_cksum = NULL; } - /* - * The header has been reallocated so we need to re-insert it into any - * lists it was on. - */ - (void) buf_hash_insert(nhdr, NULL); - - ASSERT(list_link_active(&hdr->b_l2hdr.b_l2node)); - - mutex_enter(&dev->l2ad_mtx); - - /* - * We must place the realloc'ed header back into the list at - * the same spot. Otherwise, if it's placed earlier in the list, - * l2arc_write_buffers() could find it during the function's - * write phase, and try to write it out to the l2arc. - */ - list_insert_after(&dev->l2ad_buflist, hdr, nhdr); - list_remove(&dev->l2ad_buflist, hdr); - - mutex_exit(&dev->l2ad_mtx); - - /* - * Since we're using the pointer address as the tag when - * incrementing and decrementing the l2ad_alloc refcount, we - * must remove the old pointer (that we're about to destroy) and - * add the new pointer to the refcount. Otherwise we'd remove - * the wrong pointer address when calling arc_hdr_destroy() later. - */ - - (void) refcount_remove_many(&dev->l2ad_alloc, - hdr->b_l2hdr.b_asize, hdr); - - (void) refcount_add_many(&dev->l2ad_alloc, - nhdr->b_l2hdr.b_asize, nhdr); - - buf_discard_identity(hdr); - hdr->b_freeze_cksum = NULL; - kmem_cache_free(old, hdr); - - return (nhdr); + mutex_exit(&hdr->b_l1hdr.b_freeze_lock); } - -#define ARC_MINTIME (hz>>4) /* 62 ms */ - static void arc_cksum_verify(arc_buf_t *buf) { + arc_buf_hdr_t *hdr = buf->b_hdr; zio_cksum_t zc; if (!(zfs_flags & ZFS_DEBUG_MODIFY)) return; - mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock); - if (buf->b_hdr->b_freeze_cksum == NULL || HDR_IO_ERROR(buf->b_hdr)) { - mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); + ASSERT(HDR_HAS_L1HDR(hdr)); + + mutex_enter(&hdr->b_l1hdr.b_freeze_lock); + if (hdr->b_l1hdr.b_freeze_cksum == NULL || HDR_IO_ERROR(hdr)) { + mutex_exit(&hdr->b_l1hdr.b_freeze_lock); return; } - fletcher_2_native(buf->b_data, buf->b_hdr->b_size, NULL, &zc); - if (!ZIO_CHECKSUM_EQUAL(*buf->b_hdr->b_freeze_cksum, zc)) + fletcher_2_native(buf->b_data, HDR_GET_LSIZE(hdr), NULL, &zc); + if (!ZIO_CHECKSUM_EQUAL(*hdr->b_l1hdr.b_freeze_cksum, zc)) panic("buffer modified while frozen!"); - mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); + mutex_exit(&hdr->b_l1hdr.b_freeze_lock); } -static int -arc_cksum_equal(arc_buf_t *buf) +static boolean_t +arc_cksum_is_equal(arc_buf_hdr_t *hdr, zio_t *zio) { - zio_cksum_t zc; - int equal; + enum zio_compress compress = BP_GET_COMPRESS(zio->io_bp); + boolean_t valid_cksum; - mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock); - fletcher_2_native(buf->b_data, buf->b_hdr->b_size, NULL, &zc); - equal = ZIO_CHECKSUM_EQUAL(*buf->b_hdr->b_freeze_cksum, zc); - mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); + ASSERT(!BP_IS_EMBEDDED(zio->io_bp)); + VERIFY3U(BP_GET_PSIZE(zio->io_bp), ==, HDR_GET_PSIZE(hdr)); + + /* + * We rely on the blkptr's checksum to determine if the block + * is valid or not. When compressed arc is enabled, the l2arc + * writes the block to the l2arc just as it appears in the pool. + * This allows us to use the blkptr's checksum to validate the + * data that we just read off of the l2arc without having to store + * a separate checksum in the arc_buf_hdr_t. However, if compressed + * arc is disabled, then the data written to the l2arc is always + * uncompressed and won't match the block as it exists in the main + * pool. When this is the case, we must first compress it if it is + * compressed on the main pool before we can validate the checksum. + */ + if (!HDR_COMPRESSION_ENABLED(hdr) && compress != ZIO_COMPRESS_OFF) { + ASSERT3U(HDR_GET_COMPRESS(hdr), ==, ZIO_COMPRESS_OFF); + uint64_t lsize = HDR_GET_LSIZE(hdr); + uint64_t csize; + + void *cbuf = zio_buf_alloc(HDR_GET_PSIZE(hdr)); + csize = zio_compress_data(compress, zio->io_data, cbuf, lsize); + ASSERT3U(csize, <=, HDR_GET_PSIZE(hdr)); + if (csize < HDR_GET_PSIZE(hdr)) { + /* + * Compressed blocks are always a multiple of the + * smallest ashift in the pool. Ideally, we would + * like to round up the csize to the next + * spa_min_ashift but that value may have changed + * since the block was last written. Instead, + * we rely on the fact that the hdr's psize + * was set to the psize of the block when it was + * last written. We set the csize to that value + * and zero out any part that should not contain + * data. + */ + bzero((char *)cbuf + csize, HDR_GET_PSIZE(hdr) - csize); + csize = HDR_GET_PSIZE(hdr); + } + zio_push_transform(zio, cbuf, csize, HDR_GET_PSIZE(hdr), NULL); + } - return (equal); + /* + * Block pointers always store the checksum for the logical data. + * If the block pointer has the gang bit set, then the checksum + * it represents is for the reconstituted data and not for an + * individual gang member. The zio pipeline, however, must be able to + * determine the checksum of each of the gang constituents so it + * treats the checksum comparison differently than what we need + * for l2arc blocks. This prevents us from using the + * zio_checksum_error() interface directly. Instead we must call the + * zio_checksum_error_impl() so that we can ensure the checksum is + * generated using the correct checksum algorithm and accounts for the + * logical I/O size and not just a gang fragment. + */ + valid_cksum = (zio_checksum_error_impl(zio->io_spa, zio->io_bp, + BP_GET_CHECKSUM(zio->io_bp), zio->io_data, zio->io_size, + zio->io_offset, NULL) == 0); + zio_pop_transforms(zio); + return (valid_cksum); } static void -arc_cksum_compute(arc_buf_t *buf, boolean_t force) +arc_cksum_compute(arc_buf_t *buf) { - if (!force && !(zfs_flags & ZFS_DEBUG_MODIFY)) + arc_buf_hdr_t *hdr = buf->b_hdr; + + if (!(zfs_flags & ZFS_DEBUG_MODIFY)) return; + ASSERT(HDR_HAS_L1HDR(hdr)); mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock); - if (buf->b_hdr->b_freeze_cksum != NULL) { - mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); + if (hdr->b_l1hdr.b_freeze_cksum != NULL) { + mutex_exit(&hdr->b_l1hdr.b_freeze_lock); return; } - buf->b_hdr->b_freeze_cksum = kmem_alloc(sizeof (zio_cksum_t), KM_SLEEP); - fletcher_2_native(buf->b_data, buf->b_hdr->b_size, - NULL, buf->b_hdr->b_freeze_cksum); - mutex_exit(&buf->b_hdr->b_l1hdr.b_freeze_lock); + hdr->b_l1hdr.b_freeze_cksum = kmem_alloc(sizeof (zio_cksum_t), + KM_SLEEP); + fletcher_2_native(buf->b_data, HDR_GET_LSIZE(hdr), NULL, + hdr->b_l1hdr.b_freeze_cksum); + mutex_exit(&hdr->b_l1hdr.b_freeze_lock); #ifdef illumos arc_buf_watch(buf); #endif @@ -1733,7 +1855,7 @@ arc_buf_watch(arc_buf_t *buf) procctl_t ctl; ctl.cmd = PCWATCH; ctl.prwatch.pr_vaddr = (uintptr_t)buf->b_data; - ctl.prwatch.pr_size = buf->b_hdr->b_size; + ctl.prwatch.pr_size = HDR_GET_LSIZE(buf->b_hdr); ctl.prwatch.pr_wflags = WA_WRITE; result = write(arc_procfd, &ctl, sizeof (ctl)); ASSERT3U(result, ==, sizeof (ctl)); @@ -1745,11 +1867,14 @@ arc_buf_watch(arc_buf_t *buf) static arc_buf_contents_t arc_buf_type(arc_buf_hdr_t *hdr) { + arc_buf_contents_t type; if (HDR_ISTYPE_METADATA(hdr)) { - return (ARC_BUFC_METADATA); + type = ARC_BUFC_METADATA; } else { - return (ARC_BUFC_DATA); + type = ARC_BUFC_DATA; } + VERIFY3U(hdr->b_type, ==, type); + return (type); } static uint32_t @@ -1771,29 +1896,29 @@ arc_bufc_to_flags(arc_buf_contents_t typ void arc_buf_thaw(arc_buf_t *buf) { + arc_buf_hdr_t *hdr = buf->b_hdr; + if (zfs_flags & ZFS_DEBUG_MODIFY) { - if (buf->b_hdr->b_l1hdr.b_state != arc_anon) + if (hdr->b_l1hdr.b_state != arc_anon) panic("modifying non-anon buffer!"); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:16:53 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4D7DEC1127F; Fri, 14 Oct 2016 07:16:53 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0CB40E62; Fri, 14 Oct 2016 07:16:52 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7GqMj060635; Fri, 14 Oct 2016 07:16:52 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7Gpiw060632; Fri, 14 Oct 2016 07:16:51 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140716.u9E7Gpiw060632@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:16:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307268 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:16:53 -0000 Author: mav Date: Fri Oct 14 07:16:51 2016 New Revision: 307268 URL: https://svnweb.freebsd.org/changeset/base/307268 Log: MFC r305324: MFV r303077: 7072 zfs fails to expand if lun added when os is in shutdown state illumos/illumos-gate@c39a2aae1e2c439d156021edfc20910dad7f9891 https://github.com/illumos/illumos-gate/commit/c39a2aae1e2c439d156021edfc20910da d7f9891 https://www.illumos.org/issues/7072 upstream: 38733 zfs fails to expand if lun added when os is in shutdown state DLPX-36910 spares and caches should not display expandable space DLPX-39262 vdev_disk_open spam zfs_dbgmsg buffer Reviewed by: Igor Kozhukhov Reviewed by: Dan Kimmel Reviewed by: Matthew Ahrens Reviewed by: Prakash Surya Reviewed by: Alex Reece Approved by: Dan McDonald Author: George Wilson Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c Fri Oct 14 07:16:11 2016 (r307267) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c Fri Oct 14 07:16:51 2016 (r307268) @@ -489,7 +489,13 @@ metaslab_class_expandable_space(metaslab continue; } - space += tvd->vdev_max_asize - tvd->vdev_asize; + /* + * Calculate if we have enough space to add additional + * metaslabs. We report the expandable space in terms + * of the metaslab size since that's the unit of expansion. + */ + space += P2ALIGN(tvd->vdev_max_asize - tvd->vdev_asize, + 1ULL << tvd->vdev_ms_shift); } spa_config_exit(mc->mc_spa, SCL_VDEV, FTAG); return (space); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c Fri Oct 14 07:16:11 2016 (r307267) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c Fri Oct 14 07:16:51 2016 (r307268) @@ -2808,6 +2808,7 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t * { spa_t *spa = vd->vdev_spa; vdev_t *rvd = spa->spa_root_vdev; + vdev_t *tvd = vd->vdev_top; ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0); @@ -2818,8 +2819,15 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t * vs->vs_rsize = vdev_get_min_asize(vd); if (vd->vdev_ops->vdev_op_leaf) vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE; - if (vd->vdev_max_asize != 0) - vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize; + /* + * Report expandable space on top-level, non-auxillary devices only. + * The expandable space is reported in terms of metaslab sized units + * since that determines how much space the pool can expand. + */ + if (vd->vdev_aux == NULL && tvd != NULL && vd->vdev_max_asize != 0) { + vs->vs_esize = P2ALIGN(vd->vdev_max_asize - vd->vdev_asize, + 1ULL << tvd->vdev_ms_shift); + } vs->vs_configured_ashift = vd->vdev_top != NULL ? vd->vdev_top->vdev_ashift : vd->vdev_ashift; vs->vs_logical_ashift = vd->vdev_logical_ashift; Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c Fri Oct 14 07:16:11 2016 (r307267) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c Fri Oct 14 07:16:51 2016 (r307268) @@ -241,34 +241,6 @@ vdev_disk_rele(vdev_t *vd) } } -static uint64_t -vdev_disk_get_space(vdev_t *vd, uint64_t capacity, uint_t blksz) -{ - ASSERT(vd->vdev_wholedisk); - - vdev_disk_t *dvd = vd->vdev_tsd; - dk_efi_t dk_ioc; - efi_gpt_t *efi; - uint64_t avail_space = 0; - int efisize = EFI_LABEL_SIZE * 2; - - dk_ioc.dki_data = kmem_alloc(efisize, KM_SLEEP); - dk_ioc.dki_lba = 1; - dk_ioc.dki_length = efisize; - dk_ioc.dki_data_64 = (uint64_t)(uintptr_t)dk_ioc.dki_data; - efi = dk_ioc.dki_data; - - if (ldi_ioctl(dvd->vd_lh, DKIOCGETEFI, (intptr_t)&dk_ioc, - FKIOCTL, kcred, NULL) == 0) { - uint64_t efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA); - - if (capacity > efi_altern_lba) - avail_space = (capacity - efi_altern_lba) * blksz; - } - kmem_free(dk_ioc.dki_data, efisize); - return (avail_space); -} - /* * We want to be loud in DEBUG kernels when DKIOCGMEDIAINFOEXT fails, or when * even a fallback to DKIOCGMEDIAINFO fails. @@ -559,10 +531,7 @@ skip_open: * Adjust max_psize upward accordingly since we know * we own the whole disk now. */ - *max_psize += vdev_disk_get_space(vd, capacity, blksz); - zfs_dbgmsg("capacity change: vdev %s, psize %llu, " - "max_psize %llu", vd->vdev_path, *psize, - *max_psize); + *max_psize = capacity * blksz; } /* From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:19:10 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3440DC1134E; Fri, 14 Oct 2016 07:19:10 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0FCF4192; Fri, 14 Oct 2016 07:19:09 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7J9YX060830; Fri, 14 Oct 2016 07:19:09 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7J9f0060829; Fri, 14 Oct 2016 07:19:09 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140719.u9E7J9f0060829@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:19:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307270 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:19:10 -0000 Author: mav Date: Fri Oct 14 07:19:08 2016 New Revision: 307270 URL: https://svnweb.freebsd.org/changeset/base/307270 Log: MFC r305325: MFV r303078: 7086 ztest attempts dva_get_dsize_sync on an embedded blockpointer illumos/illumos-gate@926549256b71acd595f69b236779ff6b78fa08ef https://github.com/illumos/illumos-gate/commit/926549256b71acd595f69b236779ff6b7 8fa08ef https://www.illumos.org/issues/7086 In dbuf_dirty(), we need to grab the dn_struct_rwlock before looking at the db_blkptr, to prevent it from being changed by syncing context. Otherwise we may see that ztest got a segfault from this stack: libzpool.so.1`dva_get_dsize_sync+0x98(872f000, b32b240, fed7811b, 0, b4cda20, 0) libzpool.so.1`bp_get_dsize+0x60(872f000, b32b240, 0, 97cb780, 9d4c1a8, 0) libzpool.so.1`dbuf_dirty+0x9b3(ce0a100, 97cb780, 9, fecd2530) libzpool.so.1`dmu_buf_will_dirty+0xc3(ce0a100, 97cb780, ea293d6c, 1) libzpool.so.1`zap_lockdir+0x1a0(8aaa3c0, 1, 0, 97cb780, 1, 1) libzpool.so.1`zap_remove_norm+0x30(8aaa3c0, 1, 0, 8728b10, 0, 97cb780) libzpool.so.1`zap_remove+0x29(8aaa3c0, 1, 0, 8728b10, 97cb780, a) ztest_replay_remove+0x225(ea294588, 8728ae8, 0, 38010000, 0, 0) ztest_remove+0x9f(ea294588, ea293f50, 4, 3) ztest_object_init+0x78(ea294588, ea293f50, 4e0, 1) ztest_dmu_object_alloc_free+0x71(ea294588, 13) ztest_dmu_objset_create_destroy+0x224(80cef08, 13, 0, 805d36c, 9017ad44, 0) ztest_execute+0x89(a, 807c720, 13, 0) ztest_thread+0xea(13, 0, 0, 0) libc.so.1`_thrp_setup+0x88(f0983240) libc.so.1`_lwp_start(f0983240, 0, 0, 0, 0, 0) Looking into it a bit, we see that this is an embedded blockpointer, so BP_GET_NDVAS should have returned 0: b32b240::blkptr EMBEDDED [L0 ZAP_OTHER] et=0 LZ4 size=200L/4aP birth=80L Instead, it looks like another thread is modifying this blockpointer: b32b240::ugrep | ::whatis f47a0e0c is in [ stack tid=0x19f ] ebd6ec40 is in [ stack tid=0x226 ] ea293bd0 is in [ stack tid=0x244 ] ea293be4 is in [ stack tid=0x244 ] Reviewed by: Prakash Surya Reviewed by: George Wilson Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:18:27 2016 (r307269) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:19:08 2016 (r307270) @@ -1655,7 +1655,20 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t dnode_setdirty(dn, tx); DB_DNODE_EXIT(db); return (dr); - } else if (do_free_accounting) { + } + + /* + * The dn_struct_rwlock prevents db_blkptr from changing + * due to a write from syncing context completing + * while we are running, so we want to acquire it before + * looking at db_blkptr. + */ + if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) { + rw_enter(&dn->dn_struct_rwlock, RW_READER); + drop_struct_lock = TRUE; + } + + if (do_free_accounting) { blkptr_t *bp = db->db_blkptr; int64_t willfree = (bp && !BP_IS_HOLE(bp)) ? bp_get_dsize(os->os_spa, bp) : db->db.db_size; @@ -1671,11 +1684,6 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t dnode_willuse_space(dn, -willfree, tx); } - if (!RW_WRITE_HELD(&dn->dn_struct_rwlock)) { - rw_enter(&dn->dn_struct_rwlock, RW_READER); - drop_struct_lock = TRUE; - } - if (db->db_level == 0) { dnode_new_blkid(dn, db->db_blkid, tx, drop_struct_lock); ASSERT(dn->dn_maxblkid >= db->db_blkid); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:20:51 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 356B5C114FC; Fri, 14 Oct 2016 07:20:51 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0ECB6902; Fri, 14 Oct 2016 07:20:50 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7Ko2O061028; Fri, 14 Oct 2016 07:20:50 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7Ko3P061027; Fri, 14 Oct 2016 07:20:50 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140720.u9E7Ko3P061027@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:20:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307272 - stable/10/cddl/contrib/opensolaris/cmd/ztest X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:20:51 -0000 Author: mav Date: Fri Oct 14 07:20:49 2016 New Revision: 307272 URL: https://svnweb.freebsd.org/changeset/base/307272 Log: MFC r305326: MFV r303079: 7147 ztest: ztest_ddt_repair fails with ztest_pattern_match assertion illumos/illumos-gate@aab80726335c76a7cae32c7300890248d73a51e3 https://github.com/illumos/illumos-gate/commit/aab80726335c76a7cae32c7300890248d 73a51e3 https://www.illumos.org/issues/7147 Here's the dbuf we're currently reading: 966f200::dbuf addr object lvl blkid holds os 966f200 4 0 0 1 ztest/ds_3 966f200::print dmu_buf_t db_data db_data = 0x9ae0400 0x9ae0400/10J 0x9ae0400: c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d c1c7ced932020d The pattern we're expecting is actually this: a34ae10b5f2db2. If we attempt to read the block on disk we find that it has matches what ztest_ddt_repair() would have written: ~c1c7ced932020d=J ff3e383126cdfdf2 966f200::print dmu_buf_impl_t db_blkptr | ::blkptr DVA0=<0:71d3c00:800> [L0 UINT64_OTHER] SHA256 OFF LE contiguous dedup single size=400L/400P birth=55L/55P fill=1 cksum=18486450d3ce8c6d:75a72f4bbf117b0f:2d3a226314eb5650:2eb0fd68648b1af0 1. zdb -U /rpool/tmp/zpool.cache -R ztest 0:71d3c00:800 | head Found vdev type: mirror 0:71d3c00:800 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 000000: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. 000010: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. 000020: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. 000030: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. 000040: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. 000050: ff3e383126cdfdf2 ff3e383126cdfdf2 ...&18>....&18>. Reviewed by: Matthew Ahrens Reviewed by: Prakash Surya Approved by: Robert Mustacchi Author: George Wilson Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:20:07 2016 (r307271) +++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:20:49 2016 (r307272) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012 Martin Matuska . All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. @@ -5022,9 +5022,14 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_ return; } + dmu_objset_stats_t dds; + dsl_pool_config_enter(dmu_objset_pool(os), FTAG); + dmu_objset_fast_stat(os, &dds); + dsl_pool_config_exit(dmu_objset_pool(os), FTAG); + object = od[0].od_object; blocksize = od[0].od_blocksize; - pattern = zs->zs_guid ^ dmu_objset_fsid_guid(os); + pattern = zs->zs_guid ^ dds.dds_guid; ASSERT(object != 0); @@ -5627,9 +5632,13 @@ ztest_run(ztest_shared_t *zs) metaslab_preload_limit = ztest_random(20) + 1; ztest_spa = spa; + dmu_objset_stats_t dds; VERIFY0(dmu_objset_own(ztest_opts.zo_pool, DMU_OST_ANY, B_TRUE, FTAG, &os)); - zs->zs_guid = dmu_objset_fsid_guid(os); + dsl_pool_config_enter(dmu_objset_pool(os), FTAG); + dmu_objset_fast_stat(os, &dds); + dsl_pool_config_exit(dmu_objset_pool(os), FTAG); + zs->zs_guid = dds.dds_guid; dmu_objset_disown(os, FTAG); spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN; From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:22:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CCF58C116CA; Fri, 14 Oct 2016 07:22:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 899D2DF8; Fri, 14 Oct 2016 07:22:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7MiFs064687; Fri, 14 Oct 2016 07:22:44 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7Mi38064686; Fri, 14 Oct 2016 07:22:44 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140722.u9E7Mi38064686@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:22:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307274 - stable/10/cddl/contrib/opensolaris/cmd/ztest X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:22:45 -0000 Author: mav Date: Fri Oct 14 07:22:44 2016 New Revision: 307274 URL: https://svnweb.freebsd.org/changeset/base/307274 Log: MFC r305327: MFV r303080: 6451 ztest fails due to checksum errors illumos/illumos-gate@f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7 https://github.com/illumos/illumos-gate/commit/f9eb9fdf196b6ed476e4ffc69cecd8b0d a3cb7e7 https://www.illumos.org/issues/6451 Sometimes ztest fails because zdb detects checksum errors. e.g.: Traversing all blocks to verify checksums and verify nothing leaked ... zdb_blkptr_cb: Got error 50 reading <71, 47, 0, 8000160> DVA0=<0:1cc2000: 180000> [L0 other uint64[]] sha256 uncompressed LE contiguou s unique single size=100000L/100000P birth=271L/271P fill=1 cksum=c5a3e27d1ed0f894:843bca3a5473c4bf:f76a19b6830a2e4:91292591613a12bf -- skipping zdb_blkptr_cb: Got error 50 reading <71, 47, 0, 800000180> DVA0=<0:ce16800: 180000> [L0 other uint64[]] sha256 uncompressed LE contigu ous unique single size=100000L/100000P birth=840L/840P fill=1 cksum=5d018f3d061e17f3:6d1584784587bf63:2805a74a0ce37369:ba68a214806c7e75 -- skipping zdb_blkptr_cb: Got error 50 reading <71, 47, 0, 1000000360> DVA0=<0:10d37400: 180000> [L0 other uint64[]] sha256 uncompressed LE conti guous unique single size=100000L/100000P birth=904L/904P fill=1 cksum=fa1e11d4138bd14b:86c9488c444473e3:f31e43c72e72e46b:e3446472d1174d ba -- skipping zdb_blkptr_cb: Got error 50 reading <71, 47, 0, 400000002c0> DVA0=<0:127ef400: 180000> [L0 other uint64[]] sha256 uncompressed LE cont iguous dedup single size=100000L/100000P birth=549L/549P fill=1 cksum=30e14955ebf13522:66dc2ff8067e6810:4607e750abb9d3b3:6582b8af909fcb 58 -- skipping zdb_blkptr_cb: Got error 50 reading <657, 5, 0, 1c0> DVA0=<0:1a180400:180000> [L0 other uint64[]] fletcher4 uncompressed LE contiguou s unique single size=100000L/100000P birth=1091L/1091P fill=1 cksum=a6cf1e50: 29b3bd01c57e5:36779b914035db9a:db61cdcf6bec56f0 -- skippin g The problem is that ztest_fault_inject() can inject multiple faults into the same block. It is designed such that it can inject errors on all leafs of a RAID-Z or mirror, but for a given range of offsets, it will only inject errors Reviewed by: George Wilson Reviewed by: Prakash Surya Reviewed by: Jorgen Lundman Approved by: Dan McDonald Author: Matthew Ahrens Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:21:55 2016 (r307273) +++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:22:44 2016 (r307274) @@ -4793,7 +4793,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint6 char path0[MAXPATHLEN]; char pathrand[MAXPATHLEN]; size_t fsize; - int bshift = SPA_OLD_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ + int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ int iters = 1000; int maxfaults; int mirror_save; @@ -4954,6 +4954,31 @@ ztest_fault_inject(ztest_ds_t *zd, uint6 fsize = lseek(fd, 0, SEEK_END); while (--iters != 0) { + /* + * The offset must be chosen carefully to ensure that + * we do not inject a given logical block with errors + * on two different leaf devices, because ZFS can not + * tolerate that (if maxfaults==1). + * + * We divide each leaf into chunks of size + * (# leaves * SPA_MAXBLOCKSIZE * 4). Within each chunk + * there is a series of ranges to which we can inject errors. + * Each range can accept errors on only a single leaf vdev. + * The error injection ranges are separated by ranges + * which we will not inject errors on any device (DMZs). + * Each DMZ must be large enough such that a single block + * can not straddle it, so that a single block can not be + * a target in two different injection ranges (on different + * leaf vdevs). + * + * For example, with 3 leaves, each chunk looks like: + * 0 to 32M: injection range for leaf 0 + * 32M to 64M: DMZ - no injection allowed + * 64M to 96M: injection range for leaf 1 + * 96M to 128M: DMZ - no injection allowed + * 128M to 160M: injection range for leaf 2 + * 160M to 192M: DMZ - no injection allowed + */ offset = ztest_random(fsize / (leaves << bshift)) * (leaves << bshift) + (leaf << bshift) + (ztest_random(1ULL << (bshift - 1)) & -8ULL); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:24:44 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F3711C11788; Fri, 14 Oct 2016 07:24:44 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CBFAF115; Fri, 14 Oct 2016 07:24:44 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7OhbK064887; Fri, 14 Oct 2016 07:24:43 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7OhSh064886; Fri, 14 Oct 2016 07:24:43 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140724.u9E7OhSh064886@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:24:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307276 - stable/10/cddl/contrib/opensolaris/cmd/ztest X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:24:45 -0000 Author: mav Date: Fri Oct 14 07:24:43 2016 New Revision: 307276 URL: https://svnweb.freebsd.org/changeset/base/307276 Log: MFC r305328: MFV r303081: 7163 ztest failures due to excess error injection illumos/illumos-gate@f34284d835bc555f987c1310df46c034c3101155 https://github.com/illumos/illumos-gate/commit/f34284d835bc555f987c1310df46c034c 3101155 https://www.illumos.org/issues/7163 Running zloop from zfs-precommit hit this assertion: *panicstr/s 0xfffffd7fd7419370: assertion failed for thread 0xfffffd7fe29ed240, thread-id 577: parent != NULL, file ../../../uts/common/fs/zfs/dbuf.c, line 1827 $c libc.so.1`_lwp_kill+0xa() libc.so.1`_assfail+0x182(fffffd7ffb1c29fa, fffffd7ffb1cc028, 723) libc.so.1`assfail+0x19(fffffd7ffb1c29fa, fffffd7ffb1cc028, 723) libzpool.so.1`dbuf_dirty+0xc69(10e3bc10, 3601700) libzpool.so.1`dbuf_dirty+0x61e(10c73640, 3601700) libzpool.so.1`dbuf_dirty+0x61e(10e28280, 3601700) libzpool.so.1`dmu_buf_will_fill+0x64(10e28280, 3601700) libzpool.so.1`dmu_write+0x1b6(2c7e640, d, 400000002e000000, 200, 3717b40, 3601700) ztest_replay_write+0x568(4950d0, 3717a80, 0) ztest_write+0x125(4950d0, d, 400000002e000000, 200, 413f000) ztest_io+0x1bb(4950d0, d, 400000002e000000) ztest_dmu_write_parallel+0xaa(4950d0, 6) ztest_execute+0x83(1, 420c98, 6) ztest_thread+0xf4(6) libc.so.1`_thrp_setup+0x8a(fffffd7fe29ed240) libc.so.1`_lwp_start() This is another manifestation of ECKSUM in ztest: The lowest level ancestor that’s in memory is the L8 (topmost). The L7 ancestor is blkid 0x10: ::dbufs -O 0x2c7e640 -o d -l 7 |::dbuf addr object lvl blkid holds os 600be50 d 7 4 1 ztest/ds_6 719d880 d 7 0 4 ztest/ds_6 Reviewed by: George Wilson Reviewed by: Paul Dagnelie Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:23:58 2016 (r307275) +++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c Fri Oct 14 07:24:43 2016 (r307276) @@ -4793,7 +4793,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint6 char path0[MAXPATHLEN]; char pathrand[MAXPATHLEN]; size_t fsize; - int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ + int bshift = SPA_MAXBLOCKSHIFT + 2; int iters = 1000; int maxfaults; int mirror_save; @@ -4983,7 +4983,29 @@ ztest_fault_inject(ztest_ds_t *zd, uint6 (leaves << bshift) + (leaf << bshift) + (ztest_random(1ULL << (bshift - 1)) & -8ULL); - if (offset >= fsize) + /* + * Only allow damage to the labels at one end of the vdev. + * + * If all labels are damaged, the device will be totally + * inaccessible, which will result in loss of data, + * because we also damage (parts of) the other side of + * the mirror/raidz. + * + * Additionally, we will always have both an even and an + * odd label, so that we can handle crashes in the + * middle of vdev_config_sync(). + */ + if ((leaf & 1) == 0 && offset < VDEV_LABEL_START_SIZE) + continue; + + /* + * The two end labels are stored at the "end" of the disk, but + * the end of the disk (vdev_psize) is aligned to + * sizeof (vdev_label_t). + */ + uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t)); + if ((leaf & 1) == 1 && + offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE) continue; VERIFY(mutex_lock(&ztest_vdev_lock) == 0); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:27:43 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id ACACBC118AD; Fri, 14 Oct 2016 07:27:43 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F1ADD7E3; Fri, 14 Oct 2016 07:27:42 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7Rgss065215; Fri, 14 Oct 2016 07:27:42 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7Rfi9065204; Fri, 14 Oct 2016 07:27:41 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140727.u9E7Rfi9065204@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:27:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307279 - in stable/10/sys/cddl/contrib/opensolaris/uts/common: fs/zfs fs/zfs/sys sys/fs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:27:43 -0000 Author: mav Date: Fri Oct 14 07:27:40 2016 New Revision: 307279 URL: https://svnweb.freebsd.org/changeset/base/307279 Log: MFC r305331: MFV r304155: 7090 zfs should improve allocation order and throttle allocations illumos/illumos-gate@0f7643c7376dd69a08acbfc9d1d7d548b10c846a https://github.com/illumos/illumos-gate/commit/0f7643c7376dd69a08acbfc9d1d7d548b 10c846a https://www.illumos.org/issues/7090 When write I/Os are issued, they are issued in block order but the ZIO pipelin e will drive them asynchronously through the allocation stage which can result i n blocks being allocated out-of-order. It would be nice to preserve as much of the logical order as possible. In addition, the allocations are equally scattered across all top-level VDEVs but not all top-level VDEVs are created equally. The pipeline should be able t o detect devices that are more capable of handling allocations and should allocate more blocks to those devices. This allows for dynamic allocation distribution when devices are imbalanced as fuller devices will tend to be slower than empty devices. The change includes a new pool-wide allocation queue which would throttle and order allocations in the ZIO pipeline. The queue would be ordered by issued time and offset and would provide an initial amount of allocation of work to each top-level vdev. The allocation logic utilizes a reservation system to reserve allocations that will be performed by the allocator. Once an allocatio n is successfully completed it's scheduled on a given top-level vdev. Each top- level vdev maintains a maximum number of allocations that it can handle (mg_alloc_queue_depth). The pool-wide reserved allocations (top-levels * mg_alloc_queue_depth) are distributed across the top-level vdevs metaslab groups and round robin across all eligible metaslab groups to distribute the work. As top-levels complete their work, they receive additional work from the pool-wide allocation queue until the allocation queue is emptied. Reviewed by: Adam Leventhal Reviewed by: Alex Reece Reviewed by: Christopher Siden Reviewed by: Dan Kimmel Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Reviewed by: Prakash Surya Reviewed by: Sebastien Roy Approved by: Robert Mustacchi Author: George Wilson Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c Fri Oct 14 07:27:40 2016 (r307279) @@ -38,17 +38,8 @@ SYSCTL_DECL(_vfs_zfs); SYSCTL_NODE(_vfs_zfs, OID_AUTO, metaslab, CTLFLAG_RW, 0, "ZFS metaslab"); -/* - * Allow allocations to switch to gang blocks quickly. We do this to - * avoid having to load lots of space_maps in a given txg. There are, - * however, some cases where we want to avoid "fast" ganging and instead - * we want to do an exhaustive search of all metaslabs on this device. - * Currently we don't allow any gang, slog, or dump device related allocations - * to "fast" gang. - */ -#define CAN_FASTGANG(flags) \ - (!((flags) & (METASLAB_GANG_CHILD | METASLAB_GANG_HEADER | \ - METASLAB_GANG_AVOID))) +#define GANG_ALLOCATION(flags) \ + ((flags) & (METASLAB_GANG_CHILD | METASLAB_GANG_HEADER)) #define METASLAB_WEIGHT_PRIMARY (1ULL << 63) #define METASLAB_WEIGHT_SECONDARY (1ULL << 62) @@ -277,6 +268,8 @@ metaslab_class_create(spa_t *spa, metasl mc->mc_spa = spa; mc->mc_rotor = NULL; mc->mc_ops = ops; + mutex_init(&mc->mc_lock, NULL, MUTEX_DEFAULT, NULL); + refcount_create_tracked(&mc->mc_alloc_slots); return (mc); } @@ -290,6 +283,8 @@ metaslab_class_destroy(metaslab_class_t ASSERT(mc->mc_space == 0); ASSERT(mc->mc_dspace == 0); + refcount_destroy(&mc->mc_alloc_slots); + mutex_destroy(&mc->mc_lock); kmem_free(mc, sizeof (metaslab_class_t)); } @@ -533,9 +528,10 @@ metaslab_compare(const void *x1, const v /* * Update the allocatable flag and the metaslab group's capacity. * The allocatable flag is set to true if the capacity is below - * the zfs_mg_noalloc_threshold. If a metaslab group transitions - * from allocatable to non-allocatable or vice versa then the metaslab - * group's class is updated to reflect the transition. + * the zfs_mg_noalloc_threshold or has a fragmentation value that is + * greater than zfs_mg_fragmentation_threshold. If a metaslab group + * transitions from allocatable to non-allocatable or vice versa then the + * metaslab group's class is updated to reflect the transition. */ static void metaslab_group_alloc_update(metaslab_group_t *mg) @@ -544,22 +540,45 @@ metaslab_group_alloc_update(metaslab_gro metaslab_class_t *mc = mg->mg_class; vdev_stat_t *vs = &vd->vdev_stat; boolean_t was_allocatable; + boolean_t was_initialized; ASSERT(vd == vd->vdev_top); mutex_enter(&mg->mg_lock); was_allocatable = mg->mg_allocatable; + was_initialized = mg->mg_initialized; mg->mg_free_capacity = ((vs->vs_space - vs->vs_alloc) * 100) / (vs->vs_space + 1); + mutex_enter(&mc->mc_lock); + + /* + * If the metaslab group was just added then it won't + * have any space until we finish syncing out this txg. + * At that point we will consider it initialized and available + * for allocations. We also don't consider non-activated + * metaslab groups (e.g. vdevs that are in the middle of being removed) + * to be initialized, because they can't be used for allocation. + */ + mg->mg_initialized = metaslab_group_initialized(mg); + if (!was_initialized && mg->mg_initialized) { + mc->mc_groups++; + } else if (was_initialized && !mg->mg_initialized) { + ASSERT3U(mc->mc_groups, >, 0); + mc->mc_groups--; + } + if (mg->mg_initialized) + mg->mg_no_free_space = B_FALSE; + /* * A metaslab group is considered allocatable if it has plenty * of free space or is not heavily fragmented. We only take * fragmentation into account if the metaslab group has a valid * fragmentation metric (i.e. a value between 0 and 100). */ - mg->mg_allocatable = (mg->mg_free_capacity > zfs_mg_noalloc_threshold && + mg->mg_allocatable = (mg->mg_activation_count > 0 && + mg->mg_free_capacity > zfs_mg_noalloc_threshold && (mg->mg_fragmentation == ZFS_FRAG_INVALID || mg->mg_fragmentation <= zfs_mg_fragmentation_threshold)); @@ -582,6 +601,7 @@ metaslab_group_alloc_update(metaslab_gro mc->mc_alloc_groups--; else if (!was_allocatable && mg->mg_allocatable) mc->mc_alloc_groups++; + mutex_exit(&mc->mc_lock); mutex_exit(&mg->mg_lock); } @@ -598,6 +618,9 @@ metaslab_group_create(metaslab_class_t * mg->mg_vd = vd; mg->mg_class = mc; mg->mg_activation_count = 0; + mg->mg_initialized = B_FALSE; + mg->mg_no_free_space = B_TRUE; + refcount_create_tracked(&mg->mg_alloc_queue_depth); mg->mg_taskq = taskq_create("metaslab_group_taskq", metaslab_load_pct, minclsyspri, 10, INT_MAX, TASKQ_THREADS_CPU_PCT); @@ -620,6 +643,7 @@ metaslab_group_destroy(metaslab_group_t taskq_destroy(mg->mg_taskq); avl_destroy(&mg->mg_metaslab_tree); mutex_destroy(&mg->mg_lock); + refcount_destroy(&mg->mg_alloc_queue_depth); kmem_free(mg, sizeof (metaslab_group_t)); } @@ -691,6 +715,15 @@ metaslab_group_passivate(metaslab_group_ metaslab_class_minblocksize_update(mc); } +boolean_t +metaslab_group_initialized(metaslab_group_t *mg) +{ + vdev_t *vd = mg->mg_vd; + vdev_stat_t *vs = &vd->vdev_stat; + + return (vs->vs_space != 0 && mg->mg_activation_count > 0); +} + uint64_t metaslab_group_get_space(metaslab_group_t *mg) { @@ -860,30 +893,97 @@ metaslab_group_fragmentation(metaslab_gr * group should avoid allocations if its free capacity is less than the * zfs_mg_noalloc_threshold or its fragmentation metric is greater than * zfs_mg_fragmentation_threshold and there is at least one metaslab group - * that can still handle allocations. + * that can still handle allocations. If the allocation throttle is enabled + * then we skip allocations to devices that have reached their maximum + * allocation queue depth unless the selected metaslab group is the only + * eligible group remaining. */ static boolean_t -metaslab_group_allocatable(metaslab_group_t *mg) +metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor, + uint64_t psize) { - vdev_t *vd = mg->mg_vd; - spa_t *spa = vd->vdev_spa; + spa_t *spa = mg->mg_vd->vdev_spa; metaslab_class_t *mc = mg->mg_class; /* - * We use two key metrics to determine if a metaslab group is - * considered allocatable -- free space and fragmentation. If - * the free space is greater than the free space threshold and - * the fragmentation is less than the fragmentation threshold then - * consider the group allocatable. There are two case when we will - * not consider these key metrics. The first is if the group is - * associated with a slog device and the second is if all groups - * in this metaslab class have already been consider ineligible + * We can only consider skipping this metaslab group if it's + * in the normal metaslab class and there are other metaslab + * groups to select from. Otherwise, we always consider it eligible * for allocations. */ - return ((mg->mg_free_capacity > zfs_mg_noalloc_threshold && - (mg->mg_fragmentation == ZFS_FRAG_INVALID || - mg->mg_fragmentation <= zfs_mg_fragmentation_threshold)) || - mc != spa_normal_class(spa) || mc->mc_alloc_groups == 0); + if (mc != spa_normal_class(spa) || mc->mc_groups <= 1) + return (B_TRUE); + + /* + * If the metaslab group's mg_allocatable flag is set (see comments + * in metaslab_group_alloc_update() for more information) and + * the allocation throttle is disabled then allow allocations to this + * device. However, if the allocation throttle is enabled then + * check if we have reached our allocation limit (mg_alloc_queue_depth) + * to determine if we should allow allocations to this metaslab group. + * If all metaslab groups are no longer considered allocatable + * (mc_alloc_groups == 0) or we're trying to allocate the smallest + * gang block size then we allow allocations on this metaslab group + * regardless of the mg_allocatable or throttle settings. + */ + if (mg->mg_allocatable) { + metaslab_group_t *mgp; + int64_t qdepth; + uint64_t qmax = mg->mg_max_alloc_queue_depth; + + if (!mc->mc_alloc_throttle_enabled) + return (B_TRUE); + + /* + * If this metaslab group does not have any free space, then + * there is no point in looking further. + */ + if (mg->mg_no_free_space) + return (B_FALSE); + + qdepth = refcount_count(&mg->mg_alloc_queue_depth); + + /* + * If this metaslab group is below its qmax or it's + * the only allocatable metasable group, then attempt + * to allocate from it. + */ + if (qdepth < qmax || mc->mc_alloc_groups == 1) + return (B_TRUE); + ASSERT3U(mc->mc_alloc_groups, >, 1); + + /* + * Since this metaslab group is at or over its qmax, we + * need to determine if there are metaslab groups after this + * one that might be able to handle this allocation. This is + * racy since we can't hold the locks for all metaslab + * groups at the same time when we make this check. + */ + for (mgp = mg->mg_next; mgp != rotor; mgp = mgp->mg_next) { + qmax = mgp->mg_max_alloc_queue_depth; + + qdepth = refcount_count(&mgp->mg_alloc_queue_depth); + + /* + * If there is another metaslab group that + * might be able to handle the allocation, then + * we return false so that we skip this group. + */ + if (qdepth < qmax && !mgp->mg_no_free_space) + return (B_FALSE); + } + + /* + * We didn't find another group to handle the allocation + * so we can't skip this metaslab group even though + * we are at or over our qmax. + */ + return (B_TRUE); + + } else if (mc->mc_alloc_groups == 0 || psize == SPA_MINBLOCKSIZE) { + return (B_TRUE); + } + return (B_FALSE); } /* @@ -2151,8 +2251,57 @@ metaslab_distance(metaslab_t *msp, dva_t return (0); } +/* + * ========================================================================== + * Metaslab block operations + * ========================================================================== + */ + +static void +metaslab_group_alloc_increment(spa_t *spa, uint64_t vdev, void *tag, int flags) +{ + if (!(flags & METASLAB_ASYNC_ALLOC) || + flags & METASLAB_DONT_THROTTLE) + return; + + metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg; + if (!mg->mg_class->mc_alloc_throttle_enabled) + return; + + (void) refcount_add(&mg->mg_alloc_queue_depth, tag); +} + +void +metaslab_group_alloc_decrement(spa_t *spa, uint64_t vdev, void *tag, int flags) +{ + if (!(flags & METASLAB_ASYNC_ALLOC) || + flags & METASLAB_DONT_THROTTLE) + return; + + metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg; + if (!mg->mg_class->mc_alloc_throttle_enabled) + return; + + (void) refcount_remove(&mg->mg_alloc_queue_depth, tag); +} + +void +metaslab_group_alloc_verify(spa_t *spa, const blkptr_t *bp, void *tag) +{ +#ifdef ZFS_DEBUG + const dva_t *dva = bp->blk_dva; + int ndvas = BP_GET_NDVAS(bp); + + for (int d = 0; d < ndvas; d++) { + uint64_t vdev = DVA_GET_VDEV(&dva[d]); + metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg; + VERIFY(refcount_not_held(&mg->mg_alloc_queue_depth, tag)); + } +#endif +} + static uint64_t -metaslab_group_alloc(metaslab_group_t *mg, uint64_t psize, uint64_t asize, +metaslab_group_alloc(metaslab_group_t *mg, uint64_t asize, uint64_t txg, uint64_t min_distance, dva_t *dva, int d) { spa_t *spa = mg->mg_vd->vdev_spa; @@ -2179,10 +2328,10 @@ metaslab_group_alloc(metaslab_group_t *m if (msp->ms_weight < asize) { spa_dbgmsg(spa, "%s: failed to meet weight " "requirement: vdev %llu, txg %llu, mg %p, " - "msp %p, psize %llu, asize %llu, " + "msp %p, asize %llu, " "weight %llu", spa_name(spa), mg->mg_vd->vdev_id, txg, - mg, msp, psize, asize, msp->ms_weight); + mg, msp, asize, msp->ms_weight); mutex_exit(&mg->mg_lock); return (-1ULL); } @@ -2264,7 +2413,6 @@ metaslab_group_alloc(metaslab_group_t *m msp->ms_access_txg = txg + metaslab_unload_delay; mutex_exit(&msp->ms_lock); - return (offset); } @@ -2281,7 +2429,6 @@ metaslab_alloc_dva(spa_t *spa, metaslab_ int all_zero; int zio_lock = B_FALSE; boolean_t allocatable; - uint64_t offset = -1ULL; uint64_t asize; uint64_t distance; @@ -2351,7 +2498,6 @@ top: all_zero = B_TRUE; do { ASSERT(mg->mg_activation_count == 1); - vd = mg->mg_vd; /* @@ -2367,24 +2513,23 @@ top: /* * Determine if the selected metaslab group is eligible - * for allocations. If we're ganging or have requested - * an allocation for the smallest gang block size - * then we don't want to avoid allocating to the this - * metaslab group. If we're in this condition we should - * try to allocate from any device possible so that we - * don't inadvertently return ENOSPC and suspend the pool + * for allocations. If we're ganging then don't allow + * this metaslab group to skip allocations since that would + * inadvertently return ENOSPC and suspend the pool * even though space is still available. */ - if (allocatable && CAN_FASTGANG(flags) && - psize > SPA_GANGBLOCKSIZE) - allocatable = metaslab_group_allocatable(mg); + if (allocatable && !GANG_ALLOCATION(flags) && !zio_lock) { + allocatable = metaslab_group_allocatable(mg, rotor, + psize); + } if (!allocatable) goto next; + ASSERT(mg->mg_initialized); + /* - * Avoid writing single-copy data to a failing vdev - * unless the user instructs us that it is okay. + * Avoid writing single-copy data to a failing vdev. */ if ((vd->vdev_stat.vs_write_errors > 0 || vd->vdev_state < VDEV_STATE_HEALTHY) && @@ -2404,8 +2549,32 @@ top: asize = vdev_psize_to_asize(vd, psize); ASSERT(P2PHASE(asize, 1ULL << vd->vdev_ashift) == 0); - offset = metaslab_group_alloc(mg, psize, asize, txg, distance, - dva, d); + uint64_t offset = metaslab_group_alloc(mg, asize, txg, + distance, dva, d); + + mutex_enter(&mg->mg_lock); + if (offset == -1ULL) { + mg->mg_failed_allocations++; + if (asize == SPA_GANGBLOCKSIZE) { + /* + * This metaslab group was unable to allocate + * the minimum gang block size so it must be + * out of space. We must notify the allocation + * throttle to start skipping allocation + * attempts to this metaslab group until more + * space becomes available. + * + * Note: this failure cannot be caused by the + * allocation throttle since the allocation + * throttle is only responsible for skipping + * devices and not failing block allocations. + */ + mg->mg_no_free_space = B_TRUE; + } + } + mg->mg_allocations++; + mutex_exit(&mg->mg_lock); + if (offset != -1ULL) { /* * If we've just selected this metaslab group, @@ -2586,9 +2755,57 @@ metaslab_claim_dva(spa_t *spa, const dva return (0); } +/* + * Reserve some allocation slots. The reservation system must be called + * before we call into the allocator. If there aren't any available slots + * then the I/O will be throttled until an I/O completes and its slots are + * freed up. The function returns true if it was successful in placing + * the reservation. + */ +boolean_t +metaslab_class_throttle_reserve(metaslab_class_t *mc, int slots, zio_t *zio, + int flags) +{ + uint64_t available_slots = 0; + boolean_t slot_reserved = B_FALSE; + + ASSERT(mc->mc_alloc_throttle_enabled); + mutex_enter(&mc->mc_lock); + + uint64_t reserved_slots = refcount_count(&mc->mc_alloc_slots); + if (reserved_slots < mc->mc_alloc_max_slots) + available_slots = mc->mc_alloc_max_slots - reserved_slots; + + if (slots <= available_slots || GANG_ALLOCATION(flags)) { + /* + * We reserve the slots individually so that we can unreserve + * them individually when an I/O completes. + */ + for (int d = 0; d < slots; d++) { + reserved_slots = refcount_add(&mc->mc_alloc_slots, zio); + } + zio->io_flags |= ZIO_FLAG_IO_ALLOCATING; + slot_reserved = B_TRUE; + } + + mutex_exit(&mc->mc_lock); + return (slot_reserved); +} + +void +metaslab_class_throttle_unreserve(metaslab_class_t *mc, int slots, zio_t *zio) +{ + ASSERT(mc->mc_alloc_throttle_enabled); + mutex_enter(&mc->mc_lock); + for (int d = 0; d < slots; d++) { + (void) refcount_remove(&mc->mc_alloc_slots, zio); + } + mutex_exit(&mc->mc_lock); +} + int metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp, - int ndvas, uint64_t txg, blkptr_t *hintbp, int flags) + int ndvas, uint64_t txg, blkptr_t *hintbp, int flags, zio_t *zio) { dva_t *dva = bp->blk_dva; dva_t *hintdva = hintbp->blk_dva; @@ -2614,11 +2831,21 @@ metaslab_alloc(spa_t *spa, metaslab_clas if (error != 0) { for (d--; d >= 0; d--) { metaslab_free_dva(spa, &dva[d], txg, B_TRUE); + metaslab_group_alloc_decrement(spa, + DVA_GET_VDEV(&dva[d]), zio, flags); bzero(&dva[d], sizeof (dva_t)); } spa_config_exit(spa, SCL_ALLOC, FTAG); return (error); + } else { + /* + * Update the metaslab group's queue depth + * based on the newly allocated dva. + */ + metaslab_group_alloc_increment(spa, + DVA_GET_VDEV(&dva[d]), zio, flags); } + } ASSERT(error == 0); ASSERT(BP_GET_NDVAS(bp) == ndvas); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c Fri Oct 14 07:27:40 2016 (r307279) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. */ #include @@ -74,6 +74,13 @@ refcount_create(refcount_t *rc) } void +refcount_create_tracked(refcount_t *rc) +{ + refcount_create(rc); + rc->rc_tracked = B_TRUE; +} + +void refcount_create_untracked(refcount_t *rc) { refcount_create(rc); @@ -256,4 +263,60 @@ refcount_transfer_ownership(refcount_t * ASSERT(found); mutex_exit(&rc->rc_mtx); } + +/* + * If tracking is enabled, return true if a reference exists that matches + * the "holder" tag. If tracking is disabled, then return true if a reference + * might be held. + */ +boolean_t +refcount_held(refcount_t *rc, void *holder) +{ + reference_t *ref; + + mutex_enter(&rc->rc_mtx); + + if (!rc->rc_tracked) { + mutex_exit(&rc->rc_mtx); + return (rc->rc_count > 0); + } + + for (ref = list_head(&rc->rc_list); ref; + ref = list_next(&rc->rc_list, ref)) { + if (ref->ref_holder == holder) { + mutex_exit(&rc->rc_mtx); + return (B_TRUE); + } + } + mutex_exit(&rc->rc_mtx); + return (B_FALSE); +} + +/* + * If tracking is enabled, return true if a reference does not exist that + * matches the "holder" tag. If tracking is disabled, always return true + * since the reference might not be held. + */ +boolean_t +refcount_not_held(refcount_t *rc, void *holder) +{ + reference_t *ref; + + mutex_enter(&rc->rc_mtx); + + if (!rc->rc_tracked) { + mutex_exit(&rc->rc_mtx); + return (B_TRUE); + } + + for (ref = list_head(&rc->rc_list); ref; + ref = list_next(&rc->rc_list, ref)) { + if (ref->ref_holder == holder) { + mutex_exit(&rc->rc_mtx); + return (B_FALSE); + } + } + mutex_exit(&rc->rc_mtx); + return (B_TRUE); +} #endif /* ZFS_DEBUG */ Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Fri Oct 14 07:27:40 2016 (r307279) @@ -1333,7 +1333,6 @@ spa_unload(spa_t *spa) ddt_unload(spa); - /* * Drop and purge level 2 cache */ @@ -3638,6 +3637,7 @@ spa_create(const char *pool, nvlist_t *n spa->spa_uberblock.ub_txg = txg - 1; spa->spa_uberblock.ub_version = version; spa->spa_ubsync = spa->spa_uberblock; + spa->spa_load_state = SPA_LOAD_CREATE; /* * Create "The Godfather" zio to hold all async IOs @@ -3823,6 +3823,7 @@ spa_create(const char *pool, nvlist_t *n */ spa_evicting_os_wait(spa); spa->spa_minref = refcount_count(&spa->spa_refcount); + spa->spa_load_state = SPA_LOAD_NONE; mutex_exit(&spa_namespace_lock); @@ -5522,7 +5523,7 @@ spa_nvlist_lookup_by_guid(nvlist_t **nvp static void spa_vdev_remove_aux(nvlist_t *config, char *name, nvlist_t **dev, int count, - nvlist_t *dev_to_remove) + nvlist_t *dev_to_remove) { nvlist_t **newdev = NULL; @@ -6635,6 +6636,8 @@ spa_sync(spa_t *spa, uint64_t txg) vdev_t *vd; dmu_tx_t *tx; int error; + uint32_t max_queue_depth = zfs_vdev_async_write_max_active * + zfs_vdev_queue_depth_pct / 100; VERIFY(spa_writeable(spa)); @@ -6646,6 +6649,10 @@ spa_sync(spa_t *spa, uint64_t txg) spa->spa_syncing_txg = txg; spa->spa_sync_pass = 0; + mutex_enter(&spa->spa_alloc_lock); + VERIFY0(avl_numnodes(&spa->spa_alloc_tree)); + mutex_exit(&spa->spa_alloc_lock); + /* * If there are any pending vdev state changes, convert them * into config changes that go out with this transaction group. @@ -6705,6 +6712,38 @@ spa_sync(spa_t *spa, uint64_t txg) } /* + * Set the top-level vdev's max queue depth. Evaluate each + * top-level's async write queue depth in case it changed. + * The max queue depth will not change in the middle of syncing + * out this txg. + */ + uint64_t queue_depth_total = 0; + for (int c = 0; c < rvd->vdev_children; c++) { + vdev_t *tvd = rvd->vdev_child[c]; + metaslab_group_t *mg = tvd->vdev_mg; + + if (mg == NULL || mg->mg_class != spa_normal_class(spa) || + !metaslab_group_initialized(mg)) + continue; + + /* + * It is safe to do a lock-free check here because only async + * allocations look at mg_max_alloc_queue_depth, and async + * allocations all happen from spa_sync(). + */ + ASSERT0(refcount_count(&mg->mg_alloc_queue_depth)); + mg->mg_max_alloc_queue_depth = max_queue_depth; + queue_depth_total += mg->mg_max_alloc_queue_depth; + } + metaslab_class_t *mc = spa_normal_class(spa); + ASSERT0(refcount_count(&mc->mc_alloc_slots)); + mc->mc_alloc_max_slots = queue_depth_total; + mc->mc_alloc_throttle_enabled = zio_dva_throttle_enabled; + + ASSERT3U(mc->mc_alloc_max_slots, <=, + max_queue_depth * rvd->vdev_children); + + /* * Iterate to convergence. */ do { @@ -6846,6 +6885,10 @@ spa_sync(spa_t *spa, uint64_t txg) dsl_pool_sync_done(dp, txg); + mutex_enter(&spa->spa_alloc_lock); + VERIFY0(avl_numnodes(&spa->spa_alloc_tree)); + mutex_exit(&spa->spa_alloc_lock); + /* * Update usable space statistics. */ Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c Fri Oct 14 07:27:40 2016 (r307279) @@ -657,6 +657,7 @@ spa_add(const char *name, nvlist_t *conf mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&spa->spa_alloc_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL); cv_init(&spa->spa_evicting_os_cv, NULL, CV_DEFAULT, NULL); @@ -713,6 +714,9 @@ spa_add(const char *name, nvlist_t *conf spa_active_count++; } + avl_create(&spa->spa_alloc_tree, zio_timestamp_compare, + sizeof (zio_t), offsetof(zio_t, io_alloc_node)); + /* * Every pool starts with the default cachefile */ @@ -791,6 +795,7 @@ spa_remove(spa_t *spa) kmem_free(dp, sizeof (spa_config_dirent_t)); } + avl_destroy(&spa->spa_alloc_tree); list_destroy(&spa->spa_config_list); nvlist_free(spa->spa_label_features); @@ -824,6 +829,7 @@ spa_remove(spa_t *spa) cv_destroy(&spa->spa_scrub_io_cv); cv_destroy(&spa->spa_suspend_cv); + mutex_destroy(&spa->spa_alloc_lock); mutex_destroy(&spa->spa_async_lock); mutex_destroy(&spa->spa_errlist_lock); mutex_destroy(&spa->spa_errlog_lock); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h Fri Oct 14 07:27:40 2016 (r307279) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_METASLAB_H @@ -55,14 +55,15 @@ void metaslab_sync_done(metaslab_t *, ui void metaslab_sync_reassess(metaslab_group_t *); uint64_t metaslab_block_maxsize(metaslab_t *); -#define METASLAB_HINTBP_FAVOR 0x0 -#define METASLAB_HINTBP_AVOID 0x1 -#define METASLAB_GANG_HEADER 0x2 -#define METASLAB_GANG_CHILD 0x4 -#define METASLAB_GANG_AVOID 0x8 +#define METASLAB_HINTBP_FAVOR 0x0 +#define METASLAB_HINTBP_AVOID 0x1 +#define METASLAB_GANG_HEADER 0x2 +#define METASLAB_GANG_CHILD 0x4 +#define METASLAB_ASYNC_ALLOC 0x8 +#define METASLAB_DONT_THROTTLE 0x10 int metaslab_alloc(spa_t *, metaslab_class_t *, uint64_t, - blkptr_t *, int, uint64_t, blkptr_t *, int); + blkptr_t *, int, uint64_t, blkptr_t *, int, zio_t *); void metaslab_free(spa_t *, const blkptr_t *, uint64_t, boolean_t); int metaslab_claim(spa_t *, const blkptr_t *, uint64_t); void metaslab_check_free(spa_t *, const blkptr_t *); @@ -73,6 +74,9 @@ int metaslab_class_validate(metaslab_cla void metaslab_class_histogram_verify(metaslab_class_t *); uint64_t metaslab_class_fragmentation(metaslab_class_t *); uint64_t metaslab_class_expandable_space(metaslab_class_t *); +boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, + zio_t *, int); +void metaslab_class_throttle_unreserve(metaslab_class_t *, int, zio_t *); void metaslab_class_space_update(metaslab_class_t *, int64_t, int64_t, int64_t, int64_t); @@ -86,10 +90,13 @@ metaslab_group_t *metaslab_group_create( void metaslab_group_destroy(metaslab_group_t *); void metaslab_group_activate(metaslab_group_t *); void metaslab_group_passivate(metaslab_group_t *); +boolean_t metaslab_group_initialized(metaslab_group_t *); uint64_t metaslab_group_get_space(metaslab_group_t *); void metaslab_group_histogram_verify(metaslab_group_t *); uint64_t metaslab_group_fragmentation(metaslab_group_t *); void metaslab_group_histogram_remove(metaslab_group_t *, metaslab_t *); +void metaslab_group_alloc_decrement(spa_t *, uint64_t, void *, int); +void metaslab_group_alloc_verify(spa_t *, const blkptr_t *, void *); #ifdef __cplusplus } Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h Fri Oct 14 07:27:40 2016 (r307279) @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_METASLAB_IMPL_H @@ -59,11 +59,42 @@ extern "C" { * to use a block allocator that best suits that class. */ struct metaslab_class { + kmutex_t mc_lock; spa_t *mc_spa; metaslab_group_t *mc_rotor; metaslab_ops_t *mc_ops; uint64_t mc_aliquot; + + /* + * Track the number of metaslab groups that have been initialized + * and can accept allocations. An initialized metaslab group is + * one has been completely added to the config (i.e. we have + * updated the MOS config and the space has been added to the pool). + */ + uint64_t mc_groups; + + /* + * Toggle to enable/disable the allocation throttle. + */ + boolean_t mc_alloc_throttle_enabled; + + /* + * The allocation throttle works on a reservation system. Whenever + * an asynchronous zio wants to perform an allocation it must + * first reserve the number of blocks that it wants to allocate. + * If there aren't sufficient slots available for the pending zio + * then that I/O is throttled until more slots free up. The current + * number of reserved allocations is maintained by the mc_alloc_slots + * refcount. The mc_alloc_max_slots value determines the maximum + * number of allocations that the system allows. Gang blocks are + * allowed to reserve slots even if we've reached the maximum + * number of allocations allowed. + */ + uint64_t mc_alloc_max_slots; + refcount_t mc_alloc_slots; + uint64_t mc_alloc_groups; /* # of allocatable groups */ + uint64_t mc_alloc; /* total allocated space */ uint64_t mc_deferred; /* total deferred frees */ uint64_t mc_space; /* total space (alloc + free) */ @@ -86,6 +117,15 @@ struct metaslab_group { avl_tree_t mg_metaslab_tree; uint64_t mg_aliquot; boolean_t mg_allocatable; /* can we allocate? */ + + /* + * A metaslab group is considered to be initialized only after + * we have updated the MOS config and added the space to the pool. + * We only allow allocation attempts to a metaslab group if it + * has been initialized. + */ + boolean_t mg_initialized; + uint64_t mg_free_capacity; /* percentage free */ int64_t mg_bias; int64_t mg_activation_count; @@ -94,6 +134,27 @@ struct metaslab_group { taskq_t *mg_taskq; metaslab_group_t *mg_prev; metaslab_group_t *mg_next; + + /* + * Each metaslab group can handle mg_max_alloc_queue_depth allocations + * which are tracked by mg_alloc_queue_depth. It's possible for a + * metaslab group to handle more allocations than its max. This + * can occur when gang blocks are required or when other groups + * are unable to handle their share of allocations. + */ + uint64_t mg_max_alloc_queue_depth; + refcount_t mg_alloc_queue_depth; + + /* + * A metalab group that can no longer allocate the minimum block + * size will set mg_no_free_space. Once a metaslab group is out + * of space then its share of work must be distributed to other + * groups. + */ + boolean_t mg_no_free_space; + + uint64_t mg_allocations; + uint64_t mg_failed_allocations; uint64_t mg_fragmentation; uint64_t mg_histogram[RANGE_TREE_HISTOGRAM_SIZE]; }; Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h Fri Oct 14 07:27:40 2016 (r307279) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. */ #ifndef _SYS_REFCOUNT_H @@ -64,6 +64,7 @@ typedef struct refcount { void refcount_create(refcount_t *rc); void refcount_create_untracked(refcount_t *rc); +void refcount_create_tracked(refcount_t *rc); void refcount_destroy(refcount_t *rc); void refcount_destroy_many(refcount_t *rc, uint64_t number); int refcount_is_zero(refcount_t *rc); @@ -74,6 +75,8 @@ int64_t refcount_add_many(refcount_t *rc int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder_tag); void refcount_transfer(refcount_t *dst, refcount_t *src); void refcount_transfer_ownership(refcount_t *, void *, void *); +boolean_t refcount_held(refcount_t *, void *); +boolean_t refcount_not_held(refcount_t *, void *); void refcount_sysinit(void); void refcount_fini(void); @@ -86,6 +89,7 @@ typedef struct refcount { #define refcount_create(rc) ((rc)->rc_count = 0) #define refcount_create_untracked(rc) ((rc)->rc_count = 0) +#define refcount_create_tracked(rc) ((rc)->rc_count = 0) #define refcount_destroy(rc) ((rc)->rc_count = 0) #define refcount_destroy_many(rc, number) ((rc)->rc_count = 0) #define refcount_is_zero(rc) ((rc)->rc_count == 0) @@ -102,6 +106,8 @@ typedef struct refcount { atomic_add_64(&(dst)->rc_count, __tmp); \ } #define refcount_transfer_ownership(rc, current_holder, new_holder) +#define refcount_held(rc, holder) ((rc)->rc_count > 0) +#define refcount_not_held(rc, holder) (B_TRUE) #define refcount_sysinit() #define refcount_fini() Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h Fri Oct 14 07:27:40 2016 (r307279) @@ -159,6 +159,8 @@ struct spa { uint64_t spa_last_synced_guid; /* last synced guid */ list_t spa_config_dirty_list; /* vdevs with dirty config */ list_t spa_state_dirty_list; /* vdevs with dirty state */ + kmutex_t spa_alloc_lock; + avl_tree_t spa_alloc_tree; spa_aux_vdev_t spa_spares; /* hot spares */ spa_aux_vdev_t spa_l2cache; /* L2ARC cache devices */ nvlist_t *spa_label_features; /* Features for reading MOS */ Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h Fri Oct 14 07:27:40 2016 (r307279) @@ -53,6 +53,9 @@ typedef struct vdev_queue vdev_queue_t; typedef struct vdev_cache vdev_cache_t; typedef struct vdev_cache_entry vdev_cache_entry_t; +extern int zfs_vdev_queue_depth_pct; +extern uint32_t zfs_vdev_async_write_max_active; + /* * Virtual device operations */ @@ -190,7 +193,18 @@ struct vdev { uint64_t vdev_deflate_ratio; /* deflation ratio (x512) */ uint64_t vdev_islog; /* is an intent log device */ uint64_t vdev_removing; /* device is being removed? */ - boolean_t vdev_ishole; /* is a hole in the namespace */ + boolean_t vdev_ishole; /* is a hole in the namespace */ + kmutex_t vdev_queue_lock; /* protects vdev_queue_depth */ + + /* + * The queue depth parameters determine how many async writes are + * still pending (i.e. allocated by net yet issued to disk) per + * top-level (vdev_async_write_queue_depth) and the maximum allowed + * (vdev_max_async_write_queue_depth). These values only apply to + * top-level vdevs. + */ + uint64_t vdev_async_write_queue_depth; + uint64_t vdev_max_async_write_queue_depth; /* * Leaf vdev state. Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h Fri Oct 14 07:27:29 2016 (r307278) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h Fri Oct 14 07:27:40 2016 (r307279) @@ -175,6 +175,7 @@ enum zio_flag { ZIO_FLAG_DONT_CACHE = 1 << 11, ZIO_FLAG_NODATA = 1 << 12, ZIO_FLAG_INDUCE_DAMAGE = 1 << 13, + ZIO_FLAG_IO_ALLOCATING = 1 << 14, #define ZIO_FLAG_DDT_INHERIT (ZIO_FLAG_IO_RETRY - 1) #define ZIO_FLAG_GANG_INHERIT (ZIO_FLAG_IO_RETRY - 1) @@ -182,27 +183,27 @@ enum zio_flag { /* * Flags inherited by vdev children. */ - ZIO_FLAG_IO_RETRY = 1 << 14, /* must be first for INHERIT */ - ZIO_FLAG_PROBE = 1 << 15, - ZIO_FLAG_TRYHARD = 1 << 16, - ZIO_FLAG_OPTIONAL = 1 << 17, + ZIO_FLAG_IO_RETRY = 1 << 15, /* must be first for INHERIT */ + ZIO_FLAG_PROBE = 1 << 16, + ZIO_FLAG_TRYHARD = 1 << 17, + ZIO_FLAG_OPTIONAL = 1 << 18, #define ZIO_FLAG_VDEV_INHERIT (ZIO_FLAG_DONT_QUEUE - 1) /* *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:29:24 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 73985C119AA; Fri, 14 Oct 2016 07:29:24 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4F4BCB13; Fri, 14 Oct 2016 07:29:24 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7TNpW065392; Fri, 14 Oct 2016 07:29:23 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7TNH7065391; Fri, 14 Oct 2016 07:29:23 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140729.u9E7TNH7065391@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:29:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307281 - stable/10/cddl/contrib/opensolaris/cmd/zdb X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:29:24 -0000 Author: mav Date: Fri Oct 14 07:29:23 2016 New Revision: 307281 URL: https://svnweb.freebsd.org/changeset/base/307281 Log: MFC r305332: MFV r304159: 7277 zdb should be able to print zfs_dbgmsg's illumos/illumos-gate@29bdd2f916366ece37c4748bca6b3d61f57a223b https://github.com/illumos/illumos-gate/commit/29bdd2f916366ece37c4748bca6b3d61f 57a223b https://www.illumos.org/issues/7277 ztest always prints the debug messages (zfs_dbgmsg()) by calling zfs_dbgmsg_print(). We should add a flag to zdb to make it do this as well before exiting. Reviewed by: George Wilson Reviewed by: Matthew Ahrens Reviewed by: Igor Kozhukhov Approved by: Dan McDonald Author: Pavel Zakharov Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Directory Properties: stable/10/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct 14 07:28:43 2016 (r307280) +++ stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct 14 07:29:23 2016 (r307281) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -117,7 +117,7 @@ static void usage(void) { (void) fprintf(stderr, - "Usage: %s [-CumMdibcsDvhLXFPA] [-t txg] [-e [-p path...]] " + "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] " "[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n" " %s [-divPA] [-e -p path...] [-U config] dataset " "[object...]\n" @@ -178,12 +178,23 @@ usage(void) (void) fprintf(stderr, " -I -- " "specify the maximum number of " "checksumming I/Os [default is 200]\n"); + (void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before " + "exiting\n"); (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " "to make only that option verbose\n"); (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); exit(1); } +static void +dump_debug_buffer() +{ + if (dump_opt['G']) { + (void) printf("\n"); + zfs_dbgmsg_print("zdb"); + } +} + /* * Called for usage errors that are discovered after a call to spa_open(), * dmu_bonus_hold(), or pool_match(). abort() is called for other errors. @@ -200,6 +211,8 @@ fatal(const char *fmt, ...) va_end(ap); (void) fprintf(stderr, "\n"); + dump_debug_buffer(); + exit(1); } @@ -3104,8 +3117,10 @@ dump_zpool(spa_t *spa) if (dump_opt['h']) dump_history(spa); - if (rc != 0) + if (rc != 0) { + dump_debug_buffer(); exit(rc); + } } #define ZDB_FLAG_CHECKSUM 0x0001 @@ -3576,7 +3591,7 @@ main(int argc, char **argv) spa_config_path = spa_config_path_env; while ((c = getopt(argc, argv, - "bcdhilmMI:suCDRSAFLXx:evp:t:U:P")) != -1) { + "bcdhilmMI:suCDRSAFLXx:evp:t:U:PG")) != -1) { switch (c) { case 'b': case 'c': @@ -3592,6 +3607,7 @@ main(int argc, char **argv) case 'M': case 'R': case 'S': + case 'G': dump_opt[c]++; dump_all = 0; break; @@ -3827,6 +3843,8 @@ main(int argc, char **argv) fuid_table_destroy(); sa_loaded = B_FALSE; + dump_debug_buffer(); + libzfs_fini(g_zfs); kernel_fini(); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:30:56 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 06E81C11B28; Fri, 14 Oct 2016 07:30:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id ABFA9EE0; Fri, 14 Oct 2016 07:30:55 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7Us9P067602; Fri, 14 Oct 2016 07:30:54 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7UsoM067600; Fri, 14 Oct 2016 07:30:54 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140730.u9E7UsoM067600@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:30:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307283 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:30:56 -0000 Author: mav Date: Fri Oct 14 07:30:54 2016 New Revision: 307283 URL: https://svnweb.freebsd.org/changeset/base/307283 Log: MFC r305333: MFV r304156: 7235 remove unused func dsl_dataset_set_blkptr illumos/illumos-gate@bd56f80007857b960e0981ed0797ad8ec844a96b https://github.com/illumos/illumos-gate/commit/bd56f80007857b960e0981ed0797ad8ec 844a96b https://www.illumos.org/issues/7235 The function dsl_dataset_set_blkptr() is unused. We should remove it. Reviewed by: George Wilson Reviewed by: Alex Reece Reviewed by: Prakash Surya Reviewed by: Igor Kozhukhov Approved by: Robert Mustacchi Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Fri Oct 14 07:30:16 2016 (r307282) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Fri Oct 14 07:30:54 2016 (r307283) @@ -1060,19 +1060,6 @@ dsl_dataset_get_blkptr(dsl_dataset_t *ds return (&dsl_dataset_phys(ds)->ds_bp); } -void -dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) -{ - ASSERT(dmu_tx_is_syncing(tx)); - /* If it's the meta-objset, set dp_meta_rootbp */ - if (ds == NULL) { - tx->tx_pool->dp_meta_rootbp = *bp; - } else { - dmu_buf_will_dirty(ds->ds_dbuf, tx); - dsl_dataset_phys(ds)->ds_bp = *bp; - } -} - spa_t * dsl_dataset_get_spa(dsl_dataset_t *ds) { Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Fri Oct 14 07:30:16 2016 (r307282) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Fri Oct 14 07:30:54 2016 (r307283) @@ -272,7 +272,6 @@ int dsl_dataset_snapshot_tmp(const char minor_t cleanup_minor, const char *htag); blkptr_t *dsl_dataset_get_blkptr(dsl_dataset_t *ds); -void dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx); spa_t *dsl_dataset_get_spa(dsl_dataset_t *ds); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:32:25 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6C91FC11BE0; Fri, 14 Oct 2016 07:32:25 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 480FD128C; Fri, 14 Oct 2016 07:32:25 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7WOl1069060; Fri, 14 Oct 2016 07:32:24 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7WO30069058; Fri, 14 Oct 2016 07:32:24 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140732.u9E7WO30069058@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:32:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307285 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:32:25 -0000 Author: mav Date: Fri Oct 14 07:32:24 2016 New Revision: 307285 URL: https://svnweb.freebsd.org/changeset/base/307285 Log: MFC r305334: MFV r304157: 7230 add assertions to dmu_send_impl() to verify that stream includes BEGIN and END records illumos/illumos-gate@12b90ee2d3b10689fc45f4930d2392f5fe1d9cfa https://github.com/illumos/illumos-gate/commit/12b90ee2d3b10689fc45f4930d2392f5f e1d9cfa https://www.illumos.org/issues/7230 A test failure occurred where a send stream had only a BEGIN record. This should not be possible if the send returns without error. Prevented this from happening in the future by adding an assertion to dmu_send_impl() to verify that if the function returns 0 (success) both a BEGIN and END record are present. Did this by adding flags to dmu_sendarg_t (indicating whether BEGIN o r END records sent), having dump_record() set flags appropriately, adding VERIFY statement to dmu_send_impl(). Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Reviewed by: Igor Kozhukhov Approved by: Robert Mustacchi Author: Matt Krantz Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 14 07:31:47 2016 (r307284) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 14 07:32:24 2016 (r307285) @@ -160,11 +160,16 @@ dump_record(dmu_sendarg_t *dsp, void *pa fletcher_4_incremental_native(dsp->dsa_drr, offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), &dsp->dsa_zc); - if (dsp->dsa_drr->drr_type != DRR_BEGIN) { + if (dsp->dsa_drr->drr_type == DRR_BEGIN) { + dsp->dsa_sent_begin = B_TRUE; + } else { ASSERT(ZIO_CHECKSUM_IS_ZERO(&dsp->dsa_drr->drr_u. drr_checksum.drr_checksum)); dsp->dsa_drr->drr_u.drr_checksum.drr_checksum = dsp->dsa_zc; } + if (dsp->dsa_drr->drr_type == DRR_END) { + dsp->dsa_sent_end = B_TRUE; + } fletcher_4_incremental_native(&dsp->dsa_drr-> drr_u.drr_checksum.drr_checksum, sizeof (zio_cksum_t), &dsp->dsa_zc); @@ -912,6 +917,8 @@ out: list_remove(&to_ds->ds_sendstreams, dsp); mutex_exit(&to_ds->ds_sendstream_lock); + VERIFY(err != 0 || (dsp->dsa_sent_begin && dsp->dsa_sent_end)); + kmem_free(drr, sizeof (dmu_replay_record_t)); kmem_free(dsp, sizeof (dmu_sendarg_t)); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h Fri Oct 14 07:31:47 2016 (r307284) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_impl.h Fri Oct 14 07:32:24 2016 (r307285) @@ -301,6 +301,8 @@ typedef struct dmu_sendarg { uint64_t dsa_last_data_offset; uint64_t dsa_resume_object; uint64_t dsa_resume_offset; + boolean_t dsa_sent_begin; + boolean_t dsa_sent_end; } dmu_sendarg_t; void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:35:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 37490C11D87; Fri, 14 Oct 2016 07:35:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F28C716F1; Fri, 14 Oct 2016 07:35:44 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7Zip5069375; Fri, 14 Oct 2016 07:35:44 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7ZhN6069369; Fri, 14 Oct 2016 07:35:43 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140735.u9E7ZhN6069369@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:35:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307287 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:35:45 -0000 Author: mav Date: Fri Oct 14 07:35:43 2016 New Revision: 307287 URL: https://svnweb.freebsd.org/changeset/base/307287 Log: MFC r305338: MFV r305335: 7003 zap_lockdir() should tag hold zap_lockdir() / zap_unlockdir() should take a "void *tag" argument which tags the hold on the zap. This will help diagnose programming errors which misuse the hold on the ZAP. Sponsored by: Intel Corp. Closes #108 Reviewed by: Pavel Zakharov Reviewed by: Steve Gonczi Reviewed by: George Wilson Reviewed by: Brian Behlendorf Author: Matthew Ahrens openzfs/openzfs@0780b3eab5a2c13e04328b39ecd2a6d0d3c4f7cb Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:33:36 2016 (r307286) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:35:43 2016 (r307287) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. @@ -2896,6 +2896,13 @@ dmu_buf_get_blkptr(dmu_buf_t *db) return (dbi->db_blkptr); } +objset_t * +dmu_buf_get_objset(dmu_buf_t *db) +{ + dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db; + return (dbi->db_objset); +} + static void dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db) { Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Fri Oct 14 07:33:36 2016 (r307286) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Fri Oct 14 07:35:43 2016 (r307287) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright 2013 DEY Storage Systems, Inc. @@ -616,6 +616,8 @@ void *dmu_buf_remove_user(dmu_buf_t *db, */ void *dmu_buf_get_user(dmu_buf_t *db); +objset_t *dmu_buf_get_objset(dmu_buf_t *db); + /* Block until any in-progress dmu buf user evictions complete. */ void dmu_buf_user_evict_wait(void); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h Fri Oct 14 07:33:36 2016 (r307286) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h Fri Oct 14 07:35:43 2016 (r307287) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, 2015 by Delphix. All rights reserved. + * Copyright (c) 2013, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -197,8 +197,8 @@ typedef struct zap_name { boolean_t zap_match(zap_name_t *zn, const char *matchname); int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, - krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp); -void zap_unlockdir(zap_t *zap); + krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp); +void zap_unlockdir(zap_t *zap, void *tag); void zap_evict(void *dbu); zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt); void zap_name_free(zap_name_t *zn); @@ -217,9 +217,10 @@ void fzap_prefetch(zap_name_t *zn); int fzap_count_write(zap_name_t *zn, int add, refcount_t *towrite, refcount_t *tooverwrite); int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, - const void *val, dmu_tx_t *tx); + const void *val, void *tag, dmu_tx_t *tx); int fzap_update(zap_name_t *zn, - int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); + int integer_size, uint64_t num_integers, const void *val, + void *tag, dmu_tx_t *tx); int fzap_length(zap_name_t *zn, uint64_t *integer_size, uint64_t *num_integers); int fzap_remove(zap_name_t *zn, dmu_tx_t *tx); @@ -229,7 +230,7 @@ void zap_put_leaf(struct zap_leaf *l); int fzap_add_cd(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, - const void *val, uint32_t cd, dmu_tx_t *tx); + const void *val, uint32_t cd, void *tag, dmu_tx_t *tx); void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags); int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Fri Oct 14 07:33:36 2016 (r307286) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Fri Oct 14 07:35:43 2016 (r307287) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. */ @@ -589,7 +589,8 @@ zap_deref_leaf(zap_t *zap, uint64_t h, d } static int -zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp) +zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, + void *tag, dmu_tx_t *tx, zap_leaf_t **lp) { zap_t *zap = zn->zn_zap; uint64_t hash = zn->zn_hash; @@ -611,9 +612,9 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf uint64_t object = zap->zap_object; zap_put_leaf(l); - zap_unlockdir(zap); + zap_unlockdir(zap, tag); err = zap_lockdir(os, object, tx, RW_WRITER, - FALSE, FALSE, &zn->zn_zap); + FALSE, FALSE, tag, &zn->zn_zap); zap = zn->zn_zap; if (err) return (err); @@ -676,7 +677,8 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf } static void -zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx) +zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, + void *tag, dmu_tx_t *tx) { zap_t *zap = zn->zn_zap; int shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift; @@ -696,9 +698,9 @@ zap_put_leaf_maybe_grow_ptrtbl(zap_name_ objset_t *os = zap->zap_objset; uint64_t zapobj = zap->zap_object; - zap_unlockdir(zap); + zap_unlockdir(zap, tag); err = zap_lockdir(os, zapobj, tx, - RW_WRITER, FALSE, FALSE, &zn->zn_zap); + RW_WRITER, FALSE, FALSE, tag, &zn->zn_zap); zap = zn->zn_zap; if (err) return; @@ -788,7 +790,7 @@ fzap_lookup(zap_name_t *zn, int fzap_add_cd(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, - const void *val, uint32_t cd, dmu_tx_t *tx) + const void *val, uint32_t cd, void *tag, dmu_tx_t *tx) { zap_leaf_t *l; int err; @@ -817,7 +819,7 @@ retry: if (err == 0) { zap_increment_num_entries(zap, 1, tx); } else if (err == EAGAIN) { - err = zap_expand_leaf(zn, l, tx, &l); + err = zap_expand_leaf(zn, l, tag, tx, &l); zap = zn->zn_zap; /* zap_expand_leaf() may change zap */ if (err == 0) goto retry; @@ -825,26 +827,27 @@ retry: out: if (zap != NULL) - zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx); + zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx); return (err); } int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, - const void *val, dmu_tx_t *tx) + const void *val, void *tag, dmu_tx_t *tx) { int err = fzap_check(zn, integer_size, num_integers); if (err != 0) return (err); return (fzap_add_cd(zn, integer_size, num_integers, - val, ZAP_NEED_CD, tx)); + val, ZAP_NEED_CD, tag, tx)); } int fzap_update(zap_name_t *zn, - int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx) + int integer_size, uint64_t num_integers, const void *val, + void *tag, dmu_tx_t *tx) { zap_leaf_t *l; int err, create; @@ -874,14 +877,14 @@ retry: } if (err == EAGAIN) { - err = zap_expand_leaf(zn, l, tx, &l); + err = zap_expand_leaf(zn, l, tag, tx, &l); zap = zn->zn_zap; /* zap_expand_leaf() may change zap */ if (err == 0) goto retry; } if (zap != NULL) - zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx); + zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx); return (err); } Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:33:36 2016 (r307286) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:35:43 2016 (r307287) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2015 by Delphix. All rights reserved. + * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -43,7 +43,8 @@ extern inline mzap_phys_t *zap_m_phys(zap_t *zap); -static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags); +static int mzap_upgrade(zap_t **zapp, + void *tag, dmu_tx_t *tx, zap_flags_t flags); uint64_t zap_getflags(zap_t *zap) @@ -459,20 +460,18 @@ mzap_open(objset_t *os, uint64_t obj, dm return (zap); } -int -zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, +static int +zap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx, krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp) { zap_t *zap; - dmu_buf_t *db; krw_t lt; - int err; - *zapp = NULL; + ASSERT0(db->db_offset); + objset_t *os = dmu_buf_get_objset(db); + uint64_t obj = db->db_object; - err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH); - if (err) - return (err); + *zapp = NULL; #ifdef ZFS_DEBUG { @@ -520,10 +519,12 @@ zap_lockdir(objset_t *os, uint64_t obj, dprintf("upgrading obj %llu: num_entries=%u\n", obj, zap->zap_m.zap_num_entries); *zapp = zap; - return (mzap_upgrade(zapp, tx, 0)); + int err = mzap_upgrade(zapp, tag, tx, 0); + if (err != 0) + rw_exit(&zap->zap_rwlock); + return (err); } - err = dmu_object_set_blocksize(os, obj, newsz, 0, tx); - ASSERT0(err); + VERIFY0(dmu_object_set_blocksize(os, obj, newsz, 0, tx)); zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1; } @@ -532,15 +533,31 @@ zap_lockdir(objset_t *os, uint64_t obj, return (0); } +int +zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, + krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp) +{ + dmu_buf_t *db; + int err; + + err = dmu_buf_hold(os, obj, 0, tag, &db, DMU_READ_NO_PREFETCH); + if (err != 0) + return (err); + err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp); + if (err != 0) + dmu_buf_rele(db, tag); + return (err); +} + void -zap_unlockdir(zap_t *zap) +zap_unlockdir(zap_t *zap, void *tag) { rw_exit(&zap->zap_rwlock); - dmu_buf_rele(zap->zap_dbuf, NULL); + dmu_buf_rele(zap->zap_dbuf, tag); } static int -mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags) +mzap_upgrade(zap_t **zapp, void *tag, dmu_tx_t *tx, zap_flags_t flags) { mzap_phys_t *mzp; int i, sz, nchunks; @@ -578,7 +595,8 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, dprintf("adding %s=%llu\n", mze->mze_name, mze->mze_value); zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT); - err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx); + err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, + tag, tx); zap = zn->zn_zap; /* fzap_add_cd() may change zap */ zap_name_free(zn); if (err) @@ -617,9 +635,9 @@ mzap_create_impl(objset_t *os, uint64_t zap_t *zap; /* Only fat zap supports flags; upgrade immediately. */ VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER, - B_FALSE, B_FALSE, &zap)); - VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags)); - zap_unlockdir(zap); + B_FALSE, B_FALSE, FTAG, &zap)); + VERIFY3U(0, ==, mzap_upgrade(&zap, FTAG, tx, flags)); + zap_unlockdir(zap, FTAG); } } @@ -714,7 +732,7 @@ zap_count(objset_t *os, uint64_t zapobj, zap_t *zap; int err; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); if (!zap->zap_ismicro) { @@ -722,7 +740,7 @@ zap_count(objset_t *os, uint64_t zapobj, } else { *count = zap->zap_m.zap_num_entries; } - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -779,25 +797,19 @@ zap_lookup(objset_t *os, uint64_t zapobj num_integers, buf, MT_EXACT, NULL, 0, NULL)); } -int -zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, +static int +zap_lookup_impl(zap_t *zap, const char *name, uint64_t integer_size, uint64_t num_integers, void *buf, matchtype_t mt, char *realname, int rn_len, boolean_t *ncp) { - zap_t *zap; - int err; + int err = 0; mzap_ent_t *mze; zap_name_t *zn; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); - if (err) - return (err); zn = zap_name_alloc(zap, name, mt); - if (zn == NULL) { - zap_unlockdir(zap); + if (zn == NULL) return (SET_ERROR(ENOTSUP)); - } if (!zap->zap_ismicro) { err = fzap_lookup(zn, integer_size, num_integers, buf, @@ -824,7 +836,24 @@ zap_lookup_norm(objset_t *os, uint64_t z } } zap_name_free(zn); - zap_unlockdir(zap); + return (err); +} + +int +zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf, + matchtype_t mt, char *realname, int rn_len, + boolean_t *ncp) +{ + zap_t *zap; + int err; + + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); + if (err != 0) + return (err); + err = zap_lookup_impl(zap, name, integer_size, + num_integers, buf, mt, realname, rn_len, ncp); + zap_unlockdir(zap, FTAG); return (err); } @@ -836,18 +865,18 @@ zap_prefetch_uint64(objset_t *os, uint64 int err; zap_name_t *zn; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } fzap_prefetch(zn); zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -859,19 +888,19 @@ zap_lookup_uint64(objset_t *os, uint64_t int err; zap_name_t *zn; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } err = fzap_lookup(zn, integer_size, num_integers, buf, NULL, 0, NULL); zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -894,12 +923,12 @@ zap_length(objset_t *os, uint64_t zapobj mzap_ent_t *mze; zap_name_t *zn; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc(zap, name, MT_EXACT); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } if (!zap->zap_ismicro) { @@ -916,7 +945,7 @@ zap_length(objset_t *os, uint64_t zapobj } } zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -928,17 +957,17 @@ zap_length_uint64(objset_t *os, uint64_t int err; zap_name_t *zn; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } err = fzap_length(zn, integer_size, num_integers); zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -997,22 +1026,24 @@ zap_add(objset_t *os, uint64_t zapobj, c const uint64_t *intval = val; zap_name_t *zn; - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc(zap, key, MT_EXACT); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } if (!zap->zap_ismicro) { - err = fzap_add(zn, integer_size, num_integers, val, tx); + err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx); zap = zn->zn_zap; /* fzap_add() may change zap */ } else if (integer_size != 8 || num_integers != 1 || strlen(key) >= MZAP_NAME_LEN) { - err = mzap_upgrade(&zn->zn_zap, tx, 0); - if (err == 0) - err = fzap_add(zn, integer_size, num_integers, val, tx); + err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0); + if (err == 0) { + err = fzap_add(zn, integer_size, num_integers, val, + FTAG, tx); + } zap = zn->zn_zap; /* fzap_add() may change zap */ } else { mze = mze_find(zn); @@ -1025,7 +1056,7 @@ zap_add(objset_t *os, uint64_t zapobj, c ASSERT(zap == zn->zn_zap); zap_name_free(zn); if (zap != NULL) /* may be NULL if fzap_add() failed */ - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1038,19 +1069,19 @@ zap_add_uint64(objset_t *os, uint64_t za int err; zap_name_t *zn; - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } - err = fzap_add(zn, integer_size, num_integers, val, tx); + err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx); zap = zn->zn_zap; /* fzap_add() may change zap */ zap_name_free(zn); if (zap != NULL) /* may be NULL if fzap_add() failed */ - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1074,25 +1105,27 @@ zap_update(objset_t *os, uint64_t zapobj (void) zap_lookup(os, zapobj, name, 8, 1, &oldval); #endif - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc(zap, name, MT_EXACT); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } if (!zap->zap_ismicro) { - err = fzap_update(zn, integer_size, num_integers, val, tx); + err = fzap_update(zn, integer_size, num_integers, val, + FTAG, tx); zap = zn->zn_zap; /* fzap_update() may change zap */ } else if (integer_size != 8 || num_integers != 1 || strlen(name) >= MZAP_NAME_LEN) { dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n", zapobj, integer_size, num_integers, name); - err = mzap_upgrade(&zn->zn_zap, tx, 0); - if (err == 0) + err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0); + if (err == 0) { err = fzap_update(zn, integer_size, num_integers, - val, tx); + val, FTAG, tx); + } zap = zn->zn_zap; /* fzap_update() may change zap */ } else { mze = mze_find(zn); @@ -1106,7 +1139,7 @@ zap_update(objset_t *os, uint64_t zapobj ASSERT(zap == zn->zn_zap); zap_name_free(zn); if (zap != NULL) /* may be NULL if fzap_upgrade() failed */ - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1119,19 +1152,19 @@ zap_update_uint64(objset_t *os, uint64_t zap_name_t *zn; int err; - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } - err = fzap_update(zn, integer_size, num_integers, val, tx); + err = fzap_update(zn, integer_size, num_integers, val, FTAG, tx); zap = zn->zn_zap; /* fzap_update() may change zap */ zap_name_free(zn); if (zap != NULL) /* may be NULL if fzap_upgrade() failed */ - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1150,12 +1183,12 @@ zap_remove_norm(objset_t *os, uint64_t z mzap_ent_t *mze; zap_name_t *zn; - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc(zap, name, mt); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } if (!zap->zap_ismicro) { @@ -1172,7 +1205,7 @@ zap_remove_norm(objset_t *os, uint64_t z } } zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1184,17 +1217,17 @@ zap_remove_uint64(objset_t *os, uint64_t int err; zap_name_t *zn; - err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap); if (err) return (err); zn = zap_name_alloc_uint64(zap, key, key_numints); if (zn == NULL) { - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (SET_ERROR(ENOTSUP)); } err = fzap_remove(zn, tx); zap_name_free(zn); - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } @@ -1226,7 +1259,7 @@ zap_cursor_fini(zap_cursor_t *zc) { if (zc->zc_zap) { rw_enter(&zc->zc_zap->zap_rwlock, RW_READER); - zap_unlockdir(zc->zc_zap); + zap_unlockdir(zc->zc_zap, NULL); zc->zc_zap = NULL; } if (zc->zc_leaf) { @@ -1273,7 +1306,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, za if (zc->zc_zap == NULL) { int hb; err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL, - RW_READER, TRUE, FALSE, &zc->zc_zap); + RW_READER, TRUE, FALSE, NULL, &zc->zc_zap); if (err) return (err); @@ -1377,7 +1410,7 @@ zap_get_stats(objset_t *os, uint64_t zap int err; zap_t *zap; - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err) return (err); @@ -1390,7 +1423,7 @@ zap_get_stats(objset_t *os, uint64_t zap } else { fzap_get_stats(zap, zs); } - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (0); } @@ -1409,7 +1442,7 @@ zap_count_write(objset_t *os, uint64_t z * - 2 blocks for possibly split leaves, * - 2 grown ptrtbl blocks * - * This also accomodates the case where an add operation to a fairly + * This also accommodates the case where an add operation to a fairly * large microzap results in a promotion to fatzap. */ if (name == NULL) { @@ -1422,10 +1455,11 @@ zap_count_write(objset_t *os, uint64_t z * We lock the zap with adding == FALSE. Because, if we pass * the actual value of add, it could trigger a mzap_upgrade(). * At present we are just evaluating the possibility of this operation - * and hence we donot want to trigger an upgrade. + * and hence we do not want to trigger an upgrade. */ - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); - if (err) + err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, + FTAG, &zap); + if (err != 0) return (err); if (!zap->zap_ismicro) { @@ -1471,6 +1505,6 @@ zap_count_write(objset_t *os, uint64_t z } } - zap_unlockdir(zap); + zap_unlockdir(zap, FTAG); return (err); } From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:37:09 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 93553C11E7C; Fri, 14 Oct 2016 07:37:09 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6C41E19E6; Fri, 14 Oct 2016 07:37:09 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7b8S3069548; Fri, 14 Oct 2016 07:37:08 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7b8At069547; Fri, 14 Oct 2016 07:37:08 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140737.u9E7b8At069547@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:37:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307289 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:37:09 -0000 Author: mav Date: Fri Oct 14 07:37:08 2016 New Revision: 307289 URL: https://svnweb.freebsd.org/changeset/base/307289 Log: MFC r305339: MFV r305336: 7247 zfs receive of deduplicated stream fails This resolves two 'zfs recv' issues. First, when receiving into an existing filesystem, a snapshot created during the receive process is not added to the guid->dataset map for the stream, resulting in failed lookups for deduped streams when a WRITE_BYREF record refers to a snapshot received earlier in the stream. Second, the newly created snapshot was also not set properly, referencing the snapshot before the new receiving dataset rather than the existing filesystem. Closes #159 Reviewed by: Matthew Ahrens Reviewed by: Dan Kimmel Author: Chris Williamson openzfs/openzfs@b09697c8c18be68abfe538de9809938239402ae8 Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 14 07:36:32 2016 (r307288) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Fri Oct 14 07:37:08 2016 (r307289) @@ -3113,6 +3113,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *t dsl_dataset_phys(origin_head)->ds_flags &= ~DS_FLAG_INCONSISTENT; + drc->drc_newsnapobj = + dsl_dataset_phys(origin_head)->ds_prev_snap_obj; + dsl_dataset_rele(origin_head, FTAG); dsl_destroy_head_sync_impl(drc->drc_ds, tx); @@ -3148,8 +3151,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *t (void) zap_remove(dp->dp_meta_objset, ds->ds_object, DS_FIELD_RESUME_TONAME, tx); } + drc->drc_newsnapobj = + dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj; } - drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj; /* * Release the hold from dmu_recv_begin. This must be done before * we return to open context, so that when we free the dataset's dnode, @@ -3191,8 +3195,6 @@ static int dmu_recv_end_modified_blocks static int dmu_recv_existing_end(dmu_recv_cookie_t *drc) { - int error; - #ifdef _KERNEL /* * We will be destroying the ds; make sure its origin is unmounted if @@ -3203,23 +3205,30 @@ dmu_recv_existing_end(dmu_recv_cookie_t zfs_destroy_unmount_origin(name); #endif - error = dsl_sync_task(drc->drc_tofs, + return (dsl_sync_task(drc->drc_tofs, dmu_recv_end_check, dmu_recv_end_sync, drc, - dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL); - - if (error != 0) - dmu_recv_cleanup_ds(drc); - return (error); + dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL)); } static int dmu_recv_new_end(dmu_recv_cookie_t *drc) { + return (dsl_sync_task(drc->drc_tofs, + dmu_recv_end_check, dmu_recv_end_sync, drc, + dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL)); +} + +int +dmu_recv_end(dmu_recv_cookie_t *drc, void *owner) +{ int error; - error = dsl_sync_task(drc->drc_tofs, - dmu_recv_end_check, dmu_recv_end_sync, drc, - dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL); + drc->drc_owner = owner; + + if (drc->drc_newfs) + error = dmu_recv_new_end(drc); + else + error = dmu_recv_existing_end(drc); if (error != 0) { dmu_recv_cleanup_ds(drc); @@ -3231,17 +3240,6 @@ dmu_recv_new_end(dmu_recv_cookie_t *drc) return (error); } -int -dmu_recv_end(dmu_recv_cookie_t *drc, void *owner) -{ - drc->drc_owner = owner; - - if (drc->drc_newfs) - return (dmu_recv_new_end(drc)); - else - return (dmu_recv_existing_end(drc)); -} - /* * Return TRUE if this objset is currently being received into. */ From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:40:22 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 362A2C11FE9; Fri, 14 Oct 2016 07:40:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F1E0A1ED6; Fri, 14 Oct 2016 07:40:21 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7eLJ8069869; Fri, 14 Oct 2016 07:40:21 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7eKHc069861; Fri, 14 Oct 2016 07:40:20 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140740.u9E7eKHc069861@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:40:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307292 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:40:22 -0000 Author: mav Date: Fri Oct 14 07:40:20 2016 New Revision: 307292 URL: https://svnweb.freebsd.org/changeset/base/307292 Log: MFC r305340: MFC r305337: 7004 dmu_tx_hold_zap() does dnode_hold() 7x on same object Using a benchmark which has 32 threads creating 2 million files in the same directory, on a machine with 16 CPU cores, I observed poor performance. I noticed that dmu_tx_hold_zap() was using about 30% of all CPU, and doing dnode_hold() 7 times on the same object (the ZAP object that is being held). dmu_tx_hold_zap() keeps a hold on the dnode_t the entire time it is running, in dmu_tx_hold_t:txh_dnode, so it would be nice to use the dnode_t that we already have in hand, rather than repeatedly calling dnode_hold(). To do this, we need to pass the dnode_t down through all the intermediate calls that dmu_tx_hold_zap() makes, making these routines take the dnode_t* rather than an objset_t* and a uint64_t object number. In particular, the following routines will need to have analogous *_by_dnode() variants created: dmu_buf_hold_noread() dmu_buf_hold() zap_lookup() zap_lookup_norm() zap_count_write() zap_lockdir() zap_count_write() This can improve performance on the benchmark described above by 100%, from 30,000 file creations per second to 60,000. (This improvement is on top of that provided by working around the object allocation issue. Peak performance of ~90,000 creations per second was observed with 8 CPUs; adding CPUs past that decreased performance due to lock contention.) The CPU used by dmu_tx_hold_zap() was reduced by 88%, from 340 CPU-seconds to 40 CPU-seconds. Sponsored by: Intel Corp. Closes #109 Reviewed by: Steve Gonczi Reviewed by: George Wilson Reviewed by: Pavel Zakharov Reviewed by: Ned Bass Reviewed by: Brian Behlendorf Author: Matthew Ahrens openzfs/openzfs@d3e523d489a169ab36f9ec1b2a111a60a5563a9f Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Fri Oct 14 07:40:20 2016 (r307292) @@ -2903,6 +2903,21 @@ dmu_buf_get_objset(dmu_buf_t *db) return (dbi->db_objset); } +dnode_t * +dmu_buf_dnode_enter(dmu_buf_t *db) +{ + dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db; + DB_DNODE_ENTER(dbi); + return (DB_DNODE(dbi)); +} + +void +dmu_buf_dnode_exit(dmu_buf_t *db) +{ + dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db; + DB_DNODE_EXIT(dbi); +} + static void dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db) { Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Fri Oct 14 07:40:20 2016 (r307292) @@ -131,6 +131,26 @@ const dmu_object_byteswap_info_t dmu_ot_ }; int +dmu_buf_hold_noread_by_dnode(dnode_t *dn, uint64_t offset, + void *tag, dmu_buf_t **dbp) +{ + uint64_t blkid; + dmu_buf_impl_t *db; + + blkid = dbuf_whichblock(dn, 0, offset); + rw_enter(&dn->dn_struct_rwlock, RW_READER); + db = dbuf_hold(dn, blkid, tag); + rw_exit(&dn->dn_struct_rwlock); + + if (db == NULL) { + *dbp = NULL; + return (SET_ERROR(EIO)); + } + + *dbp = &db->db; + return (0); +} +int dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset, void *tag, dmu_buf_t **dbp) { @@ -158,6 +178,29 @@ dmu_buf_hold_noread(objset_t *os, uint64 } int +dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset, + void *tag, dmu_buf_t **dbp, int flags) +{ + int err; + int db_flags = DB_RF_CANFAIL; + + if (flags & DMU_READ_NO_PREFETCH) + db_flags |= DB_RF_NOPREFETCH; + + err = dmu_buf_hold_noread_by_dnode(dn, offset, tag, dbp); + if (err == 0) { + dmu_buf_impl_t *db = (dmu_buf_impl_t *)(*dbp); + err = dbuf_read(db, NULL, db_flags); + if (err != 0) { + dbuf_rele(db, tag); + *dbp = NULL; + } + } + + return (err); +} + +int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, void *tag, dmu_buf_t **dbp, int flags) { Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c Fri Oct 14 07:40:20 2016 (r307292) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -808,15 +808,14 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t o * access the name in this fat-zap so that we'll check * for i/o errors to the leaf blocks, etc. */ - err = zap_lookup(dn->dn_objset, dn->dn_object, name, - 8, 0, NULL); + err = zap_lookup_by_dnode(dn, name, 8, 0, NULL); if (err == EIO) { tx->tx_err = err; return; } } - err = zap_count_write(dn->dn_objset, dn->dn_object, name, add, + err = zap_count_write_by_dnode(dn, name, add, &txh->txh_space_towrite, &txh->txh_space_tooverwrite); /* Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Fri Oct 14 07:40:20 2016 (r307292) @@ -78,6 +78,7 @@ struct file; typedef struct objset objset_t; typedef struct dmu_tx dmu_tx_t; typedef struct dsl_dir dsl_dir_t; +typedef struct dnode dnode_t; typedef enum dmu_object_byteswap { DMU_BSWAP_UINT8, @@ -418,7 +419,7 @@ dmu_write_embedded(objset_t *os, uint64_ #define WP_DMU_SYNC 0x2 #define WP_SPILL 0x4 -void dmu_write_policy(objset_t *os, struct dnode *dn, int level, int wp, +void dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, struct zio_prop *zp); /* * The bonus data is accessed more or less like a regular buffer. @@ -444,7 +445,7 @@ int dmu_rm_spill(objset_t *, uint64_t, d */ int dmu_spill_hold_by_bonus(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp); -int dmu_spill_hold_by_dnode(struct dnode *dn, uint32_t flags, +int dmu_spill_hold_by_dnode(dnode_t *dn, uint32_t flags, void *tag, dmu_buf_t **dbp); int dmu_spill_hold_existing(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp); @@ -464,6 +465,8 @@ int dmu_spill_hold_existing(dmu_buf_t *b */ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, void *tag, dmu_buf_t **, int flags); +int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset, + void *tag, dmu_buf_t **dbp, int flags); /* * Add a reference to a dmu buffer that has already been held via @@ -617,6 +620,8 @@ void *dmu_buf_remove_user(dmu_buf_t *db, void *dmu_buf_get_user(dmu_buf_t *db); objset_t *dmu_buf_get_objset(dmu_buf_t *db); +dnode_t *dmu_buf_dnode_enter(dmu_buf_t *db); +void dmu_buf_dnode_exit(dmu_buf_t *db); /* Block until any in-progress dmu buf user evictions complete. */ void dmu_buf_user_evict_wait(void); @@ -800,7 +805,7 @@ extern const dmu_object_byteswap_info_t */ int dmu_object_info(objset_t *os, uint64_t object, dmu_object_info_t *doi); /* Like dmu_object_info, but faster if you have a held dnode in hand. */ -void dmu_object_info_from_dnode(struct dnode *dn, dmu_object_info_t *doi); +void dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi); /* Like dmu_object_info, but faster if you have a held dbuf in hand. */ void dmu_object_info_from_db(dmu_buf_t *db, dmu_object_info_t *doi); /* Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h Fri Oct 14 07:40:20 2016 (r307292) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. */ @@ -149,7 +149,7 @@ typedef struct dnode_phys { blkptr_t dn_spill; } dnode_phys_t; -typedef struct dnode { +struct dnode { /* * Protects the structure of the dnode, including the number of levels * of indirection (dn_nlevels), dn_maxblkid, and dn_next_* @@ -247,7 +247,7 @@ typedef struct dnode { /* holds prefetch structure */ struct zfetch dn_zfetch; -} dnode_t; +}; /* * Adds a level of indirection between the dbuf and the dnode to avoid Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap.h Fri Oct 14 07:40:20 2016 (r307292) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. */ #ifndef _SYS_ZAP_H @@ -216,8 +216,14 @@ int zap_lookup_uint64(objset_t *os, uint int zap_contains(objset_t *ds, uint64_t zapobj, const char *name); int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints); +int zap_lookup_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf); +int zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf, + matchtype_t mt, char *realname, int rn_len, + boolean_t *ncp); -int zap_count_write(objset_t *os, uint64_t zapobj, const char *name, +int zap_count_write_by_dnode(dnode_t *dn, const char *name, int add, refcount_t *towrite, refcount_t *tooverwrite); /* Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c Fri Oct 14 07:40:20 2016 (r307292) @@ -270,6 +270,7 @@ zap_table_load(zap_t *zap, zap_table_phy uint64_t blk, off; int err; dmu_buf_t *db; + dnode_t *dn; int bs = FZAP_BLOCK_SHIFT(zap); ASSERT(RW_LOCK_HELD(&zap->zap_rwlock)); @@ -277,8 +278,15 @@ zap_table_load(zap_t *zap, zap_table_phy blk = idx >> (bs-3); off = idx & ((1<<(bs-3))-1); - err = dmu_buf_hold(zap->zap_objset, zap->zap_object, + /* + * Note: this is equivalent to dmu_buf_hold(), but we use + * _dnode_enter / _by_dnode because it's faster because we don't + * have to hold the dnode. + */ + dn = dmu_buf_dnode_enter(zap->zap_dbuf); + err = dmu_buf_hold_by_dnode(dn, (tbl->zt_blk + blk) << bs, FTAG, &db, DMU_READ_NO_PREFETCH); + dmu_buf_dnode_exit(zap->zap_dbuf); if (err) return (err); *valp = ((uint64_t *)db->db_data)[off]; @@ -292,9 +300,11 @@ zap_table_load(zap_t *zap, zap_table_phy */ blk = (idx*2) >> (bs-3); - err = dmu_buf_hold(zap->zap_objset, zap->zap_object, + dn = dmu_buf_dnode_enter(zap->zap_dbuf); + err = dmu_buf_hold_by_dnode(dn, (tbl->zt_nextblk + blk) << bs, FTAG, &db, DMU_READ_NO_PREFETCH); + dmu_buf_dnode_exit(zap->zap_dbuf); if (err == 0) dmu_buf_rele(db, FTAG); } @@ -505,8 +515,10 @@ zap_get_leaf_byblk(zap_t *zap, uint64_t ASSERT(RW_LOCK_HELD(&zap->zap_rwlock)); - err = dmu_buf_hold(zap->zap_objset, zap->zap_object, + dnode_t *dn = dmu_buf_dnode_enter(zap->zap_dbuf); + err = dmu_buf_hold_by_dnode(dn, blkid << bs, NULL, &db, DMU_READ_NO_PREFETCH); + dmu_buf_dnode_exit(zap->zap_dbuf); if (err) return (err); Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:40:04 2016 (r307291) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:40:20 2016 (r307292) @@ -533,6 +533,24 @@ zap_lockdir_impl(dmu_buf_t *db, void *ta return (0); } +static int +zap_lockdir_by_dnode(dnode_t *dn, dmu_tx_t *tx, + krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp) +{ + dmu_buf_t *db; + int err; + + err = dmu_buf_hold_by_dnode(dn, 0, tag, &db, DMU_READ_NO_PREFETCH); + if (err != 0) { + return (err); + } + err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp); + if (err != 0) { + dmu_buf_rele(db, tag); + } + return (err); +} + int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp) @@ -858,6 +876,33 @@ zap_lookup_norm(objset_t *os, uint64_t z } int +zap_lookup_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf) +{ + return (zap_lookup_norm_by_dnode(dn, name, integer_size, + num_integers, buf, MT_EXACT, NULL, 0, NULL)); +} + +int +zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf, + matchtype_t mt, char *realname, int rn_len, + boolean_t *ncp) +{ + zap_t *zap; + int err; + + err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, + FTAG, &zap); + if (err != 0) + return (err); + err = zap_lookup_impl(zap, name, integer_size, + num_integers, buf, mt, realname, rn_len, ncp); + zap_unlockdir(zap, FTAG); + return (err); +} + +int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints) { @@ -1428,7 +1473,7 @@ zap_get_stats(objset_t *os, uint64_t zap } int -zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, +zap_count_write_by_dnode(dnode_t *dn, const char *name, int add, refcount_t *towrite, refcount_t *tooverwrite) { zap_t *zap; @@ -1457,7 +1502,7 @@ zap_count_write(objset_t *os, uint64_t z * At present we are just evaluating the possibility of this operation * and hence we do not want to trigger an upgrade. */ - err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, + err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, FTAG, &zap); if (err != 0) return (err); From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:41:45 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8D1CBC110CF; Fri, 14 Oct 2016 07:41:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5D55E2E9; Fri, 14 Oct 2016 07:41:45 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7fiqE073427; Fri, 14 Oct 2016 07:41:44 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7fiWa073426; Fri, 14 Oct 2016 07:41:44 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140741.u9E7fiWa073426@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:41:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307294 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:41:45 -0000 Author: mav Date: Fri Oct 14 07:41:44 2016 New Revision: 307294 URL: https://svnweb.freebsd.org/changeset/base/307294 Log: MFC r305342: Missed FreeBSD-specific piece of r305338. Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:41:11 2016 (r307293) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Fri Oct 14 07:41:44 2016 (r307294) @@ -1418,7 +1418,7 @@ zap_cursor_move_to_key(zap_cursor_t *zc, if (zc->zc_zap == NULL) { err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL, - RW_READER, TRUE, FALSE, &zc->zc_zap); + RW_READER, TRUE, FALSE, FTAG, &zc->zc_zap); if (err) return (err); } else { From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:43:30 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 168FCC1127C; Fri, 14 Oct 2016 07:43:30 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DA76EA5F; Fri, 14 Oct 2016 07:43:29 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7hTPi073610; Fri, 14 Oct 2016 07:43:29 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7hTil073609; Fri, 14 Oct 2016 07:43:29 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140743.u9E7hTil073609@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:43:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307296 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:43:30 -0000 Author: mav Date: Fri Oct 14 07:43:28 2016 New Revision: 307296 URL: https://svnweb.freebsd.org/changeset/base/307296 Log: MFC r305456 (by avg): fix zfs pool creation accidentally broken by r305331 The upstream change introduced a new load state, SPA_LOAD_CREATE, and vdev_geom code needs to be aware of it. Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Fri Oct 14 07:42:53 2016 (r307295) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Fri Oct 14 07:43:28 2016 (r307296) @@ -730,7 +730,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi if (vd->vdev_spa->spa_splitting_newspa || (vd->vdev_prevstate == VDEV_STATE_UNKNOWN && - vd->vdev_spa->spa_load_state == SPA_LOAD_NONE)) { + vd->vdev_spa->spa_load_state == SPA_LOAD_NONE || + vd->vdev_spa->spa_load_state == SPA_LOAD_CREATE)) { /* * We are dealing with a vdev that hasn't been previously * opened (since boot), and we are not loading an From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:45:11 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 72733C11387; Fri, 14 Oct 2016 07:45:11 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3D003D81; Fri, 14 Oct 2016 07:45:11 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7jAG7073841; Fri, 14 Oct 2016 07:45:10 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7jAbQ073840; Fri, 14 Oct 2016 07:45:10 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140745.u9E7jAbQ073840@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:45:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307298 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:45:11 -0000 Author: mav Date: Fri Oct 14 07:45:10 2016 New Revision: 307298 URL: https://svnweb.freebsd.org/changeset/base/307298 Log: MFC r305561: MFV r305560: 7278 tuning zfs_arc_max does not impact arc_c_min When changing zfs_arc_max (e.g. as zdb does), it may be set to less than the default arc_c_min. arc_c_min should decrease to not be more than arc_c_max, but it doesn't; therefore tuning of arc_c_max is ineffective. Reviewed by: Dan Kimmel Reviewed by: Paul Dagnelie Reviewed by: Prakash Surya Reviewed by: Igor Kozhukhov Author: Matthew Ahrens openzfs/openzfs@608764beadaf4bb71c5d8fe1818e8392ac66a61b Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Oct 14 07:44:24 2016 (r307297) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Oct 14 07:45:10 2016 (r307298) @@ -5998,8 +5998,10 @@ arc_init(void) * Allow the tunables to override our calculations if they are * reasonable. */ - if (zfs_arc_max > arc_abs_min && zfs_arc_max < kmem_size()) + if (zfs_arc_max > arc_abs_min && zfs_arc_max < kmem_size()) { arc_c_max = zfs_arc_max; + arc_c_min = MIN(arc_c_min, arc_c_max); + } if (zfs_arc_min > arc_abs_min && zfs_arc_min <= arc_c_max) arc_c_min = zfs_arc_min; #endif From owner-svn-src-stable-10@freebsd.org Fri Oct 14 07:47:09 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 141BCC11475; Fri, 14 Oct 2016 07:47:09 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BE884D7; Fri, 14 Oct 2016 07:47:08 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9E7l771074044; Fri, 14 Oct 2016 07:47:07 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9E7l7PC074043; Fri, 14 Oct 2016 07:47:07 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610140747.u9E7l7PC074043@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 07:47:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307300 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 07:47:09 -0000 Author: mav Date: Fri Oct 14 07:47:07 2016 New Revision: 307300 URL: https://svnweb.freebsd.org/changeset/base/307300 Log: MFC r305563: MFV r305562: 7259 DS_FIELD_LARGE_BLOCKS is unused The DS_FIELD_LARGE_BLOCKS macro has been unused since the integration of this patch: commit ca0cc3918a1789fa839194af2a9245f801a06b1a Author: Matthew Ahrens Date: Fri Jul 24 09:53:55 2015 -0700 5959 clean up per-dataset feature count code Reviewed by: Toomas Soome Reviewed by: George Wilson Reviewed by: Alex Reece Approved by: Richard Lowe This patch simply removes this macro from dsl_dataset.h. Reviewed by: Dan Kimmel Reviewed by: Prakash Surya Reviewed by: Dan McDonald Reviewed by: Igor Kozhukhov Author: Matthew Ahrens Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Fri Oct 14 07:46:09 2016 (r307299) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h Fri Oct 14 07:47:07 2016 (r307300) @@ -86,13 +86,6 @@ struct dsl_pool; #define DS_FIELD_BOOKMARK_NAMES "com.delphix:bookmarks" /* - * This field is present (with value=0) if this dataset may contain large - * blocks (>128KB). If it is present, then this dataset - * is counted in the refcount of the SPA_FEATURE_LARGE_BLOCKS feature. - */ -#define DS_FIELD_LARGE_BLOCKS "org.open-zfs:large_blocks" - -/* * These fields are set on datasets that are in the middle of a resumable * receive, and allow the sender to resume the send if it is interrupted. */ From owner-svn-src-stable-10@freebsd.org Fri Oct 14 18:43:19 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 38D46C125D8; Fri, 14 Oct 2016 18:43:19 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0A9E9B89; Fri, 14 Oct 2016 18:43:18 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9EIhI3M026504; Fri, 14 Oct 2016 18:43:18 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9EIhIOc026503; Fri, 14 Oct 2016 18:43:18 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610141843.u9EIhIOc026503@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 14 Oct 2016 18:43:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307331 - stable/10/sys/sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2016 18:43:19 -0000 Author: mav Date: Fri Oct 14 18:43:17 2016 New Revision: 307331 URL: https://svnweb.freebsd.org/changeset/base/307331 Log: Bump __FreeBSD_version for todays ZFS merges. Modified: stable/10/sys/sys/param.h Modified: stable/10/sys/sys/param.h ============================================================================== --- stable/10/sys/sys/param.h Fri Oct 14 18:42:30 2016 (r307330) +++ stable/10/sys/sys/param.h Fri Oct 14 18:43:17 2016 (r307331) @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1003508 /* Master, propagated to newvers */ +#define __FreeBSD_version 1003509 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From owner-svn-src-stable-10@freebsd.org Sat Oct 15 12:28:16 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1A7E2C11D8E; Sat, 15 Oct 2016 12:28:16 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A981D375; Sat, 15 Oct 2016 12:28:15 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FCSEQl027250; Sat, 15 Oct 2016 12:28:14 GMT (envelope-from bapt@FreeBSD.org) Received: (from bapt@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FCSEWb027249; Sat, 15 Oct 2016 12:28:14 GMT (envelope-from bapt@FreeBSD.org) Message-Id: <201610151228.u9FCSEWb027249@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bapt set sender to bapt@FreeBSD.org using -f From: Baptiste Daroussin Date: Sat, 15 Oct 2016 12:28:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307355 - stable/10/share/misc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 12:28:16 -0000 Author: bapt Date: Sat Oct 15 12:28:14 2016 New Revision: 307355 URL: https://svnweb.freebsd.org/changeset/base/307355 Log: MFC r297289, r300542, r306854 Update pci_vendors to 2016-10-03 Modified: stable/10/share/misc/pci_vendors Directory Properties: stable/10/ (props changed) Modified: stable/10/share/misc/pci_vendors ============================================================================== --- stable/10/share/misc/pci_vendors Sat Oct 15 12:23:54 2016 (r307354) +++ stable/10/share/misc/pci_vendors Sat Oct 15 12:28:14 2016 (r307355) @@ -3,11 +3,11 @@ # # List of PCI ID's # -# Version: 2015.07.31 -# Date: 2015-07-31 03:15:02 +# Version: 2016.10.03 +# Date: 2016-10-03 03:15:01 # -# Maintained by Martin Mares and other volunteers from the -# PCI ID Project at http://pci-ids.ucw.cz/. +# Maintained by Albert Pool, Martin Mares, and other volunteers from +# the PCI ID Project at http://pci-ids.ucw.cz/. # # New data are always welcome, especially if they are accurate. If you have # anything to contribute, please follow the instructions at the web site. @@ -23,6 +23,7 @@ # device device_name <-- single tab # subvendor subdevice subsystem_name <-- two tabs +0001 SafeNet (wrong ID) 0010 Allied Telesis, Inc (Wrong ID) # This is a relabelled RTL-8139 8139 AT-2500TX V3 Ethernet @@ -243,6 +244,19 @@ 1000 1000 LSI53C895A PCI to Ultra2 SCSI Controller 0013 53c875a 1000 1000 LSI53C875A PCI to Ultra SCSI Controller + 0014 MegaRAID Tri-Mode SAS3516 + 1d49 0602 ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter + 0016 MegaRAID Tri-Mode SAS3508 + 1d49 0601 ThinkSystem RAID 930-8i 2GB Flash PCIe 12Gb Adapter + 1d49 0603 ThinkSystem RAID 930-24i 4GB Flash PCIe 12Gb Adapter + 1d49 0604 ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter + 0017 MegaRAID Tri-Mode SAS3408 + 1d49 0500 ThinkSystem RAID 530-8i PCIe 12Gb Adapter + 1d49 0502 ThinkSystem RAID 530-8i Dense Adapter + 001b MegaRAID Tri-Mode SAS3504 + 1d49 0605 ThinkSystem RAID 930-4i 2GB Flash Flex Adapter + 001c MegaRAID Tri-Mode SAS3404 + 1d49 0501 ThinkSystem RAID 530-4i Flex Adapter 0020 53c1010 Ultra3 SCSI Adapter 1000 1000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller 107b 1040 Server Onboard 53C1010-33 @@ -272,6 +286,7 @@ 103c 12c5 Ultra320 SCSI [A7173A] 103c 1323 Core I/O LAN/SCSI Combo [AB314A] 103c 3108 Single Channel Ultra320 SCSI HBA G2 + 103c 322a SC11Xe Ultra320 Single Channel PCIe x4 SCSI Host Bus Adapter (412911-B21) 124b 1170 PMC-USCSI320 # VMware's emulation of this device. Was missing from the list. 15ad 1976 LSI Logic Parallel SCSI Controller @@ -287,6 +302,10 @@ 0050 SAS1064 PCI-X Fusion-MPT SAS 1028 1f04 SAS 5/E 1028 1f09 SAS 5i/R + 0052 MegaRAID SAS-3 3216/3224 [Cutlass] + 0053 MegaRAID SAS-3 3216/3224 [Cutlass] + 1000 9350 MegaRAID SAS 9341-16i + 1000 9351 MegaRAID SAS 9341-24i 0054 SAS1068 PCI-X Fusion-MPT SAS 1028 1f04 SAS 5/E Adapter Controller 1028 1f05 SAS 5/i Adapter Controller @@ -345,6 +364,8 @@ 005c SAS1064A PCI-X Fusion-MPT SAS 005d MegaRAID SAS-3 3108 [Invader] 1000 9361 MegaRAID SAS 9361-8i + 1000 9364 MegaRAID SAS 9364-8i + 1000 936a MegaRAID SAS 9364-8i 1028 1f41 PERC H830 Adapter 1028 1f42 PERC H730P Adapter 1028 1f43 PERC H730 Adapter @@ -357,6 +378,7 @@ 1028 1f54 PERC FD33xD 17aa 1052 ThinkServer RAID 720i 17aa 1053 ThinkServer RAID 720ix + 1d49 0600 ThinkSystem RAID 730-8i 1GB Cache PCIe 12Gb Adapter 005e SAS1066 PCI-X Fusion-MPT SAS 005f MegaRAID SAS-3 3008 [Fury] 1028 1f44 PERC H330 Adapter @@ -364,6 +386,7 @@ 1028 1f4c PERC H330 Mini (for blades) 1028 1f4d PERC H330 Embedded (for monolithic) 1054 306a SAS 3004 iMR ROMB + 1d49 04db ServeRAID M1210 SAS/SATA Controller 0060 MegaRAID SAS 1078 1000 1006 MegaRAID SAS 8888ELP 1000 100a MegaRAID SAS 8708ELP @@ -474,6 +497,21 @@ 007c MegaRAID SAS 1078DE 1014 0395 ServeRAID-AR10is SAS/SATA Controller 007e SSS6200 PCI-Express Flash SSD + 1000 0504 Nytro NWD-BLP4-800 + 1000 0507 Nytro NWD-BLP4-1600 + 1000 0581 Nytro NWD-BLP4-400 + 1000 100d Nytro NWD-BFH6-1200 + 1000 100e Nytro NWD-BFH8-1600 + 1000 107e Nytro NWD-BFH8-3200 + 1000 1310 Nytro XP6302-8B1536 + 1000 1311 Nytro XP6302-8B2048 + 1000 1314 Nytro XP6302-8B4096 + 1000 150c Nytro XP6210-4A2048 + 1000 150f Nytro XP6210-4B2048 + 1000 160b Nytro XP6209-4A1024 + 1000 1613 Nytro XP6209-4B2048 + 108e 050a Nytro ELP4x200_4d_n + 108e 0581 Nytro ELP4x100_4d_n 0080 SAS2208 PCI-Express Fusion-MPT SAS-2 0081 SAS2208 PCI-Express Fusion-MPT SAS-2 0082 SAS2208 PCI-Express Fusion-MPT SAS-2 @@ -482,6 +520,9 @@ 0085 SAS2208 PCI-Express Fusion-MPT SAS-2 0086 SAS2308 PCI-Express Fusion-MPT SAS-2 0087 SAS2308 PCI-Express Fusion-MPT SAS-2 + 1000 3020 9207-8i SAS2.1 HBA + 1000 3040 9207-8e SAS2.1 HBA + 1000 3050 SAS9217-8i 1590 0044 H220i 008f 53c875J 1092 8000 FirePort 40 SCSI Controller @@ -492,8 +533,38 @@ 0095 SAS3108 PCI-Express Fusion-MPT SAS-3 0096 SAS3004 PCI-Express Fusion-MPT SAS-3 0097 SAS3008 PCI-Express Fusion-MPT SAS-3 + 1000 3090 SAS9311-8i + 1000 30e0 SAS9300-8i 1028 1f45 12GB/s HBA internal 1028 1f46 12Gbps HBA + 00ab SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) + 00ac SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + 1d49 0201 ThinkSystem 9400-16i PCIe 12Gb HBA + 1d49 0203 ThinkSystem 9400-16e PCIe 12Gb HBA + 00ae SAS3508 Fusion-MPT Tri-Mode RAID On Chip (ROC) + 00af SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + 1d49 0200 ThinkSystem 9400-8i PCIe 12Gb HBA + 1d49 0202 ThinkSystem 9400-8e PCIe 12Gb HBA + 00be SAS3504 Fusion-MPT Tri-Mode RAID On Chip (ROC) + 00bf SAS3404 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + 00c0 SAS3324 PCI-Express Fusion-MPT SAS-3 + 00c1 SAS3324 PCI-Express Fusion-MPT SAS-3 + 00c2 SAS3324 PCI-Express Fusion-MPT SAS-3 + 00c3 SAS3324 PCI-Express Fusion-MPT SAS-3 + 00c4 SAS3224 PCI-Express Fusion-MPT SAS-3 + 00c5 SAS3316 PCI-Express Fusion-MPT SAS-3 + 00c6 SAS3316 PCI-Express Fusion-MPT SAS-3 + 00c7 SAS3316 PCI-Express Fusion-MPT SAS-3 + 00c8 SAS3316 PCI-Express Fusion-MPT SAS-3 + 00c9 SAS3216 PCI-Express Fusion-MPT SAS-3 + 00ce MegaRAID SAS-3 3316 [Intruder] + 1000 9371 MegaRAID SAS 9361-16i + 1000 9390 MegaRAID SAS 9380-8i8e + 00cf MegaRAID SAS-3 3324 [Intruder] + 1000 9370 MegaRAID SAS 9361-24i + 00d0 SAS3716 Fusion-MPT Tri-Mode RAID Controller Chip (ROC) + 00d1 SAS3616 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) + 00d3 MegaRAID Tri-Mode SAS3716W 0407 MegaRAID 1000 0530 MegaRAID 530 SCSI 320-0X RAID Controller 1000 0531 MegaRAID 531 SCSI 320-4X RAID Controller @@ -1260,7 +1331,7 @@ 5652 RV410/M26 [Mobility Radeon X700] 5653 RV410/M26 [Mobility Radeon X700] 1025 0080 Aspire 5024WLMi - 103c 0940 HP Compaq NW8240 Mobile Workstation + 103c 0940 Compaq NW8240 Mobile Workstation 5654 264VT [Mach64 VT] 1002 5654 Mach64VT Reference 5655 264VT3 [Mach64 VT3] @@ -1350,23 +1421,23 @@ 5a11 RD890 Northbridge only single slot PCI-e GFX Hydra part 5a12 RD890 Northbridge only dual slot (2x8) PCI-e GFX Hydra part 15d9 a811 H8DGU - 5a13 RD890 PCI to PCI bridge (external gfx0 port A) - 5a14 RD890 PCI to PCI bridge (external gfx0 port B) + 5a13 RD890S/SR5650 Host Bridge + 5a14 RD9x0/RX980 Host Bridge 5a15 RD890 PCI to PCI bridge (PCI express gpp port A) - 5a16 RD890 PCI to PCI bridge (PCI express gpp port B) - 5a17 RD890 PCI to PCI bridge (PCI express gpp port C) - 5a18 RD890 PCI to PCI bridge (PCI express gpp port D) + 5a16 RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GFX port 0) + 5a17 RD890/RD9x0 PCI to PCI bridge (PCI Express GFX port 1) + 5a18 RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 0) 15d9 a811 H8DGU - 5a19 RD890 PCI to PCI bridge (PCI express gpp port E) - 5a1a RD890 PCI to PCI bridge (PCI express gpp port F) - 5a1b RD890 PCI to PCI bridge (PCI express gpp port G) - 5a1c RD890 PCI to PCI bridge (PCI express gpp port H) - 5a1d RD890 PCI to PCI bridge (external gfx1 port A) - 5a1e RD890 PCI to PCI bridge (external gfx1 port B) - 5a1f RD890 PCI to PCI bridge (NB-SB link) + 5a19 RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 1) + 5a1a RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 2) + 5a1b RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 3) + 5a1c RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 4) + 5a1d RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP Port 5) + 5a1e RD890/RD9x0/RX980 PCI to PCI bridge (PCI Express GPP2 Port 0) + 5a1f RD890/RD990 PCI to PCI bridge (PCI Express GFX2 port 0) 15d9 a811 H8DGU - 5a20 RD890S PCI Express bridge for GPP2 port 1 - 5a23 RD990 I/O Memory Management Unit (IOMMU) + 5a20 RD890/RD990 PCI to PCI bridge (PCI Express GFX2 port 1) + 5a23 RD890S/RD990 I/O Memory Management Unit (IOMMU) 5a31 RC410 Host Bridge 5a33 RS400 Host Bridge 5a34 RS4xx PCI Express Port [ext gfx] @@ -1486,6 +1557,9 @@ 6646 Bonaire XT [Radeon R9 M280X] 6647 Bonaire PRO [Radeon R9 M270X] 6649 Bonaire [FirePro W5100] + 1002 0b0c FirePro W4300 + 103c 0b0c Bonaire [FirePro W4300] + 103c 230c FirePro W5100 6650 Bonaire 6651 Bonaire 6658 Bonaire XTX [Radeon R7 260X/360] @@ -1515,10 +1589,17 @@ 1462 3271 Radeon R9 360 OEM 1682 7360 Radeon R7 360 6660 Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330] + 1028 05ea Radeon HD 8670M + 1028 06bf Radeon R5 M335 + 103c 1970 Radeon HD 8670M + 103c 80be Radeon R5 M330 + 103c 8136 Radeon R5 M330 + 17aa 3804 Radeon R5 M330 17aa 3809 Radeon R5 M330 17aa 390c Radeon R5 M330 6663 Sun PRO [Radeon HD 8570A/8570M] 1025 0846 Radeon HD 8570A + 17aa 3805 Radeon HD 8570M 6664 Jet XT [Radeon R5 M240] 6665 Jet PRO [Radeon R5 M230] 17aa 368f Radeon R5 A230 @@ -2053,9 +2134,11 @@ 1462 8036 Radeon HD 8990 OEM 148c 8990 Radeon HD 8990 OEM 679e Tahiti LE [Radeon HD 7870 XT] + 1787 2328 Radeon HD 7870 Black Edition 2 GB GDDR5 [2GBD5-2DHV3E] 679f Tahiti 67a0 Hawaii XT GL [FirePro W9100] 1002 0335 FirePro S9150 + 1002 0735 FirePro S9170 1028 031f FirePro W9100 1028 0335 FirePro S9150 67a1 Hawaii PRO GL [FirePro W8100] @@ -2065,29 +2148,69 @@ 67a8 Hawaii 67a9 Hawaii 67aa Hawaii - 67b0 Hawaii XT [Radeon R9 290X] + 67b0 Hawaii XT / Grenada XT [Radeon R9 290X/390X] + 1028 0b00 Grenada XT [Radeon R9 390X] + 103c 6566 Radeon R9 390X 1043 046a R9 290X DirectCU II 1043 046c R9 290X DirectCU II OC 1043 0474 Matrix R9 290X Platinum 1043 0476 ARES III + 1043 04d7 Radeon R9 390X + 1043 04db Radeon R9 390X + 1043 04df Radeon R9 390X + 1043 04e9 Radeon R9 390X 1458 227c R9 290X WindForce 3X OC 1458 2281 R9 290X WindForce 3X OC 1458 228c R9 290X WindForce 3X 1458 228d R9 290X WindForce 3X OC 1458 2290 R9 290X WindForce 3X + 1458 22bc Radeon R9 390X + 1458 22c1 Grenada PRO [Radeon R9 390] + 1462 2015 Radeon R9 390X 1462 3070 R9 290X Lightning 1462 3071 R9 290X Lightning 1462 3072 R9 290X Lightning LE 1462 3080 R9 290X Gaming 1462 3082 R9 290X Gaming OC 148c 2347 Devil 13 Dual Core R9 290X + 148c 2357 Grenada XT [Radeon R9 390X] 1682 9290 Double Dissipation R9 290X + 1682 9395 Grenada XT [Radeon R9 390X] + 174b 0e34 Radeon R9 390X 174b e282 Vapor-X R9 290X Tri-X OC 174b e285 R9 290X Tri-X OC + 174b e324 Grenada XT2 [Radeon R9 390X] 1787 2020 R9 290X IceQ X² Turbo - 67b1 Hawaii PRO [Radeon R9 290] + 1787 2357 Grenada XT [Radeon R9 390X] + 67b1 Hawaii PRO [Radeon R9 290/390] + 1043 04dd STRIX R9 390 + 148c 2358 Radeon R9 390 + 174b e324 Sapphire Nitro R9 390 67b9 Vesuvius [Radeon R9 295X2] 67be Hawaii LE + 67c0 Ellesmere [Polaris10] + 67df Ellesmere [Radeon RX 470/480] + 1002 0b37 Radeon RX 480 + 1043 04a8 Radeon RX 480 + 1043 04b0 Radeon RX 470 + 1043 04fb Radeon RX 480 + 1462 3411 Radeon RX 470 + 1462 3413 Radeon RX 480 + 148c 2372 Radeon RX 480 + 148c 2373 Radeon RX 470 + 1682 9470 Radeon RX 470 + 1682 9480 Radeon RX 480 + 174b e347 Radeon RX 470/480 + 174b e349 Radeon RX 470 + 1787 a470 Radeon RX 470 + 1787 a480 Radeon RX 480 + 67e0 Baffin [Polaris11] + 67e1 Baffin [Polaris11] + 67e8 Baffin [Polaris11] + 67e9 Baffin [Polaris11] + 67eb Baffin [Polaris11] + 67ef Baffin [Radeon RX 460] + 67ff Baffin [Polaris11] 6800 Wimbledon XT [Radeon HD 7970M] 1002 0124 Radeon HD 7970M 8086 2110 Radeon HD 7970M @@ -2103,7 +2226,7 @@ 1002 0310 FirePro S7000 1002 0420 Radeon Sky 500 6809 Pitcairn LE GL [FirePro W5000] - 6810 Curacao XT [Radeon R7 370 / R9 270X/370 OEM] + 6810 Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] 148c 0908 Radeon R9 370 OEM 1682 7370 Radeon R7 370 6811 Curacao PRO [Radeon R7 370 / R9 270/370 OEM] @@ -2743,20 +2866,49 @@ 174b e180 Radeon HD 7350 17af 3015 Radeon HD 7350 68fe Cedar LE - 6900 Topaz XT [Radeon R7 M260/M265] - 1028 0640 Radeon R7 M265 + 6900 Topaz XT [Radeon R7 M260/M265 / M340/M360] + 1025 1056 Radeon R7 M360 / R8 M365DX + 1028 0640 Radeon R7 M260/M265 + 1028 0643 Radeon R7 M260/M265 + 1028 067f Radeon R7 M260 + 1028 130a Radeon R7 M260 + 103c 2263 Radeon R7 M260 103c 2269 Radeon R7 M260 + 103c 22c6 Radeon R7 M260 103c 22c8 Radeon R7 M260 + 103c 808c Radeon R7 M260 + 103c 8099 Radeon R7 M360 + 103c 80b5 Radeon R7 M360 + 103c 80b9 Radeon R7 M360 + 103c 811c Radeon R7 M340 + 10cf 1906 Radeon R7 M260 + 1170 9979 Radeon R7 M360 1179 f903 Radeon R7 M260 + 1179 f922 Radeon R7 M260 + 1179 f923 Radeon R7 M260 1179 f934 Radeon R7 M260 + 17aa 3822 Radeon R7 M360 + 17aa 3824 Radeon R7 M360 + 17aa 5021 Radeon R7 M260 6901 Topaz PRO [Radeon R5 M255] + 103c 1318 Radeon R6 M255DX 6921 Amethyst XT [Radeon R9 M295X] - 6929 Tonga PRO GL [FirePro Series] + 6929 Tonga XT GL [FirePro S7150] 692b Tonga PRO GL [FirePro W7100] - 692f Tonga XT GL [FirePro W8100] - 6938 Amethyst XT [Radeon R9 M295X Mac Edition] + 692f Tonga XTV GL [FirePro S7150V] + 6938 Tonga XT / Amethyst XT [Radeon R9 380X / R9 M295X] + 1043 04f5 Radeon R9 380X + 1043 04f7 Radeon R9 380X + 106b 013a Radeon R9 M295X Mac Edition + 1458 22c8 Radeon R9 380X + 148c 2350 Radeon R9 380X + 1682 9385 Radeon R9 380X + 174b e308 Radeon R9 380X Nitro 4G D5 + 17af 2006 Radeon R9 380X 6939 Tonga PRO [Radeon R9 285/380] 148c 9380 Radeon R9 380 +# Make naming scheme consistent + 174b e308 Radeon R9 380 Nitro 4G D5 700f RS100 AGP Bridge 7010 RS200/RS250 AGP Bridge 7100 R520 [Radeon X1800 XT] @@ -2877,7 +3029,12 @@ 72a8 RV570 [Radeon X1950 GT] (Secondary) 72b1 RV560 [Radeon X1650 XT] (Secondary) 72b3 RV560 [Radeon X1650 GT] (Secondary) - 7300 Fiji XT [Radeon R9 FURY X] + 7300 Fiji [Radeon R9 FURY / NANO Series] + 1002 0b36 Radeon R9 FURY X / NANO + 1002 1b36 Radeon Pro Duo + 1043 049e Radeon R9 FURY + 1043 04a0 Radeon R9 FURY X + 174b e329 Radeon R9 FURY 7833 RS350 Host Bridge 7834 RS350 [Radeon 9100 PRO/XT IGP] 7835 RS350M [Mobility Radeon 9000 IGP] @@ -3069,7 +3226,7 @@ 95cc RV620 GL [FirePro V3700] 95cd RV620 [FirePro 2450] 95cf RV620 GL [FirePro 2260] - 960f RS780 HDMI Audio [Radeon (HD) 3000 Series] + 960f RS780 HDMI Audio [Radeon 3000/3100 / HD 3200/3300] 9610 RS780 [Radeon HD 3200] 1458 d000 GA-MA78GM-S2H Motherboard 9611 RS780C [Radeon 3100] @@ -3144,10 +3301,12 @@ 985f Mullins 9874 Carrizo 9900 Trinity [Radeon HD 7660G] + 103c 1985 Pavilion 17-e163sg Notebook PC # AMD A10-5800K CPU 9901 Trinity [Radeon HD 7660D] 9902 Trinity HDMI Audio Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 9903 Trinity [Radeon HD 7640G] 103c 194e ProBook 455 G1 Notebook 103c 1952 ProBook 455 G1 Notebook @@ -3168,6 +3327,8 @@ 9917 Trinity [Radeon HD 7620G] 9918 Trinity [Radeon HD 7600G] 9919 Trinity [Radeon HD 7500G] + 9920 Liverpool [Playstation 4 APU] + 9921 Liverpool HDMI/DP Audio Controller 9990 Trinity [Radeon HD 7520G] 9991 Trinity [Radeon HD 7540D] 9992 Trinity [Radeon HD 7420G] @@ -3186,34 +3347,41 @@ 99a0 Trinity [Radeon HD 7520G] 99a2 Trinity [Radeon HD 7420G] 99a4 Trinity [Radeon HD 7400G] - aa00 R600 HDMI Audio [Radeon HD 2900 Series] + aa00 R600 HDMI Audio [Radeon HD 2900 GT/PRO/XT] + aa01 RV635 HDMI Audio [Radeon HD 3650/3730/3750] aa08 RV630 HDMI Audio [Radeon HD 2600 Series] - aa10 RV610 HDMI Audio [Radeon HD 2350/2400 Series] + aa10 RV610 HDMI Audio [Radeon HD 2350 PRO / 2400 PRO/XT / HD 3410] 174b aa10 Radeon HD 2400 PRO 18bc aa10 Radeon HD 2400 PRO aa18 RV670/680 HDMI Audio [Radeon HD 3690/3800 Series] - aa20 RV635 HDMI Audio [Radeon HD 3600 Series] - aa28 RV620 HDMI Audio [Radeon HD 3400 Series] + aa20 RV635 HDMI Audio [Radeon HD 3650/3730/3750] + aa28 RV620 HDMI Audio [Radeon HD 3450/3470/3550/3570] aa30 RV770 HDMI Audio [Radeon HD 4850/4870] 174b aa30 Radeon HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink aa38 RV710/730 HDMI Audio [Radeon HD 4000 series] 103c 3628 dv6-1190en - aa50 Cypress HDMI Audio [Radeon HD 5800 Series] + aa50 Cypress HDMI Audio [Radeon HD 5830/5850/5870 / 6850/6870 Rebrand] aa58 Juniper HDMI Audio [Radeon HD 5700 Series] # 5500, 5600 and mobile 5700 series aa60 Redwood HDMI Audio [Radeon HD 5000 Series] 1025 033d Mobility Radeon HD 5650 1025 0347 Aspire 7740G - aa68 Cedar HDMI Audio [Radeon HD 5400/6300 Series] + aa68 Cedar HDMI Audio [Radeon HD 5400/6300/7300 Series] 1028 aa68 XPS 8300 - aa80 Cayman/Antilles HDMI Audio [Radeon HD 6900 Series] + aa80 Cayman/Antilles HDMI Audio [Radeon HD 6930/6950/6970/6990] aa88 Barts HDMI Audio [Radeon HD 6800 Series] - aa90 Turks/Whistler HDMI Audio [Radeon HD 6000 Series] + aa90 Turks HDMI Audio [Radeon HD 6500/6600 / 6700M Series] 1028 04a3 Precision M4600 aa98 Caicos HDMI Audio [Radeon HD 6400 Series] 174b aa98 Radeon HD 6450 1GB DDR3 - aaa0 Tahiti XT HDMI Audio [Radeon HD 7970 Series] + aaa0 Tahiti HDMI Audio [Radeon HD 7870 XT / 7950/7970] aab0 Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series] + aac0 Tobago HDMI Audio [Radeon R7 360 / R9 360 OEM] + aac8 Hawaii HDMI Audio [Radeon R9 290/290X / 390/390X] +# I have a Tonga card and this is the HDMI Audio part + aad8 Tonga HDMI Audio [Radeon R9 285/380] + 174b aad8 Radeon R9 285/380 HDMI Audio + aae8 Fiji HDMI/DP Audio [Radeon R9 Nano / FURY/FURY X] ac00 Theater 600 Pro ac02 TV Wonder HD 600 PCIe ac12 Theater HD T507 (DVB-T) TV tuner/capture device @@ -3630,9 +3798,13 @@ 1014 049a PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EE) 1014 04c7 PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCA) 1014 04c8 PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CD2) - 1014 0c49 PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCD) + 1014 04c9 PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCD) 044b GenWQE Accelerator Adapter 04aa Flash Adapter 90 (PCIe2 0.9TB) + 04da PCI-E IPR SAS+ Adapter (ASIC) + 1014 04fb PCIe3 x16 20GB Cache 12Gb Quad SAS RAID+ Adapter(580B) + 1014 04fc PCIe3 x8 12Gb Quad SAS RAID+ Adapter(580A) + 04ed Internal Shared Memory (ISM) virtual PCI device 3022 QLA3022 Network Adapter 4022 QLA3022 Network Adapter ffff MPIC-2 interrupt controller @@ -3727,9 +3899,12 @@ 1404 Family 15h (Models 10h-1fh) Processor Function 4 1405 Family 15h (Models 10h-1fh) Processor Function 5 1410 Family 15h (Models 10h-1fh) Processor Root Complex + 103c 1985 Pavilion 17-e163sg Notebook PC 1412 Family 15h (Models 10h-1fh) Processor Root Port + 1022 1234 Trinity A-series APU 1413 Family 15h (Models 10h-1fh) Processor Root Port 1414 Family 15h (Models 10h-1fh) Processor Root Port + 1022 1234 Trinity A-series APU 1415 Family 15h (Models 10h-1fh) Processor Root Port 1416 Family 15h (Models 10h-1fh) Processor Root Port 1417 Family 15h (Models 10h-1fh) Processor Root Port @@ -3744,7 +3919,11 @@ 1422 Family 15h (Models 30h-3fh) Processor Root Complex 1423 Family 15h (Models 30h-3fh) I/O Memory Management Unit 1426 Family 15h (Models 30h-3fh) Processor Root Port + 1436 Liverpool Processor Root Complex + 1437 Liverpool I/O Memory Management Unit + 1438 Liverpool Processor Root Port 1439 Family 16h Processor Functions 5:1 + 145b Zeppelin Non-Transparent Bridge 1510 Family 14h Processor Root Complex 174b 1001 PURE Fusion Mini 1512 Family 14h Processor Root Port @@ -3890,27 +4069,34 @@ 7802 FCH SATA Controller [RAID mode] 7803 FCH SATA Controller [RAID mode] 7804 FCH SATA Controller [AHCI mode] + 103c 1985 Pavilion 17-e163sg Notebook PC 7805 FCH SATA Controller [RAID mode] 7806 FCH SD Flash Controller 7807 FCH USB OHCI Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 7808 FCH USB EHCI Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 7809 FCH USB OHCI Controller 103c 194e ProBook 455 G1 Notebook 780b FCH SMBus Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 780c FCH IDE Controller 780d FCH Azalia Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 1043 8444 F2A85-M Series 780e FCH LPC Bridge 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 780f FCH PCI Bridge 7812 FCH USB XHCI Controller 7813 FCH SD Flash Controller 7814 FCH USB XHCI Controller 103c 194e ProBook 455 G1 Notebook + 103c 1985 Pavilion 17-e163sg Notebook PC 7900 FCH SATA Controller [IDE mode] 7901 FCH SATA Controller [AHCI mode] 7902 FCH SATA Controller [RAID mode] @@ -3923,6 +4109,7 @@ 790f FCH PCI Bridge 7914 FCH USB XHCI Controller 9600 RS780 Host Bridge + 1043 82ee M378A-CM Motherboard 1043 82f1 M3A78-EH Motherboard 9601 RS880 Host Bridge 1019 2120 A785GM-M @@ -4288,6 +4475,11 @@ 102b 2241 M9138 LP PCIe x16 102b 2280 M9188 ATX PCIe x16 102b 22c0 M9128 LP PCIe x16 + 0550 SV2 + 102b 00c0 MURA-IPX-I4EF + 102b 00c1 MURA-IPX-I4DF + 102b 00c3 MURA-IPX-I4DHF + 102b 00c5 MURA-IPX-I4EHF 0d10 MGA Ultima/Impression 1000 MGA G100 [Productiva] 102b ff01 Productiva G100 @@ -4479,6 +4671,7 @@ 103c 1293 USB add-in card 103c 1294 USB 2.0 add-in card 1179 0001 USB + 1186 0035 DUB-C2 USB 2.0 2-port 32-bit cardbus controller 12ee 7000 Root Hub 14c2 0105 PTI-205N USB 2.0 Host Controller 1799 0001 Root Hub @@ -4510,6 +4703,7 @@ 00ce uPD72871 [Firewarden] IEEE1394a OHCI 1.0 Link/1-port PHY Controller 00df Vr4131 00e0 uPD72010x USB 2.0 Controller + 1186 f100 DUB-C2 USB 2.0 2-port 32-bit cardbus controller 12ee 7001 Root hub 14c2 0205 PTI-205N USB 2.0 Host Controller 1799 0002 Root Hub @@ -4796,30 +4990,30 @@ 103c 3212 Smart Array E200 3239 Smart Array Gen9 Controllers 103c 21bd P244br - 103c 21be Smart Array + 103c 21be P741m 103c 21bf H240ar 103c 21c0 P440ar - 103c 21c1 Smart Array + 103c 21c1 P840ar 103c 21c2 P440 103c 21c3 P441 103c 21c4 Smart Array - 103c 21c5 Smart Array + 103c 21c5 P841 103c 21c6 H244br 103c 21c7 H240 103c 21c8 H241 103c 21c9 Smart Array - 103c 21ca Smart Array + 103c 21ca P246br 103c 21cb P840 103c 21cc Smart Array - 103c 21cd Smart Array - 103c 21ce Smart Array + 103c 21cd P240nr + 103c 21ce H240nr 323a Smart Array G6 controllers 103c 3241 Smart Array P212 103c 3243 Smart Array P410 103c 3245 Smart Array P410i 103c 3247 Smart Array P411 103c 3249 Smart Array P812 - 103c 324a HP Smart Array 712m (Mezzanine RAID controller) + 103c 324a Smart Array 712m (Mezzanine RAID controller) 103c 324b Smart Array P711m (Mezzanine RAID controller) 323b Smart Array Gen8 Controllers 103c 3350 P222 @@ -5140,6 +5334,7 @@ 803b 5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) 103c 309f nx9420 103c 30a3 Compaq nw8440 + 104d 8212 VAIO VGN-N21E 104d 902d VAIO VGN-NR120E 803c PCIxx12 SDA Standard Compliant SD Host Controller 103c 309f nx9420 @@ -5171,6 +5366,7 @@ 1395 2201 WL22-PC 16ab 8501 WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter 8401 ACX 100 22Mbps Wireless Interface + 8888 Multicore DSP+ARM KeyStone II SOC 9000 Wireless Interface (of unknown type) 9065 TMS320DM642 9066 ACX 111 54Mbps Wireless Interface @@ -5294,6 +5490,14 @@ 8056 Rockwell HCF 56K modem 808a Memory Stick Controller 81ce SxS Pro memory card + 908f Aeolia ACPI + 909e Aeolia Ethernet Controller (Marvell Yukon 2 Family) + 909f Aeolia SATA AHCI Controller + 90a0 Aeolia SD/MMC Host Controller + 90a1 Aeolia PCI Express Glue and Miscellaneous Devices + 90a2 Aeolia DMA Controller + 90a3 Aeolia Memory (DDR3/SPM) + 90a4 Aeolia USB 3.0 xHCI Host Controller 104e Oak Technology, Inc 0017 OTI-64017 0107 OTI-107 [Spitfire] @@ -5435,7 +5639,6 @@ 6400 MPC190 Security Processor (S1 family, encryption) 6405 MPC184 Security Processor (S1 family) 1058 Electronics & Telecommunications RSH -# Formerly: Teknor Industrial Computers Inc 1059 Kontron 105a Promise Technology, Inc. 0d30 PDC20265 (FastTrak100 Lite/Ultra100) @@ -5701,6 +5904,7 @@ 0074 U4 HT Bridge # should be 14e4:1645 1645 Broadcom NetXtreme BCM5701 Gigabit Ethernet + 2001 PCI Express SSD 106c Hynix Semiconductor 8139 8139c 100BaseTX Ethernet Controller 8801 Dual Pentium ISA/PCI Motherboard @@ -5757,13 +5961,59 @@ 101e 8493 QLA12160 on AMI MegaRAID 1240 ISP1240 SCSI Host Adapter 1280 ISP1280 SCSI Host Adapter + 1634 FastLinQ QL45000 Series 40GbE Controller + 1077 e4f1 FastLinQ QL45212H 40GbE Adapter + 1077 e4f2 FastLinQ QL45211H 40GbE Adapter + 1077 e4f3 FastLinQ QL45412H 40GbE Adapter + 1077 e4f4 FastLinQ QL45411H 40GbE Adapter + 1644 FastLinQ QL45000 Series 100GbE Controller + 1077 e4f8 FastLinQ QL45611H 100GbE Adapter + 1656 FastLinQ QL45000 Series 25GbE Controller + 1077 02a7 QL45212-DE 25GbE Adapter + 1077 e4f6 FastLinQ QL45211H 25GbE Adapter + 1077 e4f7 FastLinQ QL45212H 25GbE Adapter + 165c FastLinQ QL45000 Series 40GbE Controller (FCoE) + 1077 e4f1 FastLinQ QL45462H 40GbE FCoE Adapter + 1077 e4f2 FastLinQ QL45461H 40GbE FCoE Adapter + 165e FastLinQ QL45000 Series 40GbE Controller (iSCSI) + 1077 e4f1 FastLinQ QL45462H 40GbE iSCSI Adapter + 1077 e4f2 FastLinQ QL45461H 40GbE iSCSI Adapter + 1664 FastLinQ QL45000 Series Gigabit Ethernet Controller (SR-IOV VF) + 1077 e4f1 FastLinQ QL45462H 40GbE Adapter (SR-IOV VF) + 1077 e4f2 FastLinQ QL45461H 40GbE Adapter (SR-IOV VF) + 1077 e4f3 FastLinQ QL45412H 40GbE Adapter (SR-IOV VF) + 1077 e4f4 FastLinQ QL45411H 40GbE Adapter (SR-IOV VF) + 1077 e4f6 FastLinQ QL45211H 25GbE Adapter (SR-IOV VF) + 1077 e4f7 FastLinQ QL45212H 25GbE Adapter (SR-IOV VF) + 1077 e4f8 FastLinQ QL45611H 100GbE Adapter (SR-IOV VF) 2020 ISP2020A Fast!SCSI Basic Adapter 2031 ISP8324-based 16Gb Fibre Channel to PCI Express Adapter + 103c 17e7 HP SN1000Q 16Gb Single Port Fibre Channel Adapter + 103c 17e8 HP SN1000Q 16Gb Dual Port Fibre Channel Adapter + 103c 1939 HP QMH2672 16Gb Dual Port Fibre Channel Adapter 103c 8002 3830C 16G Fibre Channel Host Bus Adapter + 2071 ISP2714-based 16/32Gb Fibre Channel to PCIe Adapter + 1077 0283 QLE2764 Quad Port 32Gb Fibre Channel to PCIe Adapter + 1077 029e QLE2694 Quad Port 16Gb Fibre Channel to PCIe Adapter + 1077 02a2 QLE2694L Quad Port 16Gb Fibre Channel to PCIe Adapter + 1077 02ad QLE2694U Quad Port 16/32Gb Fibre Channel to PCIe Adapter 2100 QLA2100 64-bit Fibre Channel Adapter 1077 0001 QLA2100 64-bit Fibre Channel Adapter 2200 QLA2200 64-bit Fibre Channel Adapter 1077 0002 QLA2200 + 2261 ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter + 1077 0299 QLE2740 Single Port 32Gb Fibre Channel to PCIe Adapter + 1077 029a QLE2742 Dual Port 32Gb Fibre Channel to PCIe Adapter + 1077 029b QLE2690 Single Port 16Gb Fibre Channel to PCIe Adapter + 1077 029c QLE2692 Dual Port 16Gb Fibre Channel to PCIe Adapter + 1077 02a7 QLE2690 Single Port 16Gb FC to PCIe Gen3 x8 Adapter + 1077 02a8 QLE2692 Dual Port 16Gb FC to PCIe Gen3 x8 Adapter + 1077 02ab QLE2740 Single Port 32Gb FC to PCIe Gen3 x8 Adapter + 1077 02ac QLE2742 Dual Port 32Gb FC to PCIe Gen3 x8 Adapter + 1590 00f9 HPE StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter + 1590 00fa HPE StoreFabric SN1100Q 16Gb Dual Port Fibre Channel Host Bus Adapter + 1590 0203 HPE StoreFabric SN1600Q 32Gb Single Port Fibre Channel Host Bus Adapter + 1590 0204 HPE StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter 2300 QLA2300 64-bit Fibre Channel Adapter 2312 ISP2312-based 2Gb Fibre Channel to PCI-X HBA 103c 0131 2Gb Fibre Channel - Single port [A7538A] @@ -5776,7 +6026,9 @@ 103c 7040 FC1142SR 4Gb 1-port PCIe Fibre Channel Host Bus Adapter [HPAE311A] 2532 ISP2532-based 8Gb Fibre Channel to PCI Express HBA 103c 3262 StorageWorks 81Q + 103c 3263 StorageWorks 82Q 1077 0167 QME2572 Dual Port FC8 HBA Mezzanine + 1590 00fc HPE StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter 3022 ISP4022-based Ethernet NIC 3032 ISP4032-based Ethernet IPv6 NIC 4010 ISP4010-based iSCSI TOE HBA @@ -5994,6 +6246,7 @@ 1093 National Instruments 0160 PCI-DIO-96 0162 PCI-MIO-16XE-50 + 0fe1 PXI-8320 1150 PCI-6533 (PCI-DIO-32HS) 1170 PCI-MIO-16XE-10 1180 PCI-MIO-16E-1 @@ -6085,7 +6338,10 @@ 7004 PXI-6551 700b PXI-5421 700c PCI-5421 + 701a VXIpc-87xB + 701b VXIpc-770 7023 PXI-2593 + 7027 PCI-MXI-2 Universal 702c PXI-7831R 702d PCI-7831R 702e PXI-7811R @@ -6354,6 +6610,7 @@ 731d PXI-2536 7322 PXIe-6124 7327 PXI-6529 + 732c VXI-8360T 7331 PXIe-5602 7332 PXIe-5601 7333 PXI-5900 @@ -6493,6 +6750,7 @@ 75e5 PXI-6683 75e6 PXI-6683H 75ef PXIe-5632 + 761c VXI-8360LT 761f PXI-2540 7620 PXIe-2540 7621 PXI-2541 @@ -6523,6 +6781,7 @@ 76a3 PXIe-6535B 76a4 PXIe-6536B 76a5 PXIe-6537B + 783e PXI-8368 9020 PXI-2501 9030 PXI-2503 9040 PXI-2527 @@ -6532,6 +6791,7 @@ 9080 PXI-2580 9090 PCI-4021 90a0 PXI-4021 + a001 PCI-MXI-2 b001 PCI-1408 b011 PXI-1408 b021 PCI-1424 @@ -6621,7 +6881,9 @@ 1093 762b PXIe-4138 1093 762c PXIe-4144 1093 762d PXIe-4145 + 1093 762e PXIe-5606 1093 7644 PXIe-4841 + 1093 764a PCIe-8237R-S 1093 7658 PXIe-5162 (4CH) 1093 76ab PXIe-4322 1093 76ad PXIe-4112 @@ -6629,14 +6891,25 @@ 1093 76b5 PXIe-7971R 1093 76b6 PXIe-7972R 1093 76b7 PXIe-7975R + 1093 76b8 PXIe-5696 + 1093 76b9 PXIe-5654 1093 76c8 PXIe-6614 1093 76c9 PXIe-6612 1093 76cb PXIe-5646R 1093 76cc PXIe-5162 (2CH) + 1093 76ce CVS-1459 1093 76d0 PXIe-5160 (2CH) 1093 76d1 PXIe-5160 (4CH) 1093 76dc PXIe-4610 + 1093 76ec PXIe-2524 + 1093 76ed PXIe-2525 + 1093 76ee PXIe-2526 + 1093 76ef PXIe-2737 + 1093 76f0 PXIe-2738 + 1093 76f1 PXIe-2739 1093 76fb PCIe-1473R-LX110 + 1093 76fc PXIe-5105 + 1093 76fd PXIe-5114 1093 76fe PXIe-5644R 1093 76ff PXIe-5644R 1093 7700 PXIe-5644R @@ -6645,24 +6918,49 @@ 1093 7703 PXIe-5645R 1093 770c PXIe-4139 1093 7711 PXIe-4464 + 1093 7712 PXIe-4463 1093 7716 PCIe-6612 + 1093 771d Unconfigured CA4 Switch 1093 771e PXIe-4339 1093 7735 cRIO-9033 + 1093 773e PXIe-5624R 1093 774b cRIO-9031 1093 774d cRIO-9034 1093 7755 cRIO-9030 + 1093 7768 PXIe-2747 + 1093 7769 PXIe-2748 + 1093 776a PXIe-2746 1093 7777 PXIe-7976R 1093 7782 PXIe-5646R 1093 7783 PXIe-5646R 1093 7784 PXIe-5646R + 1093 7790 PXIe-5170R (4CH) + 1093 7791 PXIe-5170R (8CH) + 1093 7793 PXIe-5171R (8CH) 1093 77a5 PXIe-6345 1093 77a6 PXIe-6355 1093 77a7 PXIe-6365 1093 77a8 PXIe-6375 + 1093 77aa CVS-1458 + 1093 77ad IC-3173 1093 77b4 PXIe-7820R 1093 77b5 PXIe-7821R 1093 77b6 PXIe-7822R 1093 77b9 cRIO-9038 + 1093 77ba PXIe-4136 + 1093 77bb PXIe-4137 + 1093 77c0 PXIe-5624R + 1093 77c1 PXIe-5624R + 1093 77c2 PXIe-5624R + 1093 77ca PXIe-6738 + 1093 77cb PXIe-6739 + 1093 77db cRIO-9035 + 1093 77dc cRIO-9036 + 1093 77dd cRIO-9039 + 1093 7802 PXIe-4302 + 1093 7803 PXIe-4303 + 1093 7805 PXIe-4305 + 1093 788e PXIe-4304 c801 PCI-GPIB c811 PCI-GPIB+ c821 PXI-GPIB @@ -6700,6 +6998,13 @@ e251 PXI-8460 (2 ports) e261 PCI-CAN/DS e271 PXI-8462 + f110 VMEpc-650 + f120 VXIpc-650 + fe00 VXIpc-87x + fe41 VXIpc-860 + fe51 VXIpc-74x + fe61 VXIpc-850 + fe70 VXIpc-880 1094 First International Computers [FIC] # nee CMD Technology Inc 1095 Silicon Image, Inc. @@ -7068,11 +7373,14 @@ 8696 PEX 8696 96-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Multi-Root Switch 8717 PEX 8717 16-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch with DMA 8718 PEX 8718 16-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch + 8724 PEX 8724 24-Lane, 6-Port PCI Express Gen 3 (8 GT/s) Switch, 19 x 19mm FCBGA 8732 PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch 8734 PEX 8734 32-lane, 8-Port PCI Express Gen 3 (8.0GT/s) Switch 8747 PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch + 8748 PEX 8748 48-Lane, 12-Port PCI Express Gen 3 (8 GT/s) Switch, 27 x 27mm FCBGA # This is the Non-Transparent-Bridge Virtualized Port as presented by the PLX PEX 8732 chip, the physical bridges show up at 10b5:8732 87b0 PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch + 1093 7761 PXIe-8830mc 9016 PLX 9016 8-port serial controller 9030 PCI9030 32-bit 33MHz PCI <-> IOBus Bridge 10b5 2695 Hilscher CIF50-PB/DPS Profibus @@ -7084,6 +7392,7 @@ 10b5 3025 Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board 10b5 3068 Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board 10b5 3463 Alpermann+Velte PCL PCI D (v2) (3V/5V): Timecode Reader Board + 10b5 3591 PLURA PCL PCI L (v2) (3.3V/5V): Time Code Reader Board 12fe 0111 CPCI-ASIO4 (ESD 4-port Serial Interface Board) 1369 9c01 VX222v2 1369 9d01 VX222-Mic @@ -7096,7 +7405,7 @@ 1369 a801 LCM200 1397 3136 4xS0-ISDN PCI Adapter 1397 3137 S2M-E1-ISDN PCI Adapter - 1518 0200 Kontron ThinkIO-C + 1518 0200 ThinkIO-C 15ed 1002 MCCS 8-port Serial Hot Swap 15ed 1003 MCCS 16-port Serial Hot Swap # MIL-STD-1553B Board @@ -7193,7 +7502,7 @@ 10b5 1123 Sectra KK631 encryption board 10b5 9080 9080 [real subsystem ID not set] 12d9 0002 PCI Prosody Card - 12df 4422 4422PCI ["Do-All" Telemetry Data Aquisition System] + 12df 4422 4422PCI ["Do-All" Telemetry Data Acquisition System] 1369 9601 PCX822np 1369 a102 PCX822v2 1369 a201 PCX442 @@ -7208,6 +7517,7 @@ 1885 0700 Tsunami FPGA PMC with Altera Stratix S40 1885 0701 Tsunami FPGA PMC with Altera Stratix S30 9733 PEX 9733 33-lane, 9-port PCI Express Gen 3 (8.0 GT/s) Switch + 1d49 0001 ThinkSystem P310W-4P NVMe Switch Card 9749 PEX 9749 49-lane, 13-port PCI Express Gen 3 (8.0 GT/s) Switch a100 Blackmagic Design DeckLink bb04 B&B 3PCIOSD1A Isolated PCI Serial @@ -7889,7 +8199,7 @@ 1043 0c11 A7N8X Mainboard a0a0 03b4 UK79G-1394 motherboard 006a nForce2 AC97 Audio Controler (MCP) - 1043 8095 nForce2 AC97 Audio Controler (MCP) + 1043 8095 nForce2 AC97 Audio Controller (MCP) a0a0 0304 UK79G-1394 motherboard 006b nForce Audio Processing Unit 10de 006b nForce2 MCP Audio Processing Unit @@ -8751,7 +9061,7 @@ 0446 MCP65 SMBus 103c 30cf Pavilion dv9668eg Laptop 0447 MCP65 SMU - 103c 30cf Pavilion dv9668eg Laptop + 103c 30cf Pavilion dv9500/9600/9700 series 0448 MCP65 IDE 103c 30cf Pavilion dv9668eg Laptop 0449 MCP65 PCI bridge @@ -9575,6 +9885,8 @@ 0f00 GF108 [GeForce GT 630] 0f01 GF108 [GeForce GT 620] 0f02 GF108 [GeForce GT 730] + 0f06 GF108 [GeForce GT 730] + 0fb0 GM200 High Definition Audio 0fbb GM204 High Definition Audio Controller 0fc0 GK107 [GeForce GT 640 OEM] 0fc1 GK107 [GeForce GT 640] @@ -9619,6 +9931,7 @@ 0fea GK107M [GeForce GT 755M Mac Edition] 0fec GK107M [GeForce 710A] 0fed GK107M [GeForce 820M] + 0fee GK107M [GeForce 810M] 0fef GK107GL [GRID K340] 0ff1 GK107 [NVS 1000] 0ff2 GK107GL [GRID K1] @@ -9715,6 +10028,7 @@ 103c 2afb GeForce 705A 17aa 309d GeForce 705A 17aa 30b1 GeForce 800A + 17aa 30f3 GeForce 705A 17aa 36a1 GeForce 800A 107c GF119 [NVS 315] 107d GF119 [NVS 310] @@ -9746,7 +10060,9 @@ 10c3 GT218 [GeForce 8400 GS Rev. 3] 10c5 GT218 [GeForce 405] 10d8 GT218 [NVS 300] + 10f0 GP104 High Definition Audio Controller 1140 GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M] + 1019 0799 GeForce 820M 1019 999f GeForce GT 720M 1025 0600 GeForce GT 620M 1025 0606 GeForce GT 620M @@ -9846,6 +10162,7 @@ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Sat Oct 15 12:38:23 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2554AC131D5; Sat, 15 Oct 2016 12:38:23 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F306D1178; Sat, 15 Oct 2016 12:38:22 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FCcMO3032081; Sat, 15 Oct 2016 12:38:22 GMT (envelope-from bapt@FreeBSD.org) Received: (from bapt@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FCcMNs032079; Sat, 15 Oct 2016 12:38:22 GMT (envelope-from bapt@FreeBSD.org) Message-Id: <201610151238.u9FCcMNs032079@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bapt set sender to bapt@FreeBSD.org using -f From: Baptiste Daroussin Date: Sat, 15 Oct 2016 12:38:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307359 - stable/10/contrib/tzcode/zic X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 12:38:23 -0000 Author: bapt Date: Sat Oct 15 12:38:21 2016 New Revision: 307359 URL: https://svnweb.freebsd.org/changeset/base/307359 Log: MFC r306852 Incorporate a change from OpenBSD by millert@OpenBSD.org Don't warn about valid time zone abbreviations. POSIX through 2000 says that an abbreviation cannot start with ':', and cannot contain ',', '-', '+', NUL, or a digit. POSIX from 2001 on changes this rule to say that an abbreviation can contain only '-', '+', and alphanumeric characters from the portable character set in the current locale. To be portable to both sets of rules, an abbreviation must therefore use only ASCII letters." Adapted from tzcode2015f. This is needed to be able to update tzdata to a newer version Modified: stable/10/contrib/tzcode/zic/zdump.c stable/10/contrib/tzcode/zic/zic.c Directory Properties: stable/10/ (props changed) Modified: stable/10/contrib/tzcode/zic/zdump.c ============================================================================== --- stable/10/contrib/tzcode/zic/zdump.c Sat Oct 15 12:37:57 2016 (r307358) +++ stable/10/contrib/tzcode/zic/zdump.c Sat Oct 15 12:38:21 2016 (r307359) @@ -212,24 +212,16 @@ const char * const zone; return; cp = abbrp; wp = NULL; - while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp)) + while (isascii((unsigned char) *cp) && + (isalnum((unsigned char)*cp) || *cp == '-' || *cp == '+')) ++cp; - if (cp - abbrp == 0) - wp = _("lacks alphabetic at start"); - else if (cp - abbrp < 3) - wp = _("has fewer than 3 alphabetics"); + if (cp - abbrp < 3) + wp = _("has fewer than 3 characters"); else if (cp - abbrp > 6) - wp = _("has more than 6 alphabetics"); - if (wp == NULL && (*cp == '+' || *cp == '-')) { - ++cp; - if (isascii((unsigned char) *cp) && - isdigit((unsigned char) *cp)) - if (*cp++ == '1' && *cp >= '0' && *cp <= '4') - ++cp; - if (*cp != '\0') - wp = _("differs from POSIX standard"); - } - if (wp == NULL) + wp = _("has more than 6 characters"); + else if (*cp) + wp = "has characters other than ASCII alphanumerics, '-' or '+'"; + else return; (void) fflush(stdout); (void) fprintf(stderr, Modified: stable/10/contrib/tzcode/zic/zic.c ============================================================================== --- stable/10/contrib/tzcode/zic/zic.c Sat Oct 15 12:37:57 2016 (r307358) +++ stable/10/contrib/tzcode/zic/zic.c Sat Oct 15 12:38:21 2016 (r307359) @@ -2615,29 +2615,15 @@ const char * const string; register const char * cp; register char * wp; - /* - ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics - ** optionally followed by a + or - and a number from 1 to 14. - */ cp = string; wp = NULL; while (isascii((unsigned char) *cp) && - isalpha((unsigned char) *cp)) + (isalnum((unsigned char)*cp) || *cp == '-' || *cp == '+')) ++cp; - if (cp - string == 0) -wp = _("time zone abbreviation lacks alphabetic at start"); if (noise && cp - string > 3) -wp = _("time zone abbreviation has more than 3 alphabetics"); +wp = _("time zone abbreviation has more than 3 characters"); if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) -wp = _("time zone abbreviation has too many alphabetics"); - if (wp == NULL && (*cp == '+' || *cp == '-')) { - ++cp; - if (isascii((unsigned char) *cp) && - isdigit((unsigned char) *cp)) - if (*cp++ == '1' && - *cp >= '0' && *cp <= '4') - ++cp; - } +wp = _("time zone abbreviation has too many characters"); if (*cp != '\0') wp = _("time zone abbreviation differs from POSIX standard"); if (wp != NULL) { From owner-svn-src-stable-10@freebsd.org Sat Oct 15 12:41:42 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C7199C133CB; Sat, 15 Oct 2016 12:41:42 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7E90917F7; Sat, 15 Oct 2016 12:41:42 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FCff7u035045; Sat, 15 Oct 2016 12:41:41 GMT (envelope-from bapt@FreeBSD.org) Received: (from bapt@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FCff94035040; Sat, 15 Oct 2016 12:41:41 GMT (envelope-from bapt@FreeBSD.org) Message-Id: <201610151241.u9FCff94035040@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bapt set sender to bapt@FreeBSD.org using -f From: Baptiste Daroussin Date: Sat, 15 Oct 2016 12:41:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307362 - stable/10/contrib/tzdata X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 12:41:42 -0000 Author: bapt Date: Sat Oct 15 12:41:41 2016 New Revision: 307362 URL: https://svnweb.freebsd.org/changeset/base/307362 Log: MFC r306853 Import tzdata 2016g Modified: stable/10/contrib/tzdata/africa stable/10/contrib/tzdata/antarctica stable/10/contrib/tzdata/asia stable/10/contrib/tzdata/australasia stable/10/contrib/tzdata/backward stable/10/contrib/tzdata/etcetera stable/10/contrib/tzdata/europe stable/10/contrib/tzdata/factory stable/10/contrib/tzdata/leap-seconds.list stable/10/contrib/tzdata/leapseconds stable/10/contrib/tzdata/northamerica stable/10/contrib/tzdata/southamerica stable/10/contrib/tzdata/zone.tab stable/10/contrib/tzdata/zone1970.tab Directory Properties: stable/10/ (props changed) Modified: stable/10/contrib/tzdata/africa ============================================================================== --- stable/10/contrib/tzdata/africa Sat Oct 15 12:41:11 2016 (r307361) +++ stable/10/contrib/tzdata/africa Sat Oct 15 12:41:41 2016 (r307362) @@ -343,6 +343,12 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 # decision to abandon DST permanently. See Ahram Online 2015-04-24. # http://english.ahram.org.eg/NewsContent/1/64/128509/Egypt/Politics-/Sisi-cancels-daylight-saving-time-in-Egypt.aspx +# From Steffen Thorsen (2016-04-29): +# Egypt will have DST from July 7 until the end of October.... +# http://english.ahram.org.eg/NewsContentP/1/204655/Egypt/Daylight-savings-time-returning-to-Egypt-on--July.aspx +# From Mina Samuel (2016-07-04): +# Egyptian government took the decision to cancel the DST, + Rule Egypt 2008 only - Aug lastThu 24:00 0 - Rule Egypt 2009 only - Aug 20 24:00 0 - Rule Egypt 2010 only - Aug 10 24:00 0 - @@ -458,7 +464,7 @@ Zone Africa/Monrovia -0:43:08 - LMT 1882 # http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/ # # From Paul Eggert (2013-10-25): -# For now, assume they're reverting to the pre-2012 rules of permanent UTC+2. +# For now, assume they're reverting to the pre-2012 rules of permanent UT +02. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Libya 1951 only - Oct 14 2:00 1:00 S @@ -858,11 +864,11 @@ Rule Morocco 2009 only - Aug 21 0:00 0 Rule Morocco 2010 only - May 2 0:00 1:00 S Rule Morocco 2010 only - Aug 8 0:00 0 - Rule Morocco 2011 only - Apr 3 0:00 1:00 S -Rule Morocco 2011 only - Jul 31 0 0 - +Rule Morocco 2011 only - Jul 31 0:00 0 - Rule Morocco 2012 2013 - Apr lastSun 2:00 1:00 S -Rule Morocco 2012 only - Sep 30 3:00 0 - Rule Morocco 2012 only - Jul 20 3:00 0 - Rule Morocco 2012 only - Aug 20 2:00 1:00 S +Rule Morocco 2012 only - Sep 30 3:00 0 - Rule Morocco 2013 only - Jul 7 3:00 0 - Rule Morocco 2013 only - Aug 10 2:00 1:00 S Rule Morocco 2013 max - Oct lastSun 3:00 0 - Modified: stable/10/contrib/tzdata/antarctica ============================================================================== --- stable/10/contrib/tzdata/antarctica Sat Oct 15 12:41:11 2016 (r307361) +++ stable/10/contrib/tzdata/antarctica Sat Oct 15 12:41:41 2016 (r307362) @@ -10,10 +10,8 @@ # http://www.spri.cam.ac.uk/bob/periant.htm # for information. # Unless otherwise specified, we have no time zone information. -# -# Except for the French entries, -# I made up all time zone abbreviations mentioned here; corrections welcome! -# FORMAT is 'zzz' and GMTOFF is 0 for locations while uninhabited. + +# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited. # Argentina - year-round bases # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05 @@ -29,7 +27,7 @@ # previously sealers and scientific personnel wintered # Margaret Turner reports # http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html -# (1999-09-30) that they're UTC+5, with no DST; +# (1999-09-30) that they're UT +05, with no DST; # presumably this is when they have visitors. # # year-round bases @@ -67,24 +65,23 @@ # http://www.timeanddate.com/news/time/antartica-time-changes-2010.html # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Antarctica/Casey 0 - zzz 1969 - 8:00 - AWST 2009 Oct 18 2:00 - # Australian Western Std Time - 11:00 - CAST 2010 Mar 5 2:00 # Casey Time - 8:00 - AWST 2011 Oct 28 2:00 - 11:00 - CAST 2012 Feb 21 17:00u - 8:00 - AWST -Zone Antarctica/Davis 0 - zzz 1957 Jan 13 - 7:00 - DAVT 1964 Nov # Davis Time - 0 - zzz 1969 Feb - 7:00 - DAVT 2009 Oct 18 2:00 - 5:00 - DAVT 2010 Mar 10 20:00u - 7:00 - DAVT 2011 Oct 28 2:00 - 5:00 - DAVT 2012 Feb 21 20:00u - 7:00 - DAVT -Zone Antarctica/Mawson 0 - zzz 1954 Feb 13 - 6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time - 5:00 - MAWT +Zone Antarctica/Casey 0 - -00 1969 + 8:00 - +08 2009 Oct 18 2:00 + 11:00 - +11 2010 Mar 5 2:00 + 8:00 - +08 2011 Oct 28 2:00 + 11:00 - +11 2012 Feb 21 17:00u + 8:00 - +08 +Zone Antarctica/Davis 0 - -00 1957 Jan 13 + 7:00 - +07 1964 Nov + 0 - -00 1969 Feb + 7:00 - +07 2009 Oct 18 2:00 + 5:00 - +05 2010 Mar 10 20:00u + 7:00 - +07 2011 Oct 28 2:00 + 5:00 - +05 2012 Feb 21 20:00u + 7:00 - +07 +Zone Antarctica/Mawson 0 - -00 1954 Feb 13 + 6:00 - +06 2009 Oct 18 2:00 + 5:00 - +05 # References: # Casey Weather (1998-02-26) # http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html @@ -137,8 +134,8 @@ Zone Antarctica/Mawson 0 - zzz 1954 Feb # fishing stations operated variously 1819/1931 # # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Indian/Kerguelen 0 - zzz 1950 # Port-aux-Français - 5:00 - TFT # ISO code TF Time +Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français + 5:00 - +05 # # year-round base in the main continent # Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11 @@ -148,10 +145,10 @@ Zone Indian/Kerguelen 0 - zzz 1950 # Por # It was destroyed by fire on 1952-01-14. # # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Antarctica/DumontDUrville 0 - zzz 1947 - 10:00 - PMT 1952 Jan 14 # Port-Martin Time - 0 - zzz 1956 Nov - 10:00 - DDUT # Dumont-d'Urville Time +Zone Antarctica/DumontDUrville 0 - -00 1947 + 10:00 - +10 1952 Jan 14 + 0 - -00 1956 Nov + 10:00 - +10 # France & Italy - year-round base # Concordia, -750600+1232000, since 2005 @@ -176,8 +173,8 @@ Zone Antarctica/DumontDUrville 0 - zzz 1 # was established on 1957-01-29. Since Syowa station is still the main # station of Japan, it's appropriate for the principal location. # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Antarctica/Syowa 0 - zzz 1957 Jan 29 - 3:00 - SYOT # Syowa Time +Zone Antarctica/Syowa 0 - -00 1957 Jan 29 + 3:00 - +03 # See: # NIPR Antarctic Research Activities (1999-08-17) # http://www.nipr.ac.jp/english/ara01.html @@ -214,19 +211,19 @@ Zone Antarctica/Syowa 0 - zzz 1957 Jan 2 # correct, but they should be quite close to the actual dates. # # From Paul Eggert (2014-03-21): -# The CET-switching Troll rules require zic from tzcode 2014b or later, so as +# The CET-switching Troll rules require zic from tz 2014b or later, so as # suggested by Bengt-Inge Larsson comment them out for now, and approximate # with only UTC and CEST. Uncomment them when 2014b is more prevalent. # # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -#Rule Troll 2005 max - Mar 1 1:00u 1:00 CET -Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST -#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 CET -#Rule Troll 2004 max - Nov 7 1:00u 0:00 UTC +#Rule Troll 2005 max - Mar 1 1:00u 1:00 +01 +Rule Troll 2005 max - Mar lastSun 1:00u 2:00 +02 +#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 +01 +#Rule Troll 2004 max - Nov 7 1:00u 0:00 +00 # Remove the following line when uncommenting the above '#Rule' lines. -Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC +Rule Troll 2004 max - Oct lastSun 1:00u 0:00 +00 # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Antarctica/Troll 0 - zzz 2005 Feb 12 +Zone Antarctica/Troll 0 - -00 2005 Feb 12 0:00 Troll %s # Poland - year-round base @@ -265,10 +262,10 @@ Zone Antarctica/Troll 0 - zzz 2005 Feb 1 # changes during the year and does not necessarily correspond to mean # solar noon. So the Vostok time might have been whatever the clocks # happened to be during their visit. So we still don't really know what time -# it is at Vostok. But we'll guess UTC+6. +# it is at Vostok. But we'll guess +06. # -Zone Antarctica/Vostok 0 - zzz 1957 Dec 16 - 6:00 - VOST # Vostok time +Zone Antarctica/Vostok 0 - -00 1957 Dec 16 + 6:00 - +06 # S Africa - year-round bases # Marion Island, -4653+03752 @@ -300,8 +297,8 @@ Zone Antarctica/Vostok 0 - zzz 1957 Dec # says Rothera is -03 all year. # # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Antarctica/Rothera 0 - zzz 1976 Dec 1 - -3:00 - ROTT # Rothera time +Zone Antarctica/Rothera 0 - -00 1976 Dec 1 + -3:00 - -03 # Uruguay - year round base # Artigas, King George Island, -621104-0585107 Modified: stable/10/contrib/tzdata/asia ============================================================================== --- stable/10/contrib/tzdata/asia Sat Oct 15 12:41:11 2016 (r307361) +++ stable/10/contrib/tzdata/asia Sat Oct 15 12:41:41 2016 (r307362) @@ -79,13 +79,9 @@ Rule E-EurAsia 1979 1995 - Sep lastSun Rule E-EurAsia 1996 max - Oct lastSun 0:00 0 - Rule RussiaAsia 1981 1984 - Apr 1 0:00 1:00 S Rule RussiaAsia 1981 1983 - Oct 1 0:00 0 - -Rule RussiaAsia 1984 1991 - Sep lastSun 2:00s 0 - -Rule RussiaAsia 1985 1991 - Mar lastSun 2:00s 1:00 S -Rule RussiaAsia 1992 only - Mar lastSat 23:00 1:00 S -Rule RussiaAsia 1992 only - Sep lastSat 23:00 0 - -Rule RussiaAsia 1993 max - Mar lastSun 2:00s 1:00 S -Rule RussiaAsia 1993 1995 - Sep lastSun 2:00s 0 - -Rule RussiaAsia 1996 max - Oct lastSun 2:00s 0 - +Rule RussiaAsia 1984 1995 - Sep lastSun 2:00s 0 - +Rule RussiaAsia 1985 2011 - Mar lastSun 2:00s 1:00 S +Rule RussiaAsia 1996 2011 - Oct lastSun 2:00s 0 - # Afghanistan # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -120,31 +116,37 @@ Zone Asia/Kabul 4:36:48 - LMT 1890 # http://www.worldtimezone.com/dst_news/dst_news_armenia03.html # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 - 3:00 - YERT 1957 Mar # Yerevan Time - 4:00 RussiaAsia YER%sT 1991 Mar 31 2:00s - 3:00 1:00 YERST 1991 Sep 23 # independence - 3:00 RussiaAsia AM%sT 1995 Sep 24 2:00s - 4:00 - AMT 1997 - 4:00 RussiaAsia AM%sT 2012 Mar 25 2:00s - 4:00 - AMT + 3:00 - +03 1957 Mar + 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s + 3:00 RussiaAsia +03/+04 1995 Sep 24 2:00s + 4:00 - +04 1997 + 4:00 RussiaAsia +04/+05 # Azerbaijan + # From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23): # According to the resolution of Cabinet of Ministers, 1997 # From Paul Eggert (2015-09-17): It was Resolution No. 21 (1997-03-17). # http://code.az/files/daylight_res.pdf + +# From Steffen Thorsen (2016-03-17): +# ... the Azerbaijani Cabinet of Ministers has cancelled switching to +# daylight saving time.... +# http://www.azernews.az/azerbaijan/94137.html +# http://vestnikkavkaza.net/news/Azerbaijani-Cabinet-of-Ministers-cancels-daylight-saving-time.html +# http://en.apa.az/xeber_azerbaijan_abolishes_daylight_savings_ti_240862.html + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Azer 1997 max - Mar lastSun 4:00 1:00 S -Rule Azer 1997 max - Oct lastSun 5:00 0 - +Rule Azer 1997 2015 - Mar lastSun 4:00 1:00 S +Rule Azer 1997 2015 - Oct lastSun 5:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Baku 3:19:24 - LMT 1924 May 2 - 3:00 - BAKT 1957 Mar # Baku Time - 4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s - 3:00 1:00 BAKST 1991 Aug 30 # independence - 3:00 RussiaAsia AZ%sT 1992 Sep lastSat 23:00 - 4:00 - AZT 1996 # Azerbaijan Time - 4:00 EUAsia AZ%sT 1997 - 4:00 Azer AZ%sT + 3:00 - +03 1957 Mar + 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s + 3:00 RussiaAsia +03/+04 1992 Sep lastSun 2:00s + 4:00 - +04 1996 + 4:00 EUAsia +04/+05 1997 + 4:00 Azer +04/+05 # Bahrain # See Asia/Qatar. @@ -263,7 +265,7 @@ Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon. # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Rangoon 6:24:40 - LMT 1880 # or Yangon +Zone Asia/Yangon 6:24:40 - LMT 1880 # or Rangoon 6:24:40 - RMT 1920 # Rangoon Mean Time? 6:30 - BURT 1942 May # Burma Time 9:00 - JST 1945 May 3 @@ -378,7 +380,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # Lewiston (ME) Daily Sun (1939-05-29), p 17, said "Even the time is # different - the occupied districts going by Tokyo time, an hour # ahead of that prevailing in the rest of Shanghai." Guess that the -# Xujiahui Observatory was under French control and stuck with UT+8. +# Xujiahui Observatory was under French control and stuck with UT +08. # # In earlier versions of this file, China had many separate Zone entries, but # this was based on what were apparently incorrect data in Shanks & Pottenger. @@ -387,26 +389,26 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # Proposed in 1918 and theoretically in effect until 1949 (although in practice # mainly observed in coastal areas), the five zones were: # -# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT+8.5 +# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT +08:30 # Asia/Harbin (currently a link to Asia/Shanghai) # Heilongjiang (except Mohe county), Jilin # -# Zhongyuan Time ("Central plain Time") UT+8 +# Zhongyuan Time ("Central plain Time") UT +08 # Asia/Shanghai # most of China # This currently represents most other zones as well, # as apparently these regions have been the same since 1970. # Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest. -# Guo says Shanghai switched to UT+8 "from the end of the 19th century". +# Guo says Shanghai switched to UT +08 "from the end of the 19th century". # -# Long-shu Time (probably due to Long and Shu being two names of that area) UT+7 +# Long-shu Time (probably due to Long and Shu being two names of the area) UT +07 # Asia/Chongqing (currently a link to Asia/Shanghai) # Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan; # most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong # counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing, # Yangchun, Yangjiang, Yu'nan, and Yunfu. # -# Xin-zang Time ("Xinjiang-Tibet Time") UT+6 +# Xin-zang Time ("Xinjiang-Tibet Time") UT +06 # Asia/Urumqi # This currently represents Kunlun Time as well, # as apparently the two regions have been the same since 1970. @@ -419,7 +421,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami, # Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan. # -# Kunlun Time UT+5.5 +# Kunlun Time UT +05:30 # Asia/Kashgar (currently a link to Asia/Urumqi) # West Tibet, including Pulan, Aheqi, Shufu, Shule; # West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke, @@ -435,7 +437,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # # On the other hand, ethnic Uyghurs, who make up about half the # population of Xinjiang, typically use "Xinjiang time" which is two -# hours behind Beijing time, or UTC +0600. The government of the Xinjiang +# hours behind Beijing time, or UT +06. The government of the Xinjiang # Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as # local governments such as the Ürümqi city government use both times in # publications, referring to what is popularly called Xinjiang time as @@ -491,8 +493,8 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # having the same time as Beijing. # From Paul Eggert (2014-06-30): -# In the early days of the PRC, Tibet was given its own time zone (UT+6) but -# this was withdrawn in 1959 and never reinstated; see Tubten Khétsun, +# In the early days of the PRC, Tibet was given its own time zone (UT +06) +# but this was withdrawn in 1959 and never reinstated; see Tubten Khétsun, # Memories of life in Lhasa under Chinese Rule, Columbia U Press, ISBN # 978-0231142861 (2008), translator's introduction by Matthew Akester, p x. # As this is before our 1970 cutoff, Tibet doesn't need a separate zone. @@ -506,12 +508,12 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1: # Republics, the Soviet Union, the Kuomintang, and the People's Republic of # China, and tracking down all these organizations' timekeeping rules would be # quite a trick. Approximate this lost history by a transition from LMT to -# XJT at the start of 1928, the year of accession of the warlord Jin Shuren, +# UT +06 at the start of 1928, the year of accession of the warlord Jin Shuren, # which happens to be the date given by Shanks & Pottenger (no doubt as a -# guess) as the transition from LMT. Ignore the usage of UT+8 before -# 1986-02-01 under the theory that the transition date to UT+8 is unknown and +# guess) as the transition from LMT. Ignore the usage of +08 before +# 1986-02-01 under the theory that the transition date to +08 is unknown and # that the sort of users who prefer Asia/Urumqi now typically ignored the -# UT+8 mandate back then. +# +08 mandate back then. # Zone NAME GMTOFF RULES FORMAT [UNTIL] # Beijing time, used throughout China; represented by Shanghai. @@ -716,7 +718,7 @@ Zone Asia/Hong_Kong 7:36:42 - LMT 1904 O # be found from historical government announcement database. # From Paul Eggert (2014-07-03): -# As per Yu-Cheng Chuang, say that Taiwan was at UT+9 from 1937-10-01 +# As per Yu-Cheng Chuang, say that Taiwan was at UT +09 from 1937-10-01 # until 1945-09-21 at 01:00, overriding Shanks & Pottenger. # Likewise, use Yu-Cheng Chuang's data for DST in Taiwan. @@ -830,16 +832,15 @@ Link Asia/Nicosia Europe/Nicosia # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Tbilisi 2:59:11 - LMT 1880 2:59:11 - TBMT 1924 May 2 # Tbilisi Mean Time - 3:00 - TBIT 1957 Mar # Tbilisi Time - 4:00 RussiaAsia TBI%sT 1991 Mar 31 2:00s - 3:00 1:00 TBIST 1991 Apr 9 # independence - 3:00 RussiaAsia GE%sT 1992 # Georgia Time - 3:00 E-EurAsia GE%sT 1994 Sep lastSun - 4:00 E-EurAsia GE%sT 1996 Oct lastSun - 4:00 1:00 GEST 1997 Mar lastSun - 4:00 E-EurAsia GE%sT 2004 Jun 27 - 3:00 RussiaAsia GE%sT 2005 Mar lastSun 2:00 - 4:00 - GET + 3:00 - +03 1957 Mar + 4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s + 3:00 RussiaAsia +03/+04 1992 + 3:00 E-EurAsia +03/+04 1994 Sep lastSun + 4:00 E-EurAsia +04/+05 1996 Oct lastSun + 4:00 1:00 +05 1997 Mar lastSun + 4:00 E-EurAsia +04/+05 2004 Jun 27 + 3:00 RussiaAsia +03/+04 2005 Mar lastSun 2:00 + 4:00 - +04 # East Timor @@ -874,6 +875,15 @@ Zone Asia/Dili 8:22:20 - LMT 1912 Jan 1 9:00 - TLT # India + +# From Ian P. Beacock, in "A brief history of (modern) time", The Atlantic +# http://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/ +# (2015-12-22): +# In January 1906, several thousand cotton-mill workers rioted on the +# outskirts of Bombay.... They were protesting the proposed abolition of +# local time in favor of Indian Standard Time.... Journalists called this +# dispute the "Battle of the Clocks." It lasted nearly half a century. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata 5:53:20 - HMT 1941 Oct # Howrah Mean Time? @@ -907,7 +917,7 @@ Zone Asia/Kolkata 5:53:28 - LMT 1880 # These would be the earliest possible times for a change. # Régimes horaires pour le monde entier, by Henri Le Corre, (Éditions # Traditionnelles, 1987, Paris) says that Java and Madura switched -# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura +# from UT +09 to +07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura # (Hollandia). For now, assume all Indonesian locations other than Jayapura # switched on 1945-09-23. # @@ -918,11 +928,11 @@ Zone Asia/Kolkata 5:53:28 - LMT 1880 # summary published by the Time and Frequency Laboratory of the # Research Center for Calibration, Instrumentation and Metrology, # Indonesia, (2006-09-29). -# The abbreviations are: +# The time zone abbreviations and UT offsets are: # -# WIB - UTC+7 - Waktu Indonesia Barat (Indonesia western time) -# WITA - UTC+8 - Waktu Indonesia Tengah (Indonesia central time) -# WIT - UTC+9 - Waktu Indonesia Timur (Indonesia eastern time) +# WIB - +07 - Waktu Indonesia Barat (Indonesia western time) +# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time) +# WIT - +09 - Waktu Indonesia Timur (Indonesia eastern time) # # Zone NAME GMTOFF RULES FORMAT [UNTIL] # Java, Sumatra @@ -1084,8 +1094,15 @@ Rule Iran 2032 2033 - Mar 21 0:00 1:00 D Rule Iran 2032 2033 - Sep 21 0:00 0 S Rule Iran 2034 2035 - Mar 22 0:00 1:00 D Rule Iran 2034 2035 - Sep 22 0:00 0 S -Rule Iran 2036 2037 - Mar 21 0:00 1:00 D -Rule Iran 2036 2037 - Sep 21 0:00 0 S +# +# The following rules are approximations starting in the year 2038. +# These are the best post-2037 approximations available, given the +# restrictions of a single rule using a Gregorian-based data format. +# At some point this table will need to be extended, though quite +# possibly Iran will change the rules first. +Rule Iran 2036 max - Mar 21 0:00 1:00 D +Rule Iran 2036 max - Sep 21 0:00 0 S + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Tehran 3:25:44 - LMT 1916 3:25:44 - TMT 1946 # Tehran Mean Time @@ -1542,23 +1559,6 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # Kazakhstan -# From Paul Eggert (1996-11-22): -# Andrew Evtichov (1996-04-13) writes that Kazakhstan -# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk) -# and Aqtau (formerly Shevchenko) are the largest cities in their zones. -# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time -# IATA SSIM mentions a third time zone in Kazakhstan. - -# From Paul Eggert (2006-03-22): -# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses -# RussiaAsia rules, instead of switching at 00:00 as the IATA has it. -# Go with Shanks & Pottenger, who have them always using RussiaAsia rules. -# Also go with the following claims of Shanks & Pottenger: -# -# - Kazakhstan did not observe DST in 1991. -# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00. -# - Oral switched from +5:00 to +4:00 in spring 1989. - # From Kazakhstan Embassy's News Bulletin No. 11 # (2005-03-21): # The Government of Kazakhstan passed a resolution March 15 abolishing @@ -1575,61 +1575,232 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # everything else.... I guess that would make Kazakhstan time zones # de jure UTC+5 and UTC+6 respectively. +# From Stepan Golosunov (2016-03-27) ([*] means see later comments below): +# Review of the linked documents from http://adilet.zan.kz/ +# produced the following data for post-1991 Kazakhstan: +# +# 0. Act of the Cabinet of Ministers of the USSR +# from 1991-02-04 No. 20 +# http://pravo.gov.ru/proxy/ips/?docbody=&nd=102010545 +# removed the extra hour ("decree time") on the territory of the USSR +# starting with the last Sunday of March 1991. +# It also allowed (but not mandated) Kazakh SSR, Kirghiz SSR, Tajik SSR, +# Turkmen SSR and Uzbek SSR to not have "summer" time. +# +# The 1992-01-13 act also refers to the act of the Cabinet of Ministers +# of the Kazakh SSR from 1991-03-20 No. 170 "About the act of the Cabinet +# of Ministers of the USSR from 1991-02-04 No. 20" but I didn't found its +# text. +# +# According to Izvestia newspaper No. 68 (23334) from 1991-03-20 +# (page 6; available at http://libinfo.org/newsr/newsr2574.djvu via +# http://libinfo.org/index.php?id=58564) on 1991-03-31 at 2:00 during +# transition to "summer" time: +# Republic of Georgia, Latvian SSR, Lithuanian SSR, SSR Moldova, +# Estonian SSR; Komi ASSR; Kaliningrad oblast; Nenets autonomous okrug +# were to move clocks 1 hour forward. +# Kazakh SSR (excluding Uralsk oblast); Republic of Kyrgyzstan, Tajik +# SSR; Andijan, Jizzakh, Namangan, Sirdarya, Tashkent, Fergana oblasts +# of the Uzbek SSR were to move clocks 1 hour backwards. +# Other territories were to not move clocks. +# When the "summer" time would end on 1991-09-29, clocks were to be +# moved 1 hour backwards on the territory of the USSR excluding +# Kazakhstan, Kirghizia, Uzbekistan, Turkmenia, Tajikistan. +# +# Apparently there were last minute changes. Apparently Kazakh act No. 170 +# was one of such changes. +# +# https://ru.wikipedia.org/wiki/Декретное время +# claims that Sovetskaya Rossiya newspaper on 1991-03-29 published that +# Nenets autonomous okrug, Komi and Kazakhstan (excluding Uralsk oblast) +# were to not move clocks and Uralsk oblast was to move clocks +# forward; on 1991-09-29 Kazakhstan was to move clocks backwards. +# (Probably there were changes even after that publication. There is an +# article claiming that Kaliningrad oblast decided on 1991-03-29 to not +# move clocks.) +# +# This implies that on 1991-03-31 Asia/Oral remained on +04/+05 while +# the rest of Kazakhstan switched from +06/+07 to +05/06 or from +05/06 +# to +04/+05. It's unclear how Kzyl-Orda oblast moved into the fifth +# time belt. (By switching from +04/+05 to +05/+06 on 1991-09-29?) ... +# +# 1. Act of the Cabinet of Ministers of the Republic of Kazakhstan +# from 1992-01-13 No. 28 +# http://adilet.zan.kz/rus/docs/P920000028_ +# (text includes modification from the 1996 act) +# introduced new rules for calculation of time, mirroring Russian +# 1992-01-08 act. It specified that time would be calculated +# according to time belts plus extra hour ("decree time"), moved clocks +# on the whole territory of Kazakhstan 1 hour forward on 1992-01-19 at +# 2:00, specified DST rules. It acknowledged that Kazakhstan was +# located in the fourth and the fifth time belts and specified the +# border between them to be located east of Kustanay and Aktyubinsk +# oblasts (notably including Turgai and Kzyl-Orda oblasts into the fifth +# time belt). +# +# This means switch on 1992-01-19 at 2:00 from +04/+05 to +05/+06 for +# Asia/Aqtau, Asia/Aqtobe, Asia/Oral, Atyrau and Kustanay oblasts; from +# +05/+06 to +06/+07 for Asia/Almaty and Asia/Qyzylorda (and Arkalyk) [*].... +# +# 2. Act of the Cabinet of Ministers of the Republic of Kazakhstan +# from 1992-03-27 No. 284 +# http://adilet.zan.kz/rus/docs/P920000284_ +# cancels extra hour ("decree time") for Uralsk and Kzyl-Orda oblasts +# since the last Sunday of March 1992, while keeping them in the fourth +# and the fifth time belts respectively. +# +# 3. Order of the Prime Minister of the Republic of Kazakhstan +# from 1994-09-23 No. 384 +# http://adilet.zan.kz/rus/docs/R940000384_ +# cancels the extra hour ("decree time") on the territory of Mangystau +# oblast since the last Sunday of September 1994 (saying that time on +# the territory would correspond to the third time belt as a +# result).... +# +# 4. Act of the Government of the Republic of Kazakhstan +# from 1996-05-08 No. 575 +# http://adilet.zan.kz/rus/docs/P960000575_ +# amends the 1992-01-13 act to end summer time in October instead +# of September, mirroring identical Russian change from 1996-04-23 act. +# +# 5. Act of the Government of the Republic of Kazakhstan +# from 1999-03-26 No. 305 +# http://adilet.zan.kz/rus/docs/P990000305_ +# cancels the extra hour ("decree time") for Atyrau oblast since the +# last Sunday of March 1999 while retaining the oblast in the fourth +# time belt. +# +# This means change from +05/+06 to +04/+05. +# +# There is no zone for Atyrau currently (listed under Asia/Aqtau in +# zone1970.tab).[*] +# +# 6. Act of the Government of the Republic of Kazakhstan +# from 2000-11-23 No. 1749 +# http://adilet.zan.kz/rus/archive/docs/P000001749_/23.11.2000 +# replaces the previous five documents. +# +# The only changes I noticed are in definition of the border between the +# fourth and the fifth time belts. They account for changes in spelling +# and administrative division (splitting of Turgai oblast in 1997 +# probably changed time in territories incorporated into Kostanay oblast +# (including Arkalyk) from +06/+07 to +05/+06) and move Kyzylorda oblast +# from being in the fifth time belt and not using decree time into the +# fourth time belt (no change in practice).[*] +# +# 7. Act of the Government of the Republic of Kazakhstan +# from 2003-12-29 No. 1342 +# http://adilet.zan.kz/rus/docs/P030001342_ +# modified the 2000-11-23 act. No relevant changes, apparently. +# +# 8. Act of the Government of the Republic of Kazakhstan +# from 2004-07-20 No. 775 +# http://adilet.zan.kz/rus/archive/docs/P040000775_/20.07.2004 +# modified the 2000-11-23 act to move Kostanay and Kyzylorda oblasts into +# the fifth time belt and add Aktobe oblast to the list of regions not +# using extra hour ("decree time"), leaving Kazakhstan with only 2 time +# zones (+04/+05 and +06/+07). The changes were to be implemented +# during DST transitions in 2004 and 2005 but the acts got radically +# amended before implementation happened. +# +# 9. Act of the Government of the Republic of Kazakhstan +# from 2004-09-15 No. 1059 +# http://adilet.zan.kz/rus/docs/P040001059_ +# modified the 2000-11-23 act to remove exceptions from the "decree time" +# (leaving Kazakhstan in +05/+06 and +06/+07 zones), amended the +# 2004-07-20 act to implement changes for Atyrau, West Kazakhstan, +# Kostanay, Kyzylorda and Mangystau oblasts by not moving clocks +# during the 2014 transition to "winter" time. +# +# This means transition from +04/+05 to +05/+06 for Atyrau oblast (no +# zone currently), Asia/Oral, Asia/Aqtau and transition from +05/+06 to +# +06/+07 for Kostanay oblast (Kostanay and Arkalyk, no zones currently) +# and Asia/Qyzylorda on 2004-10-31 at 3:00....[*] +# +# 10. Act of the Government of the Republic of Kazakhstan +# from 2005-03-15 No. 231 +# http://adilet.zan.kz/rus/docs/P050000231_ +# removes DST provisions from the 2000-11-23 act, removes most of the +# (already implemented) provisions from the 2004-07-20 and 2004-09-15 +# acts, comes into effect 10 days after official publication. +# The only practical effect seems to be the abolition of the summer +# time. +# +# Unamended version of the act of the Government of the Russian Federation +# No. 23 from 1992-01-08 [See 'europe' file for details]. +# Kazakh 1992-01-13 act appears to provide the same rules and 1992-03-27 +# act was to be enacted on the last Sunday of March 1992. + +# From Paul Eggert (2016-04-15): +# The tables below should reflect Stepan Golosunov's remarks above, +# except for the items marked "[*]" which I haven't gotten to yet. +# It looks like we will need new zones Asia/Atyrau and Asia/Qostanay +# to handle changes from 1992 through 2004 that we did not previously +# know about. + # # Zone NAME GMTOFF RULES FORMAT [UNTIL] # # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan +# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA, +# KZ-KAR, KZ-SEV, KZ-PAV, and KZ-YUZ. Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata - 5:00 - ALMT 1930 Jun 21 # Alma-Ata Time - 6:00 RussiaAsia ALM%sT 1991 - 6:00 - ALMT 1992 - 6:00 RussiaAsia ALM%sT 2005 Mar 15 - 6:00 - ALMT -# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) + 5:00 - +05 1930 Jun 21 + 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s + 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s + 6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s + 6:00 - +06 +# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY) Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 - 4:00 - KIZT 1930 Jun 21 # Kizilorda Time - 5:00 - KIZT 1981 Apr 1 - 5:00 1:00 KIZST 1981 Oct 1 - 6:00 - KIZT 1982 Apr 1 - 5:00 RussiaAsia KIZ%sT 1991 - 5:00 - KIZT 1991 Dec 16 # independence - 5:00 - QYZT 1992 Jan 19 2:00 - 6:00 RussiaAsia QYZ%sT 2005 Mar 15 - 6:00 - QYZT -# Aqtobe (aka Aktobe, formerly Aktyubinsk) + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1991 Sep 29 2:00s + 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s + 6:00 RussiaAsia +06/+07 1992 Mar 29 2:00s + 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s + 6:00 - +06 +# Aqtobe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT) Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 - 4:00 - AKTT 1930 Jun 21 # Aktyubinsk Time - 5:00 - AKTT 1981 Apr 1 - 5:00 1:00 AKTST 1981 Oct 1 - 6:00 - AKTT 1982 Apr 1 - 5:00 RussiaAsia AKT%sT 1991 - 5:00 - AKTT 1991 Dec 16 # independence - 5:00 RussiaAsia AQT%sT 2005 Mar 15 # Aqtobe Time - 5:00 - AQTT -# Mangghystau + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s + 5:00 - +05 +# Qostanay (KZ-KUS) + +# Mangghystau (KZ-MAN) # Aqtau was not founded until 1963, but it represents an inhabited region, # so include time stamps before 1963. Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 - 4:00 - FORT 1930 Jun 21 # Fort Shevchenko T - 5:00 - FORT 1963 - 5:00 - SHET 1981 Oct 1 # Shevchenko Time - 6:00 - SHET 1982 Apr 1 - 5:00 RussiaAsia SHE%sT 1991 - 5:00 - SHET 1991 Dec 16 # independence - 5:00 RussiaAsia AQT%sT 1995 Mar lastSun 2:00 # Aqtau Time - 4:00 RussiaAsia AQT%sT 2005 Mar 15 - 5:00 - AQTT -# West Kazakhstan + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1963 + 5:00 - +05 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s + 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s + 5:00 - +05 + +# West Kazakhstan (KZ-ZAP) +# From Paul Eggert (2016-03-18): +# The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Asia/Oral 3:25:24 - LMT 1924 May 2 # or Ural'sk - 4:00 - URAT 1930 Jun 21 # Ural'sk time - 5:00 - URAT 1981 Apr 1 - 5:00 1:00 URAST 1981 Oct 1 - 6:00 - URAT 1982 Apr 1 - 5:00 RussiaAsia URA%sT 1989 Mar 26 2:00 - 4:00 RussiaAsia URA%sT 1991 - 4:00 - URAT 1991 Dec 16 # independence - 4:00 RussiaAsia ORA%sT 2005 Mar 15 # Oral Time - 5:00 - ORAT + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1989 Mar 26 2:00s + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s + 5:00 RussiaAsia +05/+06 1992 Mar 29 2:00s + 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s + 5:00 - +05 # Kyrgyzstan (Kirgizstan) # Transitions through 1991 are from Shanks & Pottenger. @@ -1650,11 +1821,11 @@ Rule Kyrgyz 1997 2005 - Mar lastSun 2:30 Rule Kyrgyz 1997 2004 - Oct lastSun 2:30 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 - 5:00 - FRUT 1930 Jun 21 # Frunze Time - 6:00 RussiaAsia FRU%sT 1991 Mar 31 2:00s - 5:00 1:00 FRUST 1991 Aug 31 2:00 # independence - 5:00 Kyrgyz KG%sT 2005 Aug 12 # Kyrgyzstan Time - 6:00 - KGT + 5:00 - +05 1930 Jun 21 + 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s + 5:00 RussiaAsia +05/+06 1991 Aug 31 2:00 + 5:00 Kyrgyz +05/+06 2005 Aug 12 + 6:00 - +06 ############################################################################### @@ -1693,25 +1864,24 @@ Rule ROK 1957 1960 - Sep Sun>=18 0:00 0 Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S -# From Paul Eggert (2014-10-30): +# From Paul Eggert (2016-08-23): # The Korean Wikipedia entry gives the following sources for UT offsets: # -# 1908: Official Journal Article No. 3994 (Edict No. 5) +# 1908: Official Journal Article No. 3994 (decree No. 5) # 1912: Governor-General of Korea Official Gazette Issue No. 367 # (Announcement No. 338) # 1954: Presidential Decree No. 876 (1954-03-17) # 1961: Law No. 676 (1961-08-07) -# 1987: Law No. 3919 (1986-12-31) # -# The Wikipedia entry also has confusing information about a change -# to UT+9 in April 1910, but then what would be the point of the later change -# to UT+9 on 1912-01-01? Omit the 1910 change for now. +# (Another source "1987: Law No. 3919 (1986-12-31)" was in the 2014-10-30 +# edition of the Korean Wikipedia entry.) # # I guessed that time zone abbreviations through 1945 followed the same # rules as discussed under Taiwan, with nominal switches from JST to KST # when the respective cities were taken over by the Allies after WWII. # -# For Pyongyang we have no information; guess no changes since World War II. +# For Pyongyang, guess no changes from World War II until 2015, as we +# have no information otherwise. # From Steffen Thorsen (2015-08-07): # According to many news sources, North Korea is going to change to @@ -1871,7 +2041,7 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says # there is only one time zone and that DST is observed, citing Microsoft # Windows XP as the source. Risto Nykänen (2005-05-16) reports that -# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST. +# travelmongolia.org says there are two time zones (UT +07, +08) with no DST. # Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in # Washington, DC says there are two time zones, with DST observed. # He also found @@ -2111,8 +2281,8 @@ Zone Asia/Kathmandu 5:41:16 - LMT 1920 # http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2 # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Pakistan 2002 only - Apr Sun>=2 0:01 1:00 S -Rule Pakistan 2002 only - Oct Sun>=2 0:01 0 - +Rule Pakistan 2002 only - Apr Sun>=2 0:00 1:00 S +Rule Pakistan 2002 only - Oct Sun>=2 0:00 0 - Rule Pakistan 2008 only - Jun 1 0:00 1:00 S Rule Pakistan 2008 2009 - Nov 1 0:00 0 - Rule Pakistan 2009 only - Apr 15 0:00 1:00 S @@ -2380,6 +2550,16 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # http://www.timeanddate.com/time/change/gaza-strip/gaza # http://www.timeanddate.com/time/change/west-bank/hebron +# From Hannah Kreitem (2016-03-09): +# http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728 +# [Google translation]: "The Council also decided to start daylight +# saving in Palestine as of one o'clock on Saturday morning, +# 2016-03-26, to provide the clock 60 minutes ahead." +# +# From Paul Eggert (2016-03-12): +# Predict spring transitions on March's last Saturday at 01:00 from now on. +# Leave fall predictions alone for now. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 - @@ -2408,7 +2588,8 @@ Rule Palestine 2012 2014 - Mar lastThu 2 Rule Palestine 2012 only - Sep 21 1:00 0 - Rule Palestine 2013 only - Sep Fri>=21 0:00 0 - Rule Palestine 2014 max - Oct Fri>=21 0:00 0 - -Rule Palestine 2015 max - Mar lastFri 24:00 1:00 S +Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S +Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -2496,7 +2677,7 @@ Link Asia/Qatar Asia/Bahrain # earlier date. # # Shanks & Pottenger also state that until 1968-05-01 Saudi Arabia had two -# time zones; the other zone, at UTC+4, was in the far eastern part of +# time zones; the other zone, at UT +04, was in the far eastern part of # the country. Ignore this, as it's before our 1970 cutoff. # # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -2765,10 +2946,10 @@ Zone Asia/Damascus 2:25:12 - LMT 1920 # # From Shanks & Pottenger. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 - 5:00 - DUST 1930 Jun 21 # Dushanbe Time - 6:00 RussiaAsia DUS%sT 1991 Mar 31 2:00s - 5:00 1:00 DUSST 1991 Sep 9 2:00s - 5:00 - TJT # Tajikistan Time + 5:00 - +05 1930 Jun 21 + 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s + 5:00 1:00 +05/+06 1991 Sep 9 2:00s + 5:00 - +05 # Thailand # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -2782,11 +2963,10 @@ Link Asia/Bangkok Asia/Vientiane # Laos # From Shanks & Pottenger. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad - 4:00 - ASHT 1930 Jun 21 # Ashkhabad Time - 5:00 RussiaAsia ASH%sT 1991 Mar 31 2:00 - 4:00 RussiaAsia ASH%sT 1991 Oct 27 # independence - 4:00 RussiaAsia TM%sT 1992 Jan 19 2:00 - 5:00 - TMT + 4:00 - +04 1930 Jun 21 + 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00 + 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00 + 5:00 - +05 # United Arab Emirates # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -2798,20 +2978,18 @@ Link Asia/Dubai Asia/Muscat # Oman # Byalokoz 1919 says Uzbekistan was 4:27:53. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2 - 4:00 - SAMT 1930 Jun 21 # Samarkand Time - 5:00 - SAMT 1981 Apr 1 - 5:00 1:00 SAMST 1981 Oct 1 - 6:00 - TAST 1982 Apr 1 # Tashkent Time - 5:00 RussiaAsia SAM%sT 1991 Sep 1 # independence - 5:00 RussiaAsia UZ%sT 1992 - 5:00 - UZT + 4:00 - +04 1930 Jun 21 + 5:00 - +05 1981 Apr 1 + 5:00 1:00 +06 1981 Oct 1 + 6:00 - +06 1982 Apr 1 + 5:00 RussiaAsia +05/+06 1992 + 5:00 - +05 # Milne says Tashkent was 4:37:10.8; round to nearest. Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 - 5:00 - TAST 1930 Jun 21 # Tashkent Time - 6:00 RussiaAsia TAS%sT 1991 Mar 31 2:00 - 5:00 RussiaAsia TAS%sT 1991 Sep 1 # independence - 5:00 RussiaAsia UZ%sT 1992 - 5:00 - UZT + 5:00 - +05 1930 Jun 21 + 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00 + 5:00 RussiaAsia +05/+06 1992 + 5:00 - +05 # Vietnam Modified: stable/10/contrib/tzdata/australasia ============================================================================== --- stable/10/contrib/tzdata/australasia Sat Oct 15 12:41:11 2016 (r307361) +++ stable/10/contrib/tzdata/australasia Sat Oct 15 12:41:41 2016 (r307362) @@ -60,6 +60,14 @@ Zone Australia/Eucla 8:35:28 - LMT 1895 # Hamilton is the largest, but there is also a Hamilton in Victoria, # so use Lindeman. # +# From J William Piggott (2016-02-20): +# There is no location named Holiday Islands in Queensland Australia; holiday +# islands is a colloquial term used globally. Hayman and Lindeman are at the +# north and south extremes of the Whitsunday Islands archipelago, and +# Hamilton is in between; it is reasonable to believe that this time zone +# applies to all of the Whitsundays. +# http://www.australia.gov.au/about-australia/australian-story/austn-islands +# # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule AQ 1971 only - Oct lastSun 2:00s 1:00 D Rule AQ 1972 only - Feb lastSun 2:00s 0 S @@ -235,11 +243,11 @@ Zone Australia/Lord_Howe 10:36:20 - LMT # will produce a binary file with an [A]EST-type as the first 32-bit type; # this is required for correct handling of times before 1916 by # pre-2013 versions of localtime. -Zone Antarctica/Macquarie 0 - zzz 1899 Nov +Zone Antarctica/Macquarie 0 - -00 1899 Nov 10:00 - AEST 1916 Oct 1 2:00 10:00 1:00 AEDT 1917 Feb 10:00 Aus AE%sT 1919 Apr 1 0:00s - 0 - zzz 1948 Mar 25 + 0 - -00 1948 Mar 25 10:00 Aus AE%sT 1967 10:00 AT AE%sT 2010 Apr 4 3:00 11:00 - MIST # Macquarie I Standard Time @@ -537,7 +545,7 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT # Base the Bougainville entry on the Arawa-Kieta region, which appears to have # the most people even though it was devastated in the Bougainville Civil War. # -# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates +# Although Shanks gives 1942-03-15 / 1943-11-01 for UT +09, these dates # are apparently rough guesswork from the starts of military campaigns. # The World War II entries below are instead based on Arawa-Kieta. # The Japanese occupied Kieta in July 1942, @@ -545,8 +553,8 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT # http://pwencycl.kgbudge.com/B/o/Bougainville.htm # and seem to have controlled it until their 1945-08-21 surrender. # -# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11 -# on 2014-12-28 at 02:00. They call UTC+11 "Bougainville Standard Time"; +# The Autonomous Region of Bougainville switched from UT +10 to +11 +# on 2014-12-28 at 02:00. They call +11 "Bougainville Standard Time"; # abbreviate this as BST. See: # http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/ # @@ -612,7 +620,7 @@ Link Pacific/Pago_Pago Pacific/Midway # # From Paul Eggert (2014-06-27): # The International Date Line Act 2011 # http://www.parliament.gov.ws/images/ACTS/International_Date_Line_Act__2011_-_Eng.pdf -# changed Samoa from UTC-11 to UTC+13, effective "12 o'clock midnight, on +# changed Samoa from UT -11 to +13, effective "12 o'clock midnight, on # Thursday 29th December 2011". The International Date Line was adjusted # accordingly. @@ -707,7 +715,7 @@ Zone Pacific/Funafuti 11:56:52 - LMT 190 # 1886-1891; Baker was similar but exact dates are not known. # Inhabited by civilians 1935-1942; U.S. military bases 1943-1944; # uninhabited thereafter. -# Howland observed Hawaii Standard Time (UT-10:30) in 1937; +# Howland observed Hawaii Standard Time (UT -10:30) in 1937; # see page 206 of Elgen M. Long and Marie K. Long, # Amelia Earhart: the Mystery Solved, Simon & Schuster (2000). # So most likely Howland and Baker observed Hawaii Time from 1935 @@ -1465,7 +1473,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # Zealand time. I understand that is the time they keep locally, anyhow." # For now, assume this practice goes back to the introduction of standard time # in New Zealand, as this would make Chatham Islands time almost exactly match -# LMT back when New Zealand was at UTC+11:30; also, assume Chatham Islands did +# LMT back when New Zealand was at UT +11:30; also, assume Chatham Islands did # not observe New Zealand's prewar DST. *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Sat Oct 15 13:44:15 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 04035C124FC; Sat, 15 Oct 2016 13:44:15 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B52CBF93; Sat, 15 Oct 2016 13:44:14 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FDiD8M058321; Sat, 15 Oct 2016 13:44:13 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FDiDTp058319; Sat, 15 Oct 2016 13:44:13 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201610151344.u9FDiDTp058319@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Sat, 15 Oct 2016 13:44:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307371 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 13:44:15 -0000 Author: arybchik Date: Sat Oct 15 13:44:13 2016 New Revision: 307371 URL: https://svnweb.freebsd.org/changeset/base/307371 Log: MFC r306944 sfxge(4): sync tlv_layout.h with firmwaresrc and update port-mode definition use It fixes driver attach issue to a new firmware which reports a new port-modes. Submitted by: Tom Millington Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/ef10_nic.c stable/10/sys/dev/sfxge/common/ef10_tlv_layout.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/ef10_nic.c ============================================================================== --- stable/10/sys/dev/sfxge/common/ef10_nic.c Sat Oct 15 13:42:52 2016 (r307370) +++ stable/10/sys/dev/sfxge/common/ef10_nic.c Sat Oct 15 13:44:13 2016 (r307371) @@ -164,6 +164,7 @@ ef10_nic_get_port_mode_bandwidth( break; case TLV_PORT_MODE_10G_10G_10G_10G: case TLV_PORT_MODE_10G_10G_10G_10G_Q: + case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: case TLV_PORT_MODE_10G_10G_10G_10G_Q2: bandwidth = 10000 * 4; break; @@ -1122,8 +1123,7 @@ static struct { { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G) | - (1 << TLV_PORT_MODE_10G_10G) | - (1 << TLV_PORT_MODE_10G_10G_10G_10G), + (1 << TLV_PORT_MODE_10G_10G), 1 }, /* Supported modes requiring 2 outputs per port */ @@ -1140,13 +1140,15 @@ static struct { (1 << TLV_PORT_MODE_40G) | (1 << TLV_PORT_MODE_40G_40G) | (1 << TLV_PORT_MODE_40G_10G_10G) | - (1 << TLV_PORT_MODE_10G_10G_40G), + (1 << TLV_PORT_MODE_10G_10G_40G) | + (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), 2 }, /* Supported modes requiring 4 outputs per port */ { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) | + (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1) | (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2), 4 }, Modified: stable/10/sys/dev/sfxge/common/ef10_tlv_layout.h ============================================================================== --- stable/10/sys/dev/sfxge/common/ef10_tlv_layout.h Sat Oct 15 13:42:52 2016 (r307370) +++ stable/10/sys/dev/sfxge/common/ef10_tlv_layout.h Sat Oct 15 13:44:13 2016 (r307371) @@ -553,12 +553,14 @@ struct tlv_global_port_mode { #define TLV_PORT_MODE_40G (1) /* 40G, single QSFP/40G-KR */ #define TLV_PORT_MODE_10G_10G (2) /* 2x10G, dual SFP/10G-KR or single QSFP */ #define TLV_PORT_MODE_40G_40G (3) /* 40G + 40G, dual QSFP/40G-KR (Greenport, Medford) */ -#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport, Medford) */ -#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) */ +#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport) */ +#define TLV_PORT_MODE_10G_10G_10G_10G_Q1 (4) /* 4x10G, single QSFP, cage 0 (Medford) */ +#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) OBSOLETE DO NOT USE */ #define TLV_PORT_MODE_40G_10G_10G (6) /* 1x40G + 2x10G, dual QSFP (Greenport, Medford) */ #define TLV_PORT_MODE_10G_10G_40G (7) /* 2x10G + 1x40G, dual QSFP (Greenport, Medford) */ #define TLV_PORT_MODE_10G_10G_10G_10G_Q2 (8) /* 4x10G, single QSFP, cage 1 (Medford) */ -#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q2 +#define TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2 (9) /* 2x10G + 2x10G, dual QSFP (Medford) */ +#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2 }; /* Type of the v-switch created implicitly by the firmware */ @@ -765,8 +767,8 @@ struct tlv_rx_event_merging_config { #define TLV_RX_EVENT_MERGING_CONFIG_MAX_EVENTS_MAX ((1 << 4) - 1) uint32_t timeout_ns; }; -#define TLV_RX_EVENT_MERGING_MAX_EVENTS_DEFAULT 7 -#define TLV_RX_EVENT_MERGING_TIMEOUT_NS_DEFAULT 8740 +#define TLV_RX_EVENT_MERGING_MAX_EVENTS_DEFAULT (0xffffffff) +#define TLV_RX_EVENT_MERGING_TIMEOUT_NS_DEFAULT (0xffffffff) #define TLV_TAG_PCIE_LINK_SETTINGS (0x101f0000) struct tlv_pcie_link_settings { @@ -791,9 +793,9 @@ struct tlv_tx_event_merging_config { uint32_t timeout_ns; uint32_t qempty_timeout_ns; /* Medford only */ }; -#define TLV_TX_EVENT_MERGING_MAX_EVENTS_DEFAULT 7 -#define TLV_TX_EVENT_MERGING_TIMEOUT_NS_DEFAULT 1400 -#define TLV_TX_EVENT_MERGING_QEMPTY_TIMEOUT_NS_DEFAULT 700 +#define TLV_TX_EVENT_MERGING_MAX_EVENTS_DEFAULT (0xffffffff) +#define TLV_TX_EVENT_MERGING_TIMEOUT_NS_DEFAULT (0xffffffff) +#define TLV_TX_EVENT_MERGING_QEMPTY_TIMEOUT_NS_DEFAULT (0xffffffff) /* Tx vFIFO Low latency configuration * @@ -809,6 +811,20 @@ struct tlv_tx_vfifo_ull_mode { #define TLV_TX_VFIFO_ULL_MODE_DEFAULT 0 }; +/* BIU mode + * + * Medford2 tag for selecting VI window decode (see values below) + */ +#define TLV_TAG_BIU_VI_WINDOW_MODE (0x10280000) +struct tlv_biu_vi_window_mode { + uint32_t tag; + uint32_t length; + uint8_t mode; +#define TLV_BIU_VI_WINDOW_MODE_8K 0 /* 8k per VI, CTPIO not mapped, medford/hunt compatible */ +#define TLV_BIU_VI_WINDOW_MODE_16K 1 /* 16k per VI, CTPIO mapped */ +#define TLV_BIU_VI_WINDOW_MODE_64K 2 /* 64k per VI, CTPIO mapped, POWER-friendly */ +}; + #define TLV_TAG_LICENSE (0x30800000) typedef struct tlv_license { From owner-svn-src-stable-10@freebsd.org Sat Oct 15 13:45:13 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6A3A1C1258C; Sat, 15 Oct 2016 13:45:13 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2AB81167; Sat, 15 Oct 2016 13:45:13 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FDjCSY058471; Sat, 15 Oct 2016 13:45:12 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FDjCZb058470; Sat, 15 Oct 2016 13:45:12 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201610151345.u9FDjCZb058470@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Sat, 15 Oct 2016 13:45:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307373 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 13:45:13 -0000 Author: arybchik Date: Sat Oct 15 13:45:12 2016 New Revision: 307373 URL: https://svnweb.freebsd.org/changeset/base/307373 Log: MFC r307038 sfxge(4): update external port mapping for Medford Extend the mapping table for external port numbering to support port modes which output to the second external port only. Where supported, map from the current port mode rather than inferring from all the available modes. Updated comments for clarity. Submitted by: Richard Houldsworth Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/ef10_nic.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/ef10_nic.c ============================================================================== --- stable/10/sys/dev/sfxge/common/ef10_nic.c Sat Oct 15 13:45:09 2016 (r307372) +++ stable/10/sys/dev/sfxge/common/ef10_nic.c Sat Oct 15 13:45:12 2016 (r307373) @@ -1099,41 +1099,50 @@ fail1: /* - * The external port mapping is a one-based numbering of the external - * connectors on the board. It does not distinguish off-board separated - * outputs such as multi-headed cables. - * The number of ports that map to each external port connector - * on the board is determined by the chip family and the port modes to - * which the NIC can be configured. The mapping table lists modes with - * port numbering requirements in increasing order. + * Table of mapping schemes from port number to the number of the external + * connector on the board. The external numbering does not distinguish + * off-board separated outputs such as from multi-headed cables. + * + * The count of adjacent port numbers that map to each external port + * and the offset in the numbering, is determined by the chip family and + * current port mode. + * + * For the Huntington family, the current port mode cannot be discovered, + * so the mapping used is instead the last match in the table to the full + * set of port modes to which the NIC can be configured. Therefore the + * ordering of entries in the the mapping table is significant. */ static struct { efx_family_t family; uint32_t modes_mask; - uint32_t stride; + int32_t count; + int32_t offset; } __ef10_external_port_mappings[] = { - /* Supported modes requiring 1 output per port */ + /* Supported modes with 1 output per external port */ { EFX_FAMILY_HUNTINGTON, (1 << TLV_PORT_MODE_10G) | (1 << TLV_PORT_MODE_10G_10G) | (1 << TLV_PORT_MODE_10G_10G_10G_10G), + 1, 1 }, { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G) | (1 << TLV_PORT_MODE_10G_10G), + 1, 1 }, - /* Supported modes requiring 2 outputs per port */ + /* Supported modes with 2 outputs per external port */ { EFX_FAMILY_HUNTINGTON, (1 << TLV_PORT_MODE_40G) | (1 << TLV_PORT_MODE_40G_40G) | (1 << TLV_PORT_MODE_40G_10G_10G) | (1 << TLV_PORT_MODE_10G_10G_40G), - 2 + 2, + 1 }, { EFX_FAMILY_MEDFORD, @@ -1142,15 +1151,22 @@ static struct { (1 << TLV_PORT_MODE_40G_10G_10G) | (1 << TLV_PORT_MODE_10G_10G_40G) | (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), - 2 + 2, + 1 }, - /* Supported modes requiring 4 outputs per port */ + /* Supported modes with 4 outputs per external port */ { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) | - (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1) | + (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1), + 4, + 1, + }, + { + EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2), - 4 + 4, + 2 }, }; @@ -1164,11 +1180,26 @@ ef10_external_port_mapping( int i; uint32_t port_modes; uint32_t matches; - uint32_t stride = 1; /* default 1-1 mapping */ - - if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, NULL)) != 0) { - /* No port mode information available - use default mapping */ - goto out; + uint32_t current; + int32_t count = 1; /* Default 1-1 mapping */ + int32_t offset = 1; /* Default starting external port number */ + + if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t)) != 0) { + /* + * No current port mode information + * - infer mapping from available modes + */ + if ((rc = efx_mcdi_get_port_modes(enp, + &port_modes, NULL)) != 0) { + /* + * No port mode information available + * - use default mapping + */ + goto out; + } + } else { + /* Only need to scan the current mode */ + port_modes = 1 << current; } /* @@ -1182,7 +1213,8 @@ ef10_external_port_mapping( matches = (__ef10_external_port_mappings[i].modes_mask & port_modes); if (matches != 0) { - stride = __ef10_external_port_mappings[i].stride; + count = __ef10_external_port_mappings[i].count; + offset = __ef10_external_port_mappings[i].offset; port_modes &= ~matches; } } @@ -1196,9 +1228,9 @@ ef10_external_port_mapping( out: /* * Scale as required by last matched mode and then convert to - * one-based numbering + * correctly offset numbering */ - *external_portp = (uint8_t)(port / stride) + 1; + *external_portp = (uint8_t)((port / count) + offset); return (0); fail1: From owner-svn-src-stable-10@freebsd.org Sat Oct 15 17:39:41 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 90FC3C13566; Sat, 15 Oct 2016 17:39:41 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6BC59E27; Sat, 15 Oct 2016 17:39:41 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9FHdeV2045375; Sat, 15 Oct 2016 17:39:40 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9FHdeZc045374; Sat, 15 Oct 2016 17:39:40 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201610151739.u9FHdeZc045374@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sat, 15 Oct 2016 17:39:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r307378 - stable/10/sys/dev/iscsi X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 17:39:41 -0000 Author: mav Date: Sat Oct 15 17:39:40 2016 New Revision: 307378 URL: https://svnweb.freebsd.org/changeset/base/307378 Log: MFC r282970: Close some potential races around socket start/close. There are some reports about panics on ic->ic_socket NULL derefence. This kind of races is the only way I can imagine it to happen. Modified: stable/10/sys/dev/iscsi/icl.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/iscsi/icl.c ============================================================================== --- stable/10/sys/dev/iscsi/icl.c Sat Oct 15 16:29:06 2016 (r307377) +++ stable/10/sys/dev/iscsi/icl.c Sat Oct 15 17:39:40 2016 (r307378) @@ -746,10 +746,6 @@ icl_receive_thread(void *arg) ic = arg; so = ic->ic_socket; - ICL_CONN_LOCK(ic); - ic->ic_receive_running = true; - ICL_CONN_UNLOCK(ic); - for (;;) { if (ic->ic_disconnecting) { //ICL_DEBUG("terminating"); @@ -971,8 +967,6 @@ icl_send_thread(void *arg) STAILQ_INIT(&queue); ICL_CONN_LOCK(ic); - ic->ic_send_running = true; - for (;;) { for (;;) { /* @@ -1224,35 +1218,45 @@ icl_conn_start(struct icl_conn *ic) } /* + * Register socket upcall, to get notified about incoming PDUs + * and free space to send outgoing ones. + */ + SOCKBUF_LOCK(&ic->ic_socket->so_snd); + soupcall_set(ic->ic_socket, SO_SND, icl_soupcall_send, ic); + SOCKBUF_UNLOCK(&ic->ic_socket->so_snd); + SOCKBUF_LOCK(&ic->ic_socket->so_rcv); + soupcall_set(ic->ic_socket, SO_RCV, icl_soupcall_receive, ic); + SOCKBUF_UNLOCK(&ic->ic_socket->so_rcv); + + /* * Start threads. */ + ICL_CONN_LOCK(ic); + ic->ic_send_running = ic->ic_receive_running = true; + ICL_CONN_UNLOCK(ic); error = kthread_add(icl_send_thread, ic, NULL, NULL, 0, 0, "%stx", ic->ic_name); if (error != 0) { ICL_WARN("kthread_add(9) failed with error %d", error); + ICL_CONN_LOCK(ic); + ic->ic_send_running = ic->ic_receive_running = false; + cv_signal(&ic->ic_send_cv); + ICL_CONN_UNLOCK(ic); icl_conn_close(ic); return (error); } - error = kthread_add(icl_receive_thread, ic, NULL, NULL, 0, 0, "%srx", ic->ic_name); if (error != 0) { ICL_WARN("kthread_add(9) failed with error %d", error); + ICL_CONN_LOCK(ic); + ic->ic_receive_running = false; + cv_signal(&ic->ic_send_cv); + ICL_CONN_UNLOCK(ic); icl_conn_close(ic); return (error); } - /* - * Register socket upcall, to get notified about incoming PDUs - * and free space to send outgoing ones. - */ - SOCKBUF_LOCK(&ic->ic_socket->so_snd); - soupcall_set(ic->ic_socket, SO_SND, icl_soupcall_send, ic); - SOCKBUF_UNLOCK(&ic->ic_socket->so_snd); - SOCKBUF_LOCK(&ic->ic_socket->so_rcv); - soupcall_set(ic->ic_socket, SO_RCV, icl_soupcall_receive, ic); - SOCKBUF_UNLOCK(&ic->ic_socket->so_rcv); - return (0); } @@ -1306,46 +1310,42 @@ void icl_conn_close(struct icl_conn *ic) { struct icl_pdu *pdu; + struct socket *so; - ICL_CONN_LOCK_ASSERT_NOT(ic); - - ICL_CONN_LOCK(ic); - if (ic->ic_socket == NULL) { - ICL_CONN_UNLOCK(ic); - return; - } - - /* - * Deregister socket upcalls. - */ - ICL_CONN_UNLOCK(ic); - SOCKBUF_LOCK(&ic->ic_socket->so_snd); - if (ic->ic_socket->so_snd.sb_upcall != NULL) - soupcall_clear(ic->ic_socket, SO_SND); - SOCKBUF_UNLOCK(&ic->ic_socket->so_snd); - SOCKBUF_LOCK(&ic->ic_socket->so_rcv); - if (ic->ic_socket->so_rcv.sb_upcall != NULL) - soupcall_clear(ic->ic_socket, SO_RCV); - SOCKBUF_UNLOCK(&ic->ic_socket->so_rcv); ICL_CONN_LOCK(ic); - ic->ic_disconnecting = true; - /* * Wake up the threads, so they can properly terminate. */ + ic->ic_disconnecting = true; while (ic->ic_receive_running || ic->ic_send_running) { - //ICL_DEBUG("waiting for send/receive threads to terminate"); cv_signal(&ic->ic_receive_cv); cv_signal(&ic->ic_send_cv); cv_wait(&ic->ic_send_cv, ic->ic_lock); } - //ICL_DEBUG("send/receive threads terminated"); + /* Some other thread could close the connection same time. */ + so = ic->ic_socket; + if (so == NULL) { + ICL_CONN_UNLOCK(ic); + return; + } + ic->ic_socket = NULL; + + /* + * Deregister socket upcalls. + */ ICL_CONN_UNLOCK(ic); - soclose(ic->ic_socket); + SOCKBUF_LOCK(&so->so_snd); + if (so->so_snd.sb_upcall != NULL) + soupcall_clear(so, SO_SND); + SOCKBUF_UNLOCK(&so->so_snd); + SOCKBUF_LOCK(&so->so_rcv); + if (so->so_rcv.sb_upcall != NULL) + soupcall_clear(so, SO_RCV); + SOCKBUF_UNLOCK(&so->so_rcv); + soclose(so); ICL_CONN_LOCK(ic); - ic->ic_socket = NULL; if (ic->ic_receive_pdu != NULL) { //ICL_DEBUG("freeing partially received PDU");