From owner-freebsd-net@freebsd.org Tue May 1 16:26:37 2018 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2C5CBFAF76A for ; Tue, 1 May 2018 16:26:37 +0000 (UTC) (envelope-from duostefano93@gmail.com) Received: from mail-io0-x231.google.com (mail-io0-x231.google.com [IPv6:2607:f8b0:4001:c06::231]) (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 B4C2F6B4FF for ; Tue, 1 May 2018 16:26:36 +0000 (UTC) (envelope-from duostefano93@gmail.com) Received: by mail-io0-x231.google.com with SMTP id d11-v6so14204999iof.11 for ; Tue, 01 May 2018 09:26:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=kcjnD0Z/tba0snbNCeoMM7okRLggvgiDhO2JE+bylmU=; b=rAJUQ6VQI8j6Z7h42et3pnzWUigM2sB7I9WFX2JskFZ6KC4guA1B0vdw+4PIlbIge+ 5MnEBVPIIKUT1fuKKkw1ZGbtL/wtSi4OOsXhlGq19KEIuD3550BI+rd2yX9Nkt5dnG8m petwLfjxtpxf2jLAEf8aqYfzan/kdRWXM1dQWSwOYsp5s95hmZNnSb2ZfQSvI4nKOzwV EpZ3eceYemPJ4ipyzqnVzDX91v/mUaJygNznoeiHHGTQ5K3yC7qfGgtT7VQpgS2iBnPT mLc7NdHEs3I2CyKroBnlfPD5BuTLNtH0Nu7UmxTOxzkMqrM2osj5R2a79876Hd2U/BMq 7nRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=kcjnD0Z/tba0snbNCeoMM7okRLggvgiDhO2JE+bylmU=; b=kQwELycVTPqw0VHL3oc1tlYmDKj55rfb81ne4GUAR8KYApzDmq+KUCYa/RItZfYaLM V6J5LEG5GxPgK9zE6oshUJ2HmDgHg9bYHWpf5sg+sz+K8T0KOf8uUYOgCq6MSb9zz3/l 1QfXi202nf/0z+FCZ8mH+ga47xhLh4XLFR6uSctM45ydqi1c8JB3w28YYvmNtagNCIyY kbjprYEGPTARmgFQ0krtHIcAMOQotxOBQulW5xaTS+CJXpucedhn66xs+WotUmCfmNkb 29IJ6Q80tSwzz2DDzdN8zdqy5xFDJ0QJm670vANZZBiNMZnSzlFOmNr+3vrgESnAO0mr Zk8g== X-Gm-Message-State: ALQs6tA2BECPhB1ziepSTj4e4gsZ0VtK5o7epPs7a9LHBL98gGMGUCYn OfbVqyI0o5eRqMsu8LJJTqK/oA1hFviPfH+iLDbBnKnb X-Google-Smtp-Source: AB8JxZo1Uey1+tZCFXEUeEl+8vSJ+HV4bdyzyapbdST6GEWNPJ6DclH1bKA1Rw7BgmNlJsfDs0iGYi5yIkQNxDKE0vI= X-Received: by 2002:a6b:c848:: with SMTP id y69-v6mr17361815iof.187.1525191995947; Tue, 01 May 2018 09:26:35 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a02:852e:0:0:0:0:0 with HTTP; Tue, 1 May 2018 09:26:35 -0700 (PDT) From: Stefano Duo Date: Tue, 1 May 2018 18:26:35 +0200 Message-ID: Subject: Page fault inside ifunit_ref() FreeBSD12.0-CURRENT To: freebsd-net@freebsd.org Cc: Vincenzo Maffione Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.25 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 May 2018 16:26:37 -0000 Hi, I am a GSoC student working on netmap. I am trying to get a kernel module to call nm_vi_create(), which creates a persistent VALE port. Internally, nm_vi_create() calls ifunit_ref() to check if an interface with the specified name already exists. The system panics inside ifunit_ref() due to a page fault while accessing V_ifnet. This happens using FreeBSD12.0-CURRENT. To better understand what is going on, I have written a dummy module, that only calls ifunit_ref(), here you can find the source code https://github.com/StefanoDuo/ifunit_ref_test. This is what I have found. FreeBSD11.1-STABLE: The module works correctly, either if loaded through kldload or compiled with the kernel. FreeBSD12.0-CURRENT: Calling ifunit_ref() inside the module loader function does not cause a page fault, while calling it inside a write() or ioctl() causes a page fault. This happens either if the module is loaded through kldload or compiled with the kernel. Following Vincenzo's advice (he's one of my mentors), i tried enclosing the call to ifunit_ref() between CURVNET_SET() and CURVNET_RESTORE(). This solves the problem on FreeBSD12.0-CURRENT, but only if the module is compiled with the kernel, if loaded through kldload, i still get a page fault. The problem seems related to the virtualization of the network stack, and therefore the of the V_ifnet variable. It seems that inside the module loader function i have a struct vnet selected, instead inside a write() or ioctl() call i do not. This though, doesn't explain (at least to me) why adding CURVNET_SET() and CURVNET_RESTORE(), doesn't solve the problem for modules loaded through kldload. I don't know if i'm doing something wrong (or not doing something needed), or if it's a bug introduced in FreeBSD12.0-CURRENT. Does anyone have a better idea of what's happening? Here is the panic message i get after writing to the device (causing a call to ifunit_ref). [root@freebsd ~/repos/ifunit_ref_test/sys/modules/foo_module]# echo "test" >/dev/FOO_DEV Kernel page fault with the following non-sleepable locks held: shared rw ifnet_rw (ifnet_rw) r = 0 (0xffffffff820474e8) locked @ /usr/src/sys/net/if.c:2379 stack backtrace: #0 0xffffffff80ba5cd3 at witness_debugger+0x73 #1 0xffffffff80ba70b1 at witness_warn+0x461 #2 0xffffffff80ffe2d3 at trap_pfault+0x53 #3 0xffffffff80ffdad2 at trap+0x2f2 #4 0xffffffff80fd9d9c at calltrap+0x8 #5 0xffffffff8261d10e at foo_write+0x1e #6 0xffffffff80a0a8c0 at devfs_write_f+0xf0 #7 0xffffffff80baad77 at dofilewrite+0xa7 #8 0xffffffff80baa968 at kern_writev+0x68 #9 0xffffffff80baa8f6 at sys_write+0x86 #10 0xffffffff80fff0cb at amd64_syscall+0x79b #11 0xffffffff80fda5ed at fast_syscall_common+0x101 Fatal trap 12: page fault while in kernel mode cpuid = 0; apic id = 00 fault virtual address = 0x28 fault code = supervisor read data, page not present instruction pointer = 0x20:0xffffffff80c3e2f2 stack pointer = 0x28:0xfffffe00005c0950 frame pointer = 0x28:0xfffffe00005c0960 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 700 (bash) [ thread pid 700 tid 100087 ] Stopped at ifunit_ref+0x32: movq ll+0x7(%rax),%rax And here you can find the backtrace taken from the dump. (kgdb) l *0xffffffff80c3e2f2 0xffffffff80c3e2f2 is in ifunit_ref (/usr/src/sys/net/if.c:2380). 2375 ifunit_ref(const char *name) 2376 { 2377 struct ifnet *ifp; 2378 2379 IFNET_RLOCK_NOSLEEP(); 2380 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 2381 if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0 && 2382 !(ifp->if_flags & IFF_DYING)) 2383 break; 2384 } (kgdb) bt #0 __curthread () at ./machine/pcpu.h:230 #1 doadump (textdump=0) at /usr/src/sys/kern/kern_shutdown.c:361 #2 0xffffffff8040ac9b in db_dump (dummy=, dummy2=, dummy3=, dummy4=) at /usr/src/sys/ddb/db_command.c:574 #3 0xffffffff8040aa69 in db_command (last_cmdp=, cmd_table=, dopager=) at /usr/src/sys/ddb/db_command.c:481 #4 0xffffffff8040a7e4 in db_command_loop () at /usr/src/sys/ddb/db_command.c:534 #5 0xffffffff8040da0f in db_trap (type=, code=) at /usr/src/sys/ddb/db_main.c:250 #6 0xffffffff80b85603 in kdb_trap (type=12, code=0, tf=) at /usr/src/sys/kern/subr_kdb.c:697 #7 0xffffffff80ffe1d0 in trap_fatal (frame=0xfffffe00005c0890, eva=40) at /usr/src/sys/amd64/amd64/trap.c:815 #8 0xffffffff80ffe2e2 in trap_pfault (frame=0xfffffe00005c0890, usermode=) at /usr/src/sys/amd64/amd64/trap.c:664 #9 0xffffffff80ffdad2 in trap (frame=0xfffffe00005c0890) at /usr/src/sys/amd64/amd64/trap.c:413 #10 #11 0xffffffff80c3e2f2 in ifunit_ref (name=0xffffffff8261d174 "FOO") at /usr/src/sys/net/if.c:2380 #12 0xffffffff8261d10e in foo_write (dev=, uio=, ioflag=) at /root/repos/ifunit_ref_test/sys/modules/foo_module/../../dev/foo_module/foo_module.c:50 #13 0xffffffff80a0a8c0 in devfs_write_f (fp=, uio=0xfffffe00005c0a80, cred=0xfffff80003fb0000, flags=0, td=) at /usr/src/sys/fs/devfs/devfs_vnops.c:1784 #14 0xffffffff80baad77 in fo_write (fp=, uio=, active_cred=0x1, flags=, td=) at /usr/src/sys/sys/file.h:309 #15 dofilewrite (td=0xfffff80003fb0000, fd=1, fp=0xfffff8000401c820, auio=0xfffffe00005c0a80, offset=, flags=0) at /usr/src/sys/kern/sys_generic.c:593 #16 0xffffffff80baa968 in kern_writev (td=0xfffff80003fb0000, fd=1, auio=0xfffffe00005c0a80) at /usr/src/sys/kern/sys_generic.c:507 #17 0xffffffff80baa8f6 in sys_write (td=0x0, uap=) at /usr/src/sys/kern/sys_generic.c:421 #18 0xffffffff80fff0cb in syscallenter (td=0xfffff80003fb0000) at /usr/src/sys/amd64/amd64/../../kern/subr_syscall.c:134 #19 amd64_syscall (td=0xfffff80003fb0000, traced=0) at /usr/src/sys/amd64/amd64/trap.c:936 #20 #21 0x0000000800b7baca in ?? () Backtrace stopped: Cannot access memory at address 0x7fffffffe808 Thanks, Stefano.