From owner-p4-projects@FreeBSD.ORG Fri Aug 3 07:44:04 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B6A6C16A419; Fri, 3 Aug 2007 07:44:04 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6639C16A417 for ; Fri, 3 Aug 2007 07:44:04 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 4F9AA13C465 for ; Fri, 3 Aug 2007 07:44:04 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l737i4OA049598 for ; Fri, 3 Aug 2007 07:44:04 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l737i4OS049594 for perforce@freebsd.org; Fri, 3 Aug 2007 07:44:04 GMT (envelope-from rdivacky@FreeBSD.org) Date: Fri, 3 Aug 2007 07:44:04 GMT Message-Id: <200708030744.l737i4OS049594@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 124572 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Aug 2007 07:44:05 -0000 http://perforce.freebsd.org/chv.cgi?CH=124572 Change 124572 by rdivacky@rdivacky_witten on 2007/08/03 07:43:43 IFC Affected files ... .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/amd64/amd64/local_apic.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/amd64/amd64/mp_machdep.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/dev/an/if_an.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/dev/nmdm/nmdm.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/fs/tmpfs/tmpfs.h#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/fs/tmpfs/tmpfs_subr.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/i386/i386/local_apic.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/i386/i386/mp_machdep.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/netgraph/ng_ppp.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/netgraph/ng_ppp.h#2 integrate .. //depot/projects/soc2007/rdivacky/linux_fixes/sys/pci/viapm.c#2 integrate Differences ... ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/amd64/amd64/local_apic.c#2 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.40 2007/05/08 22:01:02 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.41 2007/08/02 21:17:58 peter Exp $"); #include "opt_hwpmc_hooks.h" @@ -1060,10 +1060,6 @@ if (retval != 0) printf("%s: Failed to setup the local APIC: returned %d\n", best_enum->apic_name, retval); -#ifdef SMP - /* Last, setup the cpu topology now that we have probed CPUs */ - mp_topology(); -#endif } SYSINIT(apic_setup_local, SI_SUB_CPU, SI_ORDER_FIRST, apic_setup_local, NULL) ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/amd64/amd64/mp_machdep.c#2 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.286 2007/06/04 23:56:07 jeff Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.287 2007/08/02 21:17:58 peter Exp $"); #include "opt_cpu.h" #include "opt_kstack_pages.h" @@ -186,26 +186,14 @@ mp_topology(void) { struct cpu_group *group; - u_int regs[4]; - int logical_cpus; int apic_id; int groups; int cpu; /* Build the smp_topology map. */ /* Nothing to do if there is no HTT support. */ - if ((cpu_feature & CPUID_HTT) == 0) + if (hyperthreading_cpus <= 1) return; - logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16; - if (logical_cpus <= 1) - return; - /* Nothing to do if reported cores are physical cores. */ - if (strcmp(cpu_vendor, "GenuineIntel") == 0 && cpu_high >= 4) { - cpuid_count(4, 0, regs); - if ((regs[0] & 0x1f) != 0 && - logical_cpus <= ((regs[0] >> 26) & 0x3f) + 1) - return; - } group = &mp_groups[0]; groups = 1; for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) { @@ -215,7 +203,8 @@ * If the current group has members and we're not a logical * cpu, create a new group. */ - if (group->cg_count != 0 && (apic_id % logical_cpus) == 0) { + if (group->cg_count != 0 && + (apic_id % hyperthreading_cpus) == 0) { group++; groups++; } @@ -420,6 +409,9 @@ } set_interrupt_apic_ids(); + + /* Last, setup the cpu topology now that we have probed CPUs */ + mp_topology(); } ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/dev/an/if_an.c#2 (text+ko) ==== @@ -38,7 +38,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/an/if_an.c,v 1.81 2007/06/08 01:21:20 mjacob Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/an/if_an.c,v 1.82 2007/08/02 02:20:19 avatar Exp $"); /* * The Aironet 4500/4800 series cards come in PCMCIA, ISA and PCI form. @@ -1914,7 +1914,9 @@ error = 0; break; case SIOCGAIRONET: + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); + AN_LOCK(sc); if (error != 0) break; #ifdef ANCACHE @@ -1940,12 +1942,16 @@ error = EINVAL; break; } + AN_UNLOCK(sc); error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); + AN_LOCK(sc); break; case SIOCSAIRONET: if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); + AN_LOCK(sc); if (error != 0) break; an_setdef(sc, &sc->areq); @@ -1953,7 +1959,9 @@ case SIOCGPRIVATE_0: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); + AN_LOCK(sc); if (error) goto out; mode = l_ioctl.command; @@ -1969,18 +1977,24 @@ } if (!error) { /* copy out the updated command info */ + AN_UNLOCK(sc); error = copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl)); + AN_LOCK(sc); } break; case SIOCGPRIVATE_1: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; + AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); + AN_LOCK(sc); if (error) goto out; l_ioctl.command = 0; error = AIROMAGIC; + AN_UNLOCK(sc); (void) copyout(&error, l_ioctl.data, sizeof(error)); + AN_LOCK(sc); error = 0; break; case SIOCG80211: @@ -2030,8 +2044,10 @@ ireq->i_len = len; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, len); + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); + AN_LOCK(sc); break; case IEEE80211_IOC_NUMSSIDS: sc->areq.an_len = sizeof(sc->areq); @@ -2105,7 +2121,9 @@ */ bzero(tmpstr, len); ireq->i_len = len; + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, len); + AN_LOCK(sc); break; case IEEE80211_IOC_NUMWEPKEYS: ireq->i_val = 9; /* include home key */ @@ -2183,8 +2201,10 @@ tmpptr = config->an_nodename; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, ireq->i_len); + AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); + AN_LOCK(sc); break; case IEEE80211_IOC_CHANNEL: sc->areq.an_type = AN_RID_STATUS; @@ -2268,9 +2288,11 @@ error = EINVAL; break; } else { + AN_UNLOCK(sc); error = copyin(ireq->i_data, ssids->an_entry[ireq->i_val].an_ssid, ireq->i_len); + AN_LOCK(sc); ssids->an_entry[ireq->i_val].an_len = ireq->i_len; break; @@ -2305,7 +2327,9 @@ error = EINVAL; break; } + AN_UNLOCK(sc); error = copyin(ireq->i_data, tmpstr, 13); + AN_LOCK(sc); if (error != 0) break; /* @@ -2387,8 +2411,10 @@ break; } bzero(config->an_nodename, 16); + AN_UNLOCK(sc); error = copyin(ireq->i_data, config->an_nodename, ireq->i_len); + AN_LOCK(sc); break; case IEEE80211_IOC_CHANNEL: /* @@ -2430,7 +2456,9 @@ an_setdef(sc, &sc->areq); break; default: + AN_UNLOCK(sc); error = ether_ioctl(ifp, command, data); + AN_LOCK(sc); break; } out: @@ -3159,6 +3187,7 @@ { unsigned short rid; struct an_softc *sc; + int error; switch (l_ioctl->command) { case AIROGCAP: @@ -3210,24 +3239,30 @@ l_ioctl->len = sc->areq.an_len - 4; /* just data */ + AN_UNLOCK(sc); /* the data contains the length at first */ if (copyout(&(sc->areq.an_len), l_ioctl->data, sizeof(sc->areq.an_len))) { - return -EFAULT; + error = -EFAULT; + goto lock_exit; } /* Just copy the data back */ if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, l_ioctl->len)) { - return -EFAULT; + error = -EFAULT; + goto lock_exit; } - return 0; + error = 0; +lock_exit: + AN_LOCK(sc); + return (error); } static int writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) { struct an_softc *sc; - int rid, command; + int rid, command, error; sc = ifp->if_softc; rid = 0; @@ -3269,16 +3304,20 @@ an_read_record(sc, (struct an_ltv_gen *)&sc->areq); l_ioctl->len = sc->areq.an_len - 4; /* just data */ + AN_UNLOCK(sc); /* the data contains the length at first */ - if (copyout(&(sc->areq.an_len), l_ioctl->data, - sizeof(sc->areq.an_len))) { + error = copyout(&(sc->areq.an_len), l_ioctl->data, + sizeof(sc->areq.an_len)); + if (error) { + AN_LOCK(sc); return -EFAULT; } /* Just copy the data */ - if (copyout(&(sc->areq.an_val), l_ioctl->data + 2, - l_ioctl->len)) { + error = copyout(&(sc->areq.an_val), l_ioctl->data + 2, + l_ioctl->len); + AN_LOCK(sc); + if (error) return -EFAULT; - } return 0; break; case AIROPWEPKEY: @@ -3304,10 +3343,13 @@ sc->areq.an_type = rid; /* Just copy the data back */ - if (copyin((l_ioctl->data) + 2, &sc->areq.an_val, - l_ioctl->len)) { + AN_UNLOCK(sc); + error = copyin((l_ioctl->data) + 2, &sc->areq.an_val, + l_ioctl->len); + AN_LOCK(sc); + if (error) return -EFAULT; - } + an_cmd(sc, AN_CMD_DISABLE, 0); an_write_record(sc, (struct an_ltv_gen *)&sc->areq); an_cmd(sc, AN_CMD_ENABLE, 0); @@ -3603,7 +3645,9 @@ return ENOBUFS; break; case AIROFLSHGCHR: /* Get char from aux */ + AN_UNLOCK(sc); status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); + AN_LOCK(sc); if (status) return status; z = *(int *)&sc->areq; @@ -3612,7 +3656,9 @@ else return -1; case AIROFLSHPCHR: /* Send char to card. */ + AN_UNLOCK(sc); status = copyin(l_ioctl->data, &sc->areq, l_ioctl->len); + AN_LOCK(sc); if (status) return status; z = *(int *)&sc->areq; @@ -3627,7 +3673,9 @@ l_ioctl->len, FLASH_SIZE); return -EINVAL; } + AN_UNLOCK(sc); status = copyin(l_ioctl->data, sc->an_flash_buffer, l_ioctl->len); + AN_LOCK(sc); if (status) return status; ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/dev/nmdm/nmdm.c#2 (text+ko) ==== @@ -29,7 +29,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/nmdm/nmdm.c,v 1.38 2006/11/06 13:41:54 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/nmdm/nmdm.c,v 1.39 2007/08/01 21:38:11 emax Exp $"); /* * Pseudo-nulmodem driver @@ -401,8 +401,13 @@ static int nmdmclose(struct cdev *dev, int flag, int mode, struct thread *td) { + struct tty *tp = dev->si_tty; + int error; - return (tty_close(dev->si_tty)); + error = ttyld_close(tp, flag); + (void) tty_close(dev->si_tty); + + return (error); } static void ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/fs/tmpfs/tmpfs.h#2 (text+ko) ==== @@ -36,7 +36,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/fs/tmpfs/tmpfs.h,v 1.8 2007/07/11 14:26:27 delphij Exp $ + * $FreeBSD: src/sys/fs/tmpfs/tmpfs.h,v 1.9 2007/08/03 06:24:31 delphij Exp $ */ #ifndef _FS_TMPFS_TMPFS_H_ @@ -256,6 +256,7 @@ #define TMPFS_NODE_LOCK(node) mtx_lock(&(node)->tn_interlock) #define TMPFS_NODE_UNLOCK(node) mtx_unlock(&(node)->tn_interlock) +#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock) #define TMPFS_VNODE_ALLOCATING 1 #define TMPFS_VNODE_WANT 2 ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/fs/tmpfs/tmpfs_subr.c#2 (text+ko) ==== @@ -41,7 +41,7 @@ * Efficient memory file system supporting functions. */ #include -__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_subr.c,v 1.9 2007/07/11 14:26:27 delphij Exp $"); +__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_subr.c,v 1.10 2007/08/03 06:24:31 delphij Exp $"); #include #include @@ -215,9 +215,8 @@ break; case VREG: - if (node->tn_reg.tn_aobj != NULL) { + if (node->tn_reg.tn_aobj != NULL) vm_object_deallocate(node->tn_reg.tn_aobj); - } pages = node->tn_reg.tn_aobj_pages; break; @@ -309,11 +308,8 @@ int error; struct vnode *vp; - vp = NULL; - loop: - if (node->tn_vnode != NULL) { - vp = node->tn_vnode; + if ((vp = node->tn_vnode) != NULL) { error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td); if (error) return error; @@ -337,12 +333,16 @@ TMPFS_NODE_LOCK(node); if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) { node->tn_vpstate |= TMPFS_VNODE_WANT; - TMPFS_NODE_UNLOCK(node); - (void) tsleep((caddr_t) &node->tn_vpstate, 0, "tmpfs_vplock", 0); + error = msleep((caddr_t) &node->tn_vpstate, + TMPFS_NODE_MTX(node), PDROP | PCATCH, + "tmpfs_vplock", 0); + if (error) + return error; + goto loop; - } - - node->tn_vpstate |= TMPFS_VNODE_ALLOCATING; + } else + node->tn_vpstate |= TMPFS_VNODE_ALLOCATING; + TMPFS_NODE_UNLOCK(node); /* Get a new vnode and associate it with our node. */ @@ -367,21 +367,18 @@ case VBLK: /* FALLTHROUGH */ case VCHR: - break; - + /* FALLTHROUGH */ case VDIR: - break; - - case VFIFO: - vp->v_op = &tmpfs_fifoop_entries; - break; - + /* FALLTHROUGH */ case VLNK: /* FALLTHROUGH */ case VREG: /* FALLTHROUGH */ case VSOCK: break; + case VFIFO: + vp->v_op = &tmpfs_fifoop_entries; + break; default: MPASS(0); @@ -391,6 +388,7 @@ error = insmntque(vp, mp); if (error) { node->tn_vnode = NULL; + TMPFS_NODE_LOCK(node); if (node->tn_vpstate & TMPFS_VNODE_WANT) { node->tn_vpstate &= ~TMPFS_VNODE_WANT; TMPFS_NODE_UNLOCK(node); @@ -402,8 +400,8 @@ node->tn_vnode = vp; unlock: + TMPFS_NODE_LOCK(node); MPASS(node->tn_vpstate & TMPFS_VNODE_ALLOCATING); - TMPFS_NODE_LOCK(node); node->tn_vpstate &= ~TMPFS_VNODE_ALLOCATING; if (node->tn_vpstate & TMPFS_VNODE_WANT) { @@ -530,6 +528,7 @@ { struct tmpfs_node *dnode; + ASSERT_VOP_ELOCKED(vp, __func__); dnode = VP_TO_TMPFS_DIR(vp); TAILQ_INSERT_TAIL(&dnode->tn_dir.tn_dirhead, de, td_entries); dnode->tn_size += sizeof(struct tmpfs_dirent); @@ -549,6 +548,7 @@ { struct tmpfs_node *dnode; + ASSERT_VOP_ELOCKED(vp, __func__); dnode = VP_TO_TMPFS_DIR(vp); if (dnode->tn_dir.tn_readdir_lastp == de) { @@ -873,7 +873,7 @@ swap_pager_freespace(uobj, newpages, oldpages - newpages); vm_object_page_remove(uobj, - OFF_TO_IDX(newsize + PAGE_MASK), 0, FALSE); + OFF_TO_IDX(newsize + PAGE_MASK), 0, FALSE); } /* ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/i386/i386/local_apic.c#2 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/i386/i386/local_apic.c,v 1.42 2007/05/08 22:01:03 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/i386/i386/local_apic.c,v 1.43 2007/08/02 21:17:57 peter Exp $"); #include "opt_hwpmc_hooks.h" @@ -1064,10 +1064,6 @@ if (retval != 0) printf("%s: Failed to setup the local APIC: returned %d\n", best_enum->apic_name, retval); -#ifdef SMP - /* Last, setup the cpu topology now that we have probed CPUs */ - mp_topology(); -#endif } SYSINIT(apic_init, SI_SUB_CPU, SI_ORDER_FIRST, apic_init, NULL) ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/i386/i386/mp_machdep.c#2 (text+ko) ==== @@ -24,7 +24,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.280 2007/06/04 23:56:07 jeff Exp $"); +__FBSDID("$FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.281 2007/08/02 21:17:57 peter Exp $"); #include "opt_apic.h" #include "opt_cpu.h" @@ -241,26 +241,14 @@ mp_topology(void) { struct cpu_group *group; - u_int regs[4]; - int logical_cpus; int apic_id; int groups; int cpu; /* Build the smp_topology map. */ /* Nothing to do if there is no HTT support. */ - if ((cpu_feature & CPUID_HTT) == 0) + if (hyperthreading_cpus <= 1) return; - logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16; - if (logical_cpus <= 1) - return; - /* Nothing to do if reported cores are physical cores. */ - if (strcmp(cpu_vendor, "GenuineIntel") == 0 && cpu_high >= 4) { - cpuid_count(4, 0, regs); - if ((regs[0] & 0x1f) != 0 && - logical_cpus <= ((regs[0] >> 26) & 0x3f) + 1) - return; - } group = &mp_groups[0]; groups = 1; for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) { @@ -270,7 +258,8 @@ * If the current group has members and we're not a logical * cpu, create a new group. */ - if (group->cg_count != 0 && (apic_id % logical_cpus) == 0) { + if (group->cg_count != 0 && + (apic_id % hyperthreading_cpus) == 0) { group++; groups++; } @@ -469,6 +458,9 @@ } set_interrupt_apic_ids(); + + /* Last, setup the cpu topology now that we have probed CPUs */ + mp_topology(); } ==== //depot/projects/soc2007/rdivacky/linux_fixes/sys/netgraph/ng_ppp.c#2 (text+ko) ==== @@ -58,7 +58,7 @@ * * Authors: Archie Cobbs , Alexander Motin * - * $FreeBSD: src/sys/netgraph/ng_ppp.c,v 1.67 2007/06/04 13:50:09 mav Exp $ + * $FreeBSD: src/sys/netgraph/ng_ppp.c,v 1.69 2007/08/01 20:49:35 mav Exp $ * $Whistle: ng_ppp.c,v 1.24 1999/11/01 09:24:52 julian Exp $ */ @@ -196,7 +196,7 @@ /* Per-link private information */ struct ng_ppp_link { struct ng_ppp_link_conf conf; /* link configuration */ - struct ng_ppp_link_stat stats; /* link stats */ + struct ng_ppp_link_stat64 stats; /* link stats */ hook_p hook; /* connection to link data */ int32_t seq; /* highest rec'd seq# - MSEQ */ uint32_t latency; /* calculated link latency */ @@ -207,7 +207,7 @@ /* Total per-node private information */ struct ng_ppp_private { struct ng_ppp_bund_conf conf; /* bundle config */ - struct ng_ppp_link_stat bundleStats; /* bundle stats */ + struct ng_ppp_link_stat64 bundleStats; /* bundle stats */ struct ng_ppp_link links[NG_PPP_MAX_LINKS];/* per-link info */ int32_t xseq; /* next out MP seq # */ int32_t mseq; /* min links[i].seq */ @@ -221,6 +221,8 @@ frags; int qlen; /* fraq queue length */ struct callout fragTimer; /* fraq queue check */ + struct mtx rmtx; /* recv mutex */ + struct mtx xmtx; /* xmit mutex */ }; typedef struct ng_ppp_private *priv_p; @@ -299,7 +301,7 @@ static int ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum); static int ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, - uint16_t linkNum); + uint16_t linkNum, int plen); static int ng_ppp_bypass(node_p node, item_p item, uint16_t proto, uint16_t linkNum); @@ -381,6 +383,14 @@ &ng_ppp_stats_type_fields }; +/* Parse type for struct ng_ppp_link_stat64 */ +static const struct ng_parse_struct_field ng_ppp_stats64_type_fields[] + = NG_PPP_STATS64_TYPE_INFO; +static const struct ng_parse_type ng_ppp_stats64_type = { + &ng_parse_struct_type, + &ng_ppp_stats64_type_fields +}; + /* List of commands and how to convert arguments to/from ASCII */ static const struct ng_cmdlist ng_ppp_cmds[] = { { @@ -425,6 +435,20 @@ &ng_parse_int16_type, &ng_ppp_stats_type }, + { + NGM_PPP_COOKIE, + NGM_PPP_GET_LINK_STATS64, + "getstats64", + &ng_parse_int16_type, + &ng_ppp_stats64_type + }, + { + NGM_PPP_COOKIE, + NGM_PPP_GETCLR_LINK_STATS64, + "getclrstats64", + &ng_parse_int16_type, + &ng_ppp_stats64_type + }, { 0 } }; @@ -476,6 +500,9 @@ priv->links[i].seq = MP_NOSEQ; ng_callout_init(&priv->fragTimer); + mtx_init(&priv->rmtx, "ng_ppp_recv", NULL, MTX_DEF); + mtx_init(&priv->xmtx, "ng_ppp_xmit", NULL, MTX_DEF); + /* Done */ return (0); } @@ -515,9 +542,6 @@ !priv->conf.enableMultilink && priv->numActiveLinks >= 1) return (ENODEV); - /* MP recv code is not thread-safe. */ - NG_HOOK_FORCE_WRITER(hook); - } else { /* must be a non-link hook */ int i; @@ -615,10 +639,13 @@ case NGM_PPP_GET_LINK_STATS: case NGM_PPP_CLR_LINK_STATS: case NGM_PPP_GETCLR_LINK_STATS: + case NGM_PPP_GET_LINK_STATS64: + case NGM_PPP_GETCLR_LINK_STATS64: { - struct ng_ppp_link_stat *stats; + struct ng_ppp_link_stat64 *stats; uint16_t linkNum; + /* Process request. */ if (msg->header.arglen != sizeof(uint16_t)) ERROUT(EINVAL); linkNum = *((uint16_t *) msg->data); @@ -627,14 +654,38 @@ ERROUT(EINVAL); stats = (linkNum == NG_PPP_BUNDLE_LINKNUM) ? &priv->bundleStats : &priv->links[linkNum].stats; - if (msg->header.cmd != NGM_PPP_CLR_LINK_STATS) { + + /* Make 64bit reply. */ + if (msg->header.cmd == NGM_PPP_GET_LINK_STATS64 || + msg->header.cmd == NGM_PPP_GETCLR_LINK_STATS64) { + NG_MKRESPONSE(resp, msg, + sizeof(struct ng_ppp_link_stat64), M_NOWAIT); + if (resp == NULL) + ERROUT(ENOMEM); + bcopy(stats, resp->data, sizeof(*stats)); + } else + /* Make 32bit reply. */ + if (msg->header.cmd == NGM_PPP_GET_LINK_STATS || + msg->header.cmd == NGM_PPP_GETCLR_LINK_STATS) { + struct ng_ppp_link_stat *rs; NG_MKRESPONSE(resp, msg, sizeof(struct ng_ppp_link_stat), M_NOWAIT); if (resp == NULL) ERROUT(ENOMEM); - bcopy(stats, resp->data, sizeof(*stats)); + rs = (struct ng_ppp_link_stat *)resp->data; + /* Truncate 64->32 bits. */ + rs->xmitFrames = stats->xmitFrames; + rs->xmitOctets = stats->xmitOctets; + rs->recvFrames = stats->recvFrames; + rs->recvOctets = stats->recvOctets; + rs->badProtos = stats->badProtos; + rs->runts = stats->runts; + rs->dupFragments = stats->dupFragments; + rs->dropFragments = stats->dropFragments; } - if (msg->header.cmd != NGM_PPP_GET_LINK_STATS) + /* Clear stats. */ + if (msg->header.cmd != NGM_PPP_GET_LINK_STATS && + msg->header.cmd != NGM_PPP_GET_LINK_STATS64) bzero(stats, sizeof(*stats)); break; } @@ -684,6 +735,8 @@ /* Take down netgraph node */ ng_ppp_frag_reset(node); + mtx_destroy(&priv->rmtx); + mtx_destroy(&priv->xmtx); bzero(priv, sizeof(*priv)); FREE(priv, M_NETGRAPH_PPP); NG_NODE_SET_PRIVATE(node, NULL); @@ -812,7 +865,7 @@ return (ng_ppp_hcomp_xmit(NG_HOOK_NODE(hook), item, proto)); else return (ng_ppp_link_xmit(NG_HOOK_NODE(hook), item, proto, - linkNum)); + linkNum, 0)); } static int @@ -1177,10 +1230,6 @@ { const priv_p priv = NG_NODE_PRIVATE(node); - /* Stats */ - priv->bundleStats.recvFrames++; - priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len; - if (proto == PROT_CRYPTD) { if (priv->conf.enableDecryption && priv->hooks[HOOK_INDEX_DECRYPT] != NULL) { @@ -1234,7 +1283,7 @@ */ static int -ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum) +ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum, int plen) { const priv_p priv = NG_NODE_PRIVATE(node); struct ng_ppp_link *link; @@ -1244,8 +1293,7 @@ /* Check if link correct. */ if (linkNum >= NG_PPP_MAX_LINKS) { - NG_FREE_ITEM(item); - return (ENETDOWN); + ERROUT(ENETDOWN); } /* Get link pointer (optimization). */ @@ -1253,8 +1301,7 @@ /* Check link status (if real). */ if (link->hook == NULL) { - NG_FREE_ITEM(item); - return (ENETDOWN); + ERROUT(ENETDOWN); } /* Extract mbuf. */ @@ -1264,34 +1311,39 @@ mru = link->conf.mru; if (mru != 0 && m->m_pkthdr.len > mru) { NG_FREE_M(m); - NG_FREE_ITEM(item); - return (EMSGSIZE); + ERROUT(EMSGSIZE); } /* Prepend protocol number, possibly compressed. */ if ((m = ng_ppp_addproto(m, proto, link->conf.enableProtoComp)) == NULL) { - NG_FREE_ITEM(item); - return (ENOBUFS); + ERROUT(ENOBUFS); } /* Prepend address and control field (unless compressed). */ if (proto == PROT_LCP || !link->conf.enableACFComp) { - if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) { - NG_FREE_ITEM(item); - return (ENOBUFS); - } + if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) + ERROUT(ENOBUFS); } /* Deliver frame. */ len = m->m_pkthdr.len; NG_FWD_NEW_DATA(error, item, link->hook, m); - /* Update stats and 'bytes in queue' counter. */ + mtx_lock(&priv->xmtx); + + /* Update link stats. */ + link->stats.xmitFrames++; + link->stats.xmitOctets += len; + + /* Update bundle stats. */ + if (plen > 0) { + priv->bundleStats.xmitFrames++; + priv->bundleStats.xmitOctets += plen; + } + + /* Update 'bytes in queue' counter. */ if (error == 0) { - link->stats.xmitFrames++; - link->stats.xmitOctets += len; - /* bytesInQueue and lastWrite required only for mp_strategy. */ if (priv->conf.enableMultilink && !priv->allLinksEqual && !priv->conf.enableRoundRobin) { @@ -1305,6 +1357,11 @@ link->bytesInQueue = 50 * 1600; } } + mtx_unlock(&priv->xmtx); + return (error); + +done: + NG_FREE_ITEM(item); return (error); } @@ -1321,47 +1378,54 @@ struct ng_ppp_link * const link = &priv->links[linkNum]; uint16_t proto; struct mbuf *m; + int error = 0; KASSERT(linkNum < NG_PPP_MAX_LINKS, ("%s: bogus index 0x%x", __func__, index)); NGI_GET_M(item, m); + mtx_lock(&priv->rmtx); + /* Stats */ link->stats.recvFrames++; link->stats.recvOctets += m->m_pkthdr.len; /* Strip address and control fields, if present. */ - if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { - NG_FREE_ITEM(item); - return (ENOBUFS); - } + if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) + ERROUT(ENOBUFS); if (bcmp(mtod(m, uint8_t *), &ng_ppp_acf, 2) == 0) m_adj(m, 2); - if ((m = ng_ppp_cutproto(m, &proto)) == NULL) { - NG_FREE_ITEM(item); - return (ENOBUFS); - } + /* Get protocol number */ + if ((m = ng_ppp_cutproto(m, &proto)) == NULL) + ERROUT(ENOBUFS); NGI_M(item) = m; /* Put changed m back into item. */ if (!PROT_VALID(proto)) { link->stats.badProtos++; - NG_FREE_ITEM(item); - return (EIO); + ERROUT(EIO); } /* LCP packets must go directly to bypass. */ - if (proto >= 0xB000) + if (proto >= 0xB000) { + mtx_unlock(&priv->rmtx); return (ng_ppp_bypass(node, item, proto, linkNum)); + } - if (!link->conf.enableLink) { - /* Non-LCP packets are denied on a disabled link. */ - NG_FREE_ITEM(item); - return (ENXIO); - } + /* Other packets are denied on a disabled link. */ + if (!link->conf.enableLink) + ERROUT(ENXIO); + + /* Proceed to multilink layer. Mutex will be unlocked inside. */ + error = ng_ppp_mp_recv(node, item, proto, linkNum); + mtx_assert(&priv->rmtx, MA_NOTOWNED); + return (error); - return (ng_ppp_mp_recv(node, item, proto, linkNum)); +done: + mtx_unlock(&priv->rmtx); + NG_FREE_ITEM(item); + return (error); } /* @@ -1429,9 +1493,16 @@ struct ng_ppp_frag *qent; int i, diff, inserted; struct mbuf *m; + int error = 0; - if ((!priv->conf.enableMultilink) || proto != PROT_MP) + if ((!priv->conf.enableMultilink) || proto != PROT_MP) { + /* Stats */ + priv->bundleStats.recvFrames++; + priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len; + + mtx_unlock(&priv->rmtx); return (ng_ppp_crypt_recv(node, item, proto, linkNum)); + } NGI_GET_M(item, m); NG_FREE_ITEM(item); @@ -1443,10 +1514,10 @@ if (m->m_pkthdr.len < 2) { >>> TRUNCATED FOR MAIL (1000 lines) <<<